ia64/xen-unstable

changeset 3390:2afa7aa0076f

bitkeeper revision 1.1159.212.10 (41dde8b1uPUodrtnTKejSUrLg-fcoQ)

xend extensiosn for VMX guests
author iap10@labyrinth.cl.cam.ac.uk
date Fri Jan 07 01:41:05 2005 +0000 (2005-01-07)
parents 6223f62df1d8
children 3d57409179f9
files .rootkeys tools/examples/Makefile tools/examples/bochsrc tools/examples/mem-map.sxp tools/examples/xmexample.vmx 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
line diff
     1.1 --- a/.rootkeys	Fri Jan 07 01:16:26 2005 +0000
     1.2 +++ b/.rootkeys	Fri Jan 07 01:41:05 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/tools/examples/Makefile	Fri Jan 07 01:16:26 2005 +0000
     2.2 +++ b/tools/examples/Makefile	Fri Jan 07 01:41:05 2005 +0000
     2.3 @@ -8,6 +8,9 @@ XEN_CONFIG_DIR = /etc/xen
     2.4  XEN_CONFIGS = xend-config.sxp
     2.5  XEN_CONFIGS += xmexample1 
     2.6  XEN_CONFIGS += xmexample2
     2.7 +XEN_CONFIGS += xmexample.vmx
     2.8 +XEN_CONFIGS += mem-map.sxp
     2.9 +XEN_CONFIGS += bochsrc
    2.10  
    2.11  # Xen script dir and scripts to go there.
    2.12  XEN_SCRIPT_DIR = /etc/xen/scripts
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/examples/bochsrc	Fri Jan 07 01:41:05 2005 +0000
     3.3 @@ -0,0 +1,19 @@
     3.4 +#megs: 32
     3.5 +#romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000
     3.6 +#vgaromimage: $BXSHARE/VGABIOS-lgpl-latest
     3.7 +floppya: 1_44=a.img, status=inserted
     3.8 +floppyb: 1_44=b.img, status=inserted
     3.9 +#ata0-master: type=disk, path=minibootable.img, cylinders=900, heads=15, spt=17
    3.10 +# if you don't use absolute paths below, bochs looks under the cwd of xend, 
    3.11 +# which is usually "/"
    3.12 +ata0-master: type=disk, path=/tmp/min-fc2-i386.img, cylinders=800, heads=4, spt=32
    3.13 +boot: c
    3.14 +
    3.15 +log: /tmp/bochsout.txt
    3.16 +#debug: action=report
    3.17 +info: action=report
    3.18 +error: action=report
    3.19 +panic: action=ask
    3.20 +
    3.21 +mouse: enabled=0
    3.22 +ips: 1500000
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/examples/mem-map.sxp	Fri Jan 07 01:41:05 2005 +0000
     4.3 @@ -0,0 +1,10 @@
     4.4 +(memmap
     4.5 + (0000000000000000  000000000009f800 "AddressRangeMemory"   WB)
     4.6 + (000000000009f800  00000000000a0000 "AddressRangeReserved" UC)
     4.7 + (00000000000a0000  00000000000bffff "AddressRangeIO"       UC)
     4.8 + (00000000000f0000  0000000000100000 "AddressRangeReserved" UC)
     4.9 + (0000000000100000  0000000008000000 "AddressRangeMemory"   WB)
    4.10 + (0000000007fff000  0000000008000000 "AddressRangeShared"   WB)
    4.11 + (0000000008000000  0000000008003000 "AddressRangeNVS"      UC)
    4.12 + (0000000008003000  000000000800d000 "AddressRangeACPI"     WB)
    4.13 + (00000000fec00000  0000000100000000 "AddressRangeIO"       UC))
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/examples/xmexample.vmx	Fri Jan 07 01:41:05 2005 +0000
     5.3 @@ -0,0 +1,93 @@
     5.4 +#  -*- mode: python; -*-
     5.5 +#============================================================================
     5.6 +# Python configuration setup for 'xm create'.
     5.7 +# This script sets the parameters used when a domain is created using 'xm create'.
     5.8 +# You use a separate script for each domain you want to create, or 
     5.9 +# you can set the parameters for the domain on the xm command line.
    5.10 +#============================================================================
    5.11 +
    5.12 +#----------------------------------------------------------------------------
    5.13 +# Kernel image file.
    5.14 +kernel = "/boot/vmlinuz-rhel3-static"
    5.15 +
    5.16 +# Optional ramdisk.
    5.17 +#ramdisk = "/boot/initrd.gz"
    5.18 +
    5.19 +# The domain build function. Default is 'linux'.
    5.20 +builder='vmx'
    5.21 +#builder='linux'
    5.22 +#builder='netbsd'
    5.23 +
    5.24 +# Initial memory allocation (in megabytes) for the new domain.
    5.25 +memory = 128
    5.26 +
    5.27 +# A name for your domain. All domains must have different names.
    5.28 +name = "ExampleVMXDomain"
    5.29 +
    5.30 +# Which CPU to start domain on? 
    5.31 +#cpu = -1   # leave to Xen to pick
    5.32 +
    5.33 +#----------------------------------------------------------------------------
    5.34 +# Define network interfaces.
    5.35 +
    5.36 +# Number of network interfaces. Default is 1.
    5.37 +#nics=1
    5.38 +nics=0
    5.39 +
    5.40 +# Optionally define mac and/or bridge for the network interfaces.
    5.41 +# Random MACs are assigned if not given.
    5.42 +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ]
    5.43 +
    5.44 +#----------------------------------------------------------------------------
    5.45 +# Define the disk devices you want the domain to have access to, and
    5.46 +# what you want them accessible as.
    5.47 +# Each disk entry is of the form phy:UNAME,DEV,MODE
    5.48 +# where UNAME is the device, DEV is the device name the domain will see,
    5.49 +# and MODE is r for read-only, w for read-write.
    5.50 +
    5.51 +#disk = [ 'phy:hda1,hda1,r' ]
    5.52 +
    5.53 +#----------------------------------------------------------------------------
    5.54 +# Set the kernel command line for the new domain.
    5.55 +# You only need to define the IP parameters and hostname if the domain's
    5.56 +# IP config doesn't, e.g. in ifcfg-eth0 or via DHCP.
    5.57 +# You can use 'extra' to set the runlevel and custom environment
    5.58 +# variables used by custom rc scripts (e.g. VMID=, usr= ).
    5.59 +
    5.60 +# Set if you want dhcp to allocate the IP address.
    5.61 +#dhcp="dhcp"
    5.62 +# Set netmask.
    5.63 +#netmask=
    5.64 +# Set default gateway.
    5.65 +#gateway=
    5.66 +# Set the hostname.
    5.67 +#hostname= "vm%d" % vmid
    5.68 +
    5.69 +# Set root device.
    5.70 +#root = "/dev/ram0"
    5.71 +root = "/dev/hda1 ro"
    5.72 +
    5.73 +# Root device for nfs.
    5.74 +#root = "/dev/nfs"
    5.75 +# The nfs server.
    5.76 +#nfs_server = '169.254.1.0'  
    5.77 +# Root directory on the nfs server.
    5.78 +#nfs_root   = '/full/path/to/root/directory'
    5.79 +
    5.80 +# Sets runlevel 4.
    5.81 +extra = "1"
    5.82 +
    5.83 +#----------------------------------------------------------------------------
    5.84 +# Set according to whether you want the domain restarted when it exits.
    5.85 +# The default is 'onreboot', which restarts the domain when it shuts down
    5.86 +# with exit code reboot.
    5.87 +# Other values are 'always', and 'never'.
    5.88 +
    5.89 +#restart = 'onreboot'
    5.90 +
    5.91 +#============================================================================
    5.92 +
    5.93 +# New stuff
    5.94 +memmap = '/etc/xen/mem-map.sxp'
    5.95 +device_model = '/usr/sbin/device-model'
    5.96 +device_config = '/etc/xen/bochsrc'
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/libxc/linux_boot_params.h	Fri Jan 07 01:41:05 2005 +0000
     6.3 @@ -0,0 +1,163 @@
     6.4 +#ifndef __LINUX_BOOT_PARAMS_H__
     6.5 +#define __LINUX_BOOT_PARAMS_H__
     6.6 +
     6.7 +#include <asm/types.h>
     6.8 +
     6.9 +#define E820MAX	32
    6.10 +
    6.11 +struct mem_map {
    6.12 +    int nr_map;
    6.13 +    struct entry {
    6.14 +        unsigned long long addr;	/* start of memory segment */
    6.15 +        unsigned long long size;	/* size of memory segment */
    6.16 +        unsigned long type;		/* type of memory segment */
    6.17 +#define E820_RAM        1
    6.18 +#define E820_RESERVED   2
    6.19 +#define E820_ACPI       3 /* usable as RAM once ACPI tables have been read */
    6.20 +#define E820_NVS        4
    6.21 +
    6.22 +        unsigned long caching_attr;    /* used by hypervisor */
    6.23 +#define MEMMAP_UC	0
    6.24 +#define MEMMAP_WC	1
    6.25 +#define MEMMAP_WT	4
    6.26 +#define MEMMAP_WP	5
    6.27 +#define MEMMAP_WB	6
    6.28 +
    6.29 +    }map[E820MAX];
    6.30 +};
    6.31 +
    6.32 +struct e820entry {
    6.33 +	unsigned long long addr;	/* start of memory segment */
    6.34 +	unsigned long long size;	/* size of memory segment */
    6.35 +	unsigned long type;		/* type of memory segment */
    6.36 +};
    6.37 +
    6.38 +struct e820map {
    6.39 +    int nr_map;
    6.40 +    struct e820entry map[E820MAX];
    6.41 +};
    6.42 +
    6.43 +struct drive_info_struct { __u8 dummy[32]; }; 
    6.44 +
    6.45 +struct sys_desc_table { 
    6.46 +    __u16 length; 
    6.47 +    __u8 table[318]; 
    6.48 +}; 
    6.49 +
    6.50 +struct screen_info {
    6.51 +    unsigned char  orig_x;		/* 0x00 */
    6.52 +    unsigned char  orig_y;		/* 0x01 */
    6.53 +    unsigned short dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
    6.54 +    unsigned short orig_video_page;	/* 0x04 */
    6.55 +    unsigned char  orig_video_mode;	/* 0x06 */
    6.56 +    unsigned char  orig_video_cols;	/* 0x07 */
    6.57 +    unsigned short unused2;		/* 0x08 */
    6.58 +    unsigned short orig_video_ega_bx;	/* 0x0a */
    6.59 +    unsigned short unused3;		/* 0x0c */
    6.60 +    unsigned char  orig_video_lines;	/* 0x0e */
    6.61 +    unsigned char  orig_video_isVGA;	/* 0x0f */
    6.62 +    unsigned short orig_video_points;	/* 0x10 */
    6.63 +    
    6.64 +    /* VESA graphic mode -- linear frame buffer */
    6.65 +    unsigned short lfb_width;		/* 0x12 */
    6.66 +    unsigned short lfb_height;		/* 0x14 */
    6.67 +    unsigned short lfb_depth;		/* 0x16 */
    6.68 +    unsigned long  lfb_base;		/* 0x18 */
    6.69 +    unsigned long  lfb_size;		/* 0x1c */
    6.70 +    unsigned short dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
    6.71 +    unsigned short lfb_linelength;	/* 0x24 */
    6.72 +    unsigned char  red_size;		/* 0x26 */
    6.73 +    unsigned char  red_pos;		/* 0x27 */
    6.74 +    unsigned char  green_size;		/* 0x28 */
    6.75 +    unsigned char  green_pos;		/* 0x29 */
    6.76 +    unsigned char  blue_size;		/* 0x2a */
    6.77 +    unsigned char  blue_pos;		/* 0x2b */
    6.78 +    unsigned char  rsvd_size;		/* 0x2c */
    6.79 +    unsigned char  rsvd_pos;		/* 0x2d */
    6.80 +    unsigned short vesapm_seg;		/* 0x2e */
    6.81 +    unsigned short vesapm_off;		/* 0x30 */
    6.82 +    unsigned short pages;		/* 0x32 */
    6.83 +					/* 0x34 -- 0x3f reserved for future expansion */
    6.84 +};
    6.85 +
    6.86 +struct screen_info_overlap { 
    6.87 +    __u8 reserved1[2]; /* 0x00 */ 
    6.88 +    __u16 ext_mem_k; /* 0x02 */ 
    6.89 +    __u8 reserved2[0x20 - 0x04]; /* 0x04 */ 
    6.90 +    __u16 cl_magic; /* 0x20 */ 
    6.91 +#define CL_MAGIC_VALUE 0xA33F 
    6.92 +    __u16 cl_offset; /* 0x22 */ 
    6.93 +    __u8 reserved3[0x40 - 0x24]; /* 0x24 */ 
    6.94 +}; 
    6.95 +
    6.96 +
    6.97 +struct apm_bios_info {
    6.98 +    __u16 version;
    6.99 +    __u16  cseg;
   6.100 +    __u32   offset;
   6.101 +    __u16  cseg_16;
   6.102 +    __u16  dseg;
   6.103 +    __u16  flags;
   6.104 +    __u16  cseg_len;
   6.105 +    __u16  cseg_16_len;
   6.106 +    __u16  dseg_len;
   6.107 +};
   6.108 + 
   6.109 +struct linux_boot_params { 
   6.110 +    union { /* 0x00 */ 
   6.111 +       struct screen_info info; 
   6.112 +       struct screen_info_overlap overlap; 
   6.113 +    } screen; 
   6.114 + 
   6.115 +    struct apm_bios_info apm_bios_info; /* 0x40 */ 
   6.116 +    __u8 reserved4[0x80 - 0x54]; /* 0x54 */ 
   6.117 +    struct drive_info_struct drive_info; /* 0x80 */ 
   6.118 +    struct sys_desc_table sys_desc_table; /* 0xa0 */ 
   6.119 +    __u32 alt_mem_k; /* 0x1e0 */ 
   6.120 +    __u8 reserved5[4]; /* 0x1e4 */ 
   6.121 +    __u8 e820_map_nr; /* 0x1e8 */ 
   6.122 +    __u8 reserved6[8]; /* 0x1e9 */ 
   6.123 +    __u8 setup_sects; /* 0x1f1 */ 
   6.124 +    __u16 mount_root_rdonly; /* 0x1f2 */ 
   6.125 +    __u16 syssize; /* 0x1f4 */ 
   6.126 +    __u16 swapdev; /* 0x1f6 */ 
   6.127 +    __u16 ramdisk_flags; /* 0x1f8 */ 
   6.128 +#define RAMDISK_IMAGE_START_MASK 0x07FF 
   6.129 +#define RAMDISK_PROMPT_FLAG 0x8000 
   6.130 +#define RAMDISK_LOAD_FLAG 0x4000 
   6.131 +    __u16 vid_mode; /* 0x1fa */ 
   6.132 +    __u16 root_dev; /* 0x1fc */ 
   6.133 +    __u8 reserved9[1]; /* 0x1fe */ 
   6.134 +    __u8 aux_device_info; /* 0x1ff */ 
   6.135 +    /* 2.00+ */ 
   6.136 +    __u8 reserved10[2]; /* 0x200 */ 
   6.137 +    __u8 header_magic[4]; /* 0x202 */ 
   6.138 +    __u16 protocol_version; /* 0x206 */ 
   6.139 +    __u8 reserved11[8]; /* 0x208 */ 
   6.140 +    __u8 loader_type; /* 0x210 */ 
   6.141 +#define LOADER_TYPE_LOADLIN 1 
   6.142 +#define LOADER_TYPE_BOOTSECT_LOADER 2 
   6.143 +#define LOADER_TYPE_SYSLINUX 3 
   6.144 +#define LOADER_TYPE_ETHERBOOT 4 
   6.145 +#define LOADER_TYPE_UNKNOWN 0xFF 
   6.146 +    __u8 loader_flags; /* 0x211 */ 
   6.147 +    __u8 reserved12[2]; /* 0x212 */ 
   6.148 +    __u32 code32_start; /* 0x214 */ 
   6.149 +    __u32 initrd_start; /* 0x218 */ 
   6.150 +    __u32 initrd_size; /* 0x21c */ 
   6.151 +    __u8 reserved13[4]; /* 0x220 */ 
   6.152 +    /* 2.01+ */ 
   6.153 +    __u16 heap_end_ptr; /* 0x224 */ 
   6.154 +    __u8 reserved14[2]; /* 0x226 */ 
   6.155 +    /* 2.02+ */ 
   6.156 +    __u32 cmd_line_ptr; /* 0x228 */ 
   6.157 +    /* 2.03+ */ 
   6.158 +    __u32 ramdisk_max; /* 0x22c */ 
   6.159 +    __u8 reserved15[0x2d0 - 0x230]; /* 0x230 */ 
   6.160 +    struct e820entry e820_map[E820MAX]; /* 0x2d0 */ 
   6.161 +    __u64 shared_info; /* 0x550 */
   6.162 +    __u8 padding[0x800 - 0x558]; /* 0x558 */ 
   6.163 +    __u8 cmd_line[0x800]; /* 0x800 */
   6.164 +} __attribute__((packed)); 
   6.165 +
   6.166 +#endif /* __LINUX_BOOT_PARAMS_H__ */
     7.1 --- a/tools/libxc/xc.h	Fri Jan 07 01:16:26 2005 +0000
     7.2 +++ b/tools/libxc/xc.h	Fri Jan 07 01:41:05 2005 +0000
     7.3 @@ -10,6 +10,8 @@
     7.4  #define __XC_H__
     7.5  
     7.6  #include <stdint.h>
     7.7 +#include "linux_boot_params.h"
     7.8 +
     7.9  typedef uint8_t            u8;
    7.10  typedef uint16_t           u16;
    7.11  typedef uint32_t           u32;
    7.12 @@ -105,6 +107,15 @@ xc_plan9_build (int xc_handle,
    7.13  		unsigned int control_evtchn, 
    7.14  		unsigned long flags);
    7.15  
    7.16 +int xc_vmx_build(int xc_handle,
    7.17 +                 u32 domid,
    7.18 +                 const char *image_name,
    7.19 +                 struct mem_map *memmap,
    7.20 +                 const char *ramdisk_name,
    7.21 +                 const char *cmdline,
    7.22 +                 unsigned int control_evtchn,
    7.23 +                 unsigned long flags);
    7.24 +
    7.25  int xc_bvtsched_global_set(int xc_handle,
    7.26                             unsigned long ctx_allow);
    7.27  
    7.28 @@ -208,4 +219,7 @@ void *xc_map_foreign_range(int xc_handle
    7.29  void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot,
    7.30                             unsigned long *arr, int num );
    7.31  
    7.32 +int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
    7.33 +		    unsigned long max_pfns);
    7.34 +
    7.35  #endif /* __XC_H__ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/libxc/xc_vmx_build.c	Fri Jan 07 01:41:05 2005 +0000
     8.3 @@ -0,0 +1,865 @@
     8.4 +/******************************************************************************
     8.5 + * xc_vmx_build.c
     8.6 + */
     8.7 +
     8.8 +#include "xc_private.h"
     8.9 +#define ELFSIZE 32
    8.10 +#include "xc_elf.h"
    8.11 +#include <stdlib.h>
    8.12 +#include <zlib.h>
    8.13 +#include "linux_boot_params.h"
    8.14 +
    8.15 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    8.16 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    8.17 +
    8.18 +#define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
    8.19 +#define round_pgdown(_p)  ((_p)&PAGE_MASK)
    8.20 +
    8.21 +#define LINUX_BOOT_PARAMS_ADDR   0x00090000
    8.22 +#define LINUX_KERNEL_ENTR_ADDR   0x00100000
    8.23 +#define LINUX_PAGE_OFFSET        0xC0000000
    8.24 +
    8.25 +struct domain_setup_info
    8.26 +{
    8.27 +    unsigned long v_start;
    8.28 +    unsigned long v_end;
    8.29 +    unsigned long v_kernstart;
    8.30 +    unsigned long v_kernend;
    8.31 +    unsigned long v_kernentry;
    8.32 +
    8.33 +    unsigned int use_writable_pagetables;
    8.34 +    unsigned int load_bsd_symtab;
    8.35 +
    8.36 +    unsigned long symtab_addr;
    8.37 +    unsigned long symtab_len;
    8.38 +};
    8.39 +
    8.40 +static int
    8.41 +parseelfimage(
    8.42 +    char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
    8.43 +static int
    8.44 +loadelfimage(
    8.45 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
    8.46 +    unsigned long vstart);
    8.47 +static int
    8.48 +loadelfsymtab(
    8.49 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
    8.50 +    struct domain_setup_info *dsi);
    8.51 +
    8.52 +static long get_tot_pages(int xc_handle, u32 domid)
    8.53 +{
    8.54 +    dom0_op_t op;
    8.55 +    op.cmd = DOM0_GETDOMAININFO;
    8.56 +    op.u.getdomaininfo.domain = (domid_t)domid;
    8.57 +    op.u.getdomaininfo.ctxt = NULL;
    8.58 +    return (do_dom0_op(xc_handle, &op) < 0) ? 
    8.59 +        -1 : op.u.getdomaininfo.tot_pages;
    8.60 +}
    8.61 +
    8.62 +int xc_get_pfn_list(int xc_handle,
    8.63 +		 u32 domid, 
    8.64 +		 unsigned long *pfn_buf, 
    8.65 +		 unsigned long max_pfns)
    8.66 +{
    8.67 +    dom0_op_t op;
    8.68 +    int ret;
    8.69 +    op.cmd = DOM0_GETMEMLIST;
    8.70 +    op.u.getmemlist.domain   = (domid_t)domid;
    8.71 +    op.u.getmemlist.max_pfns = max_pfns;
    8.72 +    op.u.getmemlist.buffer   = pfn_buf;
    8.73 +
    8.74 +
    8.75 +    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
    8.76 +        return -1;
    8.77 +
    8.78 +    ret = do_dom0_op(xc_handle, &op);
    8.79 +
    8.80 +    (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
    8.81 +
    8.82 +    return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
    8.83 +}
    8.84 +
    8.85 +static int copy_to_domain_page(int xc_handle,
    8.86 +                               u32 domid,
    8.87 +                               unsigned long dst_pfn, 
    8.88 +                               void *src_page)
    8.89 +{
    8.90 +    void *vaddr = xc_map_foreign_range(
    8.91 +        xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
    8.92 +    if ( vaddr == NULL )
    8.93 +        return -1;
    8.94 +    memcpy(vaddr, src_page, PAGE_SIZE);
    8.95 +    munmap(vaddr, PAGE_SIZE);
    8.96 +    return 0;
    8.97 +}
    8.98 +
    8.99 +static int setup_guestos(int xc_handle,
   8.100 +                         u32 dom,
   8.101 +                         char *image, unsigned long image_size,
   8.102 +                         gzFile initrd_gfd, unsigned long initrd_len,
   8.103 +                         unsigned long nr_pages,
   8.104 +                         full_execution_context_t *ctxt,
   8.105 +                         const char *cmdline,
   8.106 +                         unsigned long shared_info_frame,
   8.107 +                         unsigned int control_evtchn,
   8.108 +                         unsigned long flags,
   8.109 +                         struct mem_map * mem_mapp)
   8.110 +{
   8.111 +    l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
   8.112 +    l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
   8.113 +    unsigned long *page_array = NULL;
   8.114 +    unsigned long l2tab;
   8.115 +    unsigned long l1tab;
   8.116 +    unsigned long count, i;
   8.117 +    shared_info_t *shared_info;
   8.118 +    struct linux_boot_params * boot_paramsp;
   8.119 +    __u16 * boot_gdtp;
   8.120 +    mmu_t *mmu = NULL;
   8.121 +    int rc;
   8.122 +
   8.123 +    unsigned long nr_pt_pages;
   8.124 +    unsigned long ppt_alloc;
   8.125 +
   8.126 +    struct domain_setup_info dsi;
   8.127 +    unsigned long vinitrd_start;
   8.128 +    unsigned long vinitrd_end;
   8.129 +    unsigned long vboot_params_start;
   8.130 +    unsigned long vboot_params_end;
   8.131 +    unsigned long vboot_gdt_start;
   8.132 +    unsigned long vboot_gdt_end;
   8.133 +    unsigned long vpt_start;
   8.134 +    unsigned long vpt_end;
   8.135 +    unsigned long v_end;
   8.136 +
   8.137 +    memset(&dsi, 0, sizeof(struct domain_setup_info));
   8.138 +
   8.139 +    rc = parseelfimage(image, image_size, &dsi);
   8.140 +    if ( rc != 0 )
   8.141 +        goto error_out;
   8.142 +
   8.143 +    if (dsi.use_writable_pagetables)
   8.144 +        xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable,
   8.145 +                              VMASST_TYPE_writable_pagetables);
   8.146 +
   8.147 +    if (dsi.load_bsd_symtab)
   8.148 +        loadelfsymtab(image, xc_handle, dom, NULL, &dsi);
   8.149 +
   8.150 +    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
   8.151 +    {
   8.152 +        PERROR("Guest OS must load to a page boundary.\n");
   8.153 +        goto error_out;
   8.154 +    }
   8.155 +
   8.156 +    /*
   8.157 +     * Why do we need this? The number of page-table frames depends on the 
   8.158 +     * size of the bootstrap address space. But the size of the address space 
   8.159 +     * depends on the number of page-table frames (since each one is mapped 
   8.160 +     * read-only). We have a pair of simultaneous equations in two unknowns, 
   8.161 +     * which we solve by exhaustive search.
   8.162 +     */
   8.163 +    nr_pt_pages = 1 + (nr_pages >> (PAGE_SHIFT - 2));
   8.164 +    vboot_params_start = LINUX_BOOT_PARAMS_ADDR;
   8.165 +    vboot_params_end   = vboot_params_start + PAGE_SIZE;
   8.166 +    vboot_gdt_start    = vboot_params_end;
   8.167 +    vboot_gdt_end      = vboot_gdt_start + PAGE_SIZE;
   8.168 +    v_end              = nr_pages << PAGE_SHIFT;
   8.169 +    vpt_end            = v_end - (16 << PAGE_SHIFT); /* leaving the top 64k untouched */
   8.170 +    vpt_start          = vpt_end - (nr_pt_pages << PAGE_SHIFT);
   8.171 +    vinitrd_end        = vpt_start;
   8.172 +    vinitrd_start      = vinitrd_end - initrd_len;
   8.173 +    vinitrd_start      = vinitrd_start & (~(PAGE_SIZE - 1));
   8.174 +
   8.175 +    if(initrd_len == 0)
   8.176 +        vinitrd_start = vinitrd_end = 0;
   8.177 +
   8.178 +    printf("VIRTUAL MEMORY ARRANGEMENT:\n"
   8.179 +           " Boot_params:   %08lx->%08lx\n"
   8.180 +           " boot_gdt:      %08lx->%08lx\n"
   8.181 +           " Loaded kernel: %08lx->%08lx\n"
   8.182 +           " Init. ramdisk: %08lx->%08lx\n"
   8.183 +           " Page tables:   %08lx->%08lx\n"
   8.184 +           " TOTAL:         %08lx->%08lx\n",
   8.185 +           vboot_params_start, vboot_params_end,
   8.186 +           vboot_gdt_start, vboot_gdt_end,
   8.187 +           dsi.v_kernstart, dsi.v_kernend, 
   8.188 +           vinitrd_start, vinitrd_end,
   8.189 +           vpt_start, vpt_end,
   8.190 +           dsi.v_start, v_end);
   8.191 +    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
   8.192 +    printf(" INITRD LENGTH: %08lx\n", initrd_len);
   8.193 +
   8.194 +    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
   8.195 +    {
   8.196 +        printf("Initial guest OS requires too much space\n"
   8.197 +               "(%luMB is greater than %luMB limit)\n",
   8.198 +               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
   8.199 +        goto error_out;
   8.200 +    }
   8.201 +
   8.202 +    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
   8.203 +    {
   8.204 +        PERROR("Could not allocate memory");
   8.205 +        goto error_out;
   8.206 +    }
   8.207 +
   8.208 +    if ( xc_get_pfn_list(xc_handle, dom, page_array, nr_pages) != nr_pages )
   8.209 +    {
   8.210 +        PERROR("Could not get the page frame list");
   8.211 +        goto error_out;
   8.212 +    }
   8.213 +
   8.214 +    loadelfimage(image, xc_handle, dom, page_array, dsi.v_start);
   8.215 +
   8.216 +    if (dsi.load_bsd_symtab)
   8.217 +        loadelfsymtab(image, xc_handle, dom, page_array, &dsi);
   8.218 +
   8.219 +    /* Load the initial ramdisk image. */
   8.220 +    if ( initrd_len != 0 )
   8.221 +    {
   8.222 +        for ( i = (vinitrd_start - dsi.v_start); 
   8.223 +              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
   8.224 +        {
   8.225 +            char page[PAGE_SIZE];
   8.226 +            if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
   8.227 +            {
   8.228 +                PERROR("Error reading initrd image, could not");
   8.229 +                goto error_out;
   8.230 +            }
   8.231 +            copy_to_domain_page(xc_handle, dom,
   8.232 +                                page_array[i>>PAGE_SHIFT], page);
   8.233 +        }
   8.234 +    }
   8.235 +
   8.236 +    if ( (mmu = init_mmu_updates(xc_handle, dom)) == NULL )
   8.237 +        goto error_out;
   8.238 +
   8.239 +    /* First allocate page for page dir. */
   8.240 +    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
   8.241 +    l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   8.242 +    ctxt->pt_base = l2tab;
   8.243 +
   8.244 +    /* Initialise the page tables. */
   8.245 +    if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 
   8.246 +                                        PROT_READ|PROT_WRITE, 
   8.247 +                                        l2tab >> PAGE_SHIFT)) == NULL )
   8.248 +        goto error_out;
   8.249 +    memset(vl2tab, 0, PAGE_SIZE);
   8.250 +    vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
   8.251 +    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
   8.252 +    {    
   8.253 +        if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   8.254 +        {
   8.255 +            l1tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   8.256 +            if ( vl1tab != NULL )
   8.257 +                munmap(vl1tab, PAGE_SIZE);
   8.258 +            if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
   8.259 +                                                PROT_READ|PROT_WRITE,
   8.260 +                                                l1tab >> PAGE_SHIFT)) == NULL )
   8.261 +            {
   8.262 +                munmap(vl2tab, PAGE_SIZE);
   8.263 +                goto error_out;
   8.264 +            }
   8.265 +            memset(vl1tab, 0, PAGE_SIZE);
   8.266 +            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   8.267 +            *vl2e++ = l1tab | L2_PROT;
   8.268 +        }
   8.269 +
   8.270 +        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   8.271 +        if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && 
   8.272 +             (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) )
   8.273 +            *vl1e &= ~_PAGE_RW;
   8.274 +        vl1e++;
   8.275 +    }
   8.276 +    munmap(vl1tab, PAGE_SIZE);
   8.277 +    munmap(vl2tab, PAGE_SIZE);
   8.278 +
   8.279 +    /*
   8.280 +     * Pin down l2tab addr as page dir page - causes hypervisor to provide
   8.281 +     * correct protection for the page
   8.282 +     */ 
   8.283 +    if ( add_mmu_update(xc_handle, mmu,
   8.284 +                        l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE) )
   8.285 +        goto error_out;
   8.286 +
   8.287 +    boot_paramsp = xc_map_foreign_range(
   8.288 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   8.289 +        page_array[(vboot_params_start-dsi.v_start)>>PAGE_SHIFT]);
   8.290 +    memset(boot_paramsp, 0, sizeof(*boot_paramsp));
   8.291 +
   8.292 +    strncpy(boot_paramsp->cmd_line, cmdline, 0x800);
   8.293 +    boot_paramsp->cmd_line[0x800-1] = '\0';
   8.294 +    boot_paramsp->cmd_line_ptr = ((unsigned long) vboot_params_start) + offsetof(struct linux_boot_params, cmd_line);
   8.295 +
   8.296 +    boot_paramsp->setup_sects = 0;
   8.297 +    boot_paramsp->mount_root_rdonly = 1;
   8.298 +    boot_paramsp->swapdev = 0x0; 
   8.299 +    boot_paramsp->ramdisk_flags = 0x0; 
   8.300 +    boot_paramsp->root_dev = 0x0; /* We must tell kernel root dev by kernel command line. */
   8.301 +
   8.302 +    /* we don't have a ps/2 mouse now.
   8.303 +     * 0xAA means a aux mouse is there.
   8.304 +     * See detect_auxiliary_port() in pc_keyb.c.
   8.305 +     */
   8.306 +    boot_paramsp->aux_device_info = 0x0; 
   8.307 +
   8.308 +    boot_paramsp->header_magic[0] = 0x48; /* "H" */
   8.309 +    boot_paramsp->header_magic[1] = 0x64; /* "d" */
   8.310 +    boot_paramsp->header_magic[2] = 0x72; /* "r" */
   8.311 +    boot_paramsp->header_magic[3] = 0x53; /* "S" */
   8.312 +
   8.313 +    boot_paramsp->protocol_version = 0x0203; /* 2.03 */
   8.314 +    boot_paramsp->loader_type = 0x71; /* GRUB */
   8.315 +    boot_paramsp->loader_flags = 0x1; /* loaded high */
   8.316 +    boot_paramsp->code32_start = LINUX_KERNEL_ENTR_ADDR; /* 1MB */
   8.317 +    boot_paramsp->initrd_start = vinitrd_start;
   8.318 +    boot_paramsp->initrd_size = initrd_len;
   8.319 +
   8.320 +    i = (nr_pages >> (PAGE_SHIFT - 10)) - (1 << 10) - 4;
   8.321 +    boot_paramsp->alt_mem_k = i; /* alt_mem_k */
   8.322 +    boot_paramsp->screen.overlap.ext_mem_k = i & 0xFFFF; /* ext_mem_k */
   8.323 +
   8.324 +    /*
   8.325 +     * Stuff SCREAN_INFO
   8.326 +     */
   8.327 +    boot_paramsp->screen.info.orig_x = 0;
   8.328 +    boot_paramsp->screen.info.orig_y = 0;
   8.329 +    boot_paramsp->screen.info.orig_video_page = 8;
   8.330 +    boot_paramsp->screen.info.orig_video_mode = 3;
   8.331 +    boot_paramsp->screen.info.orig_video_cols = 80;
   8.332 +    boot_paramsp->screen.info.orig_video_ega_bx = 0;
   8.333 +    boot_paramsp->screen.info.orig_video_lines = 25;
   8.334 +    boot_paramsp->screen.info.orig_video_isVGA = 1;
   8.335 +    boot_paramsp->screen.info.orig_video_points = 0x0010;
   8.336 +
   8.337 +    /* seems we may NOT stuff boot_paramsp->apm_bios_info */
   8.338 +    /* seems we may NOT stuff boot_paramsp->drive_info */
   8.339 +    /* seems we may NOT stuff boot_paramsp->sys_desc_table */
   8.340 +    *((unsigned short *) &boot_paramsp->drive_info.dummy[0]) = 800;
   8.341 +    boot_paramsp->drive_info.dummy[2] = 4;
   8.342 +    boot_paramsp->drive_info.dummy[14] = 32;
   8.343 +
   8.344 +    boot_paramsp->e820_map_nr = mem_mapp->nr_map;
   8.345 +    for (i=0; i<mem_mapp->nr_map; i++) {
   8.346 +        boot_paramsp->e820_map[i].addr = mem_mapp->map[i].addr; 
   8.347 +        boot_paramsp->e820_map[i].size = mem_mapp->map[i].size; 
   8.348 +        boot_paramsp->e820_map[i].type = mem_mapp->map[i].type; 
   8.349 +    }
   8.350 +    munmap(boot_paramsp, PAGE_SIZE); 
   8.351 +
   8.352 +    boot_gdtp = xc_map_foreign_range(
   8.353 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
   8.354 +        page_array[(vboot_gdt_start-dsi.v_start)>>PAGE_SHIFT]);
   8.355 +    memset(boot_gdtp, 0, PAGE_SIZE);
   8.356 +    boot_gdtp[12*4 + 0] = boot_gdtp[13*4 + 0] = 0xffff; /* limit */
   8.357 +    boot_gdtp[12*4 + 1] = boot_gdtp[13*4 + 1] = 0x0000; /* base */
   8.358 +    boot_gdtp[12*4 + 2] = 0x9a00; boot_gdtp[13*4 + 2] = 0x9200; /* perms */
   8.359 +    boot_gdtp[12*4 + 3] = boot_gdtp[13*4 + 3] = 0x00cf; /* granu + top of limit */
   8.360 +    munmap(boot_gdtp, PAGE_SIZE);
   8.361 +
   8.362 +    /* shared_info page starts its life empty. */
   8.363 +    shared_info = xc_map_foreign_range(
   8.364 +        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
   8.365 +    memset(shared_info, 0, sizeof(shared_info_t));
   8.366 +    /* Mask all upcalls... */
   8.367 +    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   8.368 +        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
   8.369 +    munmap(shared_info, PAGE_SIZE);
   8.370 +
   8.371 +    /* Send the page update requests down to the hypervisor. */
   8.372 +    if ( finish_mmu_updates(xc_handle, mmu) )
   8.373 +        goto error_out;
   8.374 +
   8.375 +    free(mmu);
   8.376 +    free(page_array);
   8.377 +
   8.378 +    /*
   8.379 +     * Initial register values:
   8.380 +     */
   8.381 +    ctxt->cpu_ctxt.ds = 0x68;
   8.382 +    ctxt->cpu_ctxt.es = 0x0;
   8.383 +    ctxt->cpu_ctxt.fs = 0x0;
   8.384 +    ctxt->cpu_ctxt.gs = 0x0;
   8.385 +    ctxt->cpu_ctxt.ss = 0x68;
   8.386 +    ctxt->cpu_ctxt.cs = 0x60;
   8.387 +    ctxt->cpu_ctxt.eip = dsi.v_kernentry;
   8.388 +    ctxt->cpu_ctxt.edx = vboot_gdt_start;
   8.389 +    ctxt->cpu_ctxt.eax = 0x800;
   8.390 +    ctxt->cpu_ctxt.esp = vboot_gdt_end;
   8.391 +    ctxt->cpu_ctxt.ebx = 0;	/* startup_32 expects this to be 0 to signal boot cpu */
   8.392 +    ctxt->cpu_ctxt.ecx = mem_mapp->nr_map;
   8.393 +    ctxt->cpu_ctxt.esi = vboot_params_start;
   8.394 +    ctxt->cpu_ctxt.edi = vboot_params_start + 0x2d0;
   8.395 +
   8.396 +    ctxt->cpu_ctxt.eflags = (1<<2);
   8.397 +
   8.398 +    return 0;
   8.399 +
   8.400 + error_out:
   8.401 +    if ( mmu != NULL )
   8.402 +        free(mmu);
   8.403 +    if ( page_array != NULL )
   8.404 +        free(page_array);
   8.405 +    return -1;
   8.406 +}
   8.407 +
   8.408 +static unsigned long get_filesz(int fd)
   8.409 +{
   8.410 +    u16 sig;
   8.411 +    u32 _sz = 0;
   8.412 +    unsigned long sz;
   8.413 +
   8.414 +    lseek(fd, 0, SEEK_SET);
   8.415 +    read(fd, &sig, sizeof(sig));
   8.416 +    sz = lseek(fd, 0, SEEK_END);
   8.417 +    if ( sig == 0x8b1f ) /* GZIP signature? */
   8.418 +    {
   8.419 +        lseek(fd, -4, SEEK_END);
   8.420 +        read(fd, &_sz, 4);
   8.421 +        sz = _sz;
   8.422 +    }
   8.423 +    lseek(fd, 0, SEEK_SET);
   8.424 +
   8.425 +    return sz;
   8.426 +}
   8.427 +
   8.428 +static char *read_kernel_image(const char *filename, unsigned long *size)
   8.429 +{
   8.430 +    int kernel_fd = -1;
   8.431 +    gzFile kernel_gfd = NULL;
   8.432 +    char *image = NULL;
   8.433 +    unsigned int bytes;
   8.434 +
   8.435 +    if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
   8.436 +    {
   8.437 +        PERROR("Could not open kernel image");
   8.438 +        goto out;
   8.439 +    }
   8.440 +
   8.441 +    *size = get_filesz(kernel_fd);
   8.442 +
   8.443 +    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
   8.444 +    {
   8.445 +        PERROR("Could not allocate decompression state for state file");
   8.446 +        goto out;
   8.447 +    }
   8.448 +
   8.449 +    if ( (image = malloc(*size)) == NULL )
   8.450 +    {
   8.451 +        PERROR("Could not allocate memory for kernel image");
   8.452 +        goto out;
   8.453 +    }
   8.454 +
   8.455 +    if ( (bytes = gzread(kernel_gfd, image, *size)) != *size )
   8.456 +    {
   8.457 +        PERROR("Error reading kernel image, could not"
   8.458 +               " read the whole image (%d != %ld).", bytes, *size);
   8.459 +        free(image);
   8.460 +        image = NULL;
   8.461 +    }
   8.462 +
   8.463 + out:
   8.464 +    if ( kernel_gfd != NULL )
   8.465 +        gzclose(kernel_gfd);
   8.466 +    else if ( kernel_fd >= 0 )
   8.467 +        close(kernel_fd);
   8.468 +    return image;
   8.469 +}
   8.470 +
   8.471 +#define VMX_FEATURE_FLAG 0x20
   8.472 +
   8.473 +int vmx_identify(void)
   8.474 +{
   8.475 +    int eax, ecx;
   8.476 +
   8.477 +    __asm__ __volatile__ ("cpuid" 
   8.478 +			  : "=a" (eax), "=c" (ecx) 
   8.479 +			  : "0" (1) 
   8.480 +			  : "bx", "dx");
   8.481 +    if (!(ecx & VMX_FEATURE_FLAG)) {
   8.482 +        return -1;
   8.483 +    }
   8.484 +    return 0;
   8.485 +}
   8.486 +
   8.487 +int xc_vmx_build(int xc_handle,
   8.488 +                   u32 domid,
   8.489 +                   const char *image_name,
   8.490 +                   struct mem_map *mem_mapp,
   8.491 +                   const char *ramdisk_name,
   8.492 +                   const char *cmdline,
   8.493 +                   unsigned int control_evtchn,
   8.494 +                   unsigned long flags)
   8.495 +{
   8.496 +    dom0_op_t launch_op, op;
   8.497 +    int initrd_fd = -1;
   8.498 +    gzFile initrd_gfd = NULL;
   8.499 +    int rc, i;
   8.500 +    full_execution_context_t st_ctxt, *ctxt = &st_ctxt;
   8.501 +    unsigned long nr_pages;
   8.502 +    char         *image = NULL;
   8.503 +    unsigned long image_size, initrd_size=0;
   8.504 +
   8.505 +    if ( vmx_identify() < 0 )
   8.506 +    {
   8.507 +        PERROR("CPU doesn't support VMX Extensions");
   8.508 +        goto error_out;
   8.509 +    }
   8.510 +    
   8.511 +    if ( (nr_pages = get_tot_pages(xc_handle, domid)) < 0 )
   8.512 +    {
   8.513 +        PERROR("Could not find total pages for domain");
   8.514 +        goto error_out;
   8.515 +    }
   8.516 +
   8.517 +    if ( (image = read_kernel_image(image_name, &image_size)) == NULL )
   8.518 +        goto error_out;
   8.519 +
   8.520 +    if ( (ramdisk_name != NULL) && (strlen(ramdisk_name) != 0) )
   8.521 +    {
   8.522 +        if ( (initrd_fd = open(ramdisk_name, O_RDONLY)) < 0 )
   8.523 +        {
   8.524 +            PERROR("Could not open the initial ramdisk image");
   8.525 +            goto error_out;
   8.526 +        }
   8.527 +
   8.528 +        initrd_size = get_filesz(initrd_fd);
   8.529 +
   8.530 +        if ( (initrd_gfd = gzdopen(initrd_fd, "rb")) == NULL )
   8.531 +        {
   8.532 +            PERROR("Could not allocate decompression state for initrd");
   8.533 +            goto error_out;
   8.534 +        }
   8.535 +    }
   8.536 +
   8.537 +    if ( mlock(&st_ctxt, sizeof(st_ctxt) ) )
   8.538 +    {   
   8.539 +        PERROR("Unable to mlock ctxt");
   8.540 +        return 1;
   8.541 +    }
   8.542 +
   8.543 +    op.cmd = DOM0_GETDOMAININFO;
   8.544 +    op.u.getdomaininfo.domain = (domid_t)domid;
   8.545 +    op.u.getdomaininfo.ctxt = ctxt;
   8.546 +    if ( (do_dom0_op(xc_handle, &op) < 0) || 
   8.547 +         ((u16)op.u.getdomaininfo.domain != domid) )
   8.548 +    {
   8.549 +        PERROR("Could not get info on domain");
   8.550 +        goto error_out;
   8.551 +    }
   8.552 +    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ||
   8.553 +         (ctxt->pt_base != 0) )
   8.554 +    {
   8.555 +        ERROR("Domain is already constructed");
   8.556 +        goto error_out;
   8.557 +    }
   8.558 +
   8.559 +    if ( setup_guestos(xc_handle, domid, image, image_size, 
   8.560 +                       initrd_gfd, initrd_size, nr_pages, 
   8.561 +                       ctxt, cmdline,
   8.562 +                       op.u.getdomaininfo.shared_info_frame,
   8.563 +                       control_evtchn, flags, mem_mapp) < 0 )
   8.564 +    {
   8.565 +        ERROR("Error constructing guest OS");
   8.566 +        goto error_out;
   8.567 +    }
   8.568 +
   8.569 +    if ( initrd_fd >= 0 )
   8.570 +        close(initrd_fd);
   8.571 +    if ( initrd_gfd )
   8.572 +        gzclose(initrd_gfd);
   8.573 +    if ( image != NULL )
   8.574 +        free(image);
   8.575 +
   8.576 +    ctxt->flags = ECF_VMX_GUEST;
   8.577 +    /* FPU is set up to default initial state. */
   8.578 +    memset(ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
   8.579 +
   8.580 +    /* Virtual IDT is empty at start-of-day. */
   8.581 +    for ( i = 0; i < 256; i++ )
   8.582 +    {
   8.583 +        ctxt->trap_ctxt[i].vector = i;
   8.584 +        ctxt->trap_ctxt[i].cs     = FLAT_GUESTOS_CS;
   8.585 +    }
   8.586 +    ctxt->fast_trap_idx = 0;
   8.587 +
   8.588 +    /* No LDT. */
   8.589 +    ctxt->ldt_ents = 0;
   8.590 +    
   8.591 +    /* Use the default Xen-provided GDT. */
   8.592 +    ctxt->gdt_ents = 0;
   8.593 +
   8.594 +    /* Ring 1 stack is the initial stack. */
   8.595 +/*
   8.596 +    ctxt->guestos_ss  = FLAT_GUESTOS_DS;
   8.597 +    ctxt->guestos_esp = vstartinfo_start;
   8.598 +*/
   8.599 +    /* No debugging. */
   8.600 +    memset(ctxt->debugreg, 0, sizeof(ctxt->debugreg));
   8.601 +
   8.602 +    /* No callback handlers. */
   8.603 +    ctxt->event_callback_cs     = FLAT_GUESTOS_CS;
   8.604 +    ctxt->event_callback_eip    = 0;
   8.605 +    ctxt->failsafe_callback_cs  = FLAT_GUESTOS_CS;
   8.606 +    ctxt->failsafe_callback_eip = 0;
   8.607 +
   8.608 +    memset( &launch_op, 0, sizeof(launch_op) );
   8.609 +
   8.610 +    launch_op.u.builddomain.domain   = (domid_t)domid;
   8.611 +    launch_op.u.builddomain.ctxt = ctxt;
   8.612 +
   8.613 +    launch_op.cmd = DOM0_BUILDDOMAIN;
   8.614 +    rc = do_dom0_op(xc_handle, &launch_op);
   8.615 +    return rc;
   8.616 +
   8.617 + error_out:
   8.618 +    if ( initrd_gfd != NULL )
   8.619 +        gzclose(initrd_gfd);
   8.620 +    else if ( initrd_fd >= 0 )
   8.621 +        close(initrd_fd);
   8.622 +    if ( image != NULL )
   8.623 +        free(image);
   8.624 +
   8.625 +    return -1;
   8.626 +}
   8.627 +
   8.628 +static inline int is_loadable_phdr(Elf_Phdr *phdr)
   8.629 +{
   8.630 +    return ((phdr->p_type == PT_LOAD) &&
   8.631 +            ((phdr->p_flags & (PF_W|PF_X)) != 0));
   8.632 +}
   8.633 +
   8.634 +static int parseelfimage(char *elfbase, 
   8.635 +                         unsigned long elfsize,
   8.636 +                         struct domain_setup_info *dsi)
   8.637 +{
   8.638 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
   8.639 +    Elf_Phdr *phdr;
   8.640 +    Elf_Shdr *shdr;
   8.641 +    unsigned long kernstart = ~0UL, kernend=0UL;
   8.642 +    char *shstrtab;
   8.643 +    int h;
   8.644 +
   8.645 +    if ( !IS_ELF(*ehdr) )
   8.646 +    {
   8.647 +        ERROR("Kernel image does not have an ELF header.");
   8.648 +        return -EINVAL;
   8.649 +    }
   8.650 +
   8.651 +    if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
   8.652 +    {
   8.653 +        ERROR("ELF program headers extend beyond end of image.");
   8.654 +        return -EINVAL;
   8.655 +    }
   8.656 +
   8.657 +    if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
   8.658 +    {
   8.659 +        ERROR("ELF section headers extend beyond end of image.");
   8.660 +        return -EINVAL;
   8.661 +    }
   8.662 +
   8.663 +    /* Find the section-header strings table. */
   8.664 +    if ( ehdr->e_shstrndx == SHN_UNDEF )
   8.665 +    {
   8.666 +        ERROR("ELF image has no section-header strings table (shstrtab).");
   8.667 +        return -EINVAL;
   8.668 +    }
   8.669 +    shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + 
   8.670 +                        (ehdr->e_shstrndx*ehdr->e_shentsize));
   8.671 +    shstrtab = elfbase + shdr->sh_offset;
   8.672 +    
   8.673 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   8.674 +    {
   8.675 +        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   8.676 +        if ( !is_loadable_phdr(phdr) )
   8.677 +            continue;
   8.678 +        if ( phdr->p_vaddr < kernstart )
   8.679 +            kernstart = phdr->p_vaddr;
   8.680 +        if ( (phdr->p_vaddr + phdr->p_memsz) > kernend )
   8.681 +            kernend = phdr->p_vaddr + phdr->p_memsz;
   8.682 +    }
   8.683 +
   8.684 +    if ( (kernstart > kernend) || 
   8.685 +         (ehdr->e_entry < kernstart) || 
   8.686 +         (ehdr->e_entry > kernend) )
   8.687 +    {
   8.688 +        ERROR("Malformed ELF image.");
   8.689 +        return -EINVAL;
   8.690 +    }
   8.691 +
   8.692 +    dsi->v_start = 0x00000000;
   8.693 +    dsi->use_writable_pagetables = 0;
   8.694 +    dsi->load_bsd_symtab = 0;
   8.695 +
   8.696 +    dsi->v_kernstart = kernstart - LINUX_PAGE_OFFSET;
   8.697 +    dsi->v_kernend   = kernend - LINUX_PAGE_OFFSET;
   8.698 +    dsi->v_kernentry = LINUX_KERNEL_ENTR_ADDR;
   8.699 +
   8.700 +    dsi->v_end       = dsi->v_kernend;
   8.701 +
   8.702 +    return 0;
   8.703 +}
   8.704 +
   8.705 +static int
   8.706 +loadelfimage(
   8.707 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
   8.708 +    unsigned long vstart)
   8.709 +{
   8.710 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
   8.711 +    Elf_Phdr *phdr;
   8.712 +    int h;
   8.713 +
   8.714 +    char         *va;
   8.715 +    unsigned long pa, done, chunksz;
   8.716 +
   8.717 +    for ( h = 0; h < ehdr->e_phnum; h++ ) 
   8.718 +    {
   8.719 +        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
   8.720 +        if ( !is_loadable_phdr(phdr) )
   8.721 +            continue;
   8.722 +        
   8.723 +        for ( done = 0; done < phdr->p_filesz; done += chunksz )
   8.724 +        {
   8.725 +            pa = (phdr->p_vaddr + done) - vstart - LINUX_PAGE_OFFSET;
   8.726 +            va = xc_map_foreign_range(
   8.727 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   8.728 +            chunksz = phdr->p_filesz - done;
   8.729 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   8.730 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   8.731 +            memcpy(va + (pa & (PAGE_SIZE-1)),
   8.732 +                   elfbase + phdr->p_offset + done, chunksz);
   8.733 +            munmap(va, PAGE_SIZE);
   8.734 +        }
   8.735 +
   8.736 +        for ( ; done < phdr->p_memsz; done += chunksz )
   8.737 +        {
   8.738 +            pa = (phdr->p_vaddr + done) - vstart - LINUX_PAGE_OFFSET;
   8.739 +            va = xc_map_foreign_range(
   8.740 +                xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   8.741 +            chunksz = phdr->p_memsz - done;
   8.742 +            if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   8.743 +                chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   8.744 +            memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
   8.745 +            munmap(va, PAGE_SIZE);
   8.746 +        }
   8.747 +    }
   8.748 +
   8.749 +    return 0;
   8.750 +}
   8.751 +
   8.752 +static void
   8.753 +map_memcpy(
   8.754 +    unsigned long dst, char *src, unsigned long size,
   8.755 +    int xch, u32 dom, unsigned long *parray, unsigned long vstart)
   8.756 +{
   8.757 +    char *va;
   8.758 +    unsigned long chunksz, done, pa;
   8.759 +
   8.760 +    for ( done = 0; done < size; done += chunksz )
   8.761 +    {
   8.762 +        pa = dst + done - vstart;
   8.763 +        va = xc_map_foreign_range(
   8.764 +            xch, dom, PAGE_SIZE, PROT_WRITE, parray[pa>>PAGE_SHIFT]);
   8.765 +        chunksz = size - done;
   8.766 +        if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
   8.767 +            chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
   8.768 +        memcpy(va + (pa & (PAGE_SIZE-1)), src + done, chunksz);
   8.769 +        munmap(va, PAGE_SIZE);
   8.770 +    }
   8.771 +}
   8.772 +
   8.773 +#define ELFROUND (ELFSIZE / 8)
   8.774 +
   8.775 +static int
   8.776 +loadelfsymtab(
   8.777 +    char *elfbase, int xch, u32 dom, unsigned long *parray,
   8.778 +    struct domain_setup_info *dsi)
   8.779 +{
   8.780 +    Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase, *sym_ehdr;
   8.781 +    Elf_Shdr *shdr;
   8.782 +    unsigned long maxva, symva;
   8.783 +    char *p;
   8.784 +    int h, i;
   8.785 +
   8.786 +    p = malloc(sizeof(int) + sizeof(Elf_Ehdr) +
   8.787 +               ehdr->e_shnum * sizeof(Elf_Shdr));
   8.788 +    if (p == NULL)
   8.789 +        return 0;
   8.790 +
   8.791 +    maxva = (dsi->v_kernend + ELFROUND - 1) & ~(ELFROUND - 1);
   8.792 +    symva = maxva;
   8.793 +    maxva += sizeof(int);
   8.794 +    dsi->symtab_addr = maxva;
   8.795 +    dsi->symtab_len = 0;
   8.796 +    maxva += sizeof(Elf_Ehdr) + ehdr->e_shnum * sizeof(Elf_Shdr);
   8.797 +    maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   8.798 +
   8.799 +    shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr));
   8.800 +    memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum * sizeof(Elf_Shdr));
   8.801 +
   8.802 +    for ( h = 0; h < ehdr->e_shnum; h++ ) 
   8.803 +    {
   8.804 +        if ( shdr[h].sh_type == SHT_STRTAB )
   8.805 +        {
   8.806 +            /* Look for a strtab @i linked to symtab @h. */
   8.807 +            for ( i = 0; i < ehdr->e_shnum; i++ )
   8.808 +                if ( (shdr[i].sh_type == SHT_SYMTAB) &&
   8.809 +                     (shdr[i].sh_link == h) )
   8.810 +                    break;
   8.811 +            /* Skip symtab @h if we found no corresponding strtab @i. */
   8.812 +            if ( i == ehdr->e_shnum )
   8.813 +            {
   8.814 +                shdr[h].sh_offset = 0;
   8.815 +                continue;
   8.816 +            }
   8.817 +        }
   8.818 +
   8.819 +        if ( (shdr[h].sh_type == SHT_STRTAB) ||
   8.820 +             (shdr[h].sh_type == SHT_SYMTAB) )
   8.821 +        {
   8.822 +            if ( parray != NULL )
   8.823 +                map_memcpy(maxva, elfbase + shdr[h].sh_offset, shdr[h].sh_size,
   8.824 +                           xch, dom, parray, dsi->v_start);
   8.825 +
   8.826 +            /* Mangled to be based on ELF header location. */
   8.827 +            shdr[h].sh_offset = maxva - dsi->symtab_addr;
   8.828 +
   8.829 +            dsi->symtab_len += shdr[h].sh_size;
   8.830 +            maxva += shdr[h].sh_size;
   8.831 +            maxva = (maxva + ELFROUND - 1) & ~(ELFROUND - 1);
   8.832 +        }
   8.833 +
   8.834 +        shdr[h].sh_name = 0;  /* Name is NULL. */
   8.835 +    }
   8.836 +
   8.837 +    if ( dsi->symtab_len == 0 )
   8.838 +    {
   8.839 +        dsi->symtab_addr = 0;
   8.840 +        goto out;
   8.841 +    }
   8.842 +
   8.843 +    if ( parray != NULL )
   8.844 +    {
   8.845 +        *(int *)p = maxva - dsi->symtab_addr;
   8.846 +        sym_ehdr = (Elf_Ehdr *)(p + sizeof(int));
   8.847 +        memcpy(sym_ehdr, ehdr, sizeof(Elf_Ehdr));
   8.848 +        sym_ehdr->e_phoff = 0;
   8.849 +        sym_ehdr->e_shoff = sizeof(Elf_Ehdr);
   8.850 +        sym_ehdr->e_phentsize = 0;
   8.851 +        sym_ehdr->e_phnum = 0;
   8.852 +        sym_ehdr->e_shstrndx = SHN_UNDEF;
   8.853 +
   8.854 +        /* Copy total length, crafted ELF header and section header table */
   8.855 +        map_memcpy(symva, p, sizeof(int) + sizeof(Elf_Ehdr) +
   8.856 +                   ehdr->e_shnum * sizeof(Elf_Shdr), xch, dom, parray,
   8.857 +                   dsi->v_start);
   8.858 +    }
   8.859 +
   8.860 +    dsi->symtab_len = maxva - dsi->symtab_addr;
   8.861 +    dsi->v_end = round_pgup(maxva);
   8.862 +
   8.863 + out:
   8.864 +    if ( p != NULL )
   8.865 +        free(p);
   8.866 +
   8.867 +    return 0;
   8.868 +}
     9.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Fri Jan 07 01:16:26 2005 +0000
     9.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Fri Jan 07 01:41:05 2005 +0000
     9.3 @@ -16,6 +16,7 @@
     9.4  #include <arpa/inet.h>
     9.5  #include "xc_private.h"
     9.6  #include "gzip_stream.h"
     9.7 +#include "linux_boot_params.h"
     9.8  
     9.9  /* Needed for Python versions earlier than 2.3. */
    9.10  #ifndef PyMODINIT_FUNC
    9.11 @@ -393,6 +394,87 @@ static PyObject *pyxc_plan9_build(PyObje
    9.12      return zero;
    9.13  }
    9.14  
    9.15 +static PyObject *pyxc_vmx_build(PyObject *self,
    9.16 +                                  PyObject *args,
    9.17 +                                  PyObject *kwds)
    9.18 +{
    9.19 +    XcObject *xc = (XcObject *)self;
    9.20 +
    9.21 +    u32   dom;
    9.22 +    char *image, *ramdisk = NULL, *cmdline = "";
    9.23 +    PyObject *memmap;
    9.24 +    int   control_evtchn, flags = 0;
    9.25 +    int numItems, i;
    9.26 +    struct mem_map mem_map;
    9.27 +
    9.28 +    static char *kwd_list[] = { "dom", "control_evtchn", 
    9.29 +                                "image", "memmap",
    9.30 +				"ramdisk", "cmdline", "flags",
    9.31 +                                NULL };
    9.32 +
    9.33 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iisO!|ssi", kwd_list, 
    9.34 +                                      &dom, &control_evtchn, 
    9.35 +                                      &image, &PyList_Type, &memmap,
    9.36 +				      &ramdisk, &cmdline, &flags) )
    9.37 +        return NULL;
    9.38 +
    9.39 +    memset(&mem_map, 0, sizeof(mem_map));
    9.40 +    /* Parse memmap */
    9.41 +
    9.42 +    /* get the number of lines passed to us */
    9.43 +    numItems = PyList_Size(memmap) - 1;	/* removing the line 
    9.44 +					   containing "memmap" */
    9.45 +    printf ("numItems: %d\n", numItems);
    9.46 +    mem_map.nr_map = numItems;
    9.47 +   
    9.48 +
    9.49 +    /* should raise an error here. */
    9.50 +    if (numItems < 0) return NULL; /* Not a list */
    9.51 +
    9.52 +
    9.53 +    /* iterate over items of the list, grabbing ranges and parsing them */
    9.54 +    for (i = 1; i <= numItems; i++) {	// skip over "memmap"
    9.55 +	    PyObject *item, *f1, *f2, *f3, *f4;
    9.56 +	    int numFields;
    9.57 +	    unsigned long lf1, lf2, lf3, lf4;
    9.58 +	    char *sf1, *sf2;
    9.59 +	    
    9.60 +	    /* grab the string object from the next element of the list */
    9.61 +	    item = PyList_GetItem(memmap, i); /* Can't fail */
    9.62 +
    9.63 +	    /* get the number of lines passed to us */
    9.64 +	    numFields = PyList_Size(item);
    9.65 +
    9.66 +	    if (numFields != 4)
    9.67 +		    return NULL;
    9.68 +
    9.69 +	    f1 = PyList_GetItem(item, 0);
    9.70 +	    f2 = PyList_GetItem(item, 1);
    9.71 +	    f3 = PyList_GetItem(item, 2);
    9.72 +	    f4 = PyList_GetItem(item, 3);
    9.73 +
    9.74 +	    /* Convert objects to strings/longs */
    9.75 +	    sf1 = PyString_AsString(f1);
    9.76 +	    sf2 = PyString_AsString(f2);
    9.77 +	    lf3 = PyLong_AsLong(f3);
    9.78 +	    lf4 = PyLong_AsLong(f4);
    9.79 +	    sscanf(sf1, "%lx", &lf1);
    9.80 +	    sscanf(sf2, "%lx", &lf2);
    9.81 +
    9.82 +            mem_map.map[i-1].addr = lf1;
    9.83 +            mem_map.map[i-1].size = lf2 - lf1;
    9.84 +            mem_map.map[i-1].type = lf3;
    9.85 +            mem_map.map[i-1].caching_attr = lf4;
    9.86 +    }
    9.87 +
    9.88 +    if ( xc_vmx_build(xc->xc_handle, dom, image, &mem_map,
    9.89 +                        ramdisk, cmdline, control_evtchn, flags) != 0 )
    9.90 +        return PyErr_SetFromErrno(xc_error);
    9.91 +    
    9.92 +    Py_INCREF(zero);
    9.93 +    return zero;
    9.94 +}
    9.95 +
    9.96  static PyObject *pyxc_bvtsched_global_set(PyObject *self,
    9.97                                            PyObject *args,
    9.98                                            PyObject *kwds)
    9.99 @@ -943,6 +1025,17 @@ static PyMethodDef pyxc_methods[] = {
   9.100        " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   9.101        "Returns: [int] 0 on success; -1 on error.\n" },
   9.102  
   9.103 +    { "vmx_build", 
   9.104 +      (PyCFunction)pyxc_vmx_build, 
   9.105 +      METH_VARARGS | METH_KEYWORDS, "\n"
   9.106 +      "Build a new Linux guest OS.\n"
   9.107 +      " dom     [int]:      Identifier of domain to build into.\n"
   9.108 +      " image   [str]:      Name of kernel image file. May be gzipped.\n"
   9.109 +      " memmap  [str]: 	    Memory map.\n\n"
   9.110 +      " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
   9.111 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
   9.112 +      "Returns: [int] 0 on success; -1 on error.\n" },
   9.113 +
   9.114      { "bvtsched_global_set",
   9.115        (PyCFunction)pyxc_bvtsched_global_set,
   9.116        METH_VARARGS | METH_KEYWORDS, "\n"
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/python/xen/util/memmap.py	Fri Jan 07 01:41:05 2005 +0000
    10.3 @@ -0,0 +1,41 @@
    10.4 +mem_caching_attr = {
    10.5 +    'UC' : 0,
    10.6 +    'WC' : 1,
    10.7 +    'WT' : 4,
    10.8 +    'WP' : 5,
    10.9 +    'WB' : 6,
   10.10 +    };
   10.11 +
   10.12 +e820_mem_type = {
   10.13 +    'AddressRangeMemory'    : 1,
   10.14 +    'AddressRangeReserved'  : 2,
   10.15 +    'AddressRangeACPI'      : 3,
   10.16 +    'AddressRangeNVS'       : 4,
   10.17 +    'AddressRangeIO'        : 16,
   10.18 +    'AddressRangeShared'    : 17,
   10.19 +};
   10.20 +
   10.21 +MT_COL = 2
   10.22 +MA_COL = 3
   10.23 +
   10.24 +def strmap(row):
   10.25 +   if (type(row) != type([])):
   10.26 +       return row
   10.27 +   row[MT_COL] = e820_mem_type[row[MT_COL]]
   10.28 +   row[MA_COL] = mem_caching_attr[row[MA_COL]]
   10.29 +   return row
   10.30 +
   10.31 +def memmap_parse(memmap):
   10.32 +    return map(strmap, memmap)
   10.33 +
   10.34 +if __name__ == '__main__':
   10.35 +   memmap = [ 'memmap',
   10.36 +              [ '1', '2', 'AddressRangeMemory', 'UC'],
   10.37 +              [ '1', '2', 'AddressRangeReserved', 'UC'],
   10.38 +              [ '1', '2', 'AddressRangeACPI', 'WB'],
   10.39 +              [ '1', '2', 'AddressRangeNVS', 'WB'],
   10.40 +              [ '1', '2', 'AddressRangeIO', 'WB'],
   10.41 +              [ '1', '2', 'AddressRangeShared', 'WB']]
   10.42 +   print memmap_parse(memmap);
   10.43 +
   10.44 +
    11.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Fri Jan 07 01:16:26 2005 +0000
    11.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Fri Jan 07 01:41:05 2005 +0000
    11.3 @@ -20,6 +20,7 @@ from twisted.internet import defer
    11.4  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    11.5  import xen.util.ip
    11.6  from xen.util.ip import _readline, _readlines
    11.7 +from xen.xend.server import channel
    11.8  
    11.9  import sxp
   11.10  
   11.11 @@ -319,6 +320,7 @@ class XendDomainInfo:
   11.12          self.restart_time = None
   11.13          self.console_port = None
   11.14          self.savedinfo = None
   11.15 +        self.is_vmx = 0
   11.16  
   11.17      def setdom(self, dom):
   11.18          """Set the domain id.
   11.19 @@ -720,7 +722,7 @@ class XendDomainInfo:
   11.20          log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
   11.21          self.setdom(dom)
   11.22  
   11.23 -    def build_domain(self, ostype, kernel, ramdisk, cmdline):
   11.24 +    def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap):
   11.25          """Build the domain boot image.
   11.26          """
   11.27          if self.recreate or self.restore: return
   11.28 @@ -735,17 +737,26 @@ class XendDomainInfo:
   11.29          flags = 0
   11.30          if self.netif_backend: flags |= SIF_NET_BE_DOMAIN
   11.31          if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN
   11.32 -        err = buildfn(dom            = dom,
   11.33 -                      image          = kernel,
   11.34 -                      control_evtchn = self.console.getRemotePort(),
   11.35 -                      cmdline        = cmdline,
   11.36 -                      ramdisk        = ramdisk,
   11.37 -                      flags          = flags)
   11.38 +	if ostype == "vmx":
   11.39 +        	err = buildfn(dom      = dom,
   11.40 +               	      	image          = kernel,
   11.41 +                      	control_evtchn = 0,
   11.42 +			memmap	       = memmap,
   11.43 +                      	cmdline        = cmdline,
   11.44 +                      	ramdisk        = ramdisk,
   11.45 +                      	flags          = flags)
   11.46 +	else:
   11.47 +        	err = buildfn(dom            = dom,
   11.48 +               	      	image          = kernel,
   11.49 +                      	control_evtchn = self.console.getRemotePort(),
   11.50 +                      	cmdline        = cmdline,
   11.51 +                      	ramdisk        = ramdisk,
   11.52 +                      	flags          = flags)
   11.53          if err != 0:
   11.54              raise VmError('Building domain failed: type=%s dom=%d err=%d'
   11.55                            % (ostype, dom, err))
   11.56  
   11.57 -    def create_domain(self, ostype, kernel, ramdisk, cmdline):
   11.58 +    def create_domain(self, ostype, kernel, ramdisk, cmdline, memmap=''):
   11.59          """Create a domain. Builds the image but does not configure it.
   11.60  
   11.61          @param ostype:  OS type
   11.62 @@ -760,7 +771,7 @@ class XendDomainInfo:
   11.63          else:
   11.64              self.console = xendConsole.console_create(
   11.65                  self.dom, console_port=self.console_port)
   11.66 -        self.build_domain(ostype, kernel, ramdisk, cmdline)
   11.67 +        self.build_domain(ostype, kernel, ramdisk, cmdline, memmap)
   11.68          self.image = kernel
   11.69          self.ramdisk = ramdisk
   11.70          self.cmdline = cmdline
   11.71 @@ -804,6 +815,18 @@ class XendDomainInfo:
   11.72              index[dev_name] = dev_index + 1
   11.73          deferred = defer.DeferredList(dlist, fireOnOneErrback=1)
   11.74          deferred.addErrback(dlist_err)
   11.75 +        if self.is_vmx:
   11.76 +            device_model = sxp.child_value(self.config, 'device_model')
   11.77 +            device_config = sxp.child_value(self.config, 'device_config')
   11.78 +            memory = sxp.child_value(self.config, "memory")
   11.79 +            # Create an event channel
   11.80 +            device_channel = channel.eventChannel(0, self.dom)
   11.81 +            # Fork and exec device_model -f device_config <port>
   11.82 +            os.system(device_model
   11.83 +                      + " -f %s" % device_config
   11.84 +                      + " -d %d" % self.dom
   11.85 +                      + " -p %d" % device_channel['port1']
   11.86 +                      + " -m %s &" % memory)
   11.87          return deferred
   11.88  
   11.89      def device_create(self, dev_config):
   11.90 @@ -1091,7 +1114,33 @@ def vm_image_plan9(vm, image):
   11.91      vm.create_domain("plan9", kernel, ramdisk, cmdline)
   11.92      return vm
   11.93      
   11.94 -    
   11.95 +def vm_image_vmx(vm, image):
   11.96 +    """Create a VM for the VMX environment.
   11.97 +
   11.98 +    @param name:      vm name
   11.99 +    @param memory:    vm memory
  11.100 +    @param image:     image config
  11.101 +    @return: vm
  11.102 +    """
  11.103 +    kernel = sxp.child_value(image, "kernel")
  11.104 +    cmdline = ""
  11.105 +    ip = sxp.child_value(image, "ip", "dhcp")
  11.106 +    if ip:
  11.107 +        cmdline += " ip=" + ip
  11.108 +    root = sxp.child_value(image, "root")
  11.109 +    if root:
  11.110 +        cmdline += " root=" + root
  11.111 +    args = sxp.child_value(image, "args")
  11.112 +    if args:
  11.113 +        cmdline += " " + args
  11.114 +    ramdisk = sxp.child_value(image, "ramdisk", '')
  11.115 +    memmap = sxp.child_value(vm.config, "memmap", '')
  11.116 +    memmap = sxp.parse(open(memmap))[0]
  11.117 +    from xen.util.memmap import memmap_parse
  11.118 +    memmap = memmap_parse(memmap)
  11.119 +    vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap)
  11.120 +    vm.is_vmx = 1
  11.121 +    return vm
  11.122  
  11.123  def vm_dev_vif(vm, val, index, change=0):
  11.124      """Create a virtual network interface (vif).
  11.125 @@ -1215,6 +1264,7 @@ def vm_field_maxmem(vm, config, val, ind
  11.126  # Register image handlers.
  11.127  add_image_handler('linux',  vm_image_linux)
  11.128  add_image_handler('plan9',  vm_image_plan9)
  11.129 +add_image_handler('vmx',  vm_image_vmx)
  11.130  
  11.131  # Register device handlers.
  11.132  add_device_handler('vif',  vm_dev_vif)
    12.1 --- a/tools/python/xen/xm/create.py	Fri Jan 07 01:16:26 2005 +0000
    12.2 +++ b/tools/python/xen/xm/create.py	Fri Jan 07 01:41:05 2005 +0000
    12.3 @@ -210,6 +210,18 @@ gopts.var('nfs_root', val="PATH",
    12.4            fn=set_value, default=None,
    12.5            use="Set the path of the root NFS directory.")
    12.6  
    12.7 +gopts.var('memmap', val='FILE',
    12.8 +          fn=set_value, default='',
    12.9 +          use="Path to memap SXP file.")
   12.10 +
   12.11 +gopts.var('device_model', val='FILE',
   12.12 +          fn=set_value, default='',
   12.13 +          use="Path to device model program.")
   12.14 +
   12.15 +gopts.var('device_config', val='FILE',
   12.16 +          fn=set_value, default='',
   12.17 +          use="Path to device model configuration.")
   12.18 +
   12.19  def strip(pre, s):
   12.20      """Strip prefix 'pre' if present.
   12.21      """
   12.22 @@ -309,6 +321,15 @@ def configure_vfr(config, vals):
   12.23           config_vfr.append(['vif', ['id', idx], ['ip', ip]])
   12.24       config.append(config_vfr)
   12.25  
   12.26 +def configure_vmx(config_devs, vals):
   12.27 +    """Create the config for VMX devices.
   12.28 +    """
   12.29 +    memmap = vals.memmap
   12.30 +    device_model = vals.device_model
   12.31 +    device_config = vals.device_config
   12.32 +    config_devs.append(['memmap', memmap])
   12.33 +    config_devs.append(['device_model', device_model])
   12.34 +    config_devs.append(['device_config', device_config])
   12.35  
   12.36  def make_config(vals):
   12.37      """Create the domain configuration.
   12.38 @@ -337,6 +358,7 @@ def make_config(vals):
   12.39      configure_disks(config_devs, vals)
   12.40      configure_pci(config_devs, vals)
   12.41      configure_vifs(config_devs, vals)
   12.42 +    configure_vmx(config_devs, vals)
   12.43      config += config_devs
   12.44      return config
   12.45