ia64/xen-unstable

changeset 12600:9d6bc06919e0

[HVM] Re-introduce the 'apic' configuration option, default to 1.

Also simplify the HVM builder interface by doing more work in
the python wrapper, and fix mapping of shared_info page after the
change to map foreign pages by GMFN rather than MFN.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Nov 27 17:49:41 2006 +0000 (2006-11-27)
parents 93e657836d07
children 3b961863062d
files tools/examples/xmexample.hvm tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/util.c tools/firmware/hvmloader/util.h tools/libxc/xc_hvm_build.c tools/libxc/xenguest.h tools/libxc/xg_private.c tools/python/README.XendConfig tools/python/README.sxpcfg tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/image.py tools/python/xen/xm/create.py xen/include/public/hvm/hvm_info_table.h
line diff
     1.1 --- a/tools/examples/xmexample.hvm	Mon Nov 27 17:48:24 2006 +0000
     1.2 +++ b/tools/examples/xmexample.hvm	Mon Nov 27 17:49:41 2006 +0000
     1.3 @@ -39,14 +39,18 @@ name = "ExampleHVMDomain"
     1.4  #uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
     1.5  
     1.6  #-----------------------------------------------------------------------------
     1.7 -# the number of cpus guest platform has, default=1
     1.8 +# The number of cpus guest platform has, default=1
     1.9  #vcpus=1
    1.10  
    1.11 -# enable/disable HVM guest PAE, default=0 (disabled)
    1.12 -#pae=0
    1.13 +# Enable/disable HVM guest PAE, default=1 (enabled)
    1.14 +#pae=1
    1.15  
    1.16 -# enable/disable HVM guest ACPI, default=0 (disabled)
    1.17 -#acpi=0
    1.18 +# Enable/disable HVM guest ACPI, default=1 (enabled)
    1.19 +#acpi=1
    1.20 +
    1.21 +# Enable/disable HVM APIC mode, default=1 (enabled)
    1.22 +# Note that this option is ignored if vcpus > 1
    1.23 +#apic=1
    1.24  
    1.25  # List of which CPUS this domain is allowed to use, default Xen picks
    1.26  #cpus = ""         # leave to Xen to pick
     2.1 --- a/tools/firmware/hvmloader/acpi/build.c	Mon Nov 27 17:48:24 2006 +0000
     2.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Mon Nov 27 17:49:41 2006 +0000
     2.3 @@ -119,10 +119,11 @@ int acpi_build_tables(uint8_t *buf)
     2.4      struct acpi_20_madt *madt = 0;
     2.5      struct acpi_20_facs *facs;
     2.6      unsigned char       *dsdt;
     2.7 -    int offset = 0, nr_vcpus = get_vcpu_nr();
     2.8 +    int offset = 0, requires_madt;
     2.9 +
    2.10 +    requires_madt = ((get_vcpu_nr() > 1) || get_apic_mode());
    2.11  
    2.12  #define inc_offset(sz)  (offset = (offset + (sz) + 15) & ~15)
    2.13 -#define requires_madt() (nr_vcpus > 1)
    2.14  
    2.15      facs = (struct acpi_20_facs *)&buf[offset];
    2.16      memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
    2.17 @@ -143,7 +144,7 @@ int acpi_build_tables(uint8_t *buf)
    2.18                   offsetof(struct acpi_header, checksum),
    2.19                   sizeof(struct acpi_20_fadt));
    2.20  
    2.21 -    if ( requires_madt() )
    2.22 +    if ( requires_madt )
    2.23      {
    2.24          madt = (struct acpi_20_madt *)&buf[offset];
    2.25          inc_offset(construct_madt(madt));
    2.26 @@ -154,7 +155,7 @@ int acpi_build_tables(uint8_t *buf)
    2.27      inc_offset(sizeof(struct acpi_20_xsdt));
    2.28      xsdt->entry[0] = (unsigned long)fadt;
    2.29      xsdt->header.length = sizeof(struct acpi_header) + sizeof(uint64_t);
    2.30 -    if ( requires_madt() )
    2.31 +    if ( requires_madt )
    2.32      {
    2.33          xsdt->entry[1] = (unsigned long)madt;
    2.34          xsdt->header.length += sizeof(uint64_t);
    2.35 @@ -168,7 +169,7 @@ int acpi_build_tables(uint8_t *buf)
    2.36      inc_offset(sizeof(struct acpi_20_rsdt));
    2.37      rsdt->entry[0] = (unsigned long)fadt;
    2.38      rsdt->header.length = sizeof(struct acpi_header) + sizeof(uint32_t);
    2.39 -    if ( requires_madt() )
    2.40 +    if ( requires_madt )
    2.41      {
    2.42          rsdt->entry[1] = (unsigned long)madt;
    2.43          rsdt->header.length += sizeof(uint32_t);
    2.44 @@ -189,6 +190,8 @@ int acpi_build_tables(uint8_t *buf)
    2.45                   offsetof(struct acpi_20_rsdp, extended_checksum),
    2.46                   sizeof(struct acpi_20_rsdp));
    2.47  
    2.48 +#undef inc_offset
    2.49 +
    2.50      return offset;
    2.51  }
    2.52  
     3.1 --- a/tools/firmware/hvmloader/hvmloader.c	Mon Nov 27 17:48:24 2006 +0000
     3.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Nov 27 17:49:41 2006 +0000
     3.3 @@ -298,7 +298,7 @@ int main(void)
     3.4      apic_setup();
     3.5      pci_setup();
     3.6  
     3.7 -    if ( get_vcpu_nr() > 1 )
     3.8 +    if ( (get_vcpu_nr() > 1) || get_apic_mode() )
     3.9          create_mp_tables();
    3.10  
    3.11      if ( cirrus_check() )
     4.1 --- a/tools/firmware/hvmloader/util.c	Mon Nov 27 17:48:24 2006 +0000
     4.2 +++ b/tools/firmware/hvmloader/util.c	Mon Nov 27 17:49:41 2006 +0000
     4.3 @@ -535,13 +535,19 @@ static struct hvm_info_table *get_hvm_in
     4.4  int get_vcpu_nr(void)
     4.5  {
     4.6      struct hvm_info_table *t = get_hvm_info_table();
     4.7 -    return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
     4.8 +    return (t ? t->nr_vcpus : 1);
     4.9  }
    4.10  
    4.11  int get_acpi_enabled(void)
    4.12  {
    4.13      struct hvm_info_table *t = get_hvm_info_table();
    4.14 -    return (t ? t->acpi_enabled : 0); /* default no acpi */
    4.15 +    return (t ? t->acpi_enabled : 1);
    4.16 +}
    4.17 +
    4.18 +int get_apic_mode(void)
    4.19 +{
    4.20 +    struct hvm_info_table *t = get_hvm_info_table();
    4.21 +    return (t ? t->apic_mode : 1);
    4.22  }
    4.23  
    4.24  /*
     5.1 --- a/tools/firmware/hvmloader/util.h	Mon Nov 27 17:48:24 2006 +0000
     5.2 +++ b/tools/firmware/hvmloader/util.h	Mon Nov 27 17:49:41 2006 +0000
     5.3 @@ -46,6 +46,7 @@ void cpuid(uint32_t idx, uint32_t *eax, 
     5.4  /* HVM-builder info. */
     5.5  int get_vcpu_nr(void);
     5.6  int get_acpi_enabled(void);
     5.7 +int get_apic_mode(void);
     5.8  
     5.9  /* String and memory functions */
    5.10  int strcmp(const char *cs, const char *ct);
     6.1 --- a/tools/libxc/xc_hvm_build.c	Mon Nov 27 17:48:24 2006 +0000
     6.2 +++ b/tools/libxc/xc_hvm_build.c	Mon Nov 27 17:49:41 2006 +0000
     6.3 @@ -15,6 +15,8 @@
     6.4  #include <xen/hvm/params.h>
     6.5  #include <xen/hvm/e820.h>
     6.6  
     6.7 +#define SCRATCH_PFN 0xFFFFF
     6.8 +
     6.9  #define HVM_LOADER_ENTR_ADDR  0x00100000
    6.10  static int
    6.11  parseelfimage(
    6.12 @@ -24,8 +26,8 @@ loadelfimage(
    6.13      char *elfbase, int xch, uint32_t dom, unsigned long *parray,
    6.14      struct domain_setup_info *dsi);
    6.15  
    6.16 -static void xc_set_hvm_param(int handle,
    6.17 -                             domid_t dom, int param, unsigned long value)
    6.18 +int xc_set_hvm_param(
    6.19 +    int handle, domid_t dom, int param, unsigned long value)
    6.20  {
    6.21      DECLARE_HYPERCALL;
    6.22      xen_hvm_param_t arg;
    6.23 @@ -38,14 +40,30 @@ static void xc_set_hvm_param(int handle,
    6.24      arg.index = param;
    6.25      arg.value = value;
    6.26      if ( lock_pages(&arg, sizeof(arg)) != 0 )
    6.27 -    {
    6.28 -        PERROR("Could not lock memory for set parameter");
    6.29 -        return;
    6.30 -    }
    6.31 +        return -1;
    6.32      rc = do_xen_hypercall(handle, &hypercall);
    6.33      unlock_pages(&arg, sizeof(arg));
    6.34 -    if (rc < 0)
    6.35 -        PERROR("set HVM parameter failed (%d)", rc);
    6.36 +    return rc;
    6.37 +}
    6.38 +
    6.39 +int xc_get_hvm_param(
    6.40 +    int handle, domid_t dom, int param, unsigned long *value)
    6.41 +{
    6.42 +    DECLARE_HYPERCALL;
    6.43 +    xen_hvm_param_t arg;
    6.44 +    int rc;
    6.45 +
    6.46 +    hypercall.op     = __HYPERVISOR_hvm_op;
    6.47 +    hypercall.arg[0] = HVMOP_get_param;
    6.48 +    hypercall.arg[1] = (unsigned long)&arg;
    6.49 +    arg.domid = dom;
    6.50 +    arg.index = param;
    6.51 +    if ( lock_pages(&arg, sizeof(arg)) != 0 )
    6.52 +        return -1;
    6.53 +    rc = do_xen_hypercall(handle, &hypercall);
    6.54 +    unlock_pages(&arg, sizeof(arg));
    6.55 +    *value = arg.value;
    6.56 +    return rc;
    6.57  }
    6.58  
    6.59  static void build_e820map(void *e820_page, unsigned long long mem_size)
    6.60 @@ -126,67 +144,16 @@ static void build_e820map(void *e820_pag
    6.61      *(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map;
    6.62  }
    6.63  
    6.64 -static void set_hvm_info_checksum(struct hvm_info_table *t)
    6.65 -{
    6.66 -    uint8_t *ptr = (uint8_t *)t, sum = 0;
    6.67 -    unsigned int i;
    6.68 -
    6.69 -    t->checksum = 0;
    6.70 -
    6.71 -    for (i = 0; i < t->length; i++)
    6.72 -        sum += *ptr++;
    6.73 -
    6.74 -    t->checksum = -sum;
    6.75 -}
    6.76 -
    6.77 -/*
    6.78 - * Use E820 reserved memory 0x9F800 to pass HVM info to hvmloader
    6.79 - * hvmloader will use this info to set BIOS accordingly
    6.80 - */
    6.81 -static int set_hvm_info(int xc_handle, uint32_t dom,
    6.82 -                        xen_pfn_t *pfn_list, unsigned int vcpus,
    6.83 -                        unsigned int acpi)
    6.84 -{
    6.85 -    char *va_map;
    6.86 -    struct hvm_info_table *va_hvm;
    6.87 -
    6.88 -    va_map = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
    6.89 -                                  PROT_READ | PROT_WRITE,
    6.90 -                                  pfn_list[HVM_INFO_PFN]);
    6.91 -
    6.92 -    if ( va_map == NULL )
    6.93 -        return -1;
    6.94 -
    6.95 -    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
    6.96 -    memset(va_hvm, 0, sizeof(*va_hvm));
    6.97 -
    6.98 -    strncpy(va_hvm->signature, "HVM INFO", 8);
    6.99 -    va_hvm->length       = sizeof(struct hvm_info_table);
   6.100 -    va_hvm->acpi_enabled = acpi;
   6.101 -    va_hvm->nr_vcpus     = vcpus;
   6.102 -
   6.103 -    set_hvm_info_checksum(va_hvm);
   6.104 -
   6.105 -    munmap(va_map, PAGE_SIZE);
   6.106 -
   6.107 -    return 0;
   6.108 -}
   6.109 -
   6.110  static int setup_guest(int xc_handle,
   6.111                         uint32_t dom, int memsize,
   6.112                         char *image, unsigned long image_size,
   6.113 -                       vcpu_guest_context_t *ctxt,
   6.114 -                       unsigned long shared_info_frame,
   6.115 -                       unsigned int vcpus,
   6.116 -                       unsigned int pae,
   6.117 -                       unsigned int acpi,
   6.118 -                       unsigned int store_evtchn,
   6.119 -                       unsigned long *store_mfn)
   6.120 +                       vcpu_guest_context_t *ctxt)
   6.121  {
   6.122      xen_pfn_t *page_array = NULL;
   6.123      unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
   6.124      unsigned long shared_page_nr;
   6.125 -    shared_info_t *shared_info;
   6.126 +    struct xen_add_to_physmap xatp;
   6.127 +    struct shared_info *shared_info;
   6.128      void *e820_page;
   6.129      struct domain_setup_info dsi;
   6.130      uint64_t v_end;
   6.131 @@ -247,29 +214,25 @@ static int setup_guest(int xc_handle,
   6.132  
   6.133      loadelfimage(image, xc_handle, dom, page_array, &dsi);
   6.134  
   6.135 -    if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi) )
   6.136 -    {
   6.137 -        ERROR("Couldn't set hvm info for HVM guest.\n");
   6.138 -        goto error_out;
   6.139 -    }
   6.140 -
   6.141 -    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
   6.142 -
   6.143      if ( (e820_page = xc_map_foreign_range(
   6.144                xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   6.145 -              page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == NULL )
   6.146 +              E820_MAP_PAGE >> PAGE_SHIFT)) == NULL )
   6.147          goto error_out;
   6.148      memset(e820_page, 0, PAGE_SIZE);
   6.149      build_e820map(e820_page, v_end);
   6.150      munmap(e820_page, PAGE_SIZE);
   6.151  
   6.152 -    /* shared_info page starts its life empty. */
   6.153 -    if ( (shared_info = xc_map_foreign_range(
   6.154 -              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   6.155 -              shared_info_frame)) == NULL )
   6.156 +    /* Map and initialise shared_info page. */
   6.157 +    xatp.domid = dom;
   6.158 +    xatp.space = XENMAPSPACE_shared_info;
   6.159 +    xatp.idx   = 0;
   6.160 +    xatp.gpfn  = SCRATCH_PFN;
   6.161 +    if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
   6.162 +         ((shared_info = xc_map_foreign_range(
   6.163 +             xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   6.164 +             SCRATCH_PFN)) == NULL) )
   6.165          goto error_out;
   6.166      memset(shared_info, 0, PAGE_SIZE);
   6.167 -    /* Mask all upcalls... */
   6.168      for ( i = 0; i < MAX_VIRT_CPUS; i++ )
   6.169          shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
   6.170      memset(&shared_info->evtchn_mask[0], 0xff,
   6.171 @@ -282,14 +245,12 @@ static int setup_guest(int xc_handle,
   6.172          shared_page_nr = (v_end >> PAGE_SHIFT) - 1;
   6.173  
   6.174      /* Paranoia: clean pages. */
   6.175 -    if ( xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr]) ||
   6.176 -         xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-1]) ||
   6.177 -         xc_clear_domain_page(xc_handle, dom, page_array[shared_page_nr-2]) )
   6.178 +    if ( xc_clear_domain_page(xc_handle, dom, shared_page_nr) ||
   6.179 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-1) ||
   6.180 +         xc_clear_domain_page(xc_handle, dom, shared_page_nr-2) )
   6.181          goto error_out;
   6.182  
   6.183 -    *store_mfn = page_array[shared_page_nr - 1];
   6.184      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, shared_page_nr-1);
   6.185 -    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
   6.186      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2);
   6.187      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr);
   6.188  
   6.189 @@ -308,14 +269,9 @@ static int xc_hvm_build_internal(int xc_
   6.190                                   uint32_t domid,
   6.191                                   int memsize,
   6.192                                   char *image,
   6.193 -                                 unsigned long image_size,
   6.194 -                                 unsigned int vcpus,
   6.195 -                                 unsigned int pae,
   6.196 -                                 unsigned int acpi,
   6.197 -                                 unsigned int store_evtchn,
   6.198 -                                 unsigned long *store_mfn)
   6.199 +                                 unsigned long image_size)
   6.200  {
   6.201 -    struct xen_domctl launch_domctl, domctl;
   6.202 +    struct xen_domctl launch_domctl;
   6.203      vcpu_guest_context_t ctxt;
   6.204      int rc;
   6.205  
   6.206 @@ -325,20 +281,9 @@ static int xc_hvm_build_internal(int xc_
   6.207          goto error_out;
   6.208      }
   6.209  
   6.210 -    domctl.cmd = XEN_DOMCTL_getdomaininfo;
   6.211 -    domctl.domain = (domid_t)domid;
   6.212 -    if ( (xc_domctl(xc_handle, &domctl) < 0) ||
   6.213 -         ((uint16_t)domctl.domain != domid) )
   6.214 -    {
   6.215 -        PERROR("Could not get info on domain");
   6.216 -        goto error_out;
   6.217 -    }
   6.218 -
   6.219      memset(&ctxt, 0, sizeof(ctxt));
   6.220  
   6.221 -    if ( setup_guest(xc_handle, domid, memsize, image, image_size,
   6.222 -                     &ctxt, domctl.u.getdomaininfo.shared_info_frame,
   6.223 -                     vcpus, pae, acpi, store_evtchn, store_mfn) < 0)
   6.224 +    if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
   6.225      {
   6.226          ERROR("Error constructing guest OS");
   6.227          goto error_out;
   6.228 @@ -500,12 +445,7 @@ loadelfimage(
   6.229  int xc_hvm_build(int xc_handle,
   6.230                   uint32_t domid,
   6.231                   int memsize,
   6.232 -                 const char *image_name,
   6.233 -                 unsigned int vcpus,
   6.234 -                 unsigned int pae,
   6.235 -                 unsigned int acpi,
   6.236 -                 unsigned int store_evtchn,
   6.237 -                 unsigned long *store_mfn)
   6.238 +                 const char *image_name)
   6.239  {
   6.240      char *image;
   6.241      int  sts;
   6.242 @@ -515,10 +455,7 @@ int xc_hvm_build(int xc_handle,
   6.243           ((image = xc_read_image(image_name, &image_size)) == NULL) )
   6.244          return -1;
   6.245  
   6.246 -    sts = xc_hvm_build_internal(xc_handle, domid, memsize,
   6.247 -                                image, image_size,
   6.248 -                                vcpus, pae, acpi,
   6.249 -                                store_evtchn, store_mfn);
   6.250 +    sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size);
   6.251  
   6.252      free(image);
   6.253  
   6.254 @@ -535,12 +472,7 @@ int xc_hvm_build_mem(int xc_handle,
   6.255                       uint32_t domid,
   6.256                       int memsize,
   6.257                       const char *image_buffer,
   6.258 -                     unsigned long image_size,
   6.259 -                     unsigned int vcpus,
   6.260 -                     unsigned int pae,
   6.261 -                     unsigned int acpi,
   6.262 -                     unsigned int store_evtchn,
   6.263 -                     unsigned long *store_mfn)
   6.264 +                     unsigned long image_size)
   6.265  {
   6.266      int           sts;
   6.267      unsigned long img_len;
   6.268 @@ -562,9 +494,7 @@ int xc_hvm_build_mem(int xc_handle,
   6.269      }
   6.270  
   6.271      sts = xc_hvm_build_internal(xc_handle, domid, memsize,
   6.272 -                                img, img_len,
   6.273 -                                vcpus, pae, acpi,
   6.274 -                                store_evtchn, store_mfn);
   6.275 +                                img, img_len);
   6.276  
   6.277      /* xc_inflate_buffer may return the original buffer pointer (for
   6.278         for already inflated buffers), so exercise some care in freeing */
     7.1 --- a/tools/libxc/xenguest.h	Mon Nov 27 17:48:24 2006 +0000
     7.2 +++ b/tools/libxc/xenguest.h	Mon Nov 27 17:49:41 2006 +0000
     7.3 @@ -109,22 +109,17 @@ int xc_linux_build_mem(int xc_handle,
     7.4  int xc_hvm_build(int xc_handle,
     7.5                   uint32_t domid,
     7.6                   int memsize,
     7.7 -                 const char *image_name,
     7.8 -                 unsigned int vcpus,
     7.9 -                 unsigned int pae,
    7.10 -                 unsigned int acpi,
    7.11 -                 unsigned int store_evtchn,
    7.12 -                 unsigned long *store_mfn);
    7.13 +                 const char *image_name);
    7.14  
    7.15  int xc_hvm_build_mem(int xc_handle,
    7.16                       uint32_t domid,
    7.17                       int memsize,
    7.18                       const char *image_buffer,
    7.19 -                     unsigned long image_size,
    7.20 -                     unsigned int vcpus,
    7.21 -                     unsigned int pae,
    7.22 -                     unsigned int acpi,
    7.23 -                     unsigned int store_evtchn,
    7.24 -                     unsigned long *store_mfn);
    7.25 +                     unsigned long image_size);
    7.26 +
    7.27 +int xc_set_hvm_param(
    7.28 +    int handle, domid_t dom, int param, unsigned long value);
    7.29 +int xc_get_hvm_param(
    7.30 +    int handle, domid_t dom, int param, unsigned long *value);
    7.31  
    7.32  #endif /* XENGUEST_H */
     8.1 --- a/tools/libxc/xg_private.c	Mon Nov 27 17:48:24 2006 +0000
     8.2 +++ b/tools/libxc/xg_private.c	Mon Nov 27 17:49:41 2006 +0000
     8.3 @@ -192,12 +192,7 @@ unsigned long csum_page(void *page)
     8.4      int xc_handle,
     8.5      uint32_t domid,
     8.6      int memsize,
     8.7 -    const char *image_name,
     8.8 -    unsigned int vcpus,
     8.9 -    unsigned int pae,
    8.10 -    unsigned int acpi,
    8.11 -    unsigned int store_evtchn,
    8.12 -    unsigned long *store_mfn)
    8.13 +    const char *image_name)
    8.14  {
    8.15      return -ENOSYS;
    8.16  }
     9.1 --- a/tools/python/README.XendConfig	Mon Nov 27 17:48:24 2006 +0000
     9.2 +++ b/tools/python/README.XendConfig	Mon Nov 27 17:49:41 2006 +0000
     9.3 @@ -123,6 +123,7 @@ otherConfig
     9.4                                  image.hvm.vncconsole
     9.5                                  image.hvm.pae
     9.6                                  image.hvm.acpi (also in image.devices)
     9.7 +                                image.hvm.apic
     9.8                                  image.hvm.devices.boot
     9.9                                  image.hvm.devices.fda
    9.10                                  image.hvm.devices.fdb
    10.1 --- a/tools/python/README.sxpcfg	Mon Nov 27 17:48:24 2006 +0000
    10.2 +++ b/tools/python/README.sxpcfg	Mon Nov 27 17:49:41 2006 +0000
    10.3 @@ -56,6 +56,7 @@ image
    10.4    - vncconsole
    10.5    - pae
    10.6    - acpi
    10.7 +  - apic
    10.8    (parseDeviceModel)
    10.9    - boot
   10.10    - fda
    11.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Mon Nov 27 17:48:24 2006 +0000
    11.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Mon Nov 27 17:49:41 2006 +0000
    11.3 @@ -13,10 +13,13 @@
    11.4  #include <netinet/tcp.h>
    11.5  #include <sys/types.h>
    11.6  #include <sys/socket.h>
    11.7 +#include <sys/mman.h>
    11.8  #include <netdb.h>
    11.9  #include <arpa/inet.h>
   11.10  
   11.11  #include "xenctrl.h"
   11.12 +#include <xen/hvm/hvm_info_table.h>
   11.13 +#include <xen/hvm/params.h>
   11.14  
   11.15  /* Needed for Python versions earlier than 2.3. */
   11.16  #ifndef PyMODINIT_FUNC
   11.17 @@ -371,26 +374,46 @@ static PyObject *pyxc_hvm_build(XcObject
   11.18                                  PyObject *kwds)
   11.19  {
   11.20      uint32_t dom;
   11.21 +    struct hvm_info_table *va_hvm;
   11.22 +    uint8_t *va_map, sum;
   11.23      char *image;
   11.24 -    int store_evtchn;
   11.25 -    int memsize;
   11.26 -    int vcpus = 1;
   11.27 -    int pae  = 0;
   11.28 -    int acpi = 0;
   11.29 -    unsigned long store_mfn = 0;
   11.30 +    int i, store_evtchn, memsize, vcpus = 1, pae = 0, acpi = 0, apic = 1;
   11.31 +    unsigned long store_mfn;
   11.32  
   11.33      static char *kwd_list[] = { "domid", "store_evtchn",
   11.34  				"memsize", "image", "vcpus", "pae", "acpi",
   11.35 -				NULL };
   11.36 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiisiii", kwd_list,
   11.37 +				"apic", NULL };
   11.38 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|iiii", kwd_list,
   11.39                                        &dom, &store_evtchn, &memsize,
   11.40 -                                      &image, &vcpus, &pae, &acpi) )
   11.41 +                                      &image, &vcpus, &pae, &acpi, &apic) )
   11.42          return NULL;
   11.43  
   11.44 -    if ( xc_hvm_build(self->xc_handle, dom, memsize, image,
   11.45 -                      vcpus, pae, acpi, store_evtchn, &store_mfn) != 0 )
   11.46 +    if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
   11.47          return PyErr_SetFromErrno(xc_error);
   11.48  
   11.49 +    /* Set up the HVM info table. */
   11.50 +    va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE,
   11.51 +                                  PROT_READ | PROT_WRITE,
   11.52 +                                  HVM_INFO_PFN);
   11.53 +    if ( va_map == NULL )
   11.54 +        return PyErr_SetFromErrno(xc_error);
   11.55 +    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
   11.56 +    memset(va_hvm, 0, sizeof(*va_hvm));
   11.57 +    strncpy(va_hvm->signature, "HVM INFO", 8);
   11.58 +    va_hvm->length       = sizeof(struct hvm_info_table);
   11.59 +    va_hvm->acpi_enabled = acpi;
   11.60 +    va_hvm->apic_mode    = apic;
   11.61 +    va_hvm->nr_vcpus     = vcpus;
   11.62 +    for ( i = 0, sum = 0; i < va_hvm->length; i++ )
   11.63 +        sum += ((uint8_t *)va_hvm)[i];
   11.64 +    va_hvm->checksum = -sum;
   11.65 +    munmap(va_map, PAGE_SIZE);
   11.66 +
   11.67 +    xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
   11.68 +    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
   11.69 +    xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_EVTCHN,
   11.70 +                     store_evtchn);
   11.71 +
   11.72      return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
   11.73  }
   11.74  
    12.1 --- a/tools/python/xen/xend/image.py	Mon Nov 27 17:48:24 2006 +0000
    12.2 +++ b/tools/python/xen/xend/image.py	Mon Nov 27 17:49:41 2006 +0000
    12.3 @@ -252,7 +252,6 @@ class HVMImageHandler(ImageHandler):
    12.4          ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
    12.5          self.shutdownWatch = None
    12.6  
    12.7 -
    12.8      def configure(self, imageConfig, deviceConfig):
    12.9          ImageHandler.configure(self, imageConfig, deviceConfig)
   12.10  
   12.11 @@ -277,9 +276,9 @@ class HVMImageHandler(ImageHandler):
   12.12  
   12.13          self.dmargs += self.configVNC(imageConfig)
   12.14  
   12.15 -        self.pae  = int(sxp.child_value(imageConfig, 'pae', 0))
   12.16 -
   12.17 -        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
   12.18 +        self.pae  = int(sxp.child_value(imageConfig, 'pae',  1))
   12.19 +        self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
   12.20 +        self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
   12.21  
   12.22      def buildDomain(self):
   12.23          store_evtchn = self.vm.getStorePort()
   12.24 @@ -293,6 +292,7 @@ class HVMImageHandler(ImageHandler):
   12.25          log.debug("vcpus          = %d", self.vm.getVCpuCount())
   12.26          log.debug("pae            = %d", self.pae)
   12.27          log.debug("acpi           = %d", self.acpi)
   12.28 +        log.debug("apic           = %d", self.apic)
   12.29  
   12.30          self.register_shutdown_watch()
   12.31  
   12.32 @@ -302,7 +302,8 @@ class HVMImageHandler(ImageHandler):
   12.33                              memsize        = mem_mb,
   12.34                              vcpus          = self.vm.getVCpuCount(),
   12.35                              pae            = self.pae,
   12.36 -                            acpi           = self.acpi)
   12.37 +                            acpi           = self.acpi,
   12.38 +                            apic           = self.apic)
   12.39  
   12.40      # Return a list of cmd line args to the device models based on the
   12.41      # xm config file
    13.1 --- a/tools/python/xen/xm/create.py	Mon Nov 27 17:48:24 2006 +0000
    13.2 +++ b/tools/python/xen/xm/create.py	Mon Nov 27 17:49:41 2006 +0000
    13.3 @@ -174,13 +174,17 @@ gopts.var('cpus', val='CPUS',
    13.4            use="CPUS to run the domain on.")
    13.5  
    13.6  gopts.var('pae', val='PAE',
    13.7 -          fn=set_int, default=0,
    13.8 +          fn=set_int, default=1,
    13.9            use="Disable or enable PAE of HVM domain.")
   13.10  
   13.11  gopts.var('acpi', val='ACPI',
   13.12 -          fn=set_int, default=0,
   13.13 +          fn=set_int, default=1,
   13.14            use="Disable or enable ACPI of HVM domain.")
   13.15  
   13.16 +gopts.var('apic', val='APIC',
   13.17 +          fn=set_int, default=1,
   13.18 +          use="Disable or enable APIC mode.")
   13.19 +
   13.20  gopts.var('vcpus', val='VCPUS',
   13.21            fn=set_int, default=1,
   13.22            use="# of Virtual CPUS in domain.")
   13.23 @@ -664,9 +668,9 @@ def configure_hvm(config_image, vals):
   13.24               'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
   13.25               'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
   13.26               'sdl', 'display', 'xauthority',
   13.27 -             'acpi', 'usb', 'usbdevice', 'keymap' ]
   13.28 +             'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ]
   13.29      for a in args:
   13.30 -        if (vals.__dict__[a]):
   13.31 +        if a in vals.__dict__ and vals.__dict__[a] is not None:
   13.32              config_image.append([a, vals.__dict__[a]])
   13.33      config_image.append(['vncpasswd', vals.vncpasswd])
   13.34  
    14.1 --- a/xen/include/public/hvm/hvm_info_table.h	Mon Nov 27 17:48:24 2006 +0000
    14.2 +++ b/xen/include/public/hvm/hvm_info_table.h	Mon Nov 27 17:49:41 2006 +0000
    14.3 @@ -34,6 +34,7 @@ struct hvm_info_table {
    14.4      uint32_t    length;
    14.5      uint8_t     checksum;
    14.6      uint8_t     acpi_enabled;
    14.7 +    uint8_t     apic_mode;
    14.8      uint32_t    nr_vcpus;
    14.9  };
   14.10