direct-io.hg

changeset 7476:e398a9797c4c

some fixes to VMX:
1) enable ACPI in VMXAssist by default.
2) do nothing when emulating wbinvd instruction in VMXAssist.
3) use MACRO in cpu number setting/getting code.
4) remove useless parameter flags from xc_vmx_build.
5) remove usage of dsi.v_start in xc_vmx_build when not handling
vmxloader elf.
6) unmap shared_page_va when destroy VMX domain.
7) change virtual_platform_def to vmx_platform.
8) remove useless code in vmx_setup_platform.
9) change parameter of vmx_setup_platform from vcpu to domain.
10) in xen HV, vmx domain get domain processor number from the reserved
E820 area.
11) in domain.c, don't define some functions when on i386 platform or no
CONFIG_VMX.
Also removed some ugly tailing space.

Signed-off-by: Xin Li <xin.b.li@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Oct 23 11:51:15 2005 +0100 (2005-10-23)
parents 6f8ce90246f8
children 5a7baecb1c70
files tools/firmware/vmxassist/Makefile tools/firmware/vmxassist/acpi_madt.c tools/firmware/vmxassist/vm86.c tools/libxc/xc_ia64_stubs.c tools/libxc/xc_vmx_build.c tools/libxc/xenguest.h tools/python/xen/lowlevel/xc/xc.c xen/arch/x86/domain.c xen/arch/x86/vmx.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/domain.h xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_platform.h xen/include/asm-x86/vmx_vmcs.h
line diff
     1.1 --- a/tools/firmware/vmxassist/Makefile	Sat Oct 22 11:04:45 2005 +0100
     1.2 +++ b/tools/firmware/vmxassist/Makefile	Sun Oct 23 11:51:15 2005 +0100
     1.3 @@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk
     1.4  # The emulator code lives in ROM space
     1.5  TEXTADDR=0x000D0000
     1.6  
     1.7 -DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
     1.8 +DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
     1.9  XENINC=-I$(XEN_ROOT)/tools/libxc
    1.10  
    1.11  LD       = ld
     2.1 --- a/tools/firmware/vmxassist/acpi_madt.c	Sat Oct 22 11:04:45 2005 +0100
     2.2 +++ b/tools/firmware/vmxassist/acpi_madt.c	Sun Oct 23 11:51:15 2005 +0100
     2.3 @@ -24,17 +24,19 @@
     2.4  
     2.5  extern int puts(const char *s);
     2.6  
     2.7 -#define VCPU_MAGIC 0x76637075 /* "vcpu" */
     2.8 +#define VCPU_NR_PAGE        0x0009F000
     2.9 +#define VCPU_NR_OFFSET      0x00000800
    2.10 +#define VCPU_MAGIC          0x76637075  /* "vcpu" */
    2.11  
    2.12  /* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
    2.13 -static int 
    2.14 -get_vcpus(void)
    2.15 +static int
    2.16 +get_vcpu_nr(void)
    2.17  {
    2.18 -	unsigned long *vcpus;
    2.19 +	unsigned int *vcpus;
    2.20  
    2.21 -	vcpus = (unsigned long *)0x9F800;
    2.22 +	vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
    2.23  	if (vcpus[0] != VCPU_MAGIC) {
    2.24 -		puts("Bad vcpus magic, set vcpu number=1\n");
    2.25 +		puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
    2.26  		return 1;
    2.27  	}
    2.28  
    2.29 @@ -123,7 +125,7 @@ int acpi_madt_update(unsigned char *acpi
    2.30  	if (!madt)
    2.31  		return -1;
    2.32  
    2.33 -	rc = acpi_madt_set_local_apics(get_vcpus(), madt);
    2.34 +	rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt);
    2.35  	if (rc != 0)
    2.36  		return rc;
    2.37  
     3.1 --- a/tools/firmware/vmxassist/vm86.c	Sat Oct 22 11:04:45 2005 +0100
     3.2 +++ b/tools/firmware/vmxassist/vm86.c	Sun Oct 23 11:51:15 2005 +0100
     3.3 @@ -784,7 +784,6 @@ opcode(struct regs *regs)
     3.4  				}
     3.5  				break;
     3.6  			case 0x09: /* wbinvd */
     3.7 -				asm volatile ( "wbinvd" );
     3.8  				return OPC_EMULATED;
     3.9  			case 0x20: /* mov Rd, Cd (1h) */
    3.10  			case 0x22:
     4.1 --- a/tools/libxc/xc_ia64_stubs.c	Sat Oct 22 11:04:45 2005 +0100
     4.2 +++ b/tools/libxc/xc_ia64_stubs.c	Sun Oct 23 11:51:15 2005 +0100
     4.3 @@ -24,7 +24,6 @@ int xc_vmx_build(int xc_handle,
     4.4                     const char *ramdisk_name,
     4.5                     const char *cmdline,
     4.6                     unsigned int control_evtchn,
     4.7 -                   unsigned long flags,
     4.8                     unsigned int vcpus,
     4.9                     unsigned int store_evtchn,
    4.10                     unsigned long *store_mfn)
     5.1 --- a/tools/libxc/xc_vmx_build.c	Sat Oct 22 11:04:45 2005 +0100
     5.2 +++ b/tools/libxc/xc_vmx_build.c	Sun Oct 23 11:51:15 2005 +0100
     5.3 @@ -29,9 +29,12 @@
     5.4  #define E820_SHARED_PAGE 17
     5.5  #define E820_XENSTORE    18
     5.6  
     5.7 -#define E820_MAP_PAGE        0x00090000
     5.8 -#define E820_MAP_NR_OFFSET   0x000001E8
     5.9 -#define E820_MAP_OFFSET      0x000002D0
    5.10 +#define E820_MAP_PAGE       0x00090000
    5.11 +#define E820_MAP_NR_OFFSET  0x000001E8
    5.12 +#define E820_MAP_OFFSET     0x000002D0
    5.13 +
    5.14 +#define VCPU_NR_PAGE        0x0009F000
    5.15 +#define VCPU_NR_OFFSET      0x00000800
    5.16  
    5.17  struct e820entry {
    5.18      uint64_t addr;
    5.19 @@ -120,23 +123,22 @@ static unsigned char build_e820map(void 
    5.20   * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
    5.21   * vmxloader will use it to config ACPI MADT table
    5.22   */
    5.23 -#define VCPU_MAGIC 0x76637075 /* "vcpu" */
    5.24 -static int
    5.25 -set_nr_vcpus(int xc_handle, uint32_t dom, unsigned long *pfn_list,
    5.26 -             struct domain_setup_info *dsi, unsigned long vcpus)
    5.27 +#define VCPU_MAGIC      0x76637075  /* "vcpu" */
    5.28 +static int set_vcpu_nr(int xc_handle, uint32_t dom,
    5.29 +                        unsigned long *pfn_list, unsigned int vcpus)
    5.30  {
    5.31 -    char          *va_map;
    5.32 -    unsigned long *va_vcpus;
    5.33 +    char         *va_map;
    5.34 +    unsigned int *va_vcpus;
    5.35  
    5.36 -    va_map = xc_map_foreign_range(
    5.37 -        xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
    5.38 -        pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]);
    5.39 +    va_map = xc_map_foreign_range(xc_handle, dom,
    5.40 +                                  PAGE_SIZE, PROT_READ|PROT_WRITE,
    5.41 +                                  pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
    5.42      if ( va_map == NULL )
    5.43          return -1;
    5.44  
    5.45 -    va_vcpus = (unsigned long *)(va_map + 0x800);
    5.46 -    *va_vcpus++ = VCPU_MAGIC;
    5.47 -    *va_vcpus++ = vcpus;
    5.48 +    va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
    5.49 +    va_vcpus[0] = VCPU_MAGIC;
    5.50 +    va_vcpus[1] = vcpus;
    5.51  
    5.52      munmap(va_map, PAGE_SIZE);
    5.53  
    5.54 @@ -277,7 +279,6 @@ static int setup_guest(int xc_handle,
    5.55                         vcpu_guest_context_t *ctxt,
    5.56                         unsigned long shared_info_frame,
    5.57                         unsigned int control_evtchn,
    5.58 -                       unsigned long flags,
    5.59                         unsigned int vcpus,
    5.60                         unsigned int store_evtchn,
    5.61                         unsigned long *store_mfn)
    5.62 @@ -366,7 +367,7 @@ static int setup_guest(int xc_handle,
    5.63          goto error_out;
    5.64  
    5.65      /* First allocate page for page dir or pdpt */
    5.66 -    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
    5.67 +    ppt_alloc = vpt_start >> PAGE_SHIFT;
    5.68      if ( page_array[ppt_alloc] > 0xfffff )
    5.69      {
    5.70          unsigned long nmfn;
    5.71 @@ -388,8 +389,8 @@ static int setup_guest(int xc_handle,
    5.72                                          l2tab >> PAGE_SHIFT)) == NULL )
    5.73          goto error_out;
    5.74      memset(vl2tab, 0, PAGE_SIZE);
    5.75 -    vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
    5.76 -    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
    5.77 +    vl2e = &vl2tab[l2_table_offset(0)];
    5.78 +    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
    5.79      {
    5.80          if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
    5.81          {
    5.82 @@ -404,7 +405,7 @@ static int setup_guest(int xc_handle,
    5.83                  goto error_out;
    5.84              }
    5.85              memset(vl1tab, 0, PAGE_SIZE);
    5.86 -            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
    5.87 +            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
    5.88              *vl2e++ = l1tab | L2_PROT;
    5.89          }
    5.90  
    5.91 @@ -436,9 +437,8 @@ static int setup_guest(int xc_handle,
    5.92          vl3tab[i] = l2tab | L3_PROT;
    5.93      }
    5.94  
    5.95 -    vl3e = &vl3tab[l3_table_offset(dsi.v_start)];
    5.96 -
    5.97 -    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
    5.98 +    vl3e = &vl3tab[l3_table_offset(0)];
    5.99 +    for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
   5.100      {
   5.101          if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
   5.102              l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
   5.103 @@ -452,7 +452,7 @@ static int setup_guest(int xc_handle,
   5.104                                                  l2tab >> PAGE_SHIFT)) == NULL )
   5.105                  goto error_out;
   5.106  
   5.107 -            vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count << PAGE_SHIFT))];
   5.108 +            vl2e = &vl2tab[l2_table_offset(count << PAGE_SHIFT)];
   5.109          }
   5.110          if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   5.111          {
   5.112 @@ -467,7 +467,7 @@ static int setup_guest(int xc_handle,
   5.113                  goto error_out;
   5.114              }
   5.115              memset(vl1tab, 0, PAGE_SIZE);
   5.116 -            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   5.117 +            vl1e = &vl1tab[l1_table_offset(count << PAGE_SHIFT)];
   5.118              *vl2e++ = l1tab | L2_PROT;
   5.119          }
   5.120  
   5.121 @@ -488,7 +488,10 @@ static int setup_guest(int xc_handle,
   5.122              goto error_out;
   5.123      }
   5.124  
   5.125 -    set_nr_vcpus(xc_handle, dom, page_array, &dsi, vcpus);
   5.126 +    if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
   5.127 +        fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
   5.128 +        goto error_out;
   5.129 +    }
   5.130  
   5.131      *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
   5.132      shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
   5.133 @@ -566,28 +569,26 @@ static int setup_guest(int xc_handle,
   5.134      return -1;
   5.135  }
   5.136  
   5.137 -
   5.138  #define VMX_FEATURE_FLAG 0x20
   5.139  
   5.140  static int vmx_identify(void)
   5.141  {
   5.142      int eax, ecx;
   5.143  
   5.144 -#ifdef __i386__
   5.145 -    __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx"
   5.146 +    __asm__ __volatile__ (
   5.147 +#if defined(__i386__)
   5.148 +                          "push %%ebx; cpuid; pop %%ebx"
   5.149 +#elif defined(__x86_64__)
   5.150 +                          "push %%rbx; cpuid; pop %%rbx"
   5.151 +#endif
   5.152                            : "=a" (eax), "=c" (ecx)
   5.153                            : "0" (1)
   5.154                            : "dx");
   5.155 -#elif defined __x86_64__
   5.156 -    __asm__ __volatile__ ("pushq %%rbx; cpuid; popq %%rbx"
   5.157 -                          : "=a" (eax), "=c" (ecx)
   5.158 -                          : "0" (1)
   5.159 -                          : "dx");
   5.160 -#endif
   5.161  
   5.162      if (!(ecx & VMX_FEATURE_FLAG)) {
   5.163          return -1;
   5.164      }
   5.165 +
   5.166      return 0;
   5.167  }
   5.168  
   5.169 @@ -596,7 +597,6 @@ int xc_vmx_build(int xc_handle,
   5.170                   int memsize,
   5.171                   const char *image_name,
   5.172                   unsigned int control_evtchn,
   5.173 -                 unsigned long flags,
   5.174                   unsigned int vcpus,
   5.175                   unsigned int store_evtchn,
   5.176                   unsigned long *store_mfn)
   5.177 @@ -651,9 +651,9 @@ int xc_vmx_build(int xc_handle,
   5.178          goto error_out;
   5.179      }
   5.180  
   5.181 -    if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
   5.182 -                     ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
   5.183 -                     flags, vcpus, store_evtchn, store_mfn) < 0)
   5.184 +    if ( setup_guest(xc_handle, domid, memsize, image, image_size,
   5.185 +                     nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame,
   5.186 +                     control_evtchn, vcpus, store_evtchn, store_mfn) < 0)
   5.187      {
   5.188          ERROR("Error constructing guest OS");
   5.189          goto error_out;
     6.1 --- a/tools/libxc/xenguest.h	Sat Oct 22 11:04:45 2005 +0100
     6.2 +++ b/tools/libxc/xenguest.h	Sun Oct 23 11:51:15 2005 +0100
     6.3 @@ -51,13 +51,11 @@ int xc_linux_build(int xc_handle,
     6.4                     unsigned int console_evtchn,
     6.5                     unsigned long *console_mfn);
     6.6  
     6.7 -struct mem_map;
     6.8  int xc_vmx_build(int xc_handle,
     6.9                   uint32_t domid,
    6.10                   int memsize,
    6.11                   const char *image_name,
    6.12                   unsigned int control_evtchn,
    6.13 -                 unsigned long flags,
    6.14                   unsigned int vcpus,
    6.15                   unsigned int store_evtchn,
    6.16                   unsigned long *store_mfn);
     7.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sat Oct 22 11:04:45 2005 +0100
     7.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Sun Oct 23 11:51:15 2005 +0100
     7.3 @@ -429,15 +429,15 @@ static PyObject *pyxc_linux_build(PyObje
     7.4  }
     7.5  
     7.6  static PyObject *pyxc_vmx_build(PyObject *self,
     7.7 -                                  PyObject *args,
     7.8 -                                  PyObject *kwds)
     7.9 +                                PyObject *args,
    7.10 +                                PyObject *kwds)
    7.11  {
    7.12      XcObject *xc = (XcObject *)self;
    7.13  
    7.14 -    uint32_t   dom;
    7.15 +    uint32_t dom;
    7.16      char *image;
    7.17 -    int   control_evtchn, store_evtchn;
    7.18 -    int flags = 0, vcpus = 1;
    7.19 +    int control_evtchn, store_evtchn;
    7.20 +    int vcpus = 1;
    7.21      int memsize;
    7.22      unsigned long store_mfn = 0;
    7.23  
    7.24 @@ -450,7 +450,7 @@ static PyObject *pyxc_vmx_build(PyObject
    7.25          return NULL;
    7.26  
    7.27      if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn,
    7.28 -                      flags, vcpus, store_evtchn, &store_mfn) != 0 )
    7.29 +                      vcpus, store_evtchn, &store_mfn) != 0 )
    7.30          return PyErr_SetFromErrno(xc_error);
    7.31  
    7.32      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
     8.1 --- a/xen/arch/x86/domain.c	Sat Oct 22 11:04:45 2005 +0100
     8.2 +++ b/xen/arch/x86/domain.c	Sun Oct 23 11:51:15 2005 +0100
     8.3 @@ -1,6 +1,6 @@
     8.4  /******************************************************************************
     8.5   * arch/x86/domain.c
     8.6 - * 
     8.7 + *
     8.8   * x86-specific domain handling (e.g., register setup and context switching).
     8.9   */
    8.10  
    8.11 @@ -144,9 +144,7 @@ void machine_restart(char * __unused)
    8.12      smp_send_stop();
    8.13      disable_IO_APIC();
    8.14  
    8.15 -#ifdef CONFIG_VMX
    8.16      stop_vmx();
    8.17 -#endif
    8.18  
    8.19      /* Rebooting needs to touch the page at absolute address 0. */
    8.20      *((unsigned short *)__va(0x472)) = reboot_mode;
    8.21 @@ -204,7 +202,6 @@ void dump_pageframe_info(struct domain *
    8.22                 page->u.inuse.type_info);
    8.23      }
    8.24  
    8.25 -    
    8.26      page = virt_to_page(d->shared_info);
    8.27      printk("Shared_info@%p: caf=%08x, taf=%" PRtype_info "\n",
    8.28             _p(page_to_phys(page)), page->count_info,
    8.29 @@ -260,7 +257,7 @@ void arch_do_createdomain(struct vcpu *v
    8.30          return;
    8.31  
    8.32      v->arch.schedule_tail = continue_nonidle_task;
    8.33 -    
    8.34 +
    8.35      d->shared_info = alloc_xenheap_page();
    8.36      memset(d->shared_info, 0, PAGE_SIZE);
    8.37      v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
    8.38 @@ -268,7 +265,7 @@ void arch_do_createdomain(struct vcpu *v
    8.39      SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
    8.40      set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT,
    8.41              INVALID_M2P_ENTRY);
    8.42 -    
    8.43 +
    8.44      d->arch.mm_perdomain_pt = alloc_xenheap_page();
    8.45      memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE);
    8.46      set_pfn_from_mfn(virt_to_phys(d->arch.mm_perdomain_pt) >> PAGE_SHIFT,
    8.47 @@ -293,22 +290,22 @@ void arch_do_createdomain(struct vcpu *v
    8.48  #ifdef __x86_64__
    8.49      v->arch.guest_vl3table = __linear_l3_table;
    8.50      v->arch.guest_vl4table = __linear_l4_table;
    8.51 -    
    8.52 +
    8.53      d->arch.mm_perdomain_l2 = alloc_xenheap_page();
    8.54      memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE);
    8.55 -    d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = 
    8.56 +    d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] =
    8.57          l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt),
    8.58                          __PAGE_HYPERVISOR);
    8.59      d->arch.mm_perdomain_l3 = alloc_xenheap_page();
    8.60      memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE);
    8.61 -    d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = 
    8.62 +    d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] =
    8.63          l3e_from_page(virt_to_page(d->arch.mm_perdomain_l2),
    8.64                              __PAGE_HYPERVISOR);
    8.65  #endif
    8.66 -    
    8.67 +
    8.68      (void)ptwr_init(d);
    8.69 -    
    8.70 -    shadow_lock_init(d);        
    8.71 +
    8.72 +    shadow_lock_init(d);
    8.73      INIT_LIST_HEAD(&d->arch.free_shadow_frames);
    8.74  }
    8.75  
    8.76 @@ -327,34 +324,6 @@ void vcpu_migrate_cpu(struct vcpu *v, in
    8.77      }
    8.78  }
    8.79  
    8.80 -#ifdef CONFIG_VMX
    8.81 -static int vmx_switch_on;
    8.82 -
    8.83 -static void vmx_final_setup_guest(struct vcpu *v)
    8.84 -{
    8.85 -    v->arch.schedule_tail = arch_vmx_do_launch;
    8.86 -
    8.87 -    if (v == v->domain->vcpu[0]) {
    8.88 -        /*
    8.89 -         * Required to do this once per domain
    8.90 -         * XXX todo: add a seperate function to do these.
    8.91 -         */
    8.92 -        memset(&v->domain->shared_info->evtchn_mask[0], 0xff,
    8.93 -               sizeof(v->domain->shared_info->evtchn_mask));
    8.94 -
    8.95 -        /* Put the domain in shadow mode even though we're going to be using
    8.96 -         * the shared 1:1 page table initially. It shouldn't hurt */
    8.97 -        shadow_mode_enable(v->domain,
    8.98 -                           SHM_enable|SHM_refcounts|
    8.99 -                           SHM_translate|SHM_external);
   8.100 -    }
   8.101 -
   8.102 -    if (!vmx_switch_on)
   8.103 -        vmx_switch_on = 1;
   8.104 -}
   8.105 -#endif
   8.106 -
   8.107 -
   8.108  /* This is called by arch_final_setup_guest and do_boot_vcpu */
   8.109  int arch_set_info_guest(
   8.110      struct vcpu *v, struct vcpu_guest_context *c)
   8.111 @@ -422,7 +391,7 @@ int arch_set_info_guest(
   8.112      }
   8.113      else if ( !(c->flags & VGCF_VMX_GUEST) )
   8.114      {
   8.115 -        if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, 
   8.116 +        if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
   8.117                                  PGT_base_page_table) )
   8.118              return -EINVAL;
   8.119      }
   8.120 @@ -507,12 +476,6 @@ void toggle_guest_mode(struct vcpu *v)
   8.121          : "=r" (__r) : "r" (value), "0" (__r) );\
   8.122      __r; })
   8.123  
   8.124 -#if CONFIG_VMX
   8.125 -#define load_msrs(n)     if (vmx_switch_on) vmx_load_msrs(n)
   8.126 -#else
   8.127 -#define load_msrs(n)     ((void)0)
   8.128 -#endif 
   8.129 -
   8.130  /*
   8.131   * save_segments() writes a mask of segments which are dirty (non-zero),
   8.132   * allowing load_segments() to avoid some expensive segment loads and
   8.133 @@ -590,7 +553,7 @@ static void load_segments(struct vcpu *n
   8.134          struct cpu_user_regs *regs = guest_cpu_user_regs();
   8.135          unsigned long   *rsp =
   8.136              (n->arch.flags & TF_kernel_mode) ?
   8.137 -            (unsigned long *)regs->rsp : 
   8.138 +            (unsigned long *)regs->rsp :
   8.139              (unsigned long *)nctxt->kernel_sp;
   8.140  
   8.141          if ( !(n->arch.flags & TF_kernel_mode) )
   8.142 @@ -690,9 +653,9 @@ long do_switch_to_user(void)
   8.143          regs->r11 = stu.r11;
   8.144          regs->rcx = stu.rcx;
   8.145      }
   8.146 -    
   8.147 +
   8.148      /* Saved %rax gets written back to regs->rax in entry.S. */
   8.149 -    return stu.rax; 
   8.150 +    return stu.rax;
   8.151  }
   8.152  
   8.153  #define switch_kernel_stack(_n,_c) ((void)0)
   8.154 @@ -700,7 +663,6 @@ long do_switch_to_user(void)
   8.155  #elif defined(__i386__)
   8.156  
   8.157  #define load_segments(n) ((void)0)
   8.158 -#define load_msrs(n)     ((void)0)
   8.159  #define save_segments(p) ((void)0)
   8.160  
   8.161  static inline void switch_kernel_stack(struct vcpu *n, unsigned int cpu)
   8.162 @@ -725,7 +687,7 @@ static void __context_switch(void)
   8.163      if ( !is_idle_task(p->domain) )
   8.164      {
   8.165          memcpy(&p->arch.guest_context.user_regs,
   8.166 -               stack_regs, 
   8.167 +               stack_regs,
   8.168                 CTXT_SWITCH_STACK_BYTES);
   8.169          unlazy_fpu(p);
   8.170          save_segments(p);
   8.171 @@ -811,7 +773,7 @@ void context_switch_finalise(struct vcpu
   8.172          {
   8.173              load_LDT(next);
   8.174              load_segments(next);
   8.175 -            load_msrs(next);
   8.176 +            vmx_load_msrs(next);
   8.177          }
   8.178      }
   8.179  
   8.180 @@ -883,7 +845,7 @@ unsigned long __hypercall_create_continu
   8.181  #if defined(__i386__)
   8.182          regs->eax  = op;
   8.183          regs->eip -= 2;  /* re-execute 'int 0x82' */
   8.184 -        
   8.185 +
   8.186          for ( i = 0; i < nr_args; i++ )
   8.187          {
   8.188              switch ( i )
   8.189 @@ -899,7 +861,7 @@ unsigned long __hypercall_create_continu
   8.190  #elif defined(__x86_64__)
   8.191          regs->rax  = op;
   8.192          regs->rip -= 2;  /* re-execute 'syscall' */
   8.193 -        
   8.194 +
   8.195          for ( i = 0; i < nr_args; i++ )
   8.196          {
   8.197              switch ( i )
   8.198 @@ -920,20 +882,6 @@ unsigned long __hypercall_create_continu
   8.199      return op;
   8.200  }
   8.201  
   8.202 -#ifdef CONFIG_VMX
   8.203 -static void vmx_relinquish_resources(struct vcpu *v)
   8.204 -{
   8.205 -    if ( !VMX_DOMAIN(v) )
   8.206 -        return;
   8.207 -
   8.208 -    destroy_vmcs(&v->arch.arch_vmx);
   8.209 -    free_monitor_pagetable(v);
   8.210 -    rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
   8.211 -}
   8.212 -#else
   8.213 -#define vmx_relinquish_resources(_v) ((void)0)
   8.214 -#endif
   8.215 -
   8.216  static void relinquish_memory(struct domain *d, struct list_head *list)
   8.217  {
   8.218      struct list_head *ent;
   8.219 @@ -972,7 +920,7 @@ static void relinquish_memory(struct dom
   8.220          for ( ; ; )
   8.221          {
   8.222              x = y;
   8.223 -            if ( likely((x & (PGT_type_mask|PGT_validated)) != 
   8.224 +            if ( likely((x & (PGT_type_mask|PGT_validated)) !=
   8.225                          (PGT_base_page_table|PGT_validated)) )
   8.226                  break;
   8.227  
   8.228 @@ -1033,7 +981,7 @@ void domain_relinquish_resources(struct 
   8.229      shadow_mode_disable(d);
   8.230  
   8.231      /*
   8.232 -     * Relinquish GDT mappings. No need for explicit unmapping of the LDT as 
   8.233 +     * Relinquish GDT mappings. No need for explicit unmapping of the LDT as
   8.234       * it automatically gets squashed when the guest's mappings go away.
   8.235       */
   8.236      for_each_vcpu(d, v)
     9.1 --- a/xen/arch/x86/vmx.c	Sat Oct 22 11:04:45 2005 +0100
     9.2 +++ b/xen/arch/x86/vmx.c	Sun Oct 23 11:51:15 2005 +0100
     9.3 @@ -57,6 +57,47 @@ static unsigned long trace_values[NR_CPU
     9.4  #define TRACE_VMEXIT(index,value) ((void)0)
     9.5  #endif
     9.6  
     9.7 +static int vmx_switch_on;
     9.8 +
     9.9 +void vmx_final_setup_guest(struct vcpu *v)
    9.10 +{
    9.11 +    v->arch.schedule_tail = arch_vmx_do_launch;
    9.12 +
    9.13 +    if ( v == v->domain->vcpu[0] )
    9.14 +    {
    9.15 +        /*
    9.16 +         * Required to do this once per domain
    9.17 +         * XXX todo: add a seperate function to do these.
    9.18 +         */
    9.19 +        memset(&v->domain->shared_info->evtchn_mask[0], 0xff,
    9.20 +               sizeof(v->domain->shared_info->evtchn_mask));
    9.21 +
    9.22 +        /* Put the domain in shadow mode even though we're going to be using
    9.23 +         * the shared 1:1 page table initially. It shouldn't hurt */
    9.24 +        shadow_mode_enable(v->domain,
    9.25 +                           SHM_enable|SHM_refcounts|
    9.26 +                           SHM_translate|SHM_external);
    9.27 +    }
    9.28 +
    9.29 +    vmx_switch_on = 1;
    9.30 +}
    9.31 +
    9.32 +void vmx_relinquish_resources(struct vcpu *v)
    9.33 +{
    9.34 +    if ( !VMX_DOMAIN(v) )
    9.35 +        return;
    9.36 +
    9.37 +    if (v->vcpu_id == 0) {
    9.38 +        /* unmap IO shared page */
    9.39 +        struct domain *d = v->domain;
    9.40 +        unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
    9.41 +    }
    9.42 +
    9.43 +    destroy_vmcs(&v->arch.arch_vmx);
    9.44 +    free_monitor_pagetable(v);
    9.45 +    rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
    9.46 +}
    9.47 +
    9.48  #ifdef __x86_64__
    9.49  static struct msr_state percpu_msr[NR_CPUS];
    9.50  
    9.51 @@ -77,6 +118,9 @@ void vmx_load_msrs(struct vcpu *n)
    9.52      struct msr_state *host_state;
    9.53      host_state = &percpu_msr[smp_processor_id()];
    9.54  
    9.55 +    if ( !vmx_switch_on )
    9.56 +        return;
    9.57 +
    9.58      while (host_state->flags){
    9.59          int i;
    9.60  
    10.1 --- a/xen/arch/x86/vmx_io.c	Sat Oct 22 11:04:45 2005 +0100
    10.2 +++ b/xen/arch/x86/vmx_io.c	Sun Oct 23 11:51:15 2005 +0100
    10.3 @@ -883,7 +883,7 @@ asmlinkage void vmx_intr_assist(void)
    10.4      int highest_vector;
    10.5      unsigned long intr_fields, eflags, interruptibility, cpu_exec_control;
    10.6      struct vcpu *v = current;
    10.7 -    struct virtual_platform_def *plat=&v->domain->arch.vmx_platform;
    10.8 +    struct vmx_platform *plat=&v->domain->arch.vmx_platform;
    10.9      struct vmx_virpit *vpit = &plat->vmx_pit;
   10.10      struct vmx_virpic *pic= &plat->vmx_pic;
   10.11  
    11.1 --- a/xen/arch/x86/vmx_vmcs.c	Sat Oct 22 11:04:45 2005 +0100
    11.2 +++ b/xen/arch/x86/vmx_vmcs.c	Sun Oct 23 11:51:15 2005 +0100
    11.3 @@ -142,7 +142,7 @@ struct host_execution_env {
    11.4  #endif
    11.5  };
    11.6  
    11.7 -static void get_io_shared_page(struct vcpu *v)
    11.8 +static void vmx_map_io_shared_page(struct domain *d)
    11.9  {
   11.10      int i;
   11.11      unsigned char e820_map_nr;
   11.12 @@ -151,9 +151,6 @@ static void get_io_shared_page(struct vc
   11.13      unsigned long mpfn;
   11.14      unsigned long gpfn = 0;
   11.15  
   11.16 -    if (!(VMX_DOMAIN(v) && (v->vcpu_id == 0)))
   11.17 -        return;
   11.18 -
   11.19      local_flush_tlb_pge();
   11.20  
   11.21      mpfn = get_mfn_from_pfn(E820_MAP_PAGE >> PAGE_SHIFT);
   11.22 @@ -200,24 +197,61 @@ static void get_io_shared_page(struct vc
   11.23          printk("Can not map io request shared page for VMX domain.\n");
   11.24          domain_crash();
   11.25      }
   11.26 -    v->domain->arch.vmx_platform.shared_page_va = (unsigned long)p;
   11.27 +    d->arch.vmx_platform.shared_page_va = (unsigned long)p;
   11.28  
   11.29 -    VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(v->domain));
   11.30 +    VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d));
   11.31  
   11.32 -    clear_bit(iopacket_port(v->domain),
   11.33 -              &v->domain->shared_info->evtchn_mask[0]);
   11.34 +    clear_bit(iopacket_port(d),
   11.35 +              &d->shared_info->evtchn_mask[0]);
   11.36  }
   11.37  
   11.38 -static void vmx_setup_platform(struct vcpu *v)
   11.39 +#define VCPU_NR_PAGE        0x0009F000
   11.40 +#define VCPU_NR_OFFSET      0x00000800
   11.41 +#define VCPU_MAGIC          0x76637075  /* "vcpu" */
   11.42 +
   11.43 +static void vmx_set_vcpu_nr(struct domain *d)
   11.44  {
   11.45 -    struct virtual_platform_def  *platform;
   11.46 -    if (v->vcpu_id == 0) {
   11.47 -        get_io_shared_page(v);
   11.48 -        platform = &v->domain->arch.vmx_platform;
   11.49 -        pic_init(&platform->vmx_pic,  pic_irq_request, 
   11.50 -                 &platform->interrupt_request);
   11.51 -        register_pic_io_hook();
   11.52 +    unsigned char *p;
   11.53 +    unsigned long mpfn;
   11.54 +    unsigned int *vcpus;
   11.55 +
   11.56 +    mpfn = get_mfn_from_pfn(VCPU_NR_PAGE >> PAGE_SHIFT);
   11.57 +    if (mpfn == INVALID_MFN) {
   11.58 +        printk("Can not get vcpu number page mfn for VMX domain.\n");
   11.59 +        domain_crash_synchronous();
   11.60 +    }
   11.61 +
   11.62 +    p = map_domain_page(mpfn);
   11.63 +    if (p == NULL) {
   11.64 +        printk("Can not map vcpu number page for VMX domain.\n");
   11.65 +        domain_crash_synchronous();
   11.66 +    }
   11.67 +
   11.68 +    vcpus = (unsigned int *)(p + VCPU_NR_OFFSET);
   11.69 +    if (vcpus[0] != VCPU_MAGIC) {
   11.70 +        printk("Bad vcpus magic, set vcpu number to 1 by default.\n");
   11.71 +        d->arch.vmx_platform.nr_vcpu = 1;
   11.72      }
   11.73 +
   11.74 +    d->arch.vmx_platform.nr_vcpu = vcpus[1];
   11.75 +
   11.76 +    unmap_domain_page(p);
   11.77 +}
   11.78 +
   11.79 +static void vmx_setup_platform(struct domain* d)
   11.80 +{
   11.81 +    struct vmx_platform *platform;
   11.82 +
   11.83 +    if (!(VMX_DOMAIN(current) && (current->vcpu_id == 0)))
   11.84 +        return;
   11.85 +
   11.86 +    vmx_map_io_shared_page(d);
   11.87 +    vmx_set_vcpu_nr(d);
   11.88 +
   11.89 +    platform = &d->arch.vmx_platform;
   11.90 +    pic_init(&platform->vmx_pic,  pic_irq_request, 
   11.91 +             &platform->interrupt_request);
   11.92 +    register_pic_io_hook();
   11.93  }
   11.94  
   11.95  static void vmx_set_host_env(struct vcpu *v)
   11.96 @@ -249,9 +283,10 @@ static void vmx_do_launch(struct vcpu *v
   11.97  {
   11.98  /* Update CR3, GDT, LDT, TR */
   11.99      unsigned int  error = 0;
  11.100 -    unsigned long pfn = 0;
  11.101      unsigned long cr0, cr4;
  11.102 -    struct pfn_info *page;
  11.103 +
  11.104 +    if (v->vcpu_id == 0)
  11.105 +        vmx_setup_platform(v->domain);
  11.106  
  11.107      __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
  11.108  
  11.109 @@ -278,12 +313,6 @@ static void vmx_do_launch(struct vcpu *v
  11.110  
  11.111      vmx_stts();
  11.112  
  11.113 -    page = (struct pfn_info *) alloc_domheap_page(NULL);
  11.114 -    pfn = (unsigned long) (page - frame_table);
  11.115 -
  11.116 -    if ( v == v->domain->vcpu[0] )
  11.117 -        vmx_setup_platform(v);
  11.118 -
  11.119      vmx_set_host_env(v);
  11.120  
  11.121      error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
    12.1 --- a/xen/include/asm-x86/domain.h	Sat Oct 22 11:04:45 2005 +0100
    12.2 +++ b/xen/include/asm-x86/domain.h	Sun Oct 23 11:51:15 2005 +0100
    12.3 @@ -61,8 +61,8 @@ struct arch_domain
    12.4  
    12.5      struct list_head free_shadow_frames;
    12.6  
    12.7 -    pagetable_t  phys_table;               /* guest 1:1 pagetable */
    12.8 -    struct virtual_platform_def vmx_platform;
    12.9 +    pagetable_t         phys_table;         /* guest 1:1 pagetable */
   12.10 +    struct vmx_platform vmx_platform;
   12.11  } __cacheline_aligned;
   12.12  
   12.13  struct arch_vcpu
    13.1 --- a/xen/include/asm-x86/vmx.h	Sat Oct 22 11:04:45 2005 +0100
    13.2 +++ b/xen/include/asm-x86/vmx.h	Sun Oct 23 11:51:15 2005 +0100
    13.3 @@ -503,6 +503,11 @@ static inline int vmx_reflect_exception(
    13.4      return 0;
    13.5  }
    13.6  
    13.7 +static inline unsigned int vmx_get_vcpu_nr(struct domain *d)
    13.8 +{
    13.9 +    return d->arch.vmx_platform.nr_vcpu;
   13.10 +}
   13.11 +
   13.12  static inline shared_iopage_t *get_sp(struct domain *d)
   13.13  {
   13.14      return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va;
    14.1 --- a/xen/include/asm-x86/vmx_platform.h	Sat Oct 22 11:04:45 2005 +0100
    14.2 +++ b/xen/include/asm-x86/vmx_platform.h	Sun Oct 23 11:51:15 2005 +0100
    14.3 @@ -77,8 +77,10 @@ struct instruction {
    14.4  
    14.5  #define MAX_INST_LEN      32
    14.6  
    14.7 -struct virtual_platform_def {
    14.8 +struct vmx_platform {
    14.9      unsigned long          shared_page_va;
   14.10 +    unsigned int           nr_vcpu;
   14.11 +
   14.12      struct vmx_virpit      vmx_pit;
   14.13      struct vmx_io_handler  vmx_io_handler;
   14.14      struct vmx_virpic      vmx_pic;
    15.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Sat Oct 22 11:04:45 2005 +0100
    15.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Sun Oct 23 11:51:15 2005 +0100
    15.3 @@ -35,6 +35,9 @@ void vmx_restore_msrs(struct vcpu *v);
    15.4  #define vmx_restore_msrs(_v)       ((void)0)
    15.5  #endif
    15.6  
    15.7 +void vmx_final_setup_guest(struct vcpu *v);
    15.8 +void vmx_relinquish_resources(struct vcpu *v);
    15.9 +
   15.10  void vmx_enter_scheduler(void);
   15.11  
   15.12  enum {