ia64/xen-unstable

changeset 19017:8c894687c2a5

x86, hvm: Move E820 table creation into hvmloader, extend
hvm_info_table to describe memory parameters in a simpler form from
domain builder to hvmloader.

Also move reserved special page mappings immediately below the 4GB
boundary.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 08 15:27:20 2009 +0000 (2009-01-08)
parents 0d119f628795
children 61dc77689daf
files tools/firmware/hvmloader/config.h tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/util.c tools/libxc/xc_hvm_build.c tools/python/xen/lowlevel/xc/xc.c xen/include/public/hvm/hvm_info_table.h
line diff
     1.1 --- a/tools/firmware/hvmloader/config.h	Thu Jan 08 15:18:30 2009 +0000
     1.2 +++ b/tools/firmware/hvmloader/config.h	Thu Jan 08 15:27:20 2009 +0000
     1.3 @@ -1,6 +1,9 @@
     1.4  #ifndef __HVMLOADER_CONFIG_H__
     1.5  #define __HVMLOADER_CONFIG_H__
     1.6  
     1.7 +#define PAGE_SHIFT 12
     1.8 +#define PAGE_SIZE  (1ul << PAGE_SHIFT)
     1.9 +
    1.10  #define IOAPIC_BASE_ADDRESS 0xfec00000
    1.11  #define IOAPIC_ID           0x01
    1.12  #define IOAPIC_VERSION      0x11
     2.1 --- a/tools/firmware/hvmloader/hvmloader.c	Thu Jan 08 15:18:30 2009 +0000
     2.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Thu Jan 08 15:27:20 2009 +0000
     2.3 @@ -560,15 +560,67 @@ static void init_vm86_tss(void)
     2.4      printf("vm86 TSS at %08x\n", tss);
     2.5  }
     2.6  
     2.7 -/*
     2.8 - * Copy the E820 table provided by the HVM domain builder into the correct
     2.9 - * place in the memory map we share with the rombios.
    2.10 - */
    2.11 -static void copy_e820_table(void)
    2.12 +/* Create an E820 table based on memory parameters provided in hvm_info. */
    2.13 +static void build_e820_table(void)
    2.14  {
    2.15 -    uint8_t nr = *(uint8_t *)(HVM_E820_PAGE + HVM_E820_NR_OFFSET);
    2.16 -    BUG_ON(nr > 16);
    2.17 -    memcpy(E820, (char *)HVM_E820_PAGE + HVM_E820_OFFSET, nr * sizeof(*E820));
    2.18 +    struct e820entry *e820 = E820;
    2.19 +    unsigned int nr = 0;
    2.20 +
    2.21 +    /* 0x0-0x9FC00: Ordinary RAM. */
    2.22 +    e820[nr].addr = 0x0;
    2.23 +    e820[nr].size = 0x9FC00;
    2.24 +    e820[nr].type = E820_RAM;
    2.25 +    nr++;
    2.26 +
    2.27 +    /* 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). */
    2.28 +    e820[nr].addr = 0x9FC00;
    2.29 +    e820[nr].size = 0x400;
    2.30 +    e820[nr].type = E820_RESERVED;
    2.31 +    nr++;
    2.32 +
    2.33 +    /*
    2.34 +     * Following regions are standard regions of the PC memory map.
    2.35 +     * They are not covered by e820 regions. OSes will not use as RAM.
    2.36 +     * 0xA0000-0xC0000: VGA memory-mapped I/O. Not covered by E820.
    2.37 +     * 0xC0000-0xE0000: 16-bit devices, expansion ROMs (inc. vgabios).
    2.38 +     * TODO: free pages which turn out to be unused.
    2.39 +     */
    2.40 +
    2.41 +    /*
    2.42 +     * 0xE0000-0x0F0000: PC-specific area. We place various tables here.
    2.43 +     * 0xF0000-0x100000: System BIOS.
    2.44 +     * TODO: free pages which turn out to be unused.
    2.45 +     */
    2.46 +    e820[nr].addr = 0xE0000;
    2.47 +    e820[nr].size = 0x20000;
    2.48 +    e820[nr].type = E820_RESERVED;
    2.49 +    nr++;
    2.50 +
    2.51 +    /* Low RAM goes here. Reserve space for special pages. */
    2.52 +    BUG_ON((hvm_info->low_mem_pgend << PAGE_SHIFT) < (2u << 20));
    2.53 +    e820[nr].addr = 0x100000;
    2.54 +    e820[nr].size = (hvm_info->low_mem_pgend << PAGE_SHIFT) - e820[nr].addr;
    2.55 +    e820[nr].type = E820_RAM;
    2.56 +    nr++;
    2.57 +
    2.58 +    if ( hvm_info->reserved_mem_pgstart )
    2.59 +    {
    2.60 +        /* Explicitly reserve space for special pages. */
    2.61 +        e820[nr].addr = hvm_info->reserved_mem_pgstart << PAGE_SHIFT;
    2.62 +        e820[nr].size = (uint32_t)-e820[nr].addr;
    2.63 +        e820[nr].type = E820_RESERVED;
    2.64 +        nr++;
    2.65 +    }
    2.66 +
    2.67 +    if ( hvm_info->high_mem_pgend )
    2.68 +    {
    2.69 +        e820[nr].addr = ((uint64_t)1 << 32);
    2.70 +        e820[nr].size =
    2.71 +            ((uint64_t)hvm_info->high_mem_pgend << PAGE_SHIFT) - e820[nr].addr;
    2.72 +        e820[nr].type = E820_RAM;
    2.73 +        nr++;
    2.74 +    }
    2.75 +
    2.76      *E820_NR = nr;
    2.77  }
    2.78  
    2.79 @@ -581,7 +633,7 @@ int main(void)
    2.80  
    2.81      printf("HVM Loader\n");
    2.82  
    2.83 -    copy_e820_table();
    2.84 +    build_e820_table();
    2.85  
    2.86      init_hypercalls();
    2.87  
     3.1 --- a/tools/firmware/hvmloader/util.c	Thu Jan 08 15:18:30 2009 +0000
     3.2 +++ b/tools/firmware/hvmloader/util.c	Thu Jan 08 15:27:20 2009 +0000
     3.3 @@ -542,27 +542,32 @@ void __bug(char *file, int line)
     3.4          asm volatile ( "ud2" );
     3.5  }
     3.6  
     3.7 -static int validate_hvm_info(struct hvm_info_table *t)
     3.8 +static void validate_hvm_info(struct hvm_info_table *t)
     3.9  {
    3.10 -    char signature[] = "HVM INFO";
    3.11      uint8_t *ptr = (uint8_t *)t;
    3.12      uint8_t sum = 0;
    3.13      int i;
    3.14  
    3.15 -    /* strncmp(t->signature, "HVM INFO", 8) */
    3.16 -    for ( i = 0; i < 8; i++ )
    3.17 +    if ( strncmp(t->signature, "HVM INFO", 8) )
    3.18      {
    3.19 -        if ( signature[i] != t->signature[i] )
    3.20 -        {
    3.21 -            printf("Bad hvm info signature\n");
    3.22 -            return 0;
    3.23 -        }
    3.24 +        printf("Bad hvm info signature\n");
    3.25 +        BUG();
    3.26 +    }
    3.27 +
    3.28 +    if ( t->length < sizeof(struct hvm_info_table) )
    3.29 +    {
    3.30 +        printf("Bad hvm info length\n");
    3.31 +        BUG();
    3.32      }
    3.33  
    3.34      for ( i = 0; i < t->length; i++ )
    3.35          sum += ptr[i];
    3.36  
    3.37 -    return (sum == 0);
    3.38 +    if ( sum != 0 )
    3.39 +    {
    3.40 +        printf("Bad hvm info checksum\n");
    3.41 +        BUG();
    3.42 +    }
    3.43  }
    3.44  
    3.45  struct hvm_info_table *get_hvm_info_table(void)
    3.46 @@ -575,11 +580,7 @@ struct hvm_info_table *get_hvm_info_tabl
    3.47  
    3.48      t = (struct hvm_info_table *)HVM_INFO_PADDR;
    3.49  
    3.50 -    if ( !validate_hvm_info(t) )
    3.51 -    {
    3.52 -        printf("Bad hvm info table\n");
    3.53 -        BUG();
    3.54 -    }
    3.55 +    validate_hvm_info(t);
    3.56  
    3.57      table = t;
    3.58  
     4.1 --- a/tools/libxc/xc_hvm_build.c	Thu Jan 08 15:18:30 2009 +0000
     4.2 +++ b/tools/libxc/xc_hvm_build.c	Thu Jan 08 15:27:20 2009 +0000
     4.3 @@ -15,100 +15,55 @@
     4.4  #include <xen/foreign/x86_64.h>
     4.5  #include <xen/hvm/hvm_info_table.h>
     4.6  #include <xen/hvm/params.h>
     4.7 -#include "xc_e820.h"
     4.8 +#include <xen/hvm/e820.h>
     4.9  
    4.10  #include <xen/libelf/libelf.h>
    4.11  
    4.12  #define SUPERPAGE_PFN_SHIFT  9
    4.13  #define SUPERPAGE_NR_PFNS    (1UL << SUPERPAGE_PFN_SHIFT)
    4.14  
    4.15 -#define SCRATCH_PFN 0xFFFFF
    4.16 +#define SPECIALPAGE_BUFIOREQ 0
    4.17 +#define SPECIALPAGE_XENSTORE 1
    4.18 +#define SPECIALPAGE_IOREQ    2
    4.19 +#define SPECIALPAGE_IDENT_PT 3
    4.20 +#define SPECIALPAGE_SHINFO   4
    4.21 +#define NR_SPECIAL_PAGES     5
    4.22 +#define special_pfn(x) (0x100000u - NR_SPECIAL_PAGES + (x))
    4.23  
    4.24 -#define SPECIALPAGE_GUARD    0
    4.25 -#define SPECIALPAGE_BUFIOREQ 1
    4.26 -#define SPECIALPAGE_XENSTORE 2
    4.27 -#define SPECIALPAGE_IOREQ    3
    4.28 -#define SPECIALPAGE_IDENT_PT 4
    4.29 -#define NR_SPECIAL_PAGES     5
    4.30 -
    4.31 -static void build_e820map(void *e820_page, unsigned long long mem_size)
    4.32 +static void build_hvm_info(void *hvm_info_page, uint64_t mem_size)
    4.33  {
    4.34 -    struct e820entry *e820entry =
    4.35 -        (struct e820entry *)(((unsigned char *)e820_page) + HVM_E820_OFFSET);
    4.36 -    unsigned long long extra_mem_size = 0;
    4.37 -    unsigned char nr_map = 0;
    4.38 +    struct hvm_info_table *hvm_info = (struct hvm_info_table *)
    4.39 +        (((unsigned char *)hvm_info_page) + HVM_INFO_OFFSET);
    4.40 +    uint64_t lowmem_end = mem_size, highmem_end = 0;
    4.41 +    uint8_t sum;
    4.42 +    int i;
    4.43  
    4.44 -    /*
    4.45 -     * Physical address space from HVM_BELOW_4G_RAM_END to 4G is reserved
    4.46 -     * for PCI devices MMIO. So if HVM has more than HVM_BELOW_4G_RAM_END
    4.47 -     * RAM, memory beyond HVM_BELOW_4G_RAM_END will go to 4G above.
    4.48 -     */
    4.49 -    if ( mem_size > HVM_BELOW_4G_RAM_END )
    4.50 +    if ( lowmem_end > HVM_BELOW_4G_RAM_END )
    4.51      {
    4.52 -        extra_mem_size = mem_size - HVM_BELOW_4G_RAM_END;
    4.53 -        mem_size = HVM_BELOW_4G_RAM_END;
    4.54 +        highmem_end = lowmem_end + (1ull<<32) - HVM_BELOW_4G_RAM_END;
    4.55 +        lowmem_end = HVM_BELOW_4G_RAM_END;
    4.56      }
    4.57  
    4.58 -    /* 0x0-0x9FC00: Ordinary RAM. */
    4.59 -    e820entry[nr_map].addr = 0x0;
    4.60 -    e820entry[nr_map].size = 0x9FC00;
    4.61 -    e820entry[nr_map].type = E820_RAM;
    4.62 -    nr_map++;
    4.63 +    memset(hvm_info_page, 0, PAGE_SIZE);
    4.64  
    4.65 -    /* 0x9FC00-0xA0000: Extended BIOS Data Area (EBDA). */
    4.66 -    e820entry[nr_map].addr = 0x9FC00;
    4.67 -    e820entry[nr_map].size = 0x400;
    4.68 -    e820entry[nr_map].type = E820_RESERVED;
    4.69 -    nr_map++;
    4.70 -
    4.71 -    /*
    4.72 -     * Following regions are standard regions of the PC memory map.
    4.73 -     * They are not covered by e820 regions. OSes will not use as RAM.
    4.74 -     * 0xA0000-0xC0000: VGA memory-mapped I/O. Not covered by E820.
    4.75 -     * 0xC0000-0xE0000: 16-bit devices, expansion ROMs (inc. vgabios).
    4.76 -     * TODO: hvmloader should free pages which turn out to be unused.
    4.77 -     */
    4.78 +    /* Fill in the header. */
    4.79 +    strncpy(hvm_info->signature, "HVM INFO", 8);
    4.80 +    hvm_info->length = sizeof(struct hvm_info_table);
    4.81  
    4.82 -    /*
    4.83 -     * 0xE0000-0x0F0000: PC-specific area. We place ACPI tables here.
    4.84 -     *                   We *cannot* mark as E820_ACPI, for two reasons:
    4.85 -     *                    1. ACPI spec. says that E820_ACPI regions below
    4.86 -     *                       16MB must clip INT15h 0x88 and 0xe801 queries.
    4.87 -     *                       Our rombios doesn't do this.
    4.88 -     *                    2. The OS is allowed to reclaim ACPI memory after
    4.89 -     *                       parsing the tables. But our FACS is in this
    4.90 -     *                       region and it must not be reclaimed (it contains
    4.91 -     *                       the ACPI global lock!).
    4.92 -     * 0xF0000-0x100000: System BIOS.
    4.93 -     * TODO: hvmloader should free pages which turn out to be unused.
    4.94 -     */
    4.95 -    e820entry[nr_map].addr = 0xE0000;
    4.96 -    e820entry[nr_map].size = 0x20000;
    4.97 -    e820entry[nr_map].type = E820_RESERVED;
    4.98 -    nr_map++;
    4.99 +    /* Sensible defaults: these can be overridden by the caller. */
   4.100 +    hvm_info->acpi_enabled = 1;
   4.101 +    hvm_info->apic_mode = 1;
   4.102 +    hvm_info->nr_vcpus = 1;
   4.103  
   4.104 -    /* Low RAM goes here. Reserve space for special pages. */
   4.105 -    e820entry[nr_map].addr = 0x100000;
   4.106 -    e820entry[nr_map].size = (mem_size - 0x100000 -
   4.107 -                              PAGE_SIZE * NR_SPECIAL_PAGES);
   4.108 -    e820entry[nr_map].type = E820_RAM;
   4.109 -    nr_map++;
   4.110 +    /* Memory parameters. */
   4.111 +    hvm_info->low_mem_pgend = lowmem_end >> PAGE_SHIFT;
   4.112 +    hvm_info->high_mem_pgend = highmem_end >> PAGE_SHIFT;
   4.113 +    hvm_info->reserved_mem_pgstart = special_pfn(0);
   4.114  
   4.115 -    /* Explicitly reserve space for special pages (excluding guard page). */
   4.116 -    e820entry[nr_map].addr = mem_size - PAGE_SIZE * (NR_SPECIAL_PAGES - 1);
   4.117 -    e820entry[nr_map].size = PAGE_SIZE * (NR_SPECIAL_PAGES - 1);
   4.118 -    e820entry[nr_map].type = E820_RESERVED;
   4.119 -    nr_map++;
   4.120 -
   4.121 -    if ( extra_mem_size )
   4.122 -    {
   4.123 -        e820entry[nr_map].addr = (1ULL << 32);
   4.124 -        e820entry[nr_map].size = extra_mem_size;
   4.125 -        e820entry[nr_map].type = E820_RAM;
   4.126 -        nr_map++;
   4.127 -    }
   4.128 -
   4.129 -    *(((unsigned char *)e820_page) + HVM_E820_NR_OFFSET) = nr_map;
   4.130 +    /* Finish with the checksum. */
   4.131 +    for ( i = 0, sum = 0; i < hvm_info->length; i++ )
   4.132 +        sum += ((uint8_t *)hvm_info)[i];
   4.133 +    hvm_info->checksum = -sum;
   4.134  }
   4.135  
   4.136  static int loadelfimage(
   4.137 @@ -153,10 +108,10 @@ static int setup_guest(int xc_handle,
   4.138      unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
   4.139      unsigned long target_pages = (unsigned long)target << (20 - PAGE_SHIFT);
   4.140      unsigned long pod_pages = 0;
   4.141 -    unsigned long special_page_nr, entry_eip, cur_pages;
   4.142 +    unsigned long entry_eip, cur_pages;
   4.143      struct xen_add_to_physmap xatp;
   4.144      struct shared_info *shared_info;
   4.145 -    void *e820_page;
   4.146 +    void *hvm_info_page;
   4.147      uint32_t *ident_pt;
   4.148      struct elf_binary elf;
   4.149      uint64_t v_start, v_end;
   4.150 @@ -289,23 +244,22 @@ static int setup_guest(int xc_handle,
   4.151      if ( loadelfimage(&elf, xc_handle, dom, page_array) != 0 )
   4.152          goto error_out;
   4.153  
   4.154 -    if ( (e820_page = xc_map_foreign_range(
   4.155 +    if ( (hvm_info_page = xc_map_foreign_range(
   4.156                xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   4.157 -              HVM_E820_PAGE >> PAGE_SHIFT)) == NULL )
   4.158 +              HVM_INFO_PFN)) == NULL )
   4.159          goto error_out;
   4.160 -    memset(e820_page, 0, PAGE_SIZE);
   4.161 -    build_e820map(e820_page, v_end);
   4.162 -    munmap(e820_page, PAGE_SIZE);
   4.163 +    build_hvm_info(hvm_info_page, v_end);
   4.164 +    munmap(hvm_info_page, PAGE_SIZE);
   4.165  
   4.166      /* Map and initialise shared_info page. */
   4.167      xatp.domid = dom;
   4.168      xatp.space = XENMAPSPACE_shared_info;
   4.169      xatp.idx   = 0;
   4.170 -    xatp.gpfn  = SCRATCH_PFN;
   4.171 +    xatp.gpfn  = special_pfn(SPECIALPAGE_SHINFO);
   4.172      if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
   4.173           ((shared_info = xc_map_foreign_range(
   4.174               xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   4.175 -             SCRATCH_PFN)) == NULL) )
   4.176 +             special_pfn(SPECIALPAGE_SHINFO))) == NULL) )
   4.177          goto error_out;
   4.178      memset(shared_info, 0, PAGE_SIZE);
   4.179      /* NB. evtchn_upcall_mask is unused: leave as zero. */
   4.180 @@ -313,31 +267,28 @@ static int setup_guest(int xc_handle,
   4.181             sizeof(shared_info->evtchn_mask));
   4.182      munmap(shared_info, PAGE_SIZE);
   4.183  
   4.184 -    special_page_nr = (((v_end > HVM_BELOW_4G_RAM_END)
   4.185 -                        ? (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT)
   4.186 -                        : (v_end >> PAGE_SHIFT))
   4.187 -                       - NR_SPECIAL_PAGES);
   4.188 -
   4.189 -    /* Paranoia: clean special pages. */
   4.190 +    /* Allocate and clear special pages. */
   4.191      for ( i = 0; i < NR_SPECIAL_PAGES; i++ )
   4.192 -        if ( xc_clear_domain_page(xc_handle, dom, special_page_nr + i) )
   4.193 +    {
   4.194 +        xen_pfn_t pfn = special_pfn(i);
   4.195 +        if ( i == SPECIALPAGE_SHINFO )
   4.196 +            continue;
   4.197 +        rc = xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0, 0, &pfn);
   4.198 +        if ( rc != 0 )
   4.199 +        {
   4.200 +            PERROR("Could not allocate %d'th special page.\n", i);
   4.201              goto error_out;
   4.202 -
   4.203 -    /* Free the guard page that separates low RAM from special pages. */
   4.204 -    rc = xc_domain_memory_decrease_reservation(
   4.205 -        xc_handle, dom, 1, 0, &page_array[special_page_nr]);
   4.206 -    if ( rc != 0 )
   4.207 -    {
   4.208 -        PERROR("Could not deallocate guard page for HVM guest.\n");
   4.209 -        goto error_out;
   4.210 +        }
   4.211 +        if ( xc_clear_domain_page(xc_handle, dom, special_pfn(i)) )
   4.212 +            goto error_out;
   4.213      }
   4.214  
   4.215      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN,
   4.216 -                     special_page_nr + SPECIALPAGE_XENSTORE);
   4.217 +                     special_pfn(SPECIALPAGE_XENSTORE));
   4.218      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN,
   4.219 -                     special_page_nr + SPECIALPAGE_BUFIOREQ);
   4.220 +                     special_pfn(SPECIALPAGE_BUFIOREQ));
   4.221      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN,
   4.222 -                     special_page_nr + SPECIALPAGE_IOREQ);
   4.223 +                     special_pfn(SPECIALPAGE_IOREQ));
   4.224  
   4.225      /*
   4.226       * Identity-map page table is required for running with CR0.PG=0 when
   4.227 @@ -345,14 +296,14 @@ static int setup_guest(int xc_handle,
   4.228       */
   4.229      if ( (ident_pt = xc_map_foreign_range(
   4.230                xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
   4.231 -              special_page_nr + SPECIALPAGE_IDENT_PT)) == NULL )
   4.232 +              special_pfn(SPECIALPAGE_IDENT_PT))) == NULL )
   4.233          goto error_out;
   4.234      for ( i = 0; i < PAGE_SIZE / sizeof(*ident_pt); i++ )
   4.235          ident_pt[i] = ((i << 22) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
   4.236                         _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
   4.237      munmap(ident_pt, PAGE_SIZE);
   4.238      xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT,
   4.239 -                     (special_page_nr + SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
   4.240 +                     special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
   4.241  
   4.242      /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
   4.243      entry_eip = elf_uval(&elf, elf.ehdr, e_entry);
     5.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Jan 08 15:18:30 2009 +0000
     5.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Jan 08 15:27:20 2009 +0000
     5.3 @@ -903,26 +903,24 @@ static PyObject *pyxc_hvm_build(XcObject
     5.4      if ( target == -1 )
     5.5          target = memsize;
     5.6  
     5.7 -    if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize, target, image) != 0 )
     5.8 +    if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
     5.9 +                                 target, image) != 0 )
    5.10          return pyxc_error_to_exception();
    5.11  
    5.12  #if !defined(__ia64__)
    5.13 -    /* Set up the HVM info table. */
    5.14 +    /* Fix up the HVM info table. */
    5.15      va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
    5.16                                    PROT_READ | PROT_WRITE,
    5.17                                    HVM_INFO_PFN);
    5.18      if ( va_map == NULL )
    5.19          return PyErr_SetFromErrno(xc_error_obj);
    5.20      va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
    5.21 -    memset(va_hvm, 0, sizeof(*va_hvm));
    5.22 -    strncpy(va_hvm->signature, "HVM INFO", 8);
    5.23 -    va_hvm->length       = sizeof(struct hvm_info_table);
    5.24      va_hvm->acpi_enabled = acpi;
    5.25      va_hvm->apic_mode    = apic;
    5.26      va_hvm->nr_vcpus     = vcpus;
    5.27      for ( i = 0, sum = 0; i < va_hvm->length; i++ )
    5.28          sum += ((uint8_t *)va_hvm)[i];
    5.29 -    va_hvm->checksum = -sum;
    5.30 +    va_hvm->checksum -= sum;
    5.31      munmap(va_map, XC_PAGE_SIZE);
    5.32  #endif
    5.33  
     6.1 --- a/xen/include/public/hvm/hvm_info_table.h	Thu Jan 08 15:18:30 2009 +0000
     6.2 +++ b/xen/include/public/hvm/hvm_info_table.h	Thu Jan 08 15:27:20 2009 +0000
     6.3 @@ -33,9 +33,37 @@ struct hvm_info_table {
     6.4      char        signature[8]; /* "HVM INFO" */
     6.5      uint32_t    length;
     6.6      uint8_t     checksum;
     6.7 +
     6.8 +    /* Should firmware build ACPI tables? */
     6.9      uint8_t     acpi_enabled;
    6.10 +
    6.11 +    /* Should firmware build APIC descriptors (APIC MADT / MP BIOS)? */
    6.12      uint8_t     apic_mode;
    6.13 +
    6.14 +    /* How many CPUs does this domain have? */
    6.15      uint32_t    nr_vcpus;
    6.16 +
    6.17 +    /*
    6.18 +     * MEMORY MAP provided by HVM domain builder.
    6.19 +     * Notes:
    6.20 +     *  1. page_to_phys(x) = x << 12
    6.21 +     *  2. If a field is zero, the corresponding range does not exist.
    6.22 +     */
    6.23 +    /*
    6.24 +     *  0x0 to page_to_phys(low_mem_pgend)-1:
    6.25 +     *    RAM below 4GB (except for VGA hole 0xA0000-0xBFFFF)
    6.26 +     */
    6.27 +    uint32_t    low_mem_pgend;
    6.28 +    /*
    6.29 +     *  page_to_phys(reserved_mem_pgstart) to 0xFFFFFFFF:
    6.30 +     *    Reserved for special memory mappings
    6.31 +     */
    6.32 +    uint32_t    reserved_mem_pgstart;
    6.33 +    /*
    6.34 +     *  0x100000000 to page_to_phys(high_mem_pgend)-1:
    6.35 +     *    RAM above 4GB
    6.36 +     */
    6.37 +    uint32_t    high_mem_pgend;
    6.38  };
    6.39  
    6.40  #endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */