ia64/xen-unstable

changeset 3402:0451cbfd268d

bitkeeper revision 1.1159.1.529 (41e2600dbrqI8akb3gtFZjuBqzgSrQ)

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 Mon Jan 10 10:59:25 2005 +0000 (2005-01-10)
parents 553a6dd82045 eceb1ecd0973
children b25937a57863
files .rootkeys Makefile docs/src/user.tex linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c tools/examples/Makefile tools/examples/bochsrc tools/examples/mem-map.sxp tools/examples/xmexample.vmx tools/libxc/Makefile tools/libxc/linux_boot_params.h tools/libxc/xc.h tools/libxc/xc_vmx_build.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/util/memmap.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/create.py xen/arch/x86/Makefile xen/arch/x86/domain.c xen/arch/x86/memory.c xen/arch/x86/mtrr/generic.c xen/arch/x86/shadow.c xen/arch/x86/vmx.c xen/arch/x86/x86_32/entry.S xen/common/physdev.c
line diff
     1.1 --- a/.rootkeys	Sun Jan 02 17:38:14 2005 +0000
     1.2 +++ b/.rootkeys	Mon Jan 10 10:59:25 2005 +0000
     1.3 @@ -320,14 +320,18 @@ 401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/exa
     1.4  401d7e16UgeqroJQTIhwkrDVkoWgZQ tools/examples/README
     1.5  41597996VhTbNuHbuscYSfRb-WR6fA tools/examples/block-enbd
     1.6  41597996GHP2_yVih2UspXh328fgMQ tools/examples/block-file
     1.7 +41dde8af16Hulg1pgW8aOnbbxyrl7w tools/examples/bochsrc
     1.8  405ff55dawQyCHFEnJ067ChPRoXBBA tools/examples/init.d/xend
     1.9  40278d94cIUWl2eRgnwZtr4hTyWT1Q tools/examples/init.d/xendomains
    1.10 +41dde8afTUuvdtFUlOx0ZRusKxyd8w tools/examples/mem-map.sxp
    1.11  40ee75a9xFz6S05sDKu-JCLqyVTkDA tools/examples/network
    1.12  40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge
    1.13  40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp
    1.14 +41dde8af6M2Pm1Rrv_f5jEFC_BIOIA tools/examples/xmexample.vmx
    1.15  41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1
    1.16  40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2
    1.17  3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile
    1.18 +41dde8afKYRKxS4XtLv1KUegGQy_bg tools/libxc/linux_boot_params.h
    1.19  41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h
    1.20  3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec
    1.21  3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h
    1.22 @@ -347,6 +351,7 @@ 41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/lib
    1.23  3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c
    1.24  3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h
    1.25  40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c
    1.26 +41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c
    1.27  40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile
    1.28  40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c
    1.29  40e03332KYz7o1bn2MG_KPbBlyoIMA tools/libxutil/allocate.h
    1.30 @@ -473,6 +478,7 @@ 40d8915cyoVA0hJxiBFNymL7YvDaRg tools/pyt
    1.31  40dfd40aGqGkiopOOgJxSF4iCbHM0Q tools/python/xen/util/__init__.py
    1.32  4055ee4dwy4l0MghZosxoiu6zmhc9Q tools/python/xen/util/console_client.py
    1.33  40c9c468IienauFHQ_xJIcqnPJ8giQ tools/python/xen/util/ip.py
    1.34 +41dde8b0yuJX-S79w4xJKxBQ-Mhp1A tools/python/xen/util/memmap.py
    1.35  4059c6a0pnxhG8hwSOivXybbGOwuXw tools/python/xen/util/tempfile.py
    1.36  40c9c468SNuObE_YWARyS0hzTPSzKg tools/python/xen/xend/Args.py
    1.37  41597996WNvJA-DVCBmc0xU9w_XmoA tools/python/xen/xend/Blkctl.py
     2.1 --- a/Makefile	Sun Jan 02 17:38:14 2005 +0000
     2.2 +++ b/Makefile	Mon Jan 10 10:59:25 2005 +0000
     2.3 @@ -118,6 +118,43 @@ install-iptables:
     2.4  	( cd iptables-* ; \
     2.5  	  make PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install)
     2.6  
     2.7 +help:
     2.8 +	@echo 'Installation targets:'
     2.9 +	@echo '  install          - install everything'
    2.10 +	@echo '  install-xen      - install the Xen hypervisor'
    2.11 +	@echo '  install-tools    - install the control tools'
    2.12 +	@echo '  install-kernels  - install guest kernels'
    2.13 +	@echo '  install-docs     - install documentation'
    2.14 +	@echo ''
    2.15 +	@echo 'Building targets:'
    2.16 +	@echo '  dist             - build everything and place in dist/'
    2.17 +	@echo '  world            - clean everything, delete guest kernel build'
    2.18 +	@echo '                     trees then make dist'
    2.19 +	@echo '  xen              - build Xen hypervisor and place in dist/'
    2.20 +	@echo '  tools            - build tools and place in dist/'
    2.21 +	@echo '  kernels          - build guest kernels and place in dist/'
    2.22 +	@echo '  kbuild           - synonym for make kernels'
    2.23 +	@echo '  docs             - build docs and place in dist/'
    2.24 +	@echo ''
    2.25 +	@echo 'Cleaning targets:'
    2.26 +	@echo '  clean            - clean the Xen, tools and docs (but not'
    2.27 +	@echo '                     guest kernel) trees'
    2.28 +	@echo '  mrproper         - clean plus delete kernel tarballs and kernel'
    2.29 +	@echo '                     build trees'
    2.30 +	@echo '  kdelete          - delete guest kernel build trees'
    2.31 +	@echo '  kclean           - clean guest kernel build trees'
    2.32 +	@echo ''
    2.33 +	@echo 'Dependency installation targets:'
    2.34 +	@echo '  install-twisted  - install the Twisted Matrix Framework'
    2.35 +	@echo '  install-logging  - install the Python Logging package'
    2.36 +	@echo '  install-iptables - install iptables tools'
    2.37 +	@echo ''
    2.38 +	@echo 'Miscellaneous targets:'
    2.39 +	@echo '  mkpatches        - make patches against vanilla kernels from'
    2.40 +	@echo '                     sparse trees'
    2.41 +	@echo '  uninstall        - attempt to remove installed Xen tools (use'
    2.42 +	@echo '                     with extreme care!)'
    2.43 +
    2.44  # Use this target with extreme care!
    2.45  uninstall:
    2.46  	cp -a /etc/xen /etc/xen.old && rm -rf /etc/xen 
     3.1 --- a/docs/src/user.tex	Sun Jan 02 17:38:14 2005 +0000
     3.2 +++ b/docs/src/user.tex	Mon Jan 10 10:59:25 2005 +0000
     3.3 @@ -981,6 +981,7 @@ chapter covers some of the possibilities
     3.4  
     3.5  
     3.6  \section{Exporting Physical Devices as VBDs} 
     3.7 +\label{s:exporting-physical-devices-as-vbds}
     3.8  
     3.9  One of the simplest configurations is to directly export 
    3.10  individual partitions from domain 0 to other domains. To 
    3.11 @@ -1074,8 +1075,23 @@ In the configuration file set:
    3.12  As the virtual machine writes to its `disk', the sparse file will be
    3.13  filled in and consume more space up to the original 2GB.
    3.14  
    3.15 +{\bf Note that file-backed VBDs may not be appropriate for backing
    3.16 +I/O-intensive domains.}  File-backed VBDs are known to experience
    3.17 +substantial slowdowns under heavy I/O workloads, due to the I/O handling
    3.18 +by the loopback block device used to support file-backed VBDs in dom0.
    3.19 +Better I/O performance can be achieved by using either LVM-backed VBDs
    3.20 +(Section~\ref{s:using-lvm-backed-vbds}) or physical devices as VBDs
    3.21 +(Section~\ref{s:exporting-physical-devices-as-vbds}).
    3.22 +
    3.23 +Linux supports a maximum of eight file-backed VBDs across all domains by
    3.24 +default.  This limit can be statically increased by using the {\em
    3.25 +max\_loop} module parameter if CONFIG\_BLK\_DEV\_LOOP is compiled as a
    3.26 +module in the dom0 kernel, or by using the {\em max\_loop=n} boot option
    3.27 +if CONFIG\_BLK\_DEV\_LOOP is compiled directly into the dom0 kernel.
    3.28 +
    3.29  
    3.30  \section{Using LVM-backed VBDs}
    3.31 +\label{s:using-lvm-backed-vbds}
    3.32  
    3.33  A particularly appealing solution is to use LVM volumes 
    3.34  as backing for domain file-systems since this allows dynamic
     4.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S	Sun Jan 02 17:38:14 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/entry.S	Mon Jan 10 10:59:25 2005 +0000
     4.3 @@ -91,7 +91,8 @@ VM_MASK		= 0x00020000
     4.4  				shl  $sizeof_vcpu_shift,reg		; \
     4.5  				addl HYPERVISOR_shared_info,reg
     4.6  #define XEN_UNLOCK_VCPU_INFO_SMP(reg) preempt_enable(%ebp)
     4.7 -#define XEN_UNLOCK_VCPU_INFO_SMP_fixup .byte 0x00,0x00,0x00
     4.8 +#define XEN_UNLOCK_VCPU_INFO_SMP_fixup .byte 0xff,0xff,0xff
     4.9 +#define Ux00 0xff
    4.10  #define XEN_BLOCK_EVENTS(reg)	XEN_LOCK_VCPU_INFO_SMP(reg)		; \
    4.11  				movb $1,evtchn_upcall_mask(reg)		; \
    4.12      				XEN_UNLOCK_VCPU_INFO_SMP(reg)
    4.13 @@ -108,6 +109,7 @@ VM_MASK		= 0x00020000
    4.14  #define XEN_LOCK_VCPU_INFO_SMP(reg)
    4.15  #define XEN_UNLOCK_VCPU_INFO_SMP(reg)
    4.16  #define XEN_UNLOCK_VCPU_INFO_SMP_fixup
    4.17 +#define Ux00 0x00
    4.18  #define XEN_BLOCK_EVENTS(reg)	movb $1,evtchn_upcall_mask(reg)
    4.19  #define XEN_UNBLOCK_EVENTS(reg)	movb $0,evtchn_upcall_mask(reg)
    4.20  #define XEN_SAVE_UPCALL_MASK(reg,tmp,off) \
    4.21 @@ -522,24 +524,32 @@ ecrit:  /**** END OF CRITICAL REGION ***
    4.22  critical_region_fixup:
    4.23  	addl $critical_fixup_table-scrit,%eax
    4.24  	movzbl (%eax),%eax		# %eax contains num bytes popped
    4.25 -	mov  %esp,%esi
    4.26 +#ifdef CONFIG_SMP
    4.27 +	cmpb $0xff,%al
    4.28 +	jne  15f
    4.29 +	add  $1,%al
    4.30 +	GET_THREAD_INFO(%ebp)
    4.31 +	XEN_UNLOCK_VCPU_INFO_SMP(%esi)
    4.32 +15:
    4.33 +#endif
    4.34 +    	mov  %esp,%esi
    4.35  	add  %eax,%esi			# %esi points at end of src region
    4.36  	mov  %esp,%edi
    4.37  	add  $0x34,%edi			# %edi points at end of dst region
    4.38  	mov  %eax,%ecx
    4.39  	shr  $2,%ecx			# convert words to bytes
    4.40 -	je   16f			# skip loop if nothing to copy
    4.41 -15:	subl $4,%esi			# pre-decrementing copy loop
    4.42 +	je   17f			# skip loop if nothing to copy
    4.43 +16:	subl $4,%esi			# pre-decrementing copy loop
    4.44  	subl $4,%edi
    4.45  	movl (%esi),%eax
    4.46  	movl %eax,(%edi)
    4.47 -	loop 15b
    4.48 -16:	movl %edi,%esp			# final %edi is top of merged stack
    4.49 +	loop 16b
    4.50 +17:	movl %edi,%esp			# final %edi is top of merged stack
    4.51  	jmp  11b
    4.52  
    4.53  critical_fixup_table:
    4.54 -	.byte 0x00,0x00,0x00		# testb $0xff,(%esi) = XEN_TEST_PENDING
    4.55 -	.byte 0x00,0x00			# jnz  14f
    4.56 +	.byte Ux00,Ux00,Ux00		# testb $0xff,(%esi) = XEN_TEST_PENDING
    4.57 +	.byte Ux00,Ux00			# jnz  14f
    4.58  	XEN_UNLOCK_VCPU_INFO_SMP_fixup
    4.59  	.byte 0x00			# pop  %ebx
    4.60  	.byte 0x04			# pop  %ecx
    4.61 @@ -552,7 +562,7 @@ critical_fixup_table:
    4.62  	.byte 0x20			# pop  %es
    4.63  	.byte 0x24,0x24,0x24		# add  $4,%esp
    4.64  	.byte 0x28			# iret
    4.65 -	.byte 0x00,0x00,0x00,0x00	# movb $1,1(%esi)
    4.66 +	.byte Ux00,Ux00,Ux00,Ux00	# movb $1,1(%esi)
    4.67  	XEN_UNLOCK_VCPU_INFO_SMP_fixup
    4.68  	.byte 0x00,0x00			# jmp  11b
    4.69  
     5.1 --- a/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Sun Jan 02 17:38:14 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/i386/kernel/process.c	Mon Jan 10 10:59:25 2005 +0000
     5.3 @@ -93,10 +93,11 @@ EXPORT_SYMBOL(enable_hlt);
     5.4  extern int set_timeout_timer(void);
     5.5  void xen_idle(void)
     5.6  {
     5.7 -	int cpu = smp_processor_id();
     5.8 +	int cpu;
     5.9  
    5.10  	local_irq_disable();
    5.11  
    5.12 +	cpu = smp_processor_id();
    5.13  	if (rcu_pending(cpu))
    5.14  		rcu_check_callbacks(cpu, 0);
    5.15  
     6.1 --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c	Sun Jan 02 17:38:14 2005 +0000
     6.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/reboot.c	Mon Jan 10 10:59:25 2005 +0000
     6.3 @@ -217,7 +217,11 @@ static void __shutdown_handler(void *unu
     6.4  static void __sysrq_handler(void *unused)
     6.5  {
     6.6  #ifdef CONFIG_MAGIC_SYSRQ
     6.7 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
     6.8      handle_sysrq(pending_sysrq, NULL, NULL);
     6.9 +#else
    6.10 +    handle_sysrq(pending_sysrq, NULL, NULL, NULL);
    6.11 +#endif
    6.12  #endif
    6.13      pending_sysrq = -1;
    6.14  }
     7.1 --- a/tools/examples/Makefile	Sun Jan 02 17:38:14 2005 +0000
     7.2 +++ b/tools/examples/Makefile	Mon Jan 10 10:59:25 2005 +0000
     7.3 @@ -8,6 +8,9 @@ XEN_CONFIG_DIR = /etc/xen
     7.4  XEN_CONFIGS = xend-config.sxp
     7.5  XEN_CONFIGS += xmexample1 
     7.6  XEN_CONFIGS += xmexample2
     7.7 +XEN_CONFIGS += xmexample.vmx
     7.8 +XEN_CONFIGS += mem-map.sxp
     7.9 +XEN_CONFIGS += bochsrc
    7.10  
    7.11  # Xen script dir and scripts to go there.
    7.12  XEN_SCRIPT_DIR = /etc/xen/scripts
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/examples/bochsrc	Mon Jan 10 10:59:25 2005 +0000
     8.3 @@ -0,0 +1,19 @@
     8.4 +#megs: 32
     8.5 +#romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000
     8.6 +#vgaromimage: $BXSHARE/VGABIOS-lgpl-latest
     8.7 +floppya: 1_44=a.img, status=inserted
     8.8 +floppyb: 1_44=b.img, status=inserted
     8.9 +#ata0-master: type=disk, path=minibootable.img, cylinders=900, heads=15, spt=17
    8.10 +# if you don't use absolute paths below, bochs looks under the cwd of xend, 
    8.11 +# which is usually "/"
    8.12 +ata0-master: type=disk, path=/tmp/min-fc2-i386.img, cylinders=800, heads=4, spt=32
    8.13 +boot: c
    8.14 +
    8.15 +log: /tmp/bochsout.txt
    8.16 +#debug: action=report
    8.17 +info: action=report
    8.18 +error: action=report
    8.19 +panic: action=ask
    8.20 +
    8.21 +mouse: enabled=0
    8.22 +ips: 1500000
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/examples/mem-map.sxp	Mon Jan 10 10:59:25 2005 +0000
     9.3 @@ -0,0 +1,10 @@
     9.4 +(memmap
     9.5 + (0000000000000000  000000000009f800 "AddressRangeMemory"   WB)
     9.6 + (000000000009f800  00000000000a0000 "AddressRangeReserved" UC)
     9.7 + (00000000000a0000  00000000000bffff "AddressRangeIO"       UC)
     9.8 + (00000000000f0000  0000000000100000 "AddressRangeReserved" UC)
     9.9 + (0000000000100000  0000000008000000 "AddressRangeMemory"   WB)
    9.10 + (0000000007fff000  0000000008000000 "AddressRangeShared"   WB)
    9.11 + (0000000008000000  0000000008003000 "AddressRangeNVS"      UC)
    9.12 + (0000000008003000  000000000800d000 "AddressRangeACPI"     WB)
    9.13 + (00000000fec00000  0000000100000000 "AddressRangeIO"       UC))
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/examples/xmexample.vmx	Mon Jan 10 10:59:25 2005 +0000
    10.3 @@ -0,0 +1,93 @@
    10.4 +#  -*- mode: python; -*-
    10.5 +#============================================================================
    10.6 +# Python configuration setup for 'xm create'.
    10.7 +# This script sets the parameters used when a domain is created using 'xm create'.
    10.8 +# You use a separate script for each domain you want to create, or 
    10.9 +# you can set the parameters for the domain on the xm command line.
   10.10 +#============================================================================
   10.11 +
   10.12 +#----------------------------------------------------------------------------
   10.13 +# Kernel image file.
   10.14 +kernel = "/boot/vmlinuz-rhel3-static"
   10.15 +
   10.16 +# Optional ramdisk.
   10.17 +#ramdisk = "/boot/initrd.gz"
   10.18 +
   10.19 +# The domain build function. Default is 'linux'.
   10.20 +builder='vmx'
   10.21 +#builder='linux'
   10.22 +#builder='netbsd'
   10.23 +
   10.24 +# Initial memory allocation (in megabytes) for the new domain.
   10.25 +memory = 128
   10.26 +
   10.27 +# A name for your domain. All domains must have different names.
   10.28 +name = "ExampleVMXDomain"
   10.29 +
   10.30 +# Which CPU to start domain on? 
   10.31 +#cpu = -1   # leave to Xen to pick
   10.32 +
   10.33 +#----------------------------------------------------------------------------
   10.34 +# Define network interfaces.
   10.35 +
   10.36 +# Number of network interfaces. Default is 1.
   10.37 +#nics=1
   10.38 +nics=0
   10.39 +
   10.40 +# Optionally define mac and/or bridge for the network interfaces.
   10.41 +# Random MACs are assigned if not given.
   10.42 +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
   10.43 +
   10.44 +#----------------------------------------------------------------------------
   10.45 +# Define the disk devices you want the domain to have access to, and
   10.46 +# what you want them accessible as.
   10.47 +# Each disk entry is of the form phy:UNAME,DEV,MODE
   10.48 +# where UNAME is the device, DEV is the device name the domain will see,
   10.49 +# and MODE is r for read-only, w for read-write.
   10.50 +
   10.51 +#disk = [ 'phy:hda1,hda1,r' ]
   10.52 +
   10.53 +#----------------------------------------------------------------------------
   10.54 +# Set the kernel command line for the new domain.
   10.55 +# You only need to define the IP parameters and hostname if the domain's
   10.56 +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
   10.57 +# You can use 'extra' to set the runlevel and custom environment
   10.58 +# variables used by custom rc scripts (e.g. VMID=, usr= ).
   10.59 +
   10.60 +# Set if you want dhcp to allocate the IP address.
   10.61 +#dhcp="dhcp"
   10.62 +# Set netmask.
   10.63 +#netmask=
   10.64 +# Set default gateway.
   10.65 +#gateway=
   10.66 +# Set the hostname.
   10.67 +#hostname= "vm%d" % vmid
   10.68 +
   10.69 +# Set root device.
   10.70 +#root = "/dev/ram0"
   10.71 +root = "/dev/hda1 ro"
   10.72 +
   10.73 +# Root device for nfs.
   10.74 +#root = "/dev/nfs"
   10.75 +# The nfs server.
   10.76 +#nfs_server = '169.254.1.0'  
   10.77 +# Root directory on the nfs server.
   10.78 +#nfs_root   = '/full/path/to/root/directory'
   10.79 +
   10.80 +# Sets runlevel 4.
   10.81 +extra = "1"
   10.82 +
   10.83 +#----------------------------------------------------------------------------
   10.84 +# Set according to whether you want the domain restarted when it exits.
   10.85 +# The default is 'onreboot', which restarts the domain when it shuts down
   10.86 +# with exit code reboot.
   10.87 +# Other values are 'always', and 'never'.
   10.88 +
   10.89 +#restart = 'onreboot'
   10.90 +
   10.91 +#============================================================================
   10.92 +
   10.93 +# New stuff
   10.94 +memmap = '/etc/xen/mem-map.sxp'
   10.95 +device_model = '/usr/sbin/device-model'
   10.96 +device_config = '/etc/xen/bochsrc'
    11.1 --- a/tools/libxc/Makefile	Sun Jan 02 17:38:14 2005 +0000
    11.2 +++ b/tools/libxc/Makefile	Mon Jan 10 10:59:25 2005 +0000
    11.3 @@ -25,6 +25,7 @@ SRCS     += xc_misc.c
    11.4  SRCS     += xc_physdev.c
    11.5  SRCS     += xc_private.c
    11.6  SRCS     += xc_rrobin.c
    11.7 +SRCS     += xc_vmx_build.c
    11.8  
    11.9  CFLAGS   += -Wall
   11.10  CFLAGS   += -Werror
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/libxc/linux_boot_params.h	Mon Jan 10 10:59:25 2005 +0000
    12.3 @@ -0,0 +1,163 @@
    12.4 +#ifndef __LINUX_BOOT_PARAMS_H__
    12.5 +#define __LINUX_BOOT_PARAMS_H__
    12.6 +
    12.7 +#include <asm/types.h>
    12.8 +
    12.9 +#define E820MAX	32
   12.10 +
   12.11 +struct mem_map {
   12.12 +    int nr_map;
   12.13 +    struct entry {
   12.14 +        unsigned long long addr;	/* start of memory segment */
   12.15 +        unsigned long long size;	/* size of memory segment */
   12.16 +        unsigned long type;		/* type of memory segment */
   12.17 +#define E820_RAM        1
   12.18 +#define E820_RESERVED   2
   12.19 +#define E820_ACPI       3 /* usable as RAM once ACPI tables have been read */
   12.20 +#define E820_NVS        4
   12.21 +
   12.22 +        unsigned long caching_attr;    /* used by hypervisor */
   12.23 +#define MEMMAP_UC	0
   12.24 +#define MEMMAP_WC	1
   12.25 +#define MEMMAP_WT	4
   12.26 +#define MEMMAP_WP	5
   12.27 +#define MEMMAP_WB	6
   12.28 +
   12.29 +    }map[E820MAX];
   12.30 +};
   12.31 +
   12.32 +struct e820entry {
   12.33 +	unsigned long long addr;	/* start of memory segment */
   12.34 +	unsigned long long size;	/* size of memory segment */
   12.35 +	unsigned long type;		/* type of memory segment */
   12.36 +};
   12.37 +
   12.38 +struct e820map {
   12.39 +    int nr_map;
   12.40 +    struct e820entry map[E820MAX];
   12.41 +};
   12.42 +
   12.43 +struct drive_info_struct { __u8 dummy[32]; }; 
   12.44 +
   12.45 +struct sys_desc_table { 
   12.46 +    __u16 length; 
   12.47 +    __u8 table[318]; 
   12.48 +}; 
   12.49 +
   12.50 +struct screen_info {
   12.51 +    unsigned char  orig_x;		/* 0x00 */
   12.52 +    unsigned char  orig_y;		/* 0x01 */
   12.53 +    unsigned short dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
   12.54 +    unsigned short orig_video_page;	/* 0x04 */
   12.55 +    unsigned char  orig_video_mode;	/* 0x06 */
   12.56 +    unsigned char  orig_video_cols;	/* 0x07 */
   12.57 +    unsigned short unused2;		/* 0x08 */
   12.58 +    unsigned short orig_video_ega_bx;	/* 0x0a */
   12.59 +    unsigned short unused3;		/* 0x0c */
   12.60 +    unsigned char  orig_video_lines;	/* 0x0e */
   12.61 +    unsigned char  orig_video_isVGA;	/* 0x0f */
   12.62 +    unsigned short orig_video_points;	/* 0x10 */
   12.63 +    
   12.64 +    /* VESA graphic mode -- linear frame buffer */
   12.65 +    unsigned short lfb_width;		/* 0x12 */
   12.66 +    unsigned short lfb_height;		/* 0x14 */
   12.67 +    unsigned short lfb_depth;		/* 0x16 */
   12.68 +    unsigned long  lfb_base;		/* 0x18 */
   12.69 +    unsigned long  lfb_size;		/* 0x1c */
   12.70 +    unsigned short dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
   12.71 +    unsigned short lfb_linelength;	/* 0x24 */
   12.72 +    unsigned char  red_size;		/* 0x26 */
   12.73 +    unsigned char  red_pos;		/* 0x27 */
   12.74 +    unsigned char  green_size;		/* 0x28 */
   12.75 +    unsigned char  green_pos;		/* 0x29 */
   12.76 +    unsigned char  blue_size;		/* 0x2a */
   12.77 +    unsigned char  blue_pos;		/* 0x2b */
   12.78 +    unsigned char  rsvd_size;		/* 0x2c */
   12.79 +    unsigned char  rsvd_pos;		/* 0x2d */
   12.80 +    unsigned short vesapm_seg;		/* 0x2e */
   12.81 +    unsigned short vesapm_off;		/* 0x30 */
   12.82 +    unsigned short pages;		/* 0x32 */
   12.83 +					/* 0x34 -- 0x3f reserved for future expansion */
   12.84 +};
   12.85 +
   12.86 +struct screen_info_overlap { 
   12.87 +    __u8 reserved1[2]; /* 0x00 */ 
   12.88 +    __u16 ext_mem_k; /* 0x02 */ 
   12.89 +    __u8 reserved2[0x20 - 0x04]; /* 0x04 */ 
   12.90 +    __u16 cl_magic; /* 0x20 */ 
   12.91 +#define CL_MAGIC_VALUE 0xA33F 
   12.92 +    __u16 cl_offset; /* 0x22 */ 
   12.93 +    __u8 reserved3[0x40 - 0x24]; /* 0x24 */ 
   12.94 +}; 
   12.95 +
   12.96 +
   12.97 +struct apm_bios_info {
   12.98 +    __u16 version;
   12.99 +    __u16  cseg;
  12.100 +    __u32   offset;
  12.101 +    __u16  cseg_16;
  12.102 +    __u16  dseg;
  12.103 +    __u16  flags;
  12.104 +    __u16  cseg_len;
  12.105 +    __u16  cseg_16_len;
  12.106 +    __u16  dseg_len;
  12.107 +};
  12.108 + 
  12.109 +struct linux_boot_params { 
  12.110 +    union { /* 0x00 */ 
  12.111 +       struct screen_info info; 
  12.112 +       struct screen_info_overlap overlap; 
  12.113 +    } screen; 
  12.114 + 
  12.115 +    struct apm_bios_info apm_bios_info; /* 0x40 */ 
  12.116 +    __u8 reserved4[0x80 - 0x54]; /* 0x54 */ 
  12.117 +    struct drive_info_struct drive_info; /* 0x80 */ 
  12.118 +    struct sys_desc_table sys_desc_table; /* 0xa0 */ 
  12.119 +    __u32 alt_mem_k; /* 0x1e0 */ 
  12.120 +    __u8 reserved5[4]; /* 0x1e4 */ 
  12.121 +    __u8 e820_map_nr; /* 0x1e8 */ 
  12.122 +    __u8 reserved6[8]; /* 0x1e9 */ 
  12.123 +    __u8 setup_sects; /* 0x1f1 */ 
  12.124 +    __u16 mount_root_rdonly; /* 0x1f2 */ 
  12.125 +    __u16 syssize; /* 0x1f4 */ 
  12.126 +    __u16 swapdev; /* 0x1f6 */ 
  12.127 +    __u16 ramdisk_flags; /* 0x1f8 */ 
  12.128 +#define RAMDISK_IMAGE_START_MASK 0x07FF 
  12.129 +#define RAMDISK_PROMPT_FLAG 0x8000 
  12.130 +#define RAMDISK_LOAD_FLAG 0x4000 
  12.131 +    __u16 vid_mode; /* 0x1fa */ 
  12.132 +    __u16 root_dev; /* 0x1fc */ 
  12.133 +    __u8 reserved9[1]; /* 0x1fe */ 
  12.134 +    __u8 aux_device_info; /* 0x1ff */ 
  12.135 +    /* 2.00+ */ 
  12.136 +    __u8 reserved10[2]; /* 0x200 */ 
  12.137 +    __u8 header_magic[4]; /* 0x202 */ 
  12.138 +    __u16 protocol_version; /* 0x206 */ 
  12.139 +    __u8 reserved11[8]; /* 0x208 */ 
  12.140 +    __u8 loader_type; /* 0x210 */ 
  12.141 +#define LOADER_TYPE_LOADLIN 1 
  12.142 +#define LOADER_TYPE_BOOTSECT_LOADER 2 
  12.143 +#define LOADER_TYPE_SYSLINUX 3 
  12.144 +#define LOADER_TYPE_ETHERBOOT 4 
  12.145 +#define LOADER_TYPE_UNKNOWN 0xFF 
  12.146 +    __u8 loader_flags; /* 0x211 */ 
  12.147 +    __u8 reserved12[2]; /* 0x212 */ 
  12.148 +    __u32 code32_start; /* 0x214 */ 
  12.149 +    __u32 initrd_start; /* 0x218 */ 
  12.150 +    __u32 initrd_size; /* 0x21c */ 
  12.151 +    __u8 reserved13[4]; /* 0x220 */ 
  12.152 +    /* 2.01+ */ 
  12.153 +    __u16 heap_end_ptr; /* 0x224 */ 
  12.154 +    __u8 reserved14[2]; /* 0x226 */ 
  12.155 +    /* 2.02+ */ 
  12.156 +    __u32 cmd_line_ptr; /* 0x228 */ 
  12.157 +    /* 2.03+ */ 
  12.158 +    __u32 ramdisk_max; /* 0x22c */ 
  12.159 +    __u8 reserved15[0x2d0 - 0x230]; /* 0x230 */ 
  12.160 +    struct e820entry e820_map[E820MAX]; /* 0x2d0 */ 
  12.161 +    __u64 shared_info; /* 0x550 */
  12.162 +    __u8 padding[0x800 - 0x558]; /* 0x558 */ 
  12.163 +    __u8 cmd_line[0x800]; /* 0x800 */
  12.164 +} __attribute__((packed)); 
  12.165 +
  12.166 +#endif /* __LINUX_BOOT_PARAMS_H__ */
    13.1 --- a/tools/libxc/xc.h	Sun Jan 02 17:38:14 2005 +0000
    13.2 +++ b/tools/libxc/xc.h	Mon Jan 10 10:59:25 2005 +0000
    13.3 @@ -10,6 +10,8 @@
    13.4  #define __XC_H__
    13.5  
    13.6  #include <stdint.h>
    13.7 +#include "linux_boot_params.h"
    13.8 +
    13.9  typedef uint8_t            u8;
   13.10  typedef uint16_t           u16;
   13.11  typedef uint32_t           u32;
   13.12 @@ -105,6 +107,15 @@ xc_plan9_build (int xc_handle,
   13.13  		unsigned int control_evtchn, 
   13.14  		unsigned long flags);
   13.15  
   13.16 +int xc_vmx_build(int xc_handle,
   13.17 +                 u32 domid,
   13.18 +                 const char *image_name,
   13.19 +                 struct mem_map *memmap,
   13.20 +                 const char *ramdisk_name,
   13.21 +                 const char *cmdline,
   13.22 +                 unsigned int control_evtchn,
   13.23 +                 unsigned long flags);
   13.24 +
   13.25  int xc_bvtsched_global_set(int xc_handle,
   13.26                             unsigned long ctx_allow);
   13.27  
   13.28 @@ -208,4 +219,7 @@ void *xc_map_foreign_range(int xc_handle
   13.29  void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
   13.30                             unsigned long *arr, int num );
   13.31  
   13.32 +int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
   13.33 +		    unsigned long max_pfns);
   13.34 +
   13.35  #endif /* __XC_H__ */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/libxc/xc_vmx_build.c	Mon Jan 10 10:59:25 2005 +0000
    14.3 @@ -0,0 +1,865 @@
    14.4 +/******************************************************************************
    14.5 + * xc_vmx_build.c
    14.6 + */
    14.7 +
    14.8 +#include "xc_private.h"
    14.9 +#define ELFSIZE 32
   14.10 +#include "xc_elf.h"
   14.11 +#include <stdlib.h>
   14.12 +#include <zlib.h>
   14.13 +#include "linux_boot_params.h"
   14.14 +
   14.15 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   14.16 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   14.17 +
   14.18 +#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   14.19 +#define round_pgdown(_p)  ((_p)&PAGE_MASK)
   14.20 +
   14.21 +#define LINUX_BOOT_PARAMS_ADDR   0x00090000
   14.22 +#define LINUX_KERNEL_ENTR_ADDR   0x00100000
   14.23 +#define LINUX_PAGE_OFFSET        0xC0000000
   14.24 +
   14.25 +struct domain_setup_info
   14.26 +{
   14.27 +    unsigned long v_start;
   14.28 +    unsigned long v_end;
   14.29 +    unsigned long v_kernstart;
   14.30 +    unsigned long v_kernend;
   14.31 +    unsigned long v_kernentry;
   14.32 +
   14.33 +    unsigned int use_writable_pagetables;
   14.34 +    unsigned int load_bsd_symtab;
   14.35 +
   14.36 +    unsigned long symtab_addr;
   14.37 +    unsigned long symtab_len;
   14.38 +};
   14.39 +
   14.40 +static int
   14.41 +parseelfimage(
   14.42 +    char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
   14.43 +static int
   14.44 +loadelfimage(
   14.45 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
   14.46 +    unsigned long vstart);
   14.47 +static int
   14.48 +loadelfsymtab(
   14.49 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
   14.50 +    struct domain_setup_info *dsi);
   14.51 +
   14.52 +static long get_tot_pages(int xc_handle, u32 domid)
   14.53 +{
   14.54 +    dom0_op_t op;
   14.55 +    op.cmd = DOM0_GETDOMAININFO;
   14.56 +    op.u.getdomaininfo.domain = (domid_t)domid;
   14.57 +    op.u.getdomaininfo.ctxt = NULL;
   14.58 +    return (do_dom0_op(xc_handle, &op) < 0) ? 
   14.59 +        -1 : op.u.getdomaininfo.tot_pages;
   14.60 +}
   14.61 +
   14.62 +int xc_get_pfn_list(int xc_handle,
   14.63 +		 u32 domid, 
   14.64 +		 unsigned long *pfn_buf, 
   14.65 +		 unsigned long max_pfns)
   14.66 +{
   14.67 +    dom0_op_t op;
   14.68 +    int ret;
   14.69 +    op.cmd = DOM0_GETMEMLIST;
   14.70 +    op.u.getmemlist.domain   = (domid_t)domid;
   14.71 +    op.u.getmemlist.max_pfns = max_pfns;
   14.72 +    op.u.getmemlist.buffer   = pfn_buf;
   14.73 +
   14.74 +
   14.75 +    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
   14.76 +        return -1;
   14.77 +
   14.78 +    ret = do_dom0_op(xc_handle, &op);
   14.79 +
   14.80 +    (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
   14.81 +
   14.82 +    return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
   14.83 +}
   14.84 +
   14.85 +static int copy_to_domain_page(int xc_handle,
   14.86 +                               u32 domid,
   14.87 +                               unsigned long dst_pfn, 
   14.88 +                               void *src_page)
   14.89 +{
   14.90 +    void *vaddr = xc_map_foreign_range(
   14.91 +        xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
   14.92 +    if ( vaddr == NULL )
   14.93 +        return -1;
   14.94 +    memcpy(vaddr, src_page, PAGE_SIZE);
   14.95 +    munmap(vaddr, PAGE_SIZE);
   14.96 +    return 0;
   14.97 +}
   14.98 +
   14.99 +static int setup_guestos(int xc_handle,
  14.100 +                         u32 dom,
  14.101 +                         char *image, unsigned long image_size,
  14.102 +                         gzFile initrd_gfd, unsigned long initrd_len,
  14.103 +                         unsigned long nr_pages,
  14.104 +                         full_execution_context_t *ctxt,
  14.105 +                         const char *cmdline,
  14.106 +                         unsigned long shared_info_frame,
  14.107 +                         unsigned int control_evtchn,
  14.108 +                         unsigned long flags,
  14.109 +                         struct mem_map * mem_mapp)
  14.110 +{
  14.111 +    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
  14.112 +    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
  14.113 +    unsigned long *page_array = NULL;
  14.114 +    unsigned long l2tab;
  14.115 +    unsigned long l1tab;
  14.116 +    unsigned long count, i;
  14.117 +    shared_info_t *shared_info;
  14.118 +    struct linux_boot_params * boot_paramsp;
  14.119 +    __u16 * boot_gdtp;
  14.120 +    mmu_t *mmu = NULL;
  14.121 +    int rc;
  14.122 +
  14.123 +    unsigned long nr_pt_pages;
  14.124 +    unsigned long ppt_alloc;
  14.125 +
  14.126 +    struct domain_setup_info dsi;
  14.127 +    unsigned long vinitrd_start;
  14.128 +    unsigned long vinitrd_end;
  14.129 +    unsigned long vboot_params_start;
  14.130 +    unsigned long vboot_params_end;
  14.131 +    unsigned long vboot_gdt_start;
  14.132 +    unsigned long vboot_gdt_end;
  14.133 +    unsigned long vpt_start;
  14.134 +    unsigned long vpt_end;
  14.135 +    unsigned long v_end;
  14.136 +
  14.137 +    memset(&dsi, 0, sizeof(struct domain_setup_info));
  14.138 +
  14.139 +    rc = parseelfimage(image, image_size, &dsi);
  14.140 +    if ( rc != 0 )
  14.141 +        goto error_out;
  14.142 +
  14.143 +    if (dsi.use_writable_pagetables)
  14.144 +        xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable,
  14.145 +                              VMASST_TYPE_writable_pagetables);
  14.146 +
  14.147 +    if (dsi.load_bsd_symtab)
  14.148 +        loadelfsymtab(image, xc_handle, dom, NULL, &dsi);
  14.149 +
  14.150 +    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
  14.151 +    {
  14.152 +        PERROR("Guest OS must load to a page boundary.\n");
  14.153 +        goto error_out;
  14.154 +    }
  14.155 +
  14.156 +    /*
  14.157 +     * Why do we need this? The number of page-table frames depends on the 
  14.158 +     * size of the bootstrap address space. But the size of the address space 
  14.159 +     * depends on the number of page-table frames (since each one is mapped 
  14.160 +     * read-only). We have a pair of simultaneous equations in two unknowns, 
  14.161 +     * which we solve by exhaustive search.
  14.162 +     */
  14.163 +    nr_pt_pages = 1 + (nr_pages >> (PAGE_SHIFT - 2));
  14.164 +    vboot_params_start = LINUX_BOOT_PARAMS_ADDR;
  14.165 +    vboot_params_end   = vboot_params_start + PAGE_SIZE;
  14.166 +    vboot_gdt_start    = vboot_params_end;
  14.167 +    vboot_gdt_end      = vboot_gdt_start + PAGE_SIZE;
  14.168 +    v_end              = nr_pages << PAGE_SHIFT;
  14.169 +    vpt_end            = v_end - (16 << PAGE_SHIFT); /* leaving the top 64k untouched */
  14.170 +    vpt_start          = vpt_end - (nr_pt_pages << PAGE_SHIFT);
  14.171 +    vinitrd_end        = vpt_start;
  14.172 +    vinitrd_start      = vinitrd_end - initrd_len;
  14.173 +    vinitrd_start      = vinitrd_start & (~(PAGE_SIZE - 1));
  14.174 +
  14.175 +    if(initrd_len == 0)
  14.176 +        vinitrd_start = vinitrd_end = 0;
  14.177 +
  14.178 +    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
  14.179 +           " Boot_params:   %08lx->%08lx\n"
  14.180 +           " boot_gdt:      %08lx->%08lx\n"
  14.181 +           " Loaded kernel: %08lx->%08lx\n"
  14.182 +           " Init. ramdisk: %08lx->%08lx\n"
  14.183 +           " Page tables:   %08lx->%08lx\n"
  14.184 +           " TOTAL:         %08lx->%08lx\n",
  14.185 +           vboot_params_start, vboot_params_end,
  14.186 +           vboot_gdt_start, vboot_gdt_end,
  14.187 +           dsi.v_kernstart, dsi.v_kernend, 
  14.188 +           vinitrd_start, vinitrd_end,
  14.189 +           vpt_start, vpt_end,
  14.190 +           dsi.v_start, v_end);
  14.191 +    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
  14.192 +    printf(" INITRD LENGTH: %08lx\n", initrd_len);
  14.193 +
  14.194 +    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
  14.195 +    {
  14.196 +        printf("Initial guest OS requires too much space\n"
  14.197 +               "(%luMB is greater than %luMB limit)\n",
  14.198 +               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
  14.199 +        goto error_out;
  14.200 +    }
  14.201 +
  14.202 +    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
  14.203 +    {
  14.204 +        PERROR("Could not allocate memory");
  14.205 +        goto error_out;
  14.206 +    }
  14.207 +
  14.208 +    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
  14.209 +    {
  14.210 +        PERROR("Could not get the page frame list");
  14.211 +        goto error_out;
  14.212 +    }
  14.213 +
  14.214 +    loadelfimage(image, xc_handle, dom, page_array, dsi.v_start);
  14.215 +
  14.216 +    if (dsi.load_bsd_symtab)
  14.217 +        loadelfsymtab(image, xc_handle, dom, page_array, &dsi);
  14.218 +
  14.219 +    /* Load the initial ramdisk image. */
  14.220 +    if ( initrd_len != 0 )
  14.221 +    {
  14.222 +        for ( i = (vinitrd_start - dsi.v_start); 
  14.223 +              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
  14.224 +        {
  14.225 +            char page[PAGE_SIZE];
  14.226 +            if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
  14.227 +            {
  14.228 +                PERROR("Error reading initrd image, could not");
  14.229 +                goto error_out;
  14.230 +            }
  14.231 +            copy_to_domain_page(xc_handle, dom,
  14.232 +                                page_array[i>>PAGE_SHIFT], page);
  14.233 +        }
  14.234 +    }
  14.235 +
  14.236 +    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
  14.237 +        goto error_out;
  14.238 +
  14.239 +    /* First allocate page for page dir. */
  14.240 +    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
  14.241 +    l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  14.242 +    ctxt->pt_base = l2tab;
  14.243 +
  14.244 +    /* Initialise the page tables. */
  14.245 +    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
  14.246 +                                        PROT_READ|PROT_WRITE, 
  14.247 +                                        l2tab >> PAGE_SHIFT)) == NULL )
  14.248 +        goto error_out;
  14.249 +    memset(vl2tab, 0, PAGE_SIZE);
  14.250 +    vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
  14.251 +    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
  14.252 +    {    
  14.253 +        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
  14.254 +        {
  14.255 +            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
  14.256 +            if ( vl1tab != NULL )
  14.257 +                munmap(vl1tab, PAGE_SIZE);
  14.258 +            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
  14.259 +                                                PROT_READ|PROT_WRITE,
  14.260 +                                                l1tab >> PAGE_SHIFT)) == NULL )
  14.261 +            {
  14.262 +                munmap(vl2tab, PAGE_SIZE);
  14.263 +                goto error_out;
  14.264 +            }
  14.265 +            memset(vl1tab, 0, PAGE_SIZE);
  14.266 +            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
  14.267 +            *vl2e++ = l1tab | L2_PROT;
  14.268 +        }
  14.269 +
  14.270 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
  14.271 +        if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && 
  14.272 +             (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) )
  14.273 +            *vl1e &= ~_PAGE_RW;
  14.274 +        vl1e++;
  14.275 +    }
  14.276 +    munmap(vl1tab, PAGE_SIZE);
  14.277 +    munmap(vl2tab, PAGE_SIZE);
  14.278 +
  14.279 +    /*
  14.280 +     * Pin down l2tab addr as page dir page - causes hypervisor to provide
  14.281 +     * correct protection for the page
  14.282 +     */ 
  14.283 +    if ( add_mmu_update(xc_handle, mmu,
  14.284 +                        l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE) )
  14.285 +        goto error_out;
  14.286 +
  14.287 +    boot_paramsp = xc_map_foreign_range(
  14.288 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  14.289 +        page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT]);
  14.290 +    memset(boot_paramsp, 0, sizeof(*boot_paramsp));
  14.291 +
  14.292 +    strncpy(boot_paramsp->cmd_line, cmdline, 0x800);
  14.293 +    boot_paramsp->cmd_line[0x800-1] = '\0';
  14.294 +    boot_paramsp->cmd_line_ptr = ((unsigned long) vboot_params_start) + offsetof(struct linux_boot_params, cmd_line);
  14.295 +
  14.296 +    boot_paramsp->setup_sects = 0;
  14.297 +    boot_paramsp->mount_root_rdonly = 1;
  14.298 +    boot_paramsp->swapdev = 0x0; 
  14.299 +    boot_paramsp->ramdisk_flags = 0x0; 
  14.300 +    boot_paramsp->root_dev = 0x0; /* We must tell kernel root dev by kernel command line. */
  14.301 +
  14.302 +    /* we don't have a ps/2 mouse now.
  14.303 +     * 0xAA means a aux mouse is there.
  14.304 +     * See detect_auxiliary_port() in pc_keyb.c.
  14.305 +     */
  14.306 +    boot_paramsp->aux_device_info = 0x0; 
  14.307 +
  14.308 +    boot_paramsp->header_magic[0] = 0x48; /* "H" */
  14.309 +    boot_paramsp->header_magic[1] = 0x64; /* "d" */
  14.310 +    boot_paramsp->header_magic[2] = 0x72; /* "r" */
  14.311 +    boot_paramsp->header_magic[3] = 0x53; /* "S" */
  14.312 +
  14.313 +    boot_paramsp->protocol_version = 0x0203; /* 2.03 */
  14.314 +    boot_paramsp->loader_type = 0x71; /* GRUB */
  14.315 +    boot_paramsp->loader_flags = 0x1; /* loaded high */
  14.316 +    boot_paramsp->code32_start = LINUX_KERNEL_ENTR_ADDR; /* 1MB */
  14.317 +    boot_paramsp->initrd_start = vinitrd_start;
  14.318 +    boot_paramsp->initrd_size = initrd_len;
  14.319 +
  14.320 +    i = (nr_pages >> (PAGE_SHIFT - 10)) - (1 << 10) - 4;
  14.321 +    boot_paramsp->alt_mem_k = i; /* alt_mem_k */
  14.322 +    boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */
  14.323 +
  14.324 +    /*
  14.325 +     * Stuff SCREAN_INFO
  14.326 +     */
  14.327 +    boot_paramsp->screen.info.orig_x = 0;
  14.328 +    boot_paramsp->screen.info.orig_y = 0;
  14.329 +    boot_paramsp->screen.info.orig_video_page = 8;
  14.330 +    boot_paramsp->screen.info.orig_video_mode = 3;
  14.331 +    boot_paramsp->screen.info.orig_video_cols = 80;
  14.332 +    boot_paramsp->screen.info.orig_video_ega_bx = 0;
  14.333 +    boot_paramsp->screen.info.orig_video_lines = 25;
  14.334 +    boot_paramsp->screen.info.orig_video_isVGA = 1;
  14.335 +    boot_paramsp->screen.info.orig_video_points = 0x0010;
  14.336 +
  14.337 +    /* seems we may NOT stuff boot_paramsp->apm_bios_info */
  14.338 +    /* seems we may NOT stuff boot_paramsp->drive_info */
  14.339 +    /* seems we may NOT stuff boot_paramsp->sys_desc_table */
  14.340 +    *((unsigned short *) &boot_paramsp->drive_info.dummy[0]) = 800;
  14.341 +    boot_paramsp->drive_info.dummy[2] = 4;
  14.342 +    boot_paramsp->drive_info.dummy[14] = 32;
  14.343 +
  14.344 +    boot_paramsp->e820_map_nr = mem_mapp->nr_map;
  14.345 +    for (i=0; i<mem_mapp->nr_map; i++) {
  14.346 +        boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr; 
  14.347 +        boot_paramsp->e820_map[i].size = mem_mapp->map[i].size; 
  14.348 +        boot_paramsp->e820_map[i].type = mem_mapp->map[i].type; 
  14.349 +    }
  14.350 +    munmap(boot_paramsp, PAGE_SIZE); 
  14.351 +
  14.352 +    boot_gdtp = xc_map_foreign_range(
  14.353 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
  14.354 +        page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT]);
  14.355 +    memset(boot_gdtp, 0, PAGE_SIZE);
  14.356 +    boot_gdtp[12*4 + 0] = boot_gdtp[13*4 + 0] = 0xffff; /* limit */
  14.357 +    boot_gdtp[12*4 + 1] = boot_gdtp[13*4 + 1] = 0x0000; /* base */
  14.358 +    boot_gdtp[12*4 + 2] = 0x9a00; boot_gdtp[13*4 + 2] = 0x9200; /* perms */
  14.359 +    boot_gdtp[12*4 + 3] = boot_gdtp[13*4 + 3] = 0x00cf; /* granu + top of limit */
  14.360 +    munmap(boot_gdtp, PAGE_SIZE);
  14.361 +
  14.362 +    /* shared_info page starts its life empty. */
  14.363 +    shared_info = xc_map_foreign_range(
  14.364 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
  14.365 +    memset(shared_info, 0, sizeof(shared_info_t));
  14.366 +    /* Mask all upcalls... */
  14.367 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
  14.368 +        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
  14.369 +    munmap(shared_info, PAGE_SIZE);
  14.370 +
  14.371 +    /* Send the page update requests down to the hypervisor. */
  14.372 +    if ( finish_mmu_updates(xc_handle, mmu) )
  14.373 +        goto error_out;
  14.374 +
  14.375 +    free(mmu);
  14.376 +    free(page_array);
  14.377 +
  14.378 +    /*
  14.379 +     * Initial register values:
  14.380 +     */
  14.381 +    ctxt->cpu_ctxt.ds = 0x68;
  14.382 +    ctxt->cpu_ctxt.es = 0x0;
  14.383 +    ctxt->cpu_ctxt.fs = 0x0;
  14.384 +    ctxt->cpu_ctxt.gs = 0x0;
  14.385 +    ctxt->cpu_ctxt.ss = 0x68;
  14.386 +    ctxt->cpu_ctxt.cs = 0x60;
  14.387 +    ctxt->cpu_ctxt.eip = dsi.v_kernentry;
  14.388 +    ctxt->cpu_ctxt.edx = vboot_gdt_start;
  14.389 +    ctxt->cpu_ctxt.eax = 0x800;
  14.390 +    ctxt->cpu_ctxt.esp = vboot_gdt_end;
  14.391 +    ctxt->cpu_ctxt.ebx = 0;	/* startup_32 expects this to be 0 to signal boot cpu */
  14.392 +    ctxt->cpu_ctxt.ecx = mem_mapp->nr_map;
  14.393 +    ctxt->cpu_ctxt.esi = vboot_params_start;
  14.394 +    ctxt->cpu_ctxt.edi = vboot_params_start + 0x2d0;
  14.395 +
  14.396 +    ctxt->cpu_ctxt.eflags = (1<<2);
  14.397 +
  14.398 +    return 0;
  14.399 +
  14.400 + error_out:
  14.401 +    if ( mmu != NULL )
  14.402 +        free(mmu);
  14.403 +    if ( page_array != NULL )
  14.404 +        free(page_array);
  14.405 +    return -1;
  14.406 +}
  14.407 +
  14.408 +static unsigned long get_filesz(int fd)
  14.409 +{
  14.410 +    u16 sig;
  14.411 +    u32 _sz = 0;
  14.412 +    unsigned long sz;
  14.413 +
  14.414 +    lseek(fd, 0, SEEK_SET);
  14.415 +    read(fd, &sig, sizeof(sig));
  14.416 +    sz = lseek(fd, 0, SEEK_END);
  14.417 +    if ( sig == 0x8b1f ) /* GZIP signature? */
  14.418 +    {
  14.419 +        lseek(fd, -4, SEEK_END);
  14.420 +        read(fd, &_sz, 4);
  14.421 +        sz = _sz;
  14.422 +    }
  14.423 +    lseek(fd, 0, SEEK_SET);
  14.424 +
  14.425 +    return sz;
  14.426 +}
  14.427 +
  14.428 +static char *read_kernel_image(const char *filename, unsigned long *size)
  14.429 +{
  14.430 +    int kernel_fd = -1;
  14.431 +    gzFile kernel_gfd = NULL;
  14.432 +    char *image = NULL;
  14.433 +    unsigned int bytes;
  14.434 +
  14.435 +    if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
  14.436 +    {
  14.437 +        PERROR("Could not open kernel image");
  14.438 +        goto out;
  14.439 +    }
  14.440 +
  14.441 +    *size = get_filesz(kernel_fd);
  14.442 +
  14.443 +    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
  14.444 +    {
  14.445 +        PERROR("Could not allocate decompression state for state file");
  14.446 +        goto out;
  14.447 +    }
  14.448 +
  14.449 +    if ( (image = malloc(*size)) == NULL )
  14.450 +    {
  14.451 +        PERROR("Could not allocate memory for kernel image");
  14.452 +        goto out;
  14.453 +    }
  14.454 +
  14.455 +    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
  14.456 +    {
  14.457 +        PERROR("Error reading kernel image, could not"
  14.458 +               " read the whole image (%d != %ld).", bytes, *size);
  14.459 +        free(image);
  14.460 +        image = NULL;
  14.461 +    }
  14.462 +
  14.463 + out:
  14.464 +    if ( kernel_gfd != NULL )
  14.465 +        gzclose(kernel_gfd);
  14.466 +    else if ( kernel_fd >= 0 )
  14.467 +        close(kernel_fd);
  14.468 +    return image;
  14.469 +}
  14.470 +
  14.471 +#define VMX_FEATURE_FLAG 0x20
  14.472 +
  14.473 +int vmx_identify(void)
  14.474 +{
  14.475 +    int eax, ecx;
  14.476 +
  14.477 +    __asm__ __volatile__ ("cpuid" 
  14.478 +			  : "=a" (eax), "=c" (ecx) 
  14.479 +			  : "0" (1) 
  14.480 +			  : "bx", "dx");
  14.481 +    if (!(ecx & VMX_FEATURE_FLAG)) {
  14.482 +        return -1;
  14.483 +    }
  14.484 +    return 0;
  14.485 +}
  14.486 +
  14.487 +int xc_vmx_build(int xc_handle,
  14.488 +                   u32 domid,
  14.489 +                   const char *image_name,
  14.490 +                   struct mem_map *mem_mapp,
  14.491 +                   const char *ramdisk_name,
  14.492 +                   const char *cmdline,
  14.493 +                   unsigned int control_evtchn,
  14.494 +                   unsigned long flags)
  14.495 +{
  14.496 +    dom0_op_t launch_op, op;
  14.497 +    int initrd_fd = -1;
  14.498 +    gzFile initrd_gfd = NULL;
  14.499 +    int rc, i;
  14.500 +    full_execution_context_t st_ctxt, *ctxt = &st_ctxt;
  14.501 +    unsigned long nr_pages;
  14.502 +    char         *image = NULL;
  14.503 +    unsigned long image_size, initrd_size=0;
  14.504 +
  14.505 +    if ( vmx_identify() < 0 )
  14.506 +    {
  14.507 +        PERROR("CPU doesn't support VMX Extensions");
  14.508 +        goto error_out;
  14.509 +    }
  14.510 +    
  14.511 +    if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
  14.512 +    {
  14.513 +        PERROR("Could not find total pages for domain");
  14.514 +        goto error_out;
  14.515 +    }
  14.516 +
  14.517 +    if ( (image = read_kernel_image(image_name, &image_size)) == NULL )
  14.518 +        goto error_out;
  14.519 +
  14.520 +    if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
  14.521 +    {
  14.522 +        if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
  14.523 +        {
  14.524 +            PERROR("Could not open the initial ramdisk image");
  14.525 +            goto error_out;
  14.526 +        }
  14.527 +
  14.528 +        initrd_size = get_filesz(initrd_fd);
  14.529 +
  14.530 +        if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
  14.531 +        {
  14.532 +            PERROR("Could not allocate decompression state for initrd");
  14.533 +            goto error_out;
  14.534 +        }
  14.535 +    }
  14.536 +
  14.537 +    if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
  14.538 +    {   
  14.539 +        PERROR("Unable to mlock ctxt");
  14.540 +        return 1;
  14.541 +    }
  14.542 +
  14.543 +    op.cmd = DOM0_GETDOMAININFO;
  14.544 +    op.u.getdomaininfo.domain = (domid_t)domid;
  14.545 +    op.u.getdomaininfo.ctxt = ctxt;
  14.546 +    if ( (do_dom0_op(xc_handle, &op) < 0) || 
  14.547 +         ((u16)op.u.getdomaininfo.domain != domid) )
  14.548 +    {
  14.549 +        PERROR("Could not get info on domain");
  14.550 +        goto error_out;
  14.551 +    }
  14.552 +    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
  14.553 +         (ctxt->pt_base != 0) )
  14.554 +    {
  14.555 +        ERROR("Domain is already constructed");
  14.556 +        goto error_out;
  14.557 +    }
  14.558 +
  14.559 +    if ( setup_guestos(xc_handle, domid, image, image_size, 
  14.560 +                       initrd_gfd, initrd_size, nr_pages, 
  14.561 +                       ctxt, cmdline,
  14.562 +                       op.u.getdomaininfo.shared_info_frame,
  14.563 +                       control_evtchn, flags, mem_mapp) < 0 )
  14.564 +    {
  14.565 +        ERROR("Error constructing guest OS");
  14.566 +        goto error_out;
  14.567 +    }
  14.568 +
  14.569 +    if ( initrd_fd >= 0 )
  14.570 +        close(initrd_fd);
  14.571 +    if ( initrd_gfd )
  14.572 +        gzclose(initrd_gfd);
  14.573 +    if ( image != NULL )
  14.574 +        free(image);
  14.575 +
  14.576 +    ctxt->flags = ECF_VMX_GUEST;
  14.577 +    /* FPU is set up to default initial state. */
  14.578 +    memset(ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
  14.579 +
  14.580 +    /* Virtual IDT is empty at start-of-day. */
  14.581 +    for ( i = 0; i < 256; i++ )
  14.582 +    {
  14.583 +        ctxt->trap_ctxt[i].vector = i;
  14.584 +        ctxt->trap_ctxt[i].cs     = FLAT_GUESTOS_CS;
  14.585 +    }
  14.586 +    ctxt->fast_trap_idx = 0;
  14.587 +
  14.588 +    /* No LDT. */
  14.589 +    ctxt->ldt_ents = 0;
  14.590 +    
  14.591 +    /* Use the default Xen-provided GDT. */
  14.592 +    ctxt->gdt_ents = 0;
  14.593 +
  14.594 +    /* Ring 1 stack is the initial stack. */
  14.595 +/*
  14.596 +    ctxt->guestos_ss  = FLAT_GUESTOS_DS;
  14.597 +    ctxt->guestos_esp = vstartinfo_start;
  14.598 +*/
  14.599 +    /* No debugging. */
  14.600 +    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
  14.601 +
  14.602 +    /* No callback handlers. */
  14.603 +    ctxt->event_callback_cs     = FLAT_GUESTOS_CS;
  14.604 +    ctxt->event_callback_eip    = 0;
  14.605 +    ctxt->failsafe_callback_cs  = FLAT_GUESTOS_CS;
  14.606 +    ctxt->failsafe_callback_eip = 0;
  14.607 +
  14.608 +    memset( &launch_op, 0, sizeof(launch_op) );
  14.609 +
  14.610 +    launch_op.u.builddomain.domain   = (domid_t)domid;
  14.611 +    launch_op.u.builddomain.ctxt = ctxt;
  14.612 +
  14.613 +    launch_op.cmd = DOM0_BUILDDOMAIN;
  14.614 +    rc = do_dom0_op(xc_handle, &launch_op);
  14.615 +    return rc;
  14.616 +
  14.617 + error_out:
  14.618 +    if ( initrd_gfd != NULL )
  14.619 +        gzclose(initrd_gfd);
  14.620 +    else if ( initrd_fd >= 0 )
  14.621 +        close(initrd_fd);
  14.622 +    if ( image != NULL )
  14.623 +        free(image);
  14.624 +
  14.625 +    return -1;
  14.626 +}
  14.627 +
  14.628 +static inline int is_loadable_phdr(Elf_Phdr *phdr)
  14.629 +{
  14.630 +    return ((phdr->p_type == PT_LOAD) &&
  14.631 +            ((phdr->p_flags & (PF_W|PF_X)) != 0));
  14.632 +}
  14.633 +
  14.634 +static int parseelfimage(char *elfbase, 
  14.635 +                         unsigned long elfsize,
  14.636 +                         struct domain_setup_info *dsi)
  14.637 +{
  14.638 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
  14.639 +    Elf_Phdr *phdr;
  14.640 +    Elf_Shdr *shdr;
  14.641 +    unsigned long kernstart = ~0UL, kernend=0UL;
  14.642 +    char *shstrtab;
  14.643 +    int h;
  14.644 +
  14.645 +    if ( !IS_ELF(*ehdr) )
  14.646 +    {
  14.647 +        ERROR("Kernel image does not have an ELF header.");
  14.648 +        return -EINVAL;
  14.649 +    }
  14.650 +
  14.651 +    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
  14.652 +    {
  14.653 +        ERROR("ELF program headers extend beyond end of image.");
  14.654 +        return -EINVAL;
  14.655 +    }
  14.656 +
  14.657 +    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
  14.658 +    {
  14.659 +        ERROR("ELF section headers extend beyond end of image.");
  14.660 +        return -EINVAL;
  14.661 +    }
  14.662 +
  14.663 +    /* Find the section-header strings table. */
  14.664 +    if ( ehdr->e_shstrndx == SHN_UNDEF )
  14.665 +    {
  14.666 +        ERROR("ELF image has no section-header strings table (shstrtab).");
  14.667 +        return -EINVAL;
  14.668 +    }
  14.669 +    shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + 
  14.670 +                        (ehdr->e_shstrndx*ehdr->e_shentsize));
  14.671 +    shstrtab = elfbase + shdr->sh_offset;
  14.672 +    
  14.673 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
  14.674 +    {
  14.675 +        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  14.676 +        if ( !is_loadable_phdr(phdr) )
  14.677 +            continue;
  14.678 +        if ( phdr->p_vaddr < kernstart )
  14.679 +            kernstart = phdr->p_vaddr;
  14.680 +        if ( (phdr->p_vaddr + phdr->p_memsz) > kernend )
  14.681 +            kernend = phdr->p_vaddr + phdr->p_memsz;
  14.682 +    }
  14.683 +
  14.684 +    if ( (kernstart > kernend) || 
  14.685 +         (ehdr->e_entry < kernstart) || 
  14.686 +         (ehdr->e_entry > kernend) )
  14.687 +    {
  14.688 +        ERROR("Malformed ELF image.");
  14.689 +        return -EINVAL;
  14.690 +    }
  14.691 +
  14.692 +    dsi->v_start = 0x00000000;
  14.693 +    dsi->use_writable_pagetables = 0;
  14.694 +    dsi->load_bsd_symtab = 0;
  14.695 +
  14.696 +    dsi->v_kernstart = kernstart - LINUX_PAGE_OFFSET;
  14.697 +    dsi->v_kernend   = kernend - LINUX_PAGE_OFFSET;
  14.698 +    dsi->v_kernentry = LINUX_KERNEL_ENTR_ADDR;
  14.699 +
  14.700 +    dsi->v_end       = dsi->v_kernend;
  14.701 +
  14.702 +    return 0;
  14.703 +}
  14.704 +
  14.705 +static int
  14.706 +loadelfimage(
  14.707 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
  14.708 +    unsigned long vstart)
  14.709 +{
  14.710 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
  14.711 +    Elf_Phdr *phdr;
  14.712 +    int h;
  14.713 +
  14.714 +    char         *va;
  14.715 +    unsigned long pa, done, chunksz;
  14.716 +
  14.717 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
  14.718 +    {
  14.719 +        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
  14.720 +        if ( !is_loadable_phdr(phdr) )
  14.721 +            continue;
  14.722 +        
  14.723 +        for ( done = 0; done < phdr->p_filesz; done += chunksz )
  14.724 +        {
  14.725 +            pa = (phdr->p_vaddr + done) - vstart - LINUX_PAGE_OFFSET;
  14.726 +            va = xc_map_foreign_range(
  14.727 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
  14.728 +            chunksz = phdr->p_filesz - done;
  14.729 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  14.730 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  14.731 +            memcpy(va + (pa & (PAGE_SIZE-1)),
  14.732 +                   elfbase + phdr->p_offset + done, chunksz);
  14.733 +            munmap(va, PAGE_SIZE);
  14.734 +        }
  14.735 +
  14.736 +        for ( ; done < phdr->p_memsz; done += chunksz )
  14.737 +        {
  14.738 +            pa = (phdr->p_vaddr + done) - vstart - LINUX_PAGE_OFFSET;
  14.739 +            va = xc_map_foreign_range(
  14.740 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
  14.741 +            chunksz = phdr->p_memsz - done;
  14.742 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  14.743 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  14.744 +            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
  14.745 +            munmap(va, PAGE_SIZE);
  14.746 +        }
  14.747 +    }
  14.748 +
  14.749 +    return 0;
  14.750 +}
  14.751 +
  14.752 +static void
  14.753 +map_memcpy(
  14.754 +    unsigned long dst, char *src, unsigned long size,
  14.755 +    int xch, u32 dom, unsigned long *parray, unsigned long vstart)
  14.756 +{
  14.757 +    char *va;
  14.758 +    unsigned long chunksz, done, pa;
  14.759 +
  14.760 +    for ( done = 0; done < size; done += chunksz )
  14.761 +    {
  14.762 +        pa = dst + done - vstart;
  14.763 +        va = xc_map_foreign_range(
  14.764 +            xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
  14.765 +        chunksz = size - done;
  14.766 +        if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
  14.767 +            chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
  14.768 +        memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
  14.769 +        munmap(va, PAGE_SIZE);
  14.770 +    }
  14.771 +}
  14.772 +
  14.773 +#define ELFROUND (ELFSIZE / 8)
  14.774 +
  14.775 +static int
  14.776 +loadelfsymtab(
  14.777 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
  14.778 +    struct domain_setup_info *dsi)
  14.779 +{
  14.780 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr;
  14.781 +    Elf_Shdr *shdr;
  14.782 +    unsigned long maxva, symva;
  14.783 +    char *p;
  14.784 +    int h, i;
  14.785 +
  14.786 +    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
  14.787 +               ehdr->e_shnum * sizeof(Elf_Shdr));
  14.788 +    if (p == NULL)
  14.789 +        return 0;
  14.790 +
  14.791 +    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
  14.792 +    symva = maxva;
  14.793 +    maxva += sizeof(int);
  14.794 +    dsi->symtab_addr = maxva;
  14.795 +    dsi->symtab_len = 0;
  14.796 +    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
  14.797 +    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
  14.798 +
  14.799 +    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
  14.800 +    memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
  14.801 +
  14.802 +    for ( h = 0; h < ehdr->e_shnum; h++ ) 
  14.803 +    {
  14.804 +        if ( shdr[h].sh_type == SHT_STRTAB )
  14.805 +        {
  14.806 +            /* Look for a strtab @i linked to symtab @h. */
  14.807 +            for ( i = 0; i < ehdr->e_shnum; i++ )
  14.808 +                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
  14.809 +                     (shdr[i].sh_link == h) )
  14.810 +                    break;
  14.811 +            /* Skip symtab @h if we found no corresponding strtab @i. */
  14.812 +            if ( i == ehdr->e_shnum )
  14.813 +            {
  14.814 +                shdr[h].sh_offset = 0;
  14.815 +                continue;
  14.816 +            }
  14.817 +        }
  14.818 +
  14.819 +        if ( (shdr[h].sh_type == SHT_STRTAB) ||
  14.820 +             (shdr[h].sh_type == SHT_SYMTAB) )
  14.821 +        {
  14.822 +            if ( parray != NULL )
  14.823 +                map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size,
  14.824 +                           xch, dom, parray, dsi->v_start);
  14.825 +
  14.826 +            /* Mangled to be based on ELF header location. */
  14.827 +            shdr[h].sh_offset = maxva - dsi->symtab_addr;
  14.828 +
  14.829 +            dsi->symtab_len += shdr[h].sh_size;
  14.830 +            maxva += shdr[h].sh_size;
  14.831 +            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
  14.832 +        }
  14.833 +
  14.834 +        shdr[h].sh_name = 0;  /* Name is NULL. */
  14.835 +    }
  14.836 +
  14.837 +    if ( dsi->symtab_len == 0 )
  14.838 +    {
  14.839 +        dsi->symtab_addr = 0;
  14.840 +        goto out;
  14.841 +    }
  14.842 +
  14.843 +    if ( parray != NULL )
  14.844 +    {
  14.845 +        *(int *)p = maxva - dsi->symtab_addr;
  14.846 +        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
  14.847 +        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
  14.848 +        sym_ehdr->e_phoff = 0;
  14.849 +        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
  14.850 +        sym_ehdr->e_phentsize = 0;
  14.851 +        sym_ehdr->e_phnum = 0;
  14.852 +        sym_ehdr->e_shstrndx = SHN_UNDEF;
  14.853 +
  14.854 +        /* Copy total length, crafted ELF header and section header table */
  14.855 +        map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
  14.856 +                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
  14.857 +                   dsi->v_start);
  14.858 +    }
  14.859 +
  14.860 +    dsi->symtab_len = maxva - dsi->symtab_addr;
  14.861 +    dsi->v_end = round_pgup(maxva);
  14.862 +
  14.863 + out:
  14.864 +    if ( p != NULL )
  14.865 +        free(p);
  14.866 +
  14.867 +    return 0;
  14.868 +}
    15.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sun Jan 02 17:38:14 2005 +0000
    15.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Jan 10 10:59:25 2005 +0000
    15.3 @@ -16,6 +16,7 @@
    15.4  #include <arpa/inet.h>
    15.5  #include "xc_private.h"
    15.6  #include "gzip_stream.h"
    15.7 +#include "linux_boot_params.h"
    15.8  
    15.9  /* Needed for Python versions earlier than 2.3. */
   15.10  #ifndef PyMODINIT_FUNC
   15.11 @@ -393,6 +394,87 @@ static PyObject *pyxc_plan9_build(PyObje
   15.12      return zero;
   15.13  }
   15.14  
   15.15 +static PyObject *pyxc_vmx_build(PyObject *self,
   15.16 +                                  PyObject *args,
   15.17 +                                  PyObject *kwds)
   15.18 +{
   15.19 +    XcObject *xc = (XcObject *)self;
   15.20 +
   15.21 +    u32   dom;
   15.22 +    char *image, *ramdisk = NULL, *cmdline = "";
   15.23 +    PyObject *memmap;
   15.24 +    int   control_evtchn, flags = 0;
   15.25 +    int numItems, i;
   15.26 +    struct mem_map mem_map;
   15.27 +
   15.28 +    static char *kwd_list[] = { "dom", "control_evtchn", 
   15.29 +                                "image", "memmap",
   15.30 +				"ramdisk", "cmdline", "flags",
   15.31 +                                NULL };
   15.32 +
   15.33 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iisO!|ssi", kwd_list, 
   15.34 +                                      &dom, &control_evtchn, 
   15.35 +                                      &image, &PyList_Type, &memmap,
   15.36 +				      &ramdisk, &cmdline, &flags) )
   15.37 +        return NULL;
   15.38 +
   15.39 +    memset(&mem_map, 0, sizeof(mem_map));
   15.40 +    /* Parse memmap */
   15.41 +
   15.42 +    /* get the number of lines passed to us */
   15.43 +    numItems = PyList_Size(memmap) - 1;	/* removing the line 
   15.44 +					   containing "memmap" */
   15.45 +    printf ("numItems: %d\n", numItems);
   15.46 +    mem_map.nr_map = numItems;
   15.47 +   
   15.48 +
   15.49 +    /* should raise an error here. */
   15.50 +    if (numItems < 0) return NULL; /* Not a list */
   15.51 +
   15.52 +
   15.53 +    /* iterate over items of the list, grabbing ranges and parsing them */
   15.54 +    for (i = 1; i <= numItems; i++) {	// skip over "memmap"
   15.55 +	    PyObject *item, *f1, *f2, *f3, *f4;
   15.56 +	    int numFields;
   15.57 +	    unsigned long lf1, lf2, lf3, lf4;
   15.58 +	    char *sf1, *sf2;
   15.59 +	    
   15.60 +	    /* grab the string object from the next element of the list */
   15.61 +	    item = PyList_GetItem(memmap, i); /* Can't fail */
   15.62 +
   15.63 +	    /* get the number of lines passed to us */
   15.64 +	    numFields = PyList_Size(item);
   15.65 +
   15.66 +	    if (numFields != 4)
   15.67 +		    return NULL;
   15.68 +
   15.69 +	    f1 = PyList_GetItem(item, 0);
   15.70 +	    f2 = PyList_GetItem(item, 1);
   15.71 +	    f3 = PyList_GetItem(item, 2);
   15.72 +	    f4 = PyList_GetItem(item, 3);
   15.73 +
   15.74 +	    /* Convert objects to strings/longs */
   15.75 +	    sf1 = PyString_AsString(f1);
   15.76 +	    sf2 = PyString_AsString(f2);
   15.77 +	    lf3 = PyLong_AsLong(f3);
   15.78 +	    lf4 = PyLong_AsLong(f4);
   15.79 +	    sscanf(sf1, "%lx", &lf1);
   15.80 +	    sscanf(sf2, "%lx", &lf2);
   15.81 +
   15.82 +            mem_map.map[i-1].addr = lf1;
   15.83 +            mem_map.map[i-1].size = lf2 - lf1;
   15.84 +            mem_map.map[i-1].type = lf3;
   15.85 +            mem_map.map[i-1].caching_attr = lf4;
   15.86 +    }
   15.87 +
   15.88 +    if ( xc_vmx_build(xc->xc_handle, dom, image, &mem_map,
   15.89 +                        ramdisk, cmdline, control_evtchn, flags) != 0 )
   15.90 +        return PyErr_SetFromErrno(xc_error);
   15.91 +    
   15.92 +    Py_INCREF(zero);
   15.93 +    return zero;
   15.94 +}
   15.95 +
   15.96  static PyObject *pyxc_bvtsched_global_set(PyObject *self,
   15.97                                            PyObject *args,
   15.98                                            PyObject *kwds)
   15.99 @@ -943,6 +1025,17 @@ static PyMethodDef pyxc_methods[] = {
  15.100        " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
  15.101        "Returns: [int] 0 on success; -1 on error.\n" },
  15.102  
  15.103 +    { "vmx_build", 
  15.104 +      (PyCFunction)pyxc_vmx_build, 
  15.105 +      METH_VARARGS | METH_KEYWORDS, "\n"
  15.106 +      "Build a new Linux guest OS.\n"
  15.107 +      " dom     [int]:      Identifier of domain to build into.\n"
  15.108 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
  15.109 +      " memmap  [str]: 	    Memory map.\n\n"
  15.110 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
  15.111 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
  15.112 +      "Returns: [int] 0 on success; -1 on error.\n" },
  15.113 +
  15.114      { "bvtsched_global_set",
  15.115        (PyCFunction)pyxc_bvtsched_global_set,
  15.116        METH_VARARGS | METH_KEYWORDS, "\n"
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/python/xen/util/memmap.py	Mon Jan 10 10:59:25 2005 +0000
    16.3 @@ -0,0 +1,41 @@
    16.4 +mem_caching_attr = {
    16.5 +    'UC' : 0,
    16.6 +    'WC' : 1,
    16.7 +    'WT' : 4,
    16.8 +    'WP' : 5,
    16.9 +    'WB' : 6,
   16.10 +    };
   16.11 +
   16.12 +e820_mem_type = {
   16.13 +    'AddressRangeMemory'    : 1,
   16.14 +    'AddressRangeReserved'  : 2,
   16.15 +    'AddressRangeACPI'      : 3,
   16.16 +    'AddressRangeNVS'       : 4,
   16.17 +    'AddressRangeIO'        : 16,
   16.18 +    'AddressRangeShared'    : 17,
   16.19 +};
   16.20 +
   16.21 +MT_COL = 2
   16.22 +MA_COL = 3
   16.23 +
   16.24 +def strmap(row):
   16.25 +   if (type(row) != type([])):
   16.26 +       return row
   16.27 +   row[MT_COL] = e820_mem_type[row[MT_COL]]
   16.28 +   row[MA_COL] = mem_caching_attr[row[MA_COL]]
   16.29 +   return row
   16.30 +
   16.31 +def memmap_parse(memmap):
   16.32 +    return map(strmap, memmap)
   16.33 +
   16.34 +if __name__ == '__main__':
   16.35 +   memmap = [ 'memmap',
   16.36 +              [ '1', '2', 'AddressRangeMemory', 'UC'],
   16.37 +              [ '1', '2', 'AddressRangeReserved', 'UC'],
   16.38 +              [ '1', '2', 'AddressRangeACPI', 'WB'],
   16.39 +              [ '1', '2', 'AddressRangeNVS', 'WB'],
   16.40 +              [ '1', '2', 'AddressRangeIO', 'WB'],
   16.41 +              [ '1', '2', 'AddressRangeShared', 'WB']]
   16.42 +   print memmap_parse(memmap);
   16.43 +
   16.44 +
    17.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Sun Jan 02 17:38:14 2005 +0000
    17.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Mon Jan 10 10:59:25 2005 +0000
    17.3 @@ -20,6 +20,7 @@ from twisted.internet import defer
    17.4  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    17.5  import xen.util.ip
    17.6  from xen.util.ip import _readline, _readlines
    17.7 +from xen.xend.server import channel
    17.8  
    17.9  import sxp
   17.10  
   17.11 @@ -319,6 +320,7 @@ class XendDomainInfo:
   17.12          self.restart_time = None
   17.13          self.console_port = None
   17.14          self.savedinfo = None
   17.15 +        self.is_vmx = 0
   17.16  
   17.17      def setdom(self, dom):
   17.18          """Set the domain id.
   17.19 @@ -720,7 +722,7 @@ class XendDomainInfo:
   17.20          log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
   17.21          self.setdom(dom)
   17.22  
   17.23 -    def build_domain(self, ostype, kernel, ramdisk, cmdline):
   17.24 +    def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap):
   17.25          """Build the domain boot image.
   17.26          """
   17.27          if self.recreate or self.restore: return
   17.28 @@ -735,17 +737,26 @@ class XendDomainInfo:
   17.29          flags = 0
   17.30          if self.netif_backend: flags |= SIF_NET_BE_DOMAIN
   17.31          if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN
   17.32 -        err = buildfn(dom            = dom,
   17.33 -                      image          = kernel,
   17.34 -                      control_evtchn = self.console.getRemotePort(),
   17.35 -                      cmdline        = cmdline,
   17.36 -                      ramdisk        = ramdisk,
   17.37 -                      flags          = flags)
   17.38 +	if ostype == "vmx":
   17.39 +        	err = buildfn(dom      = dom,
   17.40 +               	      	image          = kernel,
   17.41 +                      	control_evtchn = 0,
   17.42 +			memmap	       = memmap,
   17.43 +                      	cmdline        = cmdline,
   17.44 +                      	ramdisk        = ramdisk,
   17.45 +                      	flags          = flags)
   17.46 +	else:
   17.47 +        	err = buildfn(dom            = dom,
   17.48 +               	      	image          = kernel,
   17.49 +                      	control_evtchn = self.console.getRemotePort(),
   17.50 +                      	cmdline        = cmdline,
   17.51 +                      	ramdisk        = ramdisk,
   17.52 +                      	flags          = flags)
   17.53          if err != 0:
   17.54              raise VmError('Building domain failed: type=%s dom=%d err=%d'
   17.55                            % (ostype, dom, err))
   17.56  
   17.57 -    def create_domain(self, ostype, kernel, ramdisk, cmdline):
   17.58 +    def create_domain(self, ostype, kernel, ramdisk, cmdline, memmap=''):
   17.59          """Create a domain. Builds the image but does not configure it.
   17.60  
   17.61          @param ostype:  OS type
   17.62 @@ -760,7 +771,7 @@ class XendDomainInfo:
   17.63          else:
   17.64              self.console = xendConsole.console_create(
   17.65                  self.dom, console_port=self.console_port)
   17.66 -        self.build_domain(ostype, kernel, ramdisk, cmdline)
   17.67 +        self.build_domain(ostype, kernel, ramdisk, cmdline, memmap)
   17.68          self.image = kernel
   17.69          self.ramdisk = ramdisk
   17.70          self.cmdline = cmdline
   17.71 @@ -804,6 +815,18 @@ class XendDomainInfo:
   17.72              index[dev_name] = dev_index + 1
   17.73          deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
   17.74          deferred.addErrback(dlist_err)
   17.75 +        if self.is_vmx:
   17.76 +            device_model = sxp.child_value(self.config, 'device_model')
   17.77 +            device_config = sxp.child_value(self.config, 'device_config')
   17.78 +            memory = sxp.child_value(self.config, "memory")
   17.79 +            # Create an event channel
   17.80 +            device_channel = channel.eventChannel(0, self.dom)
   17.81 +            # Fork and exec device_model -f device_config <port>
   17.82 +            os.system(device_model
   17.83 +                      + " -f %s" % device_config
   17.84 +                      + " -d %d" % self.dom
   17.85 +                      + " -p %d" % device_channel['port1']
   17.86 +                      + " -m %s &" % memory)
   17.87          return deferred
   17.88  
   17.89      def device_create(self, dev_config):
   17.90 @@ -1091,7 +1114,33 @@ def vm_image_plan9(vm, image):
   17.91      vm.create_domain("plan9", kernel, ramdisk, cmdline)
   17.92      return vm
   17.93      
   17.94 -    
   17.95 +def vm_image_vmx(vm, image):
   17.96 +    """Create a VM for the VMX environment.
   17.97 +
   17.98 +    @param name:      vm name
   17.99 +    @param memory:    vm memory
  17.100 +    @param image:     image config
  17.101 +    @return: vm
  17.102 +    """
  17.103 +    kernel = sxp.child_value(image, "kernel")
  17.104 +    cmdline = ""
  17.105 +    ip = sxp.child_value(image, "ip", "dhcp")
  17.106 +    if ip:
  17.107 +        cmdline += " ip=" + ip
  17.108 +    root = sxp.child_value(image, "root")
  17.109 +    if root:
  17.110 +        cmdline += " root=" + root
  17.111 +    args = sxp.child_value(image, "args")
  17.112 +    if args:
  17.113 +        cmdline += " " + args
  17.114 +    ramdisk = sxp.child_value(image, "ramdisk", '')
  17.115 +    memmap = sxp.child_value(vm.config, "memmap", '')
  17.116 +    memmap = sxp.parse(open(memmap))[0]
  17.117 +    from xen.util.memmap import memmap_parse
  17.118 +    memmap = memmap_parse(memmap)
  17.119 +    vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap)
  17.120 +    vm.is_vmx = 1
  17.121 +    return vm
  17.122  
  17.123  def vm_dev_vif(vm, val, index, change=0):
  17.124      """Create a virtual network interface (vif).
  17.125 @@ -1215,6 +1264,7 @@ def vm_field_maxmem(vm, config, val, ind
  17.126  # Register image handlers.
  17.127  add_image_handler('linux',  vm_image_linux)
  17.128  add_image_handler('plan9',  vm_image_plan9)
  17.129 +add_image_handler('vmx',  vm_image_vmx)
  17.130  
  17.131  # Register device handlers.
  17.132  add_device_handler('vif',  vm_dev_vif)
    18.1 --- a/tools/python/xen/xm/create.py	Sun Jan 02 17:38:14 2005 +0000
    18.2 +++ b/tools/python/xen/xm/create.py	Mon Jan 10 10:59:25 2005 +0000
    18.3 @@ -210,6 +210,18 @@ gopts.var('nfs_root', val="PATH",
    18.4            fn=set_value, default=None,
    18.5            use="Set the path of the root NFS directory.")
    18.6  
    18.7 +gopts.var('memmap', val='FILE',
    18.8 +          fn=set_value, default='',
    18.9 +          use="Path to memap SXP file.")
   18.10 +
   18.11 +gopts.var('device_model', val='FILE',
   18.12 +          fn=set_value, default='',
   18.13 +          use="Path to device model program.")
   18.14 +
   18.15 +gopts.var('device_config', val='FILE',
   18.16 +          fn=set_value, default='',
   18.17 +          use="Path to device model configuration.")
   18.18 +
   18.19  def strip(pre, s):
   18.20      """Strip prefix 'pre' if present.
   18.21      """
   18.22 @@ -309,6 +321,15 @@ def configure_vfr(config, vals):
   18.23           config_vfr.append(['vif', ['id', idx], ['ip', ip]])
   18.24       config.append(config_vfr)
   18.25  
   18.26 +def configure_vmx(config_devs, vals):
   18.27 +    """Create the config for VMX devices.
   18.28 +    """
   18.29 +    memmap = vals.memmap
   18.30 +    device_model = vals.device_model
   18.31 +    device_config = vals.device_config
   18.32 +    config_devs.append(['memmap', memmap])
   18.33 +    config_devs.append(['device_model', device_model])
   18.34 +    config_devs.append(['device_config', device_config])
   18.35  
   18.36  def make_config(vals):
   18.37      """Create the domain configuration.
   18.38 @@ -337,6 +358,7 @@ def make_config(vals):
   18.39      configure_disks(config_devs, vals)
   18.40      configure_pci(config_devs, vals)
   18.41      configure_vifs(config_devs, vals)
   18.42 +    configure_vmx(config_devs, vals)
   18.43      config += config_devs
   18.44      return config
   18.45  
    19.1 --- a/xen/arch/x86/Makefile	Sun Jan 02 17:38:14 2005 +0000
    19.2 +++ b/xen/arch/x86/Makefile	Mon Jan 10 10:59:25 2005 +0000
    19.3 @@ -16,7 +16,7 @@ ifneq ($(TARGET_SUBARCH),x86_32)
    19.4  OBJS := $(subst vmx.o,,$(OBJS))
    19.5  OBJS := $(subst vmx_io.o,,$(OBJS))
    19.6  OBJS := $(subst vmx_vmcs.o,,$(OBJS))
    19.7 -endif ($(TARGET_SUBARCH),x86_32)
    19.8 +endif
    19.9  
   19.10  default: boot/$(TARGET_SUBARCH).o $(OBJS) boot/mkelf32
   19.11  	$(LD) $(LDFLAGS) -r -o arch.o $(OBJS)
    20.1 --- a/xen/arch/x86/domain.c	Sun Jan 02 17:38:14 2005 +0000
    20.2 +++ b/xen/arch/x86/domain.c	Mon Jan 10 10:59:25 2005 +0000
    20.3 @@ -363,9 +363,10 @@ int arch_final_setup_guestos(struct exec
    20.4       * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically.
    20.5       * If SS RPL or DPL differs from CS RPL then we'll #GP.
    20.6       */
    20.7 -    if ( ((d->thread.user_ctxt.cs & 3) == 0) ||
    20.8 -         ((d->thread.user_ctxt.ss & 3) == 0) )
    20.9 -        return -EINVAL;
   20.10 +    if (!(c->flags & ECF_VMX_GUEST)) 
   20.11 +        if ( ((d->thread.user_ctxt.cs & 3) == 0) ||
   20.12 +             ((d->thread.user_ctxt.ss & 3) == 0) )
   20.13 +                return -EINVAL;
   20.14  
   20.15      memcpy(&d->thread.i387,
   20.16             &c->fpu_ctxt,
   20.17 @@ -412,10 +413,8 @@ int arch_final_setup_guestos(struct exec
   20.18          }
   20.19      }
   20.20  
   20.21 -#ifdef CONFIG_VMX
   20.22      if (c->flags & ECF_VMX_GUEST)
   20.23          return vmx_final_setup_guestos(d, c);
   20.24 -#endif
   20.25  
   20.26      return 0;
   20.27  }
    21.1 --- a/xen/arch/x86/memory.c	Sun Jan 02 17:38:14 2005 +0000
    21.2 +++ b/xen/arch/x86/memory.c	Mon Jan 10 10:59:25 2005 +0000
    21.3 @@ -467,11 +467,12 @@ static void put_page_from_l1e(l1_pgentry
    21.4      unsigned long    l1v  = l1_pgentry_val(l1e);
    21.5      unsigned long    pfn  = l1_pgentry_to_pagenr(l1e);
    21.6      struct pfn_info *page = &frame_table[pfn];
    21.7 -    struct domain   *e = page->u.inuse.domain;
    21.8 +    struct domain   *e;
    21.9  
   21.10      if ( !(l1v & _PAGE_PRESENT) || !pfn_is_ram(pfn) )
   21.11          return;
   21.12  
   21.13 +    e = page->u.inuse.domain;
   21.14      if ( unlikely(e != d) )
   21.15      {
   21.16          /*
    22.1 --- a/xen/arch/x86/mtrr/generic.c	Sun Jan 02 17:38:14 2005 +0000
    22.2 +++ b/xen/arch/x86/mtrr/generic.c	Mon Jan 10 10:59:25 2005 +0000
    22.3 @@ -250,7 +250,7 @@ static void prepare_set(void)
    22.4  	/*  Save value of CR4 and clear Page Global Enable (bit 7)  */
    22.5  	if ( cpu_has_pge ) {
    22.6  		cr4 = read_cr4();
    22.7 -		write_cr4(cr4 & (unsigned char) ~(1 << 7));
    22.8 +		write_cr4(cr4 & ~X86_CR4_PGE);
    22.9  	}
   22.10  
   22.11  	/* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
    23.1 --- a/xen/arch/x86/shadow.c	Sun Jan 02 17:38:14 2005 +0000
    23.2 +++ b/xen/arch/x86/shadow.c	Mon Jan 10 10:59:25 2005 +0000
    23.3 @@ -539,10 +539,10 @@ static void shadow_map_l1_into_current_l
    23.4          __shadow_set_pl2e(m, va, spl2e);
    23.5  
    23.6          gpl1e = (unsigned long *) &(linear_pg_table[
    23.7 -            (va>>L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE-1)]);
    23.8 +            (va>>L1_PAGETABLE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)]);
    23.9  
   23.10          spl1e = (unsigned long *) &(shadow_linear_pg_table[
   23.11 -            (va>>L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE-1)]);
   23.12 +            (va>>L1_PAGETABLE_SHIFT) & ~(ENTRIES_PER_L1_PAGETABLE-1)]);
   23.13  
   23.14          for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ )
   23.15              l1pte_propagate_from_guest(m, &gpl1e[i], &spl1e[i]);
    24.1 --- a/xen/arch/x86/vmx.c	Sun Jan 02 17:38:14 2005 +0000
    24.2 +++ b/xen/arch/x86/vmx.c	Mon Jan 10 10:59:25 2005 +0000
    24.3 @@ -75,7 +75,7 @@ int start_vmx()
    24.4  
    24.5  void stop_vmx()
    24.6  {
    24.7 -    if (test_bit(X86_FEATURE_VMXE, &boot_cpu_data.x86_capability))
    24.8 +    if (read_cr4() & X86_CR4_VMXE)
    24.9          __vmxoff();
   24.10  }
   24.11  
    25.1 --- a/xen/arch/x86/x86_32/entry.S	Sun Jan 02 17:38:14 2005 +0000
    25.2 +++ b/xen/arch/x86/x86_32/entry.S	Mon Jan 10 10:59:25 2005 +0000
    25.3 @@ -75,14 +75,24 @@
    25.4   *
    25.5   * We also need the room, especially because orig_eax field is used 
    25.6   * by do_IRQ(). Compared the xen_regs, we skip pushing for the following:
    25.7 - * (1/1)  u16 error_code;
    25.8 - * (2/1)  u16 entry_vector;
    25.9 + *   (10) u32 gs;                 
   25.10 + *   (9)  u32 fs;
   25.11 + *   (8)  u32 ds;
   25.12 + *   (7)  u32 es;
   25.13 + *               <- get_stack_top() (= HOST_ESP)
   25.14 + *   (6)  u32 ss;
   25.15 + *   (5)  u32 esp;
   25.16 + *   (4)  u32 eflags;
   25.17 + *   (3)  u32 cs;
   25.18   *   (2)  u32 eip;
   25.19 - *   (3)  u32 cs;
   25.20 - *   (4)  u32 eflags;
   25.21 + * (2/1)  u16 entry_vector;
   25.22 + * (1/1)  u16 error_code;
   25.23 + * However, get_stack_top() acturally returns 20 bytes below the real
   25.24 + * top of the stack to allow space for:
   25.25 + * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers.
   25.26   */
   25.27  #define VMX_MONITOR_EFLAGS	0x202 /* IF on */
   25.28 -#define NR_SKIPPED_REGS	4	/* See the above explanation */
   25.29 +#define NR_SKIPPED_REGS	6	/* See the above explanation */
   25.30  #define VMX_SAVE_ALL_NOSEGREGS \
   25.31          pushl $VMX_MONITOR_EFLAGS; \
   25.32          popf; \
    26.1 --- a/xen/common/physdev.c	Sun Jan 02 17:38:14 2005 +0000
    26.2 +++ b/xen/common/physdev.c	Mon Jan 10 10:59:25 2005 +0000
    26.3 @@ -45,6 +45,7 @@ extern void pcibios_enable_irq(struct pc
    26.4  #define INFO(_f, _a...) ((void)0)
    26.5  #endif
    26.6  
    26.7 +#define SLOPPY_CHECKING
    26.8  
    26.9  #define ACC_READ  1
   26.10  #define ACC_WRITE 2
   26.11 @@ -305,7 +306,7 @@ inline static int check_dev_acc (struct 
   26.12      return 0;
   26.13  }
   26.14  
   26.15 -
   26.16 +#ifndef SLOPPY_CHECKING
   26.17  /*
   26.18   * Base address registers contain the base address for IO regions.
   26.19   * The length can be determined by writing all 1s to the register and
   26.20 @@ -496,6 +497,7 @@ static int do_rom_address_access(phys_de
   26.21      return ret;
   26.22  
   26.23  }
   26.24 +#endif /* SLOPPY_CHECKING */
   26.25  
   26.26  /*
   26.27   * Handle a PCI config space read access if the domain has access privileges.
   26.28 @@ -512,12 +514,13 @@ static long pci_cfgreg_read(int bus, int
   26.29           * all 1s.  In this case the domain has no read access, which should
   26.30           * also look like the device is non-existent. */
   26.31          *val = 0xFFFFFFFF;
   26.32 -        return ret; /* KAF: error return seems to matter on my test machine. */
   26.33 +        return ret;
   26.34      }
   26.35  
   26.36      /* Fake out read requests for some registers. */
   26.37      switch ( reg )
   26.38      {
   26.39 +#ifndef SLOPPY_CHECKING
   26.40      case PCI_BASE_ADDRESS_0:
   26.41          ret = do_base_address_access(pdev, ACC_READ, 0, len, val);
   26.42          break;
   26.43 @@ -545,6 +548,7 @@ static long pci_cfgreg_read(int bus, int
   26.44      case PCI_ROM_ADDRESS:
   26.45          ret = do_rom_address_access(pdev, ACC_READ, len, val);
   26.46          break;        
   26.47 +#endif
   26.48  
   26.49      case PCI_INTERRUPT_LINE:
   26.50          *val = pdev->dev->irq;
   26.51 @@ -577,6 +581,7 @@ static long pci_cfgreg_write(int bus, in
   26.52      /* special treatment for some registers */
   26.53      switch (reg)
   26.54      {
   26.55 +#ifndef SLOPPY_CHECKING
   26.56      case PCI_BASE_ADDRESS_0:
   26.57          ret = do_base_address_access(pdev, ACC_WRITE, 0, len, &val);
   26.58          break;
   26.59 @@ -604,6 +609,7 @@ static long pci_cfgreg_write(int bus, in
   26.60      case PCI_ROM_ADDRESS:
   26.61          ret = do_rom_address_access(pdev, ACC_WRITE, len, &val);
   26.62          break;        
   26.63 +#endif
   26.64  
   26.65      default:
   26.66          if ( pdev->flags != ACC_WRITE )