direct-io.hg

changeset 3571:bc0fbb38cb25

bitkeeper revision 1.1159.1.540 (41f9f0eb0vCo2Pbn_siAkCKZ7XnejA)

Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
author smh22@tempest.cl.cam.ac.uk
date Fri Jan 28 07:59:39 2005 +0000 (2005-01-28)
parents 25f3f22927e9 cd26f113b1b1
children e8d6036117fd
files .rootkeys Makefile linux-2.6.10-xen-sparse/arch/xen/Kconfig linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c tools/examples/Makefile tools/libxc/Makefile tools/libxutil/Makefile tools/misc/Makefile tools/misc/miniterm/Makefile tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/server/netif.py tools/sv/Makefile tools/xentrace/Makefile tools/xfrd/Makefile xen/Makefile xen/arch/x86/domain.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_platform.c xen/include/asm-x86/shadow.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/vmx_vmcs.h xen/include/public/io/ioreq.h
line diff
     1.1 --- a/.rootkeys	Thu Jan 27 17:33:33 2005 +0000
     1.2 +++ b/.rootkeys	Fri Jan 28 07:59:39 2005 +0000
     1.3 @@ -891,6 +891,7 @@ 3ddb79bccYVzXZJyVaxuv5T42Z1Fsw xen/arch/
     1.4  3ddb79bcOftONV9h4QCxXOfiT0h91w xen/arch/x86/traps.c
     1.5  41c0c411tD3C7TpfDMiFTf7BaNd_Dg xen/arch/x86/vmx.c
     1.6  41c0c411ODt8uEmV-yUxpQLpqimE5Q xen/arch/x86/vmx_io.c
     1.7 +41f97ef5139vN42cOYHfX_Ac8WOOjA xen/arch/x86/vmx_platform.c
     1.8  41c0c4128URE0dxcO15JME_MuKBPfg xen/arch/x86/vmx_vmcs.c
     1.9  419cbedeQDg8IrO3izo3o5rQNlo0kQ xen/arch/x86/x86_32/asm-offsets.c
    1.10  3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
     2.1 --- a/Makefile	Thu Jan 27 17:33:33 2005 +0000
     2.2 +++ b/Makefile	Fri Jan 28 07:59:39 2005 +0000
     2.3 @@ -11,7 +11,7 @@ INSTALL_DIR	:= $(INSTALL) -d -m0755
     2.4  INSTALL_DATA	:= $(INSTALL) -m0644
     2.5  INSTALL_PROG	:= $(INSTALL) -m0755
     2.6  
     2.7 -KERNELS ?= *2.6*
     2.8 +KERNELS ?= linux-2.6-xen0 linux-2.6-xenU
     2.9  # linux-2.4-xen0 linux-2.4-xenU netbsd-2.0-xenU
    2.10  # You may use wildcards in the above e.g. KERNELS=*2.4*
    2.11  
    2.12 @@ -30,20 +30,12 @@ endif
    2.13  include buildconfigs/Rules.mk
    2.14  
    2.15  .PHONY:	all dist install xen tools kernels docs world clean mkpatches mrproper
    2.16 -.PHONY:	kbuild kdelete kclean install-tools install-xen install-docs
    2.17 -.PHONY: install-kernels
    2.18 +.PHONY:	kbuild kdelete kclean
    2.19  
    2.20  all: dist
    2.21  
    2.22 -# install everything into the standard system directories
    2.23 -# NB: install explicitly does not check that everything is up to date!
    2.24 -install: DESTDIR=
    2.25 -install: xen checked-tools kernels docs
    2.26 -
    2.27 -# Only check for install req'mts on 'make install', not on 'make dist'.
    2.28 -checked-tools:
    2.29 -	$(MAKE) -C tools/check install
    2.30 -	$(MAKE) -C tools install
    2.31 +# build and install everything into the standard system directories
    2.32 +install: install-xen install-tools install-kernels install-docs
    2.33  
    2.34  # build and install everything into local dist directory
    2.35  dist: xen tools kernels docs
    2.36 @@ -118,9 +110,17 @@ install-iptables:
    2.37  	tar -jxf iptables-1.2.11.tar.bz2
    2.38  	$(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install
    2.39  
    2.40 +install-%: DESTDIR=
    2.41 +install-%: %
    2.42 +	@: # do nothing
    2.43 +
    2.44  help:
    2.45  	@echo 'Installation targets:'
    2.46  	@echo '  install          - build and install everything'
    2.47 +	@echo '  install-xen      - build and install the Xen hypervisor'
    2.48 +	@echo '  install-tools    - build and install the control tools'
    2.49 +	@echo '  install-kernels  - build and install guest kernels'
    2.50 +	@echo '  install-docs     - build and install documentation'
    2.51  	@echo ''
    2.52  	@echo 'Building targets:'
    2.53  	@echo '  dist             - build and install everything into local dist directory'
    2.54 @@ -178,3 +178,4 @@ linux26:
    2.55  
    2.56  netbsd20:
    2.57  	$(MAKE) netbsd-2.0-xenU-build
    2.58 +
     3.1 --- a/linux-2.6.10-xen-sparse/arch/xen/Kconfig	Thu Jan 27 17:33:33 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/Kconfig	Fri Jan 28 07:59:39 2005 +0000
     3.3 @@ -26,7 +26,7 @@ menu "XEN"
     3.4  config XEN_PRIVILEGED_GUEST
     3.5  	bool "Privileged Guest (domain 0)"
     3.6  	default n
     3.7 -        select XEN_PHYSDEV_ACCESS
     3.8 +	select XEN_PHYSDEV_ACCESS
     3.9  	help
    3.10  	  Support for privileged operation (domain 0)
    3.11  
    3.12 @@ -35,18 +35,18 @@ config XEN_PHYSDEV_ACCESS
    3.13  	default XEN_PRIVILEGED_GUEST
    3.14  	help
    3.15  	  Assume access is available to physical hardware devices
    3.16 -          (e.g., hard drives, network cards). This allows you to configure
    3.17 -          such devices and also includes some low-level support that is
    3.18 -          otherwise not compiled into the kernel.
    3.19 +	  (e.g., hard drives, network cards). This allows you to configure
    3.20 +	  such devices and also includes some low-level support that is
    3.21 +	  otherwise not compiled into the kernel.
    3.22  
    3.23  config XEN_BLKDEV_BACKEND
    3.24 -        bool "Block-device backend driver"
    3.25 -      depends on XEN_PHYSDEV_ACCESS
    3.26 -        default y
    3.27 -        help
    3.28 -          The block-device backend driver allows the kernel to export its
    3.29 -          block devices to other guests via a high-performance shared-memory
    3.30 -          interface.
    3.31 +	bool "Block-device backend driver"
    3.32 +	depends on XEN_PHYSDEV_ACCESS
    3.33 +	default y
    3.34 +	help
    3.35 +	  The block-device backend driver allows the kernel to export its
    3.36 +	  block devices to other guests via a high-performance shared-memory
    3.37 +	  interface.
    3.38  
    3.39  config XEN_BLKDEV_TAP_BE
    3.40          bool "Block Tap support for backend driver (DANGEROUS)"
    3.41 @@ -62,87 +62,86 @@ config XEN_BLKDEV_TAP_BE
    3.42            modified to use grant tables.
    3.43  
    3.44  config XEN_NETDEV_BACKEND
    3.45 -        bool "Network-device backend driver"
    3.46 -      depends on XEN_PHYSDEV_ACCESS
    3.47 -        default y
    3.48 -        help
    3.49 -          The network-device backend driver allows the kernel to export its
    3.50 -          network devices to other guests via a high-performance shared-memory
    3.51 -          interface.
    3.52 +	bool "Network-device backend driver"
    3.53 +	depends on XEN_PHYSDEV_ACCESS
    3.54 +	default y
    3.55 +	help
    3.56 +	  The network-device backend driver allows the kernel to export its
    3.57 +	  network devices to other guests via a high-performance shared-memory
    3.58 +	  interface.
    3.59  
    3.60  config XEN_BLKDEV_FRONTEND
    3.61 -        bool "Block-device frontend driver"
    3.62 -        default y
    3.63 -        help
    3.64 -          The block-device frontend driver allows the kernel to access block
    3.65 -          devices mounted within another guest OS. Unless you are building a
    3.66 -          dedicated device-driver domain, or your master control domain
    3.67 -          (domain 0), then you almost certainly want to say Y here.
    3.68 +	bool "Block-device frontend driver"
    3.69 +	default y
    3.70 +	help
    3.71 +	  The block-device frontend driver allows the kernel to access block
    3.72 +	  devices mounted within another guest OS. Unless you are building a
    3.73 +	  dedicated device-driver domain, or your master control domain
    3.74 +	  (domain 0), then you almost certainly want to say Y here.
    3.75  
    3.76  config XEN_NETDEV_FRONTEND
    3.77 -        bool "Network-device frontend driver"
    3.78 -        default y
    3.79 -        help
    3.80 -          The network-device frontend driver allows the kernel to access
    3.81 -          network interfaces within another guest OS. Unless you are building a
    3.82 -          dedicated device-driver domain, or your master control domain
    3.83 -          (domain 0), then you almost certainly want to say Y here.
    3.84 +	bool "Network-device frontend driver"
    3.85 +	default y
    3.86 +	help
    3.87 +	  The network-device frontend driver allows the kernel to access
    3.88 +	  network interfaces within another guest OS. Unless you are building a
    3.89 +	  dedicated device-driver domain, or your master control domain
    3.90 +	  (domain 0), then you almost certainly want to say Y here.
    3.91  
    3.92  config XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER
    3.93 -        bool "Pipelined transmitter (DANGEROUS)"
    3.94 +	bool "Pipelined transmitter (DANGEROUS)"
    3.95  	depends on XEN_NETDEV_FRONTEND
    3.96 -        default n
    3.97 -        help
    3.98 -          The driver will assume that the backend is pipelining packets for
    3.99 -          transmission: whenever packets are pending in the remote backend,
   3.100 -          the driver will not send asynchronous notifications when it queues
   3.101 -          additional packets for transmission.
   3.102 -          If the backend is a dumb domain, such as a transparent Ethernet
   3.103 -          bridge with no local IP interface, it is safe to say Y here to get
   3.104 -          slightly lower network overhead.
   3.105 -          If the backend has a local IP interface; or may be doing smart things
   3.106 -          like reassembling packets to perform firewall filtering; or if you
   3.107 -          are unsure; or if you experience network hangs when this option is
   3.108 -          enabled; then you must say N here.
   3.109 +	default n
   3.110 +	help
   3.111 +	  The driver will assume that the backend is pipelining packets for
   3.112 +	  transmission: whenever packets are pending in the remote backend,
   3.113 +	  the driver will not send asynchronous notifications when it queues
   3.114 +	  additional packets for transmission.
   3.115 +	  If the backend is a dumb domain, such as a transparent Ethernet
   3.116 +	  bridge with no local IP interface, it is safe to say Y here to get
   3.117 +	  slightly lower network overhead.
   3.118 +	  If the backend has a local IP interface; or may be doing smart things
   3.119 +	  like reassembling packets to perform firewall filtering; or if you
   3.120 +	  are unsure; or if you experience network hangs when this option is
   3.121 +	  enabled; then you must say N here.
   3.122  
   3.123  config XEN_BLKDEV_TAP
   3.124 -        bool "Block device tap driver"
   3.125 -        default n
   3.126 -        help
   3.127 -          This driver allows a VM to interact on block device channels
   3.128 -          to other VMs.  Block messages may be passed through or redirected
   3.129 -          to a character device, allowing device prototyping in application
   3.130 -          space.  Odds are that you want to say N here.
   3.131 -
   3.132 +	bool "Block device tap driver"
   3.133 +	default n
   3.134 +	help
   3.135 +	  This driver allows a VM to interact on block device channels
   3.136 +	  to other VMs.  Block messages may be passed through or redirected
   3.137 +	  to a character device, allowing device prototyping in application
   3.138 +	  space.  Odds are that you want to say N here.
   3.139  
   3.140  config XEN_WRITABLE_PAGETABLES
   3.141  	bool
   3.142  	default y
   3.143  
   3.144  config XEN_SCRUB_PAGES
   3.145 -        bool "Scrub memory before freeing it to Xen"
   3.146 -        default y
   3.147 -        help
   3.148 -          Erase memory contents before freeing it back to Xen's global
   3.149 -          pool. This ensures that any secrets contained within that
   3.150 -          memory (e.g., private keys) cannot be found by other guests that
   3.151 -          may be running on the machine. Most people will want to say Y here.
   3.152 -          If security is not a concern then you may increase performance by
   3.153 -          saying N.
   3.154 +	bool "Scrub memory before freeing it to Xen"
   3.155 +	default y
   3.156 +	help
   3.157 +	  Erase memory contents before freeing it back to Xen's global
   3.158 +	  pool. This ensures that any secrets contained within that
   3.159 +	  memory (e.g., private keys) cannot be found by other guests that
   3.160 +	  may be running on the machine. Most people will want to say Y here.
   3.161 +	  If security is not a concern then you may increase performance by
   3.162 +	  saying N.
   3.163  
   3.164  choice
   3.165 -        prompt "Processor Type"
   3.166 -        default X86
   3.167 +	prompt "Processor Type"
   3.168 +	default X86
   3.169  
   3.170  config X86
   3.171 -        bool "X86"
   3.172 -        help
   3.173 -          Choose this option if your computer is a X86 architecture.
   3.174 +	bool "X86"
   3.175 +	help
   3.176 +	  Choose this option if your computer is a X86 architecture.
   3.177  
   3.178  config X86_64
   3.179 -        bool "X86_64"
   3.180 -        help
   3.181 -          Choose this option if your computer is a X86 architecture.
   3.182 +	bool "X86_64"
   3.183 +	help
   3.184 +	  Choose this option if your computer is a X86 architecture.
   3.185  
   3.186  endchoice
   3.187  
     4.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Thu Jan 27 17:33:33 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Fri Jan 28 07:59:39 2005 +0000
     4.3 @@ -1295,8 +1295,7 @@ static int __init netif_init(void)
     4.4  {
     4.5      int err = 0;
     4.6  
     4.7 -    if ( (xen_start_info.flags & SIF_INITDOMAIN) ||
     4.8 -         (xen_start_info.flags & SIF_NET_BE_DOMAIN) )
     4.9 +    if ( xen_start_info.flags & SIF_INITDOMAIN )
    4.10          return 0;
    4.11  
    4.12      IPRINTK("Initialising virtual ethernet driver.\n");
     5.1 --- a/tools/examples/Makefile	Thu Jan 27 17:33:33 2005 +0000
     5.2 +++ b/tools/examples/Makefile	Fri Jan 28 07:59:39 2005 +0000
     5.3 @@ -28,20 +28,23 @@ all:
     5.4  install: all install-initd install-configs install-scripts
     5.5  
     5.6  install-initd:
     5.7 -	$(INSTALL_DIR) $(DESTDIR)/etc/init.d
     5.8 +	[ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
     5.9  	$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
    5.10  	$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
    5.11  
    5.12  install-configs:
    5.13 -	$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)
    5.14 -	$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto
    5.15 +	[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
    5.16 +		$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)
    5.17 +	[ -d $(DESTDIR)$(XEN_CONFIG_DIR)/auto ] || \
    5.18 +		$(INSTALL_DIR) $(DESTDIR)$(XEN_CONFIG_DIR)/auto
    5.19  	for i in $(XEN_CONFIGS); \
    5.20  	    do [ -a $(DESTDIR)$(XEN_CONFIG_DIR)/$$i ] || \
    5.21  	    $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_CONFIG_DIR); \
    5.22  	done
    5.23  
    5.24  install-scripts:
    5.25 -	$(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
    5.26 +	[ -d $(DESTDIR)$(XEN_SCRIPT_DIR) ] || \
    5.27 +		$(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR)
    5.28  	for i in $(XEN_SCRIPTS); \
    5.29  	    do [ -a $(DESTDIR)$(XEN_SCRIPT_DIR)/$$i ] || \
    5.30  	    $(INSTALL_PROG) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
     6.1 --- a/tools/libxc/Makefile	Thu Jan 27 17:33:33 2005 +0000
     6.2 +++ b/tools/libxc/Makefile	Fri Jan 28 07:59:39 2005 +0000
     6.3 @@ -67,8 +67,8 @@ mk-symlinks:
     6.4  	  ln -sf ../../$(LINUX_ROOT)/include/asm-xen/linux-public/*.h . )
     6.5  
     6.6  install: all
     6.7 -	$(INSTALL_DIR) $(DESTDIR)/usr/lib
     6.8 -	$(INSTALL_DIR) $(DESTDIR)/usr/include
     6.9 +	[ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) $(DESTDIR)/usr/lib
    6.10 +	[ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include
    6.11  	$(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib
    6.12  	ln -sf libxc.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/libxc.so.$(MAJOR)
    6.13  	ln -sf libxc.so.$(MAJOR) $(DESTDIR)/usr/lib/libxc.so
     7.1 --- a/tools/libxutil/Makefile	Thu Jan 27 17:33:33 2005 +0000
     7.2 +++ b/tools/libxutil/Makefile	Fri Jan 28 07:59:39 2005 +0000
     7.3 @@ -63,7 +63,7 @@ check-for-zlib:
     7.4  	fi
     7.5  
     7.6  install: all
     7.7 -	$(INSTALL_DIR) -p $(DESTDIR)/usr/lib
     7.8 +	[ -d $(DESTDIR)/usr/lib ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/lib
     7.9  	$(INSTALL_PROG) $(LIB) $(DESTDIR)/usr/lib
    7.10  	ln -sf $(LIB_NAME).so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so.$(MAJOR)
    7.11  	ln -sf $(LIB_NAME).so.$(MAJOR) $(DESTDIR)/usr/lib/$(LIB_NAME).so
     8.1 --- a/tools/misc/Makefile	Thu Jan 27 17:33:33 2005 +0000
     8.2 +++ b/tools/misc/Makefile	Fri Jan 28 07:59:39 2005 +0000
     8.3 @@ -23,8 +23,8 @@ all: $(TARGETS)
     8.4  	$(MAKE) -C miniterm
     8.5  
     8.6  install: all
     8.7 -	$(INSTALL_DIR) $(DESTDIR)/usr/bin
     8.8 -	$(INSTALL_DIR) $(DESTDIR)/usr/sbin
     8.9 +	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
    8.10 +	[ -d $(DESTDIR)/usr/sbin ] || $(INSTALL_DIR) $(DESTDIR)/usr/sbin
    8.11  	$(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)/usr/bin
    8.12  	$(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)/usr/sbin
    8.13  #       No sense in installing miniterm on the Xen box.
     9.1 --- a/tools/misc/miniterm/Makefile	Thu Jan 27 17:33:33 2005 +0000
     9.2 +++ b/tools/misc/miniterm/Makefile	Fri Jan 28 07:59:39 2005 +0000
     9.3 @@ -9,7 +9,7 @@ TARGET = miniterm
     9.4  all: $(TARGET)
     9.5  
     9.6  install: all
     9.7 -	$(INSTALL_DIR) $(DESTDIR)/usr/bin
     9.8 +	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
     9.9  	$(INSTALL_PROG) $(TARGET) $(DESTDIR)/usr/bin
    9.10  
    9.11  clean:
    10.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Jan 27 17:33:33 2005 +0000
    10.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Jan 28 07:59:39 2005 +0000
    10.3 @@ -457,9 +457,9 @@ class XendDomainInfo:
    10.4  
    10.5              self.init_domain()
    10.6              self.configure_console()
    10.7 +            self.configure_backends()
    10.8              self.construct_image()
    10.9              self.configure_restart()
   10.10 -            self.configure_backends()
   10.11              deferred = self.configure()
   10.12              def cberr(err):
   10.13                  self.destroy()
    11.1 --- a/tools/python/xen/xend/server/netif.py	Thu Jan 27 17:33:33 2005 +0000
    11.2 +++ b/tools/python/xen/xend/server/netif.py	Fri Jan 28 07:59:39 2005 +0000
    11.3 @@ -140,7 +140,8 @@ class NetDev(controller.SplitDev):
    11.4          self.ipaddr = self._get_config_ipaddr(config) or []
    11.5          
    11.6          try:
    11.7 -            self.backendDomain = int(sxp.child_value(config, 'backend', '0'))
    11.8 +            xd = get_component('xen.xend.XendDomain')
    11.9 +            self.backendDomain = int(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id)
   11.10          except:
   11.11              raise XendError('invalid backend domain')
   11.12  
   11.13 @@ -161,7 +162,8 @@ class NetDev(controller.SplitDev):
   11.14          bridge = sxp.child_value(config, 'bridge')
   11.15          script = sxp.child_value(config, 'script')
   11.16          ipaddr = self._get_config_ipaddr(config)
   11.17 -        backendDomain = sxp.child_value(config, 'backend', '0')
   11.18 +        xd = get_component('xen.xend.XendDomain')
   11.19 +        backendDomain = str(xd.domain_lookup(sxp.child_value(config, 'backend', '0')).id)
   11.20          if (mac is not None) and (mac != self.mac):
   11.21              raise XendError("cannot change mac")
   11.22          if (backendDomain is not None) and (backendDomain != str(self.backendDomain)):
    12.1 --- a/tools/sv/Makefile	Thu Jan 27 17:33:33 2005 +0000
    12.2 +++ b/tools/sv/Makefile	Fri Jan 28 07:59:39 2005 +0000
    12.3 @@ -17,15 +17,17 @@ IMAGES	+= next.png previous.png finish.p
    12.4  
    12.5  install:
    12.6  	# copy XenSV Main.rpy file
    12.7 -	@$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)
    12.8 +	@[ -d $(DESTDIR)$(sv_insdir) ] || $(INSTALL_DIR) $(DESTDIR)$(sv_insdir)
    12.9  	@$(INSTALL_DATA) Main.rpy $(DESTDIR)$(sv_insdir)
   12.10  
   12.11  	# copy XenSV images
   12.12 -	@$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/images
   12.13 +	@[ -d $(DESTDIR)$(sv_insdir)/images ] || \
   12.14 +		$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/images
   12.15  	@(cd images && $(INSTALL_DATA) $(IMAGES) $(DESTDIR)$(sv_insdir)/images)
   12.16  
   12.17  	# copy XenSV stylesheet
   12.18 -	@$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/inc
   12.19 +	@[ -d $(DESTDIR)$(sv_insdir)/inc ] || \
   12.20 +		$(INSTALL_DIR) $(DESTDIR)$(sv_insdir)/inc
   12.21  	@$(INSTALL_DATA) inc/style.css inc/script.js $(DESTDIR)$(sv_insdir)/inc
   12.22  
   12.23  clean:
    13.1 --- a/tools/xentrace/Makefile	Thu Jan 27 17:33:33 2005 +0000
    13.2 +++ b/tools/xentrace/Makefile	Fri Jan 28 07:59:39 2005 +0000
    13.3 @@ -24,9 +24,11 @@ MAN8     = $(wildcard *.8)
    13.4  all: $(BIN)
    13.5  
    13.6  install: all
    13.7 -	$(INSTALL_DIR) $(DESTDIR)/usr/bin
    13.8 -	$(INSTALL_DIR) $(DESTDIR)/usr/man/man1
    13.9 -	$(INSTALL_DIR) $(DESTDIR)/usr/man/man8
   13.10 +	[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
   13.11 +	[ -d $(DESTDIR)/usr/man/man1 ] || \
   13.12 +		$(INSTALL_DIR) $(DESTDIR)/usr/man/man1
   13.13 +	[ -d $(DESTDIR)/usr/man/man8 ] || \
   13.14 +		$(INSTALL_DIR) $(DESTDIR)/usr/man/man8
   13.15  	$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
   13.16  	$(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/man/man1
   13.17  	$(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/man/man8
    14.1 --- a/tools/xfrd/Makefile	Thu Jan 27 17:33:33 2005 +0000
    14.2 +++ b/tools/xfrd/Makefile	Fri Jan 28 07:59:39 2005 +0000
    14.3 @@ -70,7 +70,8 @@ xfrd: $(XFRD_PROG_OBJ)
    14.4  
    14.5  .PHONY: install
    14.6  install: xfrd
    14.7 -	$(INSTALL_DIR) $(DESTDIR)$(XFRD_INSTALL_DIR)
    14.8 +	[ -d $(DESTDIR)$(XFRD_INSTALL_DIR) ] || \
    14.9 +		$(INSTALL_DIR) $(DESTDIR)$(XFRD_INSTALL_DIR)
   14.10  	$(INSTALL_PROG) xfrd $(DESTDIR)$(XFRD_INSTALL_DIR)
   14.11  
   14.12  .PHONY: libutil
    15.1 --- a/xen/Makefile	Thu Jan 27 17:33:33 2005 +0000
    15.2 +++ b/xen/Makefile	Fri Jan 28 07:59:39 2005 +0000
    15.3 @@ -21,10 +21,11 @@ debug:
    15.4  	objdump -D -S $(TARGET)-syms > $(TARGET).s
    15.5  
    15.6  install: $(TARGET).gz
    15.7 -	$(INSTALL_DIR) $(DESTDIR)/boot
    15.8 +	[ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot
    15.9  	$(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot
   15.10  	$(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot
   15.11 -	$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io
   15.12 +	[ -d $(DESTDIR)/usr/include/xen/io ] || \
   15.13 +		$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io
   15.14  	$(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen
   15.15  	$(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io
   15.16  	$(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen
    16.1 --- a/xen/arch/x86/domain.c	Thu Jan 27 17:33:33 2005 +0000
    16.2 +++ b/xen/arch/x86/domain.c	Fri Jan 28 07:59:39 2005 +0000
    16.3 @@ -308,15 +308,21 @@ void arch_do_createdomain(struct exec_do
    16.4  }
    16.5  
    16.6  #ifdef CONFIG_VMX
    16.7 -void arch_vmx_do_resume(struct exec_domain *d) 
    16.8 +void arch_vmx_do_resume(struct exec_domain *ed) 
    16.9  {
   16.10 -    vmx_do_resume(d);
   16.11 +    u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->thread.arch_vmx.vmcs);
   16.12 +
   16.13 +    load_vmcs(&ed->thread.arch_vmx, vmcs_phys_ptr);
   16.14 +    vmx_do_resume(ed);
   16.15      reset_stack_and_jump(vmx_asm_do_resume);
   16.16  }
   16.17  
   16.18 -void arch_vmx_do_launch(struct exec_domain *d) 
   16.19 +void arch_vmx_do_launch(struct exec_domain *ed) 
   16.20  {
   16.21 -    vmx_do_launch(d);
   16.22 +    u64 vmcs_phys_ptr = (u64) virt_to_phys(ed->thread.arch_vmx.vmcs);
   16.23 +
   16.24 +    load_vmcs(&ed->thread.arch_vmx, vmcs_phys_ptr);
   16.25 +    vmx_do_launch(ed);
   16.26      reset_stack_and_jump(vmx_asm_do_launch);
   16.27  }
   16.28  
   16.29 @@ -332,14 +338,14 @@ static void monitor_mk_pagetable(struct 
   16.30      ASSERT( mpfn_info ); 
   16.31  
   16.32      mpfn = (unsigned long) (mpfn_info - frame_table);
   16.33 -    mpl2e = (l2_pgentry_t *) map_domain_mem(mpfn << PAGE_SHIFT);
   16.34 +    mpl2e = (l2_pgentry_t *) map_domain_mem(mpfn << L1_PAGETABLE_SHIFT);
   16.35      memset(mpl2e, 0, PAGE_SIZE);
   16.36  
   16.37      memcpy(&mpl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
   16.38             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
   16.39             HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
   16.40  
   16.41 -    m->monitor_table = mk_pagetable(mpfn << PAGE_SHIFT);
   16.42 +    m->monitor_table = mk_pagetable(mpfn << L1_PAGETABLE_SHIFT);
   16.43      m->shadow_mode = SHM_full_32;
   16.44  
   16.45      mpl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
   16.46 @@ -349,13 +355,42 @@ static void monitor_mk_pagetable(struct 
   16.47      unmap_domain_mem(mpl2e);
   16.48  }
   16.49  
   16.50 -static int vmx_final_setup_guestos(struct exec_domain *d,
   16.51 +/*
   16.52 + * Free the pages for monitor_table and guest_pl2e_cache
   16.53 + */
   16.54 +static void monitor_rm_pagetable(struct exec_domain *ed)
   16.55 +{
   16.56 +    struct mm_struct *m = &ed->mm;
   16.57 +    l2_pgentry_t *mpl2e;
   16.58 +    unsigned long mpfn;
   16.59 +
   16.60 +    ASSERT( m->monitor_table );
   16.61 +    
   16.62 +    mpl2e = (l2_pgentry_t *) map_domain_mem(pagetable_val(m->monitor_table));
   16.63 +    /*
   16.64 +     * First get the pfn for guest_pl2e_cache by looking at monitor_table
   16.65 +     */
   16.66 +    mpfn = l2_pgentry_val(mpl2e[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT])
   16.67 +        >> PAGE_SHIFT;
   16.68 +
   16.69 +    free_domheap_page(&frame_table[mpfn]);
   16.70 +    unmap_domain_mem(mpl2e);
   16.71 +
   16.72 +    /*
   16.73 +     * Then free monitor_table.
   16.74 +     */
   16.75 +    mpfn = (pagetable_val(m->monitor_table)) >> PAGE_SHIFT;
   16.76 +    free_domheap_page(&frame_table[mpfn]);
   16.77 +
   16.78 +    m->monitor_table = mk_pagetable(0);
   16.79 +}
   16.80 +
   16.81 +static int vmx_final_setup_guestos(struct exec_domain *ed,
   16.82                                     full_execution_context_t *full_context)
   16.83  {
   16.84      int error;
   16.85      execution_context_t *context;
   16.86      struct vmcs_struct *vmcs;
   16.87 -    unsigned long guest_pa;
   16.88  
   16.89      context = &full_context->cpu_ctxt;
   16.90  
   16.91 @@ -367,33 +402,38 @@ static int vmx_final_setup_guestos(struc
   16.92          return -ENOMEM;
   16.93      }
   16.94  
   16.95 -    memset(&d->thread.arch_vmx, 0, sizeof (struct arch_vmx_struct));
   16.96 +    memset(&ed->thread.arch_vmx, 0, sizeof (struct arch_vmx_struct));
   16.97  
   16.98 -    d->thread.arch_vmx.vmcs = vmcs;
   16.99 -    error = construct_vmcs(&d->thread.arch_vmx, context, full_context, VMCS_USE_HOST_ENV);
  16.100 +    ed->thread.arch_vmx.vmcs = vmcs;
  16.101 +    error = construct_vmcs(&ed->thread.arch_vmx, context, full_context, VMCS_USE_HOST_ENV);
  16.102      if (error < 0) {
  16.103          printk("Failed to construct a new VMCS\n");
  16.104          goto out;
  16.105      }
  16.106  
  16.107 -    monitor_mk_pagetable(d);
  16.108 -    guest_pa = pagetable_val(d->mm.pagetable);
  16.109 -    clear_bit(VMX_CPU_STATE_PG_ENABLED, &d->thread.arch_vmx.cpu_state);
  16.110 +    monitor_mk_pagetable(ed);
  16.111 +    ed->thread.schedule_tail = arch_vmx_do_launch;
  16.112 +    clear_bit(VMX_CPU_STATE_PG_ENABLED, &ed->thread.arch_vmx.cpu_state);
  16.113  
  16.114 -    d->thread.arch_vmx.vmx_platform.real_mode_data = 
  16.115 +#if defined (__i386)
  16.116 +    ed->thread.arch_vmx.vmx_platform.real_mode_data = 
  16.117          (unsigned long *) context->esi;
  16.118 +#endif
  16.119  
  16.120 -    memset(&d->domain->shared_info->evtchn_mask[0], 0xff, 
  16.121 -           sizeof(d->domain->shared_info->evtchn_mask));
  16.122 -    clear_bit(IOPACKET_PORT, &d->domain->shared_info->evtchn_mask[0]);
  16.123 -
  16.124 -    d->thread.schedule_tail = arch_vmx_do_launch;
  16.125 +    if (ed == ed->domain->exec_domain[0]) {
  16.126 +        /* 
  16.127 +         * Required to do this once per domain
  16.128 +         */
  16.129 +        memset(&ed->domain->shared_info->evtchn_mask[0], 0xff, 
  16.130 +               sizeof(ed->domain->shared_info->evtchn_mask));
  16.131 +        clear_bit(IOPACKET_PORT, &ed->domain->shared_info->evtchn_mask[0]);
  16.132 +    }
  16.133  
  16.134      return 0;
  16.135  
  16.136  out:
  16.137      free_vmcs(vmcs);
  16.138 -    d->thread.arch_vmx.vmcs = 0;
  16.139 +    ed->thread.arch_vmx.vmcs = 0;
  16.140      return error;
  16.141  }
  16.142  #endif
  16.143 @@ -707,6 +747,35 @@ static void relinquish_list(struct domai
  16.144      spin_unlock_recursive(&d->page_alloc_lock);
  16.145  }
  16.146  
  16.147 +static void vmx_domain_relinquish_memory(struct exec_domain *ed)
  16.148 +{
  16.149 +    struct domain *d = ed->domain;
  16.150 +
  16.151 +    /*
  16.152 +     * Free VMCS
  16.153 +     */
  16.154 +    ASSERT(ed->thread.arch_vmx.vmcs);
  16.155 +    free_vmcs(ed->thread.arch_vmx.vmcs);
  16.156 +    ed->thread.arch_vmx.vmcs = 0;
  16.157 +    
  16.158 +    monitor_rm_pagetable(ed);
  16.159 +
  16.160 +    if (ed == d->exec_domain[0]) {
  16.161 +        int i;
  16.162 +        unsigned long pfn;
  16.163 +
  16.164 +        for (i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++) {
  16.165 +            unsigned long l1e;
  16.166 +            
  16.167 +            l1e = l1_pgentry_val(d->mm_perdomain_pt[i]);
  16.168 +            if (l1e & _PAGE_PRESENT) {
  16.169 +                pfn = l1e >> PAGE_SHIFT;
  16.170 +                free_domheap_page(&frame_table[pfn]);
  16.171 +            }
  16.172 +        }
  16.173 +    }
  16.174 +
  16.175 +}
  16.176  
  16.177  void domain_relinquish_memory(struct domain *d)
  16.178  {
  16.179 @@ -725,6 +794,10 @@ void domain_relinquish_memory(struct dom
  16.180                                             PAGE_SHIFT]);
  16.181      }
  16.182  
  16.183 +    if (VMX_DOMAIN(d->exec_domain[0]))
  16.184 +        for_each_exec_domain(d, ed)
  16.185 +            vmx_domain_relinquish_memory(ed);
  16.186 +
  16.187      /*
  16.188       * Relinquish GDT mappings. No need for explicit unmapping of the LDT as 
  16.189       * it automatically gets squashed when the guest's mappings go away.
    17.1 --- a/xen/arch/x86/vmx.c	Thu Jan 27 17:33:33 2005 +0000
    17.2 +++ b/xen/arch/x86/vmx.c	Fri Jan 28 07:59:39 2005 +0000
    17.3 @@ -41,6 +41,11 @@ unsigned int opt_vmx_debug_level;
    17.4  extern long evtchn_send(int lport);
    17.5  extern long do_block(void);
    17.6  
    17.7 +#define VECTOR_DB   1
    17.8 +#define VECTOR_BP   3
    17.9 +#define VECTOR_GP   13
   17.10 +#define VECTOR_PG   14
   17.11 +
   17.12  int start_vmx()
   17.13  {
   17.14      struct vmcs_struct *vmcs;
   17.15 @@ -102,7 +107,7 @@ static int vmx_do_page_fault(unsigned lo
   17.16  {
   17.17      unsigned long eip, pfn;
   17.18      unsigned int index;
   17.19 -    unsigned long gpde = 0;
   17.20 +    unsigned long gpde = 0, gpte, gpa;
   17.21      int result;
   17.22      struct exec_domain *ed = current;
   17.23      struct mm_struct *m = &ed->mm;
   17.24 @@ -132,6 +137,15 @@ static int vmx_do_page_fault(unsigned lo
   17.25          m->guest_pl2e_cache[index] = 
   17.26              mk_l2_pgentry((pfn << PAGE_SHIFT) | __PAGE_HYPERVISOR);
   17.27      }
   17.28 +    
   17.29 +    if (unlikely(__get_user(gpte, (unsigned long *)
   17.30 +                            &linear_pg_table[va >> PAGE_SHIFT])))
   17.31 +        return 0;
   17.32 +    
   17.33 +    gpa = (gpte & PAGE_MASK) | (va & (PAGE_SIZE - 1));
   17.34 +
   17.35 +    if (mmio_space(gpa))
   17.36 +        handle_mmio(va, gpte, gpa);
   17.37  
   17.38      if ((result = shadow_fault(va, error_code)))
   17.39          return result;
   17.40 @@ -142,19 +156,26 @@ static int vmx_do_page_fault(unsigned lo
   17.41  static void vmx_do_general_protection_fault(struct xen_regs *regs) 
   17.42  {
   17.43      unsigned long eip, error_code;
   17.44 +    unsigned long intr_fields;
   17.45  
   17.46      __vmread(GUEST_EIP, &eip);
   17.47      __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
   17.48  
   17.49 -    VMX_DBG_LOG(DBG_LEVEL_1, 
   17.50 +    VMX_DBG_LOG(DBG_LEVEL_1,
   17.51              "vmx_general_protection_fault: eip = %lx, erro_code = %lx\n",
   17.52              eip, error_code);
   17.53  
   17.54 -    VMX_DBG_LOG(DBG_LEVEL_1, 
   17.55 +    VMX_DBG_LOG(DBG_LEVEL_1,
   17.56              "eax=%x, ebx=%x, ecx=%x, edx=%x, esi=%x, edi=%x\n",
   17.57              regs->eax, regs->ebx, regs->ecx, regs->edx, regs->esi, regs->edi);
   17.58  
   17.59 -    __vmx_bug(regs);
   17.60 +    /* Reflect it back into the guest */
   17.61 +    intr_fields = (INTR_INFO_VALID_MASK | 
   17.62 +		   INTR_TYPE_EXCEPTION |
   17.63 +		   INTR_INFO_DELIEVER_CODE_MASK |
   17.64 +		   VECTOR_GP);
   17.65 +    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, intr_fields);
   17.66 +    __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
   17.67  }
   17.68  
   17.69  static void vmx_vmexit_do_cpuid(unsigned long input, struct xen_regs *regs) 
   17.70 @@ -271,7 +292,7 @@ static inline void guest_pl2e_cache_inva
   17.71      memset(m->guest_pl2e_cache, 0, PAGE_SIZE);
   17.72  }
   17.73  
   17.74 -static inline unsigned long gva_to_gpa(unsigned long gva)
   17.75 +inline unsigned long gva_to_gpa(unsigned long gva)
   17.76  {
   17.77      unsigned long gpde, gpte, pfn, index;
   17.78      struct exec_domain *d = current;
   17.79 @@ -340,6 +361,10 @@ static void vmx_io_instruction(struct xe
   17.80      p->size = (exit_qualification & 7) + 1;
   17.81  
   17.82      if (test_bit(4, &exit_qualification)) {
   17.83 +        unsigned long eflags;
   17.84 +
   17.85 +        __vmread(GUEST_EFLAGS, &eflags);
   17.86 +        p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
   17.87          p->pdata_valid = 1;
   17.88          p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ?
   17.89              regs->esi
   17.90 @@ -725,11 +750,6 @@ asmlinkage void vmx_vmexit_handler(struc
   17.91      switch (exit_reason) {
   17.92      case EXIT_REASON_EXCEPTION_NMI:
   17.93      {
   17.94 -#define VECTOR_DB   1
   17.95 -#define VECTOR_BP   3
   17.96 -#define VECTOR_GP   13
   17.97 -#define VECTOR_PG   14
   17.98 -
   17.99          /*
  17.100           * We don't set the software-interrupt exiting (INT n). 
  17.101           * (1) We can get an exception (e.g. #PG) in the guest, or
  17.102 @@ -773,6 +793,7 @@ asmlinkage void vmx_vmexit_handler(struc
  17.103              __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
  17.104              VMX_DBG_LOG(DBG_LEVEL_VMMU, 
  17.105                      "eax=%x, ebx=%x, ecx=%x, edx=%x, esi=%x, edi=%x\n", regs.eax, regs.ebx, regs.ecx, regs.edx, regs.esi, regs.edi);
  17.106 +            d->thread.arch_vmx.vmx_platform.mpci.inst_decoder_regs = &regs;
  17.107  
  17.108              if (!(error = vmx_do_page_fault(va, error_code))) {
  17.109                  /*
    18.1 --- a/xen/arch/x86/vmx_io.c	Thu Jan 27 17:33:33 2005 +0000
    18.2 +++ b/xen/arch/x86/vmx_io.c	Fri Jan 28 07:59:39 2005 +0000
    18.3 @@ -29,8 +29,143 @@
    18.4  #include <asm/vmx_vmcs.h>
    18.5  #include <xen/event.h>
    18.6  #include <public/io/ioreq.h>
    18.7 +#include <asm/vmx_platform.h>
    18.8  
    18.9  extern long do_block();
   18.10 +  
   18.11 +#if defined (__i386__)
   18.12 +static void load_xen_regs(struct xen_regs *regs)
   18.13 +{ 
   18.14 +    /*
   18.15 +     * Write the guest register value into VMCS
   18.16 +     */
   18.17 +    __vmwrite(GUEST_SS_SELECTOR, regs->ss);
   18.18 +    __vmwrite(GUEST_ESP, regs->esp);
   18.19 +    __vmwrite(GUEST_EFLAGS, regs->eflags);
   18.20 +    __vmwrite(GUEST_CS_SELECTOR, regs->cs);
   18.21 +    __vmwrite(GUEST_EIP, regs->eip);
   18.22 +}
   18.23 +
   18.24 +static void set_reg_value (int size, int index, int seg, struct xen_regs *regs, long value)
   18.25 +{
   18.26 +    switch (size) {
   18.27 +    case BYTE:
   18.28 +        switch (index) {
   18.29 +        case 0:
   18.30 +            regs->eax &= 0xFFFFFF00;
   18.31 +            regs->eax |= (value & 0xFF);
   18.32 +            break;
   18.33 +        case 1:
   18.34 +            regs->ecx &= 0xFFFFFF00;
   18.35 +            regs->ecx |= (value & 0xFF);
   18.36 +            break;
   18.37 +        case 2:
   18.38 +            regs->edx &= 0xFFFFFF00;
   18.39 +            regs->edx |= (value & 0xFF);
   18.40 +            break;
   18.41 +        case 3:
   18.42 +            regs->ebx &= 0xFFFFFF00;
   18.43 +            regs->ebx |= (value & 0xFF);
   18.44 +            break;
   18.45 +        case 4:
   18.46 +            regs->eax &= 0xFFFF00FF;
   18.47 +            regs->eax |= ((value & 0xFF) << 8);
   18.48 +            break;
   18.49 +        case 5:
   18.50 +            regs->ecx &= 0xFFFF00FF;
   18.51 +            regs->ecx |= ((value & 0xFF) << 8);
   18.52 +            break;
   18.53 +        case 6:
   18.54 +            regs->edx &= 0xFFFF00FF;
   18.55 +            regs->edx |= ((value & 0xFF) << 8);
   18.56 +            break;
   18.57 +        case 7:
   18.58 +            regs->ebx &= 0xFFFF00FF;
   18.59 +            regs->ebx |= ((value & 0xFF) << 8);
   18.60 +            break;
   18.61 +        default:
   18.62 +            printk("size:%x, index:%x are invalid!\n", size, index);
   18.63 +            break;
   18.64 +
   18.65 +        }
   18.66 +        break;
   18.67 +    case WORD:
   18.68 +        switch (index) {
   18.69 +        case 0:
   18.70 +            regs->eax &= 0xFFFF0000;
   18.71 +            regs->eax |= (value & 0xFFFF);
   18.72 +            break;
   18.73 +        case 1:
   18.74 +            regs->ecx &= 0xFFFF0000;
   18.75 +            regs->ecx |= (value & 0xFFFF);
   18.76 +            break;
   18.77 +        case 2:
   18.78 +            regs->edx &= 0xFFFF0000;
   18.79 +            regs->edx |= (value & 0xFFFF);
   18.80 +            break;
   18.81 +        case 3:
   18.82 +            regs->ebx &= 0xFFFF0000;
   18.83 +            regs->ebx |= (value & 0xFFFF);
   18.84 +            break;
   18.85 +        case 4:
   18.86 +            regs->esp &= 0xFFFF0000;
   18.87 +            regs->esp |= (value & 0xFFFF);
   18.88 +            break;
   18.89 +
   18.90 +        case 5:
   18.91 +            regs->ebp &= 0xFFFF0000;
   18.92 +            regs->ebp |= (value & 0xFFFF);
   18.93 +            break;
   18.94 +        case 6:
   18.95 +            regs->esi &= 0xFFFF0000;
   18.96 +            regs->esi |= (value & 0xFFFF);
   18.97 +            break;
   18.98 +        case 7:
   18.99 +            regs->edi &= 0xFFFF0000;
  18.100 +            regs->edi |= (value & 0xFFFF);
  18.101 +            break;
  18.102 +        default:
  18.103 +            printk("size:%x, index:%x are invalid!\n", size, index);
  18.104 +            break;
  18.105 +        }
  18.106 +        break;
  18.107 +    case LONG:
  18.108 +        switch (index) {
  18.109 +        case 0:
  18.110 +            regs->eax = value;
  18.111 +            break;
  18.112 +        case 1:
  18.113 +            regs->ecx = value;
  18.114 +            break;
  18.115 +        case 2:
  18.116 +            regs->edx = value;
  18.117 +            break;
  18.118 +        case 3:
  18.119 +            regs->ebx = value;
  18.120 +            break;
  18.121 +        case 4:
  18.122 +            regs->esp = value;
  18.123 +            break;
  18.124 +        case 5:
  18.125 +            regs->ebp = value;
  18.126 +            break;
  18.127 +        case 6:
  18.128 +            regs->esi = value;
  18.129 +            break;
  18.130 +        case 7:
  18.131 +            regs->edi = value;
  18.132 +            break;
  18.133 +        default:
  18.134 +            printk("size:%x, index:%x are invalid!\n", size, index);
  18.135 +            break;
  18.136 +        }
  18.137 +        break;
  18.138 +    default:
  18.139 +        printk("size:%x, index:%x are invalid!\n", size, index);
  18.140 +        break;
  18.141 +    }
  18.142 +}
  18.143 +#endif
  18.144  
  18.145  void vmx_io_assist(struct exec_domain *ed) 
  18.146  {
  18.147 @@ -39,8 +174,12 @@ void vmx_io_assist(struct exec_domain *e
  18.148      struct domain *d = ed->domain;
  18.149      execution_context_t *ec = get_execution_context();
  18.150      unsigned long old_eax;
  18.151 -    unsigned long eflags;
  18.152 -    int dir;
  18.153 +    int sign;
  18.154 +    struct mi_per_cpu_info *mpci_p;
  18.155 +    struct xen_regs *inst_decoder_regs;
  18.156 +
  18.157 +    mpci_p = &ed->thread.arch_vmx.vmx_platform.mpci;
  18.158 +    inst_decoder_regs = mpci_p->inst_decoder_regs;
  18.159  
  18.160      /* clear the pending event */
  18.161      ed->vcpu_info->evtchn_upcall_pending = 0;
  18.162 @@ -68,24 +207,39 @@ void vmx_io_assist(struct exec_domain *e
  18.163          return;
  18.164      }
  18.165  
  18.166 -    __vmread(GUEST_EFLAGS, &eflags);
  18.167 -    dir = (eflags & X86_EFLAGS_DF);
  18.168 +    sign = (p->df) ? -1 : 1;
  18.169 +    if (p->port_mm) {
  18.170 +        if (p->pdata_valid) {
  18.171 +            ec->esi += sign * p->count * p->size;
  18.172 +            ec->edi += sign * p->count * p->size;
  18.173 +        } else {
  18.174 +            if (p->dir == IOREQ_WRITE) {
  18.175 +                return;
  18.176 +            }
  18.177 +            int size = -1, index = -1;
  18.178 +
  18.179 +            size = operand_size(ed->thread.arch_vmx.vmx_platform.mpci.mmio_target);
  18.180 +            index = operand_index(ed->thread.arch_vmx.vmx_platform.mpci.mmio_target);
  18.181 +
  18.182 +            if (ed->thread.arch_vmx.vmx_platform.mpci.mmio_target & WZEROEXTEND) {
  18.183 +                p->u.data = p->u.data & 0xffff;
  18.184 +            }        
  18.185 +            set_reg_value(size, index, 0, (struct xen_regs *)ec, p->u.data);
  18.186 +
  18.187 +        }
  18.188 +        load_xen_regs((struct xen_regs *)ec);
  18.189 +        return;
  18.190 +    }
  18.191  
  18.192      if (p->dir == IOREQ_WRITE) {
  18.193          if (p->pdata_valid) {
  18.194 -            if (!dir)
  18.195 -                ec->esi += p->count * p->size;
  18.196 -            else
  18.197 -                ec->esi -= p->count * p->size;
  18.198 +            ec->esi += sign * p->count * p->size;
  18.199              ec->ecx -= p->count;
  18.200          }
  18.201          return;
  18.202      } else {
  18.203          if (p->pdata_valid) {
  18.204 -            if (!dir)
  18.205 -                ec->edi += p->count * p->size;
  18.206 -            else
  18.207 -                ec->edi -= p->count * p->size;
  18.208 +            ec->edi += sign * p->count * p->size;
  18.209              ec->ecx -= p->count;
  18.210              return;
  18.211          }
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/xen/arch/x86/vmx_platform.c	Fri Jan 28 07:59:39 2005 +0000
    19.3 @@ -0,0 +1,554 @@
    19.4 +/*
    19.5 + * vmx_platform.c: handling x86 platform related MMIO instructions
    19.6 + * Copyright (c) 2004, Intel Corporation.
    19.7 + *
    19.8 + * This program is free software; you can redistribute it and/or modify it
    19.9 + * under the terms and conditions of the GNU General Public License,
   19.10 + * version 2, as published by the Free Software Foundation.
   19.11 + *
   19.12 + * This program is distributed in the hope it will be useful, but WITHOUT
   19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   19.15 + * more details.
   19.16 + *
   19.17 + * You should have received a copy of the GNU General Public License along with
   19.18 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   19.19 + * Place - Suite 330, Boston, MA 02111-1307 USA.
   19.20 + *
   19.21 + */
   19.22 +
   19.23 +#include <xen/config.h>
   19.24 +#include <xen/types.h>
   19.25 +#include <xen/mm.h>
   19.26 +#include <asm/shadow.h>
   19.27 +#include <asm/domain_page.h>
   19.28 +#include <asm/page.h> 
   19.29 +#include <xen/event.h> 
   19.30 +#include <xen/trace.h>
   19.31 +#include <asm/vmx.h>
   19.32 +#include <asm/vmx_platform.h>
   19.33 +#include <public/io/ioreq.h>
   19.34 +
   19.35 +#include <xen/lib.h>
   19.36 +#include <xen/sched.h>
   19.37 +#include <asm/current.h>
   19.38 +
   19.39 +#define DECODE_success  1
   19.40 +#define DECODE_failure  0
   19.41 +
   19.42 +#if defined (__x86_64__)
   19.43 +static void store_xen_regs(struct xen_regs *regs)
   19.44 +{
   19.45 +
   19.46 +}
   19.47 +
   19.48 +static long get_reg_value(int size, int index, int seg, struct xen_regs *regs) 
   19.49 +{
   19.50 +    return 0;
   19.51 +}
   19.52 +#elif defined (__i386__)
   19.53 +static void store_xen_regs(struct xen_regs *regs)
   19.54 +{
   19.55 +    __vmread(GUEST_SS_SELECTOR, &regs->ss);
   19.56 +    __vmread(GUEST_ESP, &regs->esp);
   19.57 +    __vmread(GUEST_EFLAGS, &regs->eflags);
   19.58 +    __vmread(GUEST_CS_SELECTOR, &regs->cs);
   19.59 +    __vmread(GUEST_EIP, &regs->eip);
   19.60 +}
   19.61 +
   19.62 +static long get_reg_value(int size, int index, int seg, struct xen_regs *regs)
   19.63 +{                    
   19.64 +    /*               
   19.65 +     * Reference the db_reg[] table
   19.66 +     */              
   19.67 +    switch (size) {  
   19.68 +    case BYTE: 
   19.69 +        switch (index) { 
   19.70 +        case 0: //%al
   19.71 +            return (char)(regs->eax & 0xFF);
   19.72 +        case 1: //%cl  
   19.73 +            return (char)(regs->ecx & 0xFF);
   19.74 +        case 2: //%dl
   19.75 +            return (char)(regs->edx & 0xFF); 
   19.76 +        case 3: //%bl
   19.77 +            return (char)(regs->ebx & 0xFF);
   19.78 +        case 4: //%ah
   19.79 +            return (char)((regs->eax & 0xFF00) >> 8);
   19.80 +        case 5: //%ch 
   19.81 +            return (char)((regs->ecx & 0xFF00) >> 8);
   19.82 +        case 6: //%dh
   19.83 +            return (char)((regs->edx & 0xFF00) >> 8);
   19.84 +        case 7: //%bh
   19.85 +            return (char)((regs->ebx & 0xFF00) >> 8);
   19.86 +        default:
   19.87 +            printk("(get_reg_value)size case 0 error\n"); 
   19.88 +            return -1; 
   19.89 +        }
   19.90 +    case WORD:
   19.91 +        switch (index) {
   19.92 +        case 0: //%ax
   19.93 +            return (short)(regs->eax & 0xFFFF);
   19.94 +        case 1: //%cx
   19.95 +            return (short)(regs->ecx & 0xFFFF);
   19.96 +        case 2: //%dx
   19.97 +            return (short)(regs->edx & 0xFFFF);
   19.98 +        case 3: //%bx
   19.99 +            return (short)(regs->ebx & 0xFFFF);
  19.100 +        case 4: //%sp
  19.101 +            return (short)(regs->esp & 0xFFFF);
  19.102 +            break;
  19.103 +        case 5: //%bp
  19.104 +            return (short)(regs->ebp & 0xFFFF);
  19.105 +        case 6: //%si
  19.106 +            return (short)(regs->esi & 0xFFFF);
  19.107 +        case 7: //%di
  19.108 +            return (short)(regs->edi & 0xFFFF);
  19.109 +        default:
  19.110 +            printk("(get_reg_value)size case 1 error\n");
  19.111 +            return -1;
  19.112 +        }
  19.113 +    case LONG:
  19.114 +        switch (index) {
  19.115 +        case 0: //%eax
  19.116 +            return regs->eax;
  19.117 +        case 1: //%ecx
  19.118 +            return regs->ecx;
  19.119 +        case 2: //%edx
  19.120 +            return regs->edx;
  19.121 +
  19.122 +        case 3: //%ebx
  19.123 +            return regs->ebx;
  19.124 +        case 4: //%esp
  19.125 +            return regs->esp;
  19.126 +        case 5: //%ebp
  19.127 +            return regs->ebp;
  19.128 +        case 6: //%esi
  19.129 +            return regs->esi;
  19.130 +        case 7: //%edi
  19.131 +            return regs->edi;
  19.132 +        default:
  19.133 +            printk("(get_reg_value)size case 2 error\n");
  19.134 +            return -1;
  19.135 +        }
  19.136 +    default:
  19.137 +        printk("(get_reg_value)size case error\n");
  19.138 +        return -1;
  19.139 +    }
  19.140 +}
  19.141 +#endif
  19.142 +
  19.143 +static inline unsigned char *check_prefix(unsigned char *inst, struct instruction *thread_inst)
  19.144 +{
  19.145 +    while (1) {
  19.146 +        switch (*inst) {
  19.147 +            case 0xf3: //REPZ
  19.148 +            case 0xf2: //REPNZ
  19.149 +            case 0xf0: //LOCK
  19.150 +            case 0x2e: //CS
  19.151 +            case 0x36: //SS
  19.152 +            case 0x3e: //DS
  19.153 +            case 0x26: //ES
  19.154 +            case 0x64: //FS
  19.155 +            case 0x65: //GS
  19.156 +                break;
  19.157 +            case 0x66: //32bit->16bit
  19.158 +                thread_inst->op_size = WORD;
  19.159 +                break;
  19.160 +            case 0x67:
  19.161 +                break;
  19.162 +            default:
  19.163 +                return inst;
  19.164 +        }
  19.165 +        inst++;
  19.166 +    }
  19.167 +}
  19.168 +
  19.169 +static inline unsigned long get_immediate(const unsigned char *inst, int op_size)
  19.170 +{
  19.171 +    int mod, reg, rm;
  19.172 +    unsigned long val = 0;
  19.173 +    int i;
  19.174 +
  19.175 +    mod = (*inst >> 6) & 3;
  19.176 +    reg = (*inst >> 3) & 7;
  19.177 +    rm = *inst & 7;
  19.178 +
  19.179 +    inst++; //skip ModR/M byte
  19.180 +    if (mod != 3 && rm == 4) {
  19.181 +        inst++; //skip SIB byte
  19.182 +    }
  19.183 +
  19.184 +    switch(mod) {
  19.185 +        case 0:
  19.186 +            if (rm == 5) {
  19.187 +                inst = inst + 4; //disp32, skip 4 bytes
  19.188 +            }
  19.189 +            break;
  19.190 +        case 1:
  19.191 +            inst++; //disp8, skip 1 byte
  19.192 +            break;
  19.193 +        case 2:
  19.194 +            inst = inst + 4; //disp32, skip 4 bytes
  19.195 +    }
  19.196 +    for (i = 0; i < op_size; i++) {
  19.197 +        val |= (*inst++ & 0xff) << (8 * i);
  19.198 +    }
  19.199 +    
  19.200 +    return val;
  19.201 +}
  19.202 +
  19.203 +static inline int get_index(const unsigned char *inst)
  19.204 +{
  19.205 +    int mod, reg, rm;
  19.206 +
  19.207 +    mod = (*inst >> 6) & 3;
  19.208 +    reg = (*inst >> 3) & 7;
  19.209 +    rm = *inst & 7;
  19.210 +
  19.211 +    //Only one operand in the instruction is register
  19.212 +    if (mod == 3) {
  19.213 +        return rm;
  19.214 +    } else {
  19.215 +        return reg;
  19.216 +    }
  19.217 +    return 0;
  19.218 +}
  19.219 +
  19.220 +static int vmx_decode(const unsigned char *inst, struct instruction *thread_inst)
  19.221 +{
  19.222 +    int index;
  19.223 +
  19.224 +    switch(*inst) {
  19.225 +        case 0x88:
  19.226 +            /* mov r8 to m8 */
  19.227 +            thread_inst->op_size = BYTE;
  19.228 +            index = get_index((inst + 1));
  19.229 +            thread_inst->operand[0] = mk_operand(BYTE, index, 0, REGISTER);
  19.230 +            break;
  19.231 +        case 0x89:
  19.232 +            /* mov r32/16 to m32/16 */
  19.233 +            index = get_index((inst + 1));
  19.234 +            if (thread_inst->op_size == WORD) {
  19.235 +                thread_inst->operand[0] = mk_operand(WORD, index, 0, REGISTER);
  19.236 +            } else {
  19.237 +                thread_inst->op_size = LONG;
  19.238 +                thread_inst->operand[0] = mk_operand(LONG, index, 0, REGISTER);
  19.239 +            }
  19.240 +            break;
  19.241 +        case 0x8a:
  19.242 +            /* mov m8 to r8 */
  19.243 +            thread_inst->op_size = BYTE;
  19.244 +            index = get_index((inst + 1));
  19.245 +            thread_inst->operand[1] = mk_operand(BYTE, index, 0, REGISTER);
  19.246 +            break;
  19.247 +        case 0x8b:
  19.248 +            /* mov r32/16 to m32/16 */
  19.249 +            index = get_index((inst + 1));
  19.250 +            if (thread_inst->op_size == WORD) {
  19.251 +                thread_inst->operand[1] = mk_operand(WORD, index, 0, REGISTER);
  19.252 +            } else {
  19.253 +                thread_inst->op_size = LONG;
  19.254 +                thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
  19.255 +            }
  19.256 +            break;
  19.257 +        case 0x8c:
  19.258 +        case 0x8e:
  19.259 +            printk("%x, This opcode hasn't been handled yet!", *inst);
  19.260 +            return DECODE_failure;
  19.261 +            /* Not handle it yet. */
  19.262 +
  19.263 +        case 0xa0:
  19.264 +            /* mov byte to al */
  19.265 +            thread_inst->op_size = BYTE;
  19.266 +            thread_inst->operand[1] = mk_operand(BYTE, 0, 0, REGISTER);
  19.267 +            break;
  19.268 +        case 0xa1:
  19.269 +            /* mov word/doubleword to ax/eax */
  19.270 +            if (thread_inst->op_size == WORD) {
  19.271 +                thread_inst->operand[1] = mk_operand(WORD, 0, 0, REGISTER);
  19.272 +            } else {
  19.273 +                thread_inst->op_size = LONG;
  19.274 +                thread_inst->operand[1] = mk_operand(LONG, 0, 0, REGISTER);
  19.275 +            }
  19.276 +            break;
  19.277 +        case 0xa2:
  19.278 +            /* mov al to (seg:offset) */
  19.279 +            thread_inst->op_size = BYTE;
  19.280 +            thread_inst->operand[0] = mk_operand(BYTE, 0, 0, REGISTER);
  19.281 +            break;
  19.282 +        case 0xa3:
  19.283 +            /* mov ax/eax to (seg:offset) */
  19.284 +            if (thread_inst->op_size == WORD) {
  19.285 +                thread_inst->operand[0] = mk_operand(WORD, 0, 0, REGISTER);
  19.286 +            } else {
  19.287 +                thread_inst->op_size = LONG;
  19.288 +                thread_inst->operand[0] = mk_operand(LONG, 0, 0, REGISTER);
  19.289 +            }
  19.290 +            break;
  19.291 +        case 0xa4:
  19.292 +            /* movsb */
  19.293 +            thread_inst->op_size = BYTE;
  19.294 +            strcpy(thread_inst->i_name, "movs");
  19.295 +            
  19.296 +            return DECODE_success;
  19.297 +        case 0xa5:
  19.298 +            /* movsw/movsl */
  19.299 +            if (thread_inst->op_size == WORD) {
  19.300 +            } else {
  19.301 +                thread_inst->op_size = LONG;
  19.302 +            }
  19.303 +            
  19.304 +            strcpy(thread_inst->i_name, "movs");
  19.305 +            
  19.306 +            return DECODE_success;
  19.307 +
  19.308 +        case 0xc6:
  19.309 +            /* mov imm8 to m8 */
  19.310 +            thread_inst->op_size = BYTE;
  19.311 +            thread_inst->operand[0] = mk_operand(BYTE, 0, 0, IMMEDIATE);
  19.312 +            thread_inst->immediate = get_immediate((inst+1), thread_inst->op_size);
  19.313 +            break;
  19.314 +        case 0xc7:
  19.315 +            /* mov imm16/32 to m16/32 */
  19.316 +            if (thread_inst->op_size == WORD) {
  19.317 +                thread_inst->operand[0] = mk_operand(WORD, 0, 0, IMMEDIATE);
  19.318 +            } else {
  19.319 +                thread_inst->op_size = LONG;
  19.320 +                thread_inst->operand[0] = mk_operand(LONG, 0, 0, IMMEDIATE);
  19.321 +            }
  19.322 +            thread_inst->immediate = get_immediate((inst+1), thread_inst->op_size);
  19.323 +            break;
  19.324 +
  19.325 +        case 0x0f:
  19.326 +            break;
  19.327 +        default:
  19.328 +            printk("%x, This opcode hasn't been handled yet!", *inst);
  19.329 +            return DECODE_failure;
  19.330 +    }
  19.331 +    
  19.332 +    strcpy(thread_inst->i_name, "mov");
  19.333 +    if (*inst != 0x0f) {
  19.334 +        return DECODE_success;
  19.335 +    }
  19.336 +
  19.337 +    inst++;
  19.338 +    switch (*inst) {
  19.339 +                    
  19.340 +        /* movz */
  19.341 +        case 0xb7:
  19.342 +            index = get_index((inst + 1));
  19.343 +            thread_inst->operand[1] = mk_operand(LONG, index, 0, REGISTER);
  19.344 +            strcpy(thread_inst->i_name, "movzw");
  19.345 +            
  19.346 +            return DECODE_success;
  19.347 +        default:
  19.348 +            printk("0f %x, This opcode hasn't been handled yet!", *inst);
  19.349 +            return DECODE_failure;
  19.350 +    }
  19.351 +
  19.352 +    /* will never reach here */
  19.353 +    return DECODE_failure;
  19.354 +}
  19.355 +
  19.356 +static int inst_copy_from_guest(char *buf, unsigned long guest_eip, int inst_len)
  19.357 +{
  19.358 +    unsigned long gpte;
  19.359 +    unsigned long mfn;
  19.360 +    unsigned long ma;
  19.361 +    unsigned char * inst_start;
  19.362 +        
  19.363 +    if (inst_len > MAX_INST_LEN || inst_len <= 0) {
  19.364 +        return 0;
  19.365 +    }
  19.366 +
  19.367 +    if ((guest_eip & PAGE_MASK) == ((guest_eip + inst_len) & PAGE_MASK)) {
  19.368 +        if ( unlikely(__get_user(gpte, (unsigned long *)
  19.369 +                                 &linear_pg_table[guest_eip >> PAGE_SHIFT])) )
  19.370 +            {
  19.371 +                printk("inst_copy_from_guest- EXIT: read gpte faulted" );
  19.372 +                return 0;
  19.373 +            }
  19.374 +        mfn = phys_to_machine_mapping[gpte >> PAGE_SHIFT];
  19.375 +        ma = (mfn << PAGE_SHIFT) | (guest_eip & (PAGE_SIZE - 1));
  19.376 +        inst_start = (unsigned char *)map_domain_mem(ma);
  19.377 +                
  19.378 +        strncpy(buf, inst_start, inst_len);
  19.379 +        unmap_domain_mem(inst_start);
  19.380 +    } else {
  19.381 +        // Todo: In two page frames
  19.382 +    }
  19.383 +        
  19.384 +    return inst_len;
  19.385 +}
  19.386 +
  19.387 +static void init_instruction(struct instruction *mmio_inst)
  19.388 +{
  19.389 +    memset(mmio_inst->i_name, '0', I_NAME_LEN);
  19.390 +    mmio_inst->op_size =  0;
  19.391 +    mmio_inst->offset = 0;
  19.392 +    mmio_inst->immediate = 0;
  19.393 +    mmio_inst->seg_sel = 0;
  19.394 +    mmio_inst->op_num = 0;
  19.395 +
  19.396 +    mmio_inst->operand[0] = 0;
  19.397 +    mmio_inst->operand[1] = 0;
  19.398 +    mmio_inst->operand[2] = 0;
  19.399 +        
  19.400 +    mmio_inst->flags = 0;
  19.401 +}
  19.402 +
  19.403 +static int read_from_mmio(struct instruction *inst_p)
  19.404 +{
  19.405 +    // Only for mov instruction now!!!
  19.406 +    if (inst_p->operand[1] & REGISTER)
  19.407 +        return 1;
  19.408 +
  19.409 +    return 0;
  19.410 +}
  19.411 +
  19.412 +// dir:  1 read from mmio
  19.413 +//       0 write to mmio
  19.414 +static void send_mmio_req(unsigned long gpa, 
  19.415 +                   struct instruction *inst_p, long value, int dir, int pvalid)
  19.416 +{
  19.417 +    struct exec_domain *d = current;
  19.418 +    vcpu_iodata_t *vio;
  19.419 +    ioreq_t *p;
  19.420 +    struct mi_per_cpu_info *mpci_p;
  19.421 +    struct xen_regs *inst_decoder_regs;
  19.422 +    extern inline unsigned long gva_to_gpa(unsigned long gva);
  19.423 +    extern long evtchn_send(int lport);
  19.424 +    extern long do_block(void);
  19.425 +
  19.426 +    mpci_p = &current->thread.arch_vmx.vmx_platform.mpci;
  19.427 +    inst_decoder_regs = mpci_p->inst_decoder_regs;
  19.428 +    vio = (vcpu_iodata_t *) d->thread.arch_vmx.vmx_platform.shared_page_va;
  19.429 +        
  19.430 +    if (vio == NULL) {
  19.431 +        printk("bad shared page\n");
  19.432 +        domain_crash(); 
  19.433 +    }
  19.434 +    p = &vio->vp_ioreq;
  19.435 +        
  19.436 +    set_bit(ARCH_VMX_IO_WAIT, &d->thread.arch_vmx.flags);
  19.437 +    p->dir = dir;
  19.438 +    p->pdata_valid = pvalid;
  19.439 +    p->count = 1;
  19.440 +
  19.441 +    p->port_mm = 1;
  19.442 +    p->size = inst_p->op_size;
  19.443 +    p->addr = gpa;
  19.444 +    p->u.data = value;
  19.445 +
  19.446 +    // p->state = STATE_UPSTREAM_SENDING;
  19.447 +    p->state = STATE_IOREQ_READY;
  19.448 +
  19.449 +    // Try to use ins/outs' framework
  19.450 +    if (pvalid) {
  19.451 +        // Handle "movs"
  19.452 +        p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ?
  19.453 +                               inst_decoder_regs->esi
  19.454 +                               : inst_decoder_regs->edi); 
  19.455 +        p->u.pdata = (void *) gva_to_gpa(p->u.data);
  19.456 +        p->count = inst_decoder_regs->ecx;
  19.457 +        inst_decoder_regs->ecx = 0;
  19.458 +        p->df = (inst_decoder_regs->eflags & EF_DF) ? 1 : 0;
  19.459 +    }
  19.460 +
  19.461 +    evtchn_send(IOPACKET_PORT);
  19.462 +    do_block(); 
  19.463 +
  19.464 +}
  19.465 +
  19.466 +void handle_mmio(unsigned long va, unsigned long gpte, unsigned long gpa)
  19.467 +{
  19.468 +    unsigned long eip;
  19.469 +    unsigned long inst_len;
  19.470 +    struct mi_per_cpu_info *mpci_p;
  19.471 +    struct xen_regs *inst_decoder_regs;
  19.472 +    struct instruction mmio_inst;
  19.473 +    unsigned char inst[MAX_INST_LEN];
  19.474 +    int ret;
  19.475 +     
  19.476 +    mpci_p = &current->thread.arch_vmx.vmx_platform.mpci;
  19.477 +    inst_decoder_regs = mpci_p->inst_decoder_regs;
  19.478 +
  19.479 +    __vmread(GUEST_EIP, &eip);
  19.480 +    __vmread(INSTRUCTION_LEN, &inst_len);
  19.481 +
  19.482 +    memset(inst, '0', MAX_INST_LEN);
  19.483 +    ret = inst_copy_from_guest(inst, eip, inst_len);
  19.484 +    if (ret != inst_len) {
  19.485 +        printk("handle_mmio - EXIT: get guest instruction fault\n");
  19.486 +        domain_crash();
  19.487 +    }
  19.488 +
  19.489 +    init_instruction(&mmio_inst);
  19.490 +    
  19.491 +    if (vmx_decode(check_prefix(inst, &mmio_inst), &mmio_inst) == DECODE_failure)
  19.492 +        domain_crash();
  19.493 +
  19.494 +    __vmwrite(GUEST_EIP, eip + inst_len);
  19.495 +    store_xen_regs(inst_decoder_regs);
  19.496 +
  19.497 +    // Only handle "mov" and "movs" instructions!
  19.498 +    if (!strncmp(mmio_inst.i_name, "movzw", 5)) {
  19.499 +        long value = 0;
  19.500 +        int index;
  19.501 +
  19.502 +        if (read_from_mmio(&mmio_inst)) {
  19.503 +            // Send the request and waiting for return value.
  19.504 +            mpci_p->mmio_target = mmio_inst.operand[1] | WZEROEXTEND;
  19.505 +            mmio_inst.op_size = WORD;       
  19.506 +            send_mmio_req(gpa, &mmio_inst, value, 1, 0);
  19.507 +        } else {
  19.508 +            // Write to MMIO
  19.509 +            if (mmio_inst.operand[0] & IMMEDIATE) {
  19.510 +                value = mmio_inst.immediate;
  19.511 +            } else if (mmio_inst.operand[0] & REGISTER) {
  19.512 +                index = operand_index(mmio_inst.operand[0]);
  19.513 +                value = get_reg_value(WORD, index, 0, inst_decoder_regs);
  19.514 +            } else {
  19.515 +                domain_crash();
  19.516 +            }
  19.517 +            mmio_inst.op_size = WORD;
  19.518 +            send_mmio_req(gpa, &mmio_inst, value, 0, 0);
  19.519 +            return; 
  19.520 +        }
  19.521 +    }
  19.522 +
  19.523 +    if (!strncmp(mmio_inst.i_name, "movs", 4)) {
  19.524 +        int tmp_dir;
  19.525 +
  19.526 +        tmp_dir = ((va == inst_decoder_regs->edi) ? IOREQ_WRITE : IOREQ_READ);
  19.527 +        send_mmio_req(gpa, &mmio_inst, 0, tmp_dir, 1);
  19.528 +        return;
  19.529 +    }
  19.530 +
  19.531 +    if (!strncmp(mmio_inst.i_name, "mov", 3)) {
  19.532 +        long value = 0;
  19.533 +        int size, index;
  19.534 +
  19.535 +        if (read_from_mmio(&mmio_inst)) {
  19.536 +            // Send the request and waiting for return value.
  19.537 +            mpci_p->mmio_target = mmio_inst.operand[1];
  19.538 +            send_mmio_req(gpa, &mmio_inst, value, 1, 0);
  19.539 +        } else {
  19.540 +            // Write to MMIO
  19.541 +            if (mmio_inst.operand[0] & IMMEDIATE) {
  19.542 +                value = mmio_inst.immediate;
  19.543 +            } else if (mmio_inst.operand[0] & REGISTER) {
  19.544 +                size = operand_size(mmio_inst.operand[0]);
  19.545 +                index = operand_index(mmio_inst.operand[0]);
  19.546 +                value = get_reg_value(size, index, 0, inst_decoder_regs);
  19.547 +            } else {
  19.548 +                domain_crash();
  19.549 +            }
  19.550 +            send_mmio_req(gpa, &mmio_inst, value, 0, 0);
  19.551 +            return;
  19.552 +        }
  19.553 +        domain_crash();
  19.554 +    }
  19.555 +    domain_crash();
  19.556 +}
  19.557 +
    20.1 --- a/xen/include/asm-x86/shadow.h	Thu Jan 27 17:33:33 2005 +0000
    20.2 +++ b/xen/include/asm-x86/shadow.h	Fri Jan 28 07:59:39 2005 +0000
    20.3 @@ -305,10 +305,15 @@ static inline void l1pte_propagate_from_
    20.4      case SHM_full_32:
    20.5      {
    20.6          unsigned long host_pfn, host_gpte;
    20.7 +        spte = 0;
    20.8 +
    20.9 +        if (mmio_space(gpte & 0xFFFFF000)) {
   20.10 +            *spte_p = spte;
   20.11 +            return;
   20.12 +        }
   20.13          
   20.14          host_pfn = phys_to_machine_mapping[gpte >> PAGE_SHIFT];
   20.15          host_gpte = (host_pfn << PAGE_SHIFT) | (gpte & ~PAGE_MASK);
   20.16 -        spte = 0;
   20.17  
   20.18          if ( (host_gpte & (_PAGE_PRESENT|_PAGE_ACCESSED) ) == 
   20.19               (_PAGE_PRESENT|_PAGE_ACCESSED) )
   20.20 @@ -697,7 +702,7 @@ static inline void __shadow_mk_pagetable
   20.21          SH_VVLOG("__shadow_mk_pagetable(guest_gpfn=%08lx, gpfn=%08lx\n", 
   20.22                   guest_gpfn, gpfn);
   20.23  
   20.24 -        spfn = __shadow_status(mm, gpfn) & PSH_pfn_mask;
   20.25 +        spfn = __shadow_status(mm, guest_gpfn) & PSH_pfn_mask;
   20.26          if ( unlikely(spfn == 0) ) {
   20.27              spfn = shadow_l2_table(mm, gpfn);
   20.28              mm->shadow_table = mk_pagetable(spfn<<PAGE_SHIFT);
    21.1 --- a/xen/include/asm-x86/vmx_platform.h	Thu Jan 27 17:33:33 2005 +0000
    21.2 +++ b/xen/include/asm-x86/vmx_platform.h	Fri Jan 28 07:59:39 2005 +0000
    21.3 @@ -19,6 +19,78 @@
    21.4  #ifndef __ASM_X86_VMX_PLATFORM_H__
    21.5  #define __ASM_X86_VMX_PLATFORM_H__
    21.6  
    21.7 -#include <asm/e820.h>		/* from Linux */
    21.8 +#include <asm/e820.h>       /* from Linux */
    21.9 +
   21.10 +#define MAX_OPERAND_NUM 3
   21.11 +#define I_NAME_LEN  16
   21.12 +
   21.13 +#define mk_operand(size, index, seg, flag) \
   21.14 +    (((size) << 24) | ((index) << 16) | ((seg) << 8) | (flag))
   21.15 +
   21.16 +#define operand_size(operand)   \
   21.17 +      ((operand >> 24) & 0xFF)
   21.18 +
   21.19 +#define operand_index(operand)  \
   21.20 +      ((operand >> 16) & 0xFF)
   21.21 +      //For instruction.operand[].size
   21.22 +#define BYTE    1
   21.23 +#define WORD    2
   21.24 +#define LONG    4
   21.25 +#define QUAD    8
   21.26 +
   21.27 +      //For instruction.operand[].flag
   21.28 +#define REGISTER    0x1
   21.29 +#define MEMORY      0x2
   21.30 +#define IMMEDIATE   0x4
   21.31 +#define WZEROEXTEND 0x8
   21.32 +
   21.33 +      //For instruction.flags
   21.34 +#define REPZ    0x1
   21.35 +#define REPNZ   0x2
   21.36 +
   21.37 +struct instruction {
   21.38 +    __s8    i_name[I_NAME_LEN];  //Instruction's name
   21.39 +    __s16   op_size;    //The operand's bit size, e.g. 16-bit or 32-bit.
   21.40 +
   21.41 +    __u64   offset;     //The effective address
   21.42 +          //offset = Base + (Index * Scale) + Displacement
   21.43 +
   21.44 +    __u64   immediate;
   21.45 +
   21.46 +    __u16   seg_sel;    //Segmentation selector
   21.47 +
   21.48 +    __u32   operand[MAX_OPERAND_NUM];   //The order of operand is from AT&T Assembly
   21.49 +    __s16   op_num; //The operand numbers
   21.50 +
   21.51 +    __u32   flags; //
   21.52 +};
   21.53 +
   21.54 +#define VGA_SPACE_START   0xA0000
   21.55 +#define VGA_SPACE_END     0xC0000
   21.56 +#define MAX_INST_LEN      32
   21.57 +
   21.58 +struct mi_per_cpu_info
   21.59 +{
   21.60 +    unsigned long          mmio_target;
   21.61 +    struct xen_regs        *inst_decoder_regs;
   21.62 +};
   21.63 +
   21.64 +struct virutal_platform_def {
   21.65 +    unsigned long          *real_mode_data; /* E820, etc. */
   21.66 +    unsigned long          shared_page_va;
   21.67 +    struct mi_per_cpu_info mpci;            /* MMIO */
   21.68 +};
   21.69 +
   21.70 +extern int mmio_space(unsigned long);
   21.71 +extern void handle_mmio(unsigned long, unsigned long, unsigned long);
   21.72 +extern int vmx_setup_platform(struct exec_domain *, execution_context_t *);
   21.73 +
   21.74 +extern inline int mmio_space(unsigned long gpa)
   21.75 +{
   21.76 +    if (gpa >= VGA_SPACE_START && gpa < VGA_SPACE_END) {
   21.77 +        return 1;
   21.78 +    }
   21.79 +    return 0;
   21.80 +}
   21.81  
   21.82  #endif
    22.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Thu Jan 27 17:33:33 2005 +0000
    22.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Fri Jan 28 07:59:39 2005 +0000
    22.3 @@ -39,15 +39,7 @@ union vmcs_arbytes {
    22.4      unsigned int bytes;
    22.5  };
    22.6  
    22.7 -struct virutal_platform_def {
    22.8 -    unsigned long   *real_mode_data; /* E820, etc. */
    22.9 -    unsigned long   shared_page_va;
   22.10 -};
   22.11 -
   22.12 -int vmx_setup_platform(struct exec_domain *, execution_context_t *);
   22.13 -
   22.14  #define VMX_CPU_STATE_PG_ENABLED        0       
   22.15 -
   22.16  #define VMCS_SIZE                       0x1000
   22.17  
   22.18  struct vmcs_struct {
   22.19 @@ -62,10 +54,6 @@ struct arch_vmx_struct {
   22.20      unsigned long           cpu_cr3;
   22.21      unsigned long           cpu_state;
   22.22      struct virutal_platform_def     vmx_platform; 
   22.23 -#if 0
   22.24 -    /* open */
   22.25 -    unsigned long *page_list; /* page list for MMIO */
   22.26 -#endif
   22.27  };
   22.28  
   22.29  #define vmx_schedule_tail(next)         \
    23.1 --- a/xen/include/public/io/ioreq.h	Thu Jan 27 17:33:33 2005 +0000
    23.2 +++ b/xen/include/public/io/ioreq.h	Fri Jan 28 07:59:39 2005 +0000
    23.3 @@ -41,10 +41,11 @@ typedef struct {
    23.4          u64     data;           /*  data                        */
    23.5          void    *pdata;         /*  pointer to data             */
    23.6      } u;
    23.7 -    u8      state:5;
    23.8 +    u8      state:4;
    23.9      u8      pdata_valid:1;	/* if 1, use pdata above        */
   23.10      u8      dir:1;		/*  1=read, 0=write             */
   23.11      u8      port_mm:1;		/*  0=portio, 1=mmio            */
   23.12 +    u8      df:1;
   23.13  } ioreq_t;
   23.14  
   23.15  #define MAX_VECTOR    256