ia64/xen-unstable

changeset 14722:171fba41a44e

hvm ioemu x86: Avoid assumptions about memory map.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Apr 04 17:58:06 2007 +0100 (2007-04-04)
parents 0f8a327ebd4d
children 10f06a7a05e9
files tools/ioemu/vl.c
line diff
     1.1 --- a/tools/ioemu/vl.c	Wed Apr 04 16:34:56 2007 +0100
     1.2 +++ b/tools/ioemu/vl.c	Wed Apr 04 17:58:06 2007 +0100
     1.3 @@ -88,6 +88,7 @@
     1.4  
     1.5  #include "exec-all.h"
     1.6  
     1.7 +#include <xen/hvm/params.h>
     1.8  #define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
     1.9  #define DEFAULT_BRIDGE "xenbr0"
    1.10  
    1.11 @@ -5886,7 +5887,8 @@ int set_mm_mapping(int xc_handle, uint32
    1.12  
    1.13  void suspend(int sig)
    1.14  {
    1.15 -   fprintf(logfile, "suspend sig handler called with requested=%d!\n", suspend_requested);
    1.16 +    fprintf(logfile, "suspend sig handler called with requested=%d!\n",
    1.17 +            suspend_requested);
    1.18      if (sig != SIGUSR1)
    1.19          fprintf(logfile, "suspend signal dismatch, get sig=%d!\n", sig);
    1.20      suspend_requested = 1;
    1.21 @@ -5900,33 +5902,29 @@ static unsigned long nr_buckets;
    1.22  static unsigned long last_address_index = ~0UL;
    1.23  static uint8_t      *last_address_vaddr;
    1.24  
    1.25 -static int qemu_map_cache_init(unsigned long nr_pages)
    1.26 -{
    1.27 -    unsigned long max_pages = MAX_MCACHE_SIZE >> PAGE_SHIFT;
    1.28 -    int i;
    1.29 -
    1.30 -    if (nr_pages < max_pages)
    1.31 -        max_pages = nr_pages;
    1.32 -
    1.33 -    nr_buckets   = max_pages + (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1;
    1.34 -    nr_buckets >>= (MCACHE_BUCKET_SHIFT - PAGE_SHIFT);
    1.35 +static int qemu_map_cache_init(void)
    1.36 +{
    1.37 +    unsigned long size;
    1.38 +
    1.39 +    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
    1.40 +                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
    1.41 +                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
    1.42      fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx\n", nr_buckets);
    1.43  
    1.44 -    mapcache_entry = malloc(nr_buckets * sizeof(struct map_cache));
    1.45 -    if (mapcache_entry == NULL) {
    1.46 +    /*
    1.47 +     * Use mmap() directly: lets us allocate a big hash table with no up-front
    1.48 +     * cost in storage space. The OS will allocate memory only for the buckets
    1.49 +     * that we actually use. All others will contain all zeroes.
    1.50 +     */
    1.51 +    size = nr_buckets * sizeof(struct map_cache);
    1.52 +    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
    1.53 +    mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
    1.54 +                          MAP_SHARED|MAP_ANONYMOUS, 0, 0);
    1.55 +    if (mapcache_entry == MAP_FAILED) {
    1.56          errno = ENOMEM;
    1.57          return -1;
    1.58      }
    1.59  
    1.60 -    memset(mapcache_entry, 0, nr_buckets * sizeof(struct map_cache));
    1.61 -
    1.62 -    /*
    1.63 -     * To avoid ENOMEM from xc_map_foreign_batch() at runtime, we
    1.64 -     * pre-fill all the map caches in advance.
    1.65 -     */
    1.66 -    for (i = 0; i < nr_buckets; i++)
    1.67 -       (void)qemu_map_cache(((target_phys_addr_t)i) << MCACHE_BUCKET_SHIFT);
    1.68 -
    1.69      return 0;
    1.70  }
    1.71  
    1.72 @@ -6038,11 +6036,14 @@ int main(int argc, char **argv)
    1.73      QEMUMachine *machine;
    1.74      char usb_devices[MAX_USB_CMDLINE][128];
    1.75      int usb_devices_index;
    1.76 -    unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
    1.77 -    xen_pfn_t *page_array;
    1.78 +    unsigned long ioreq_pfn;
    1.79      extern void *shared_page;
    1.80      extern void *buffered_io_page;
    1.81 +#ifdef __ia64__
    1.82 +    unsigned long nr_pages;
    1.83 +    xen_pfn_t *page_array;
    1.84      extern void *buffered_pio_page;
    1.85 +#endif
    1.86  
    1.87      char qemu_dm_logfilename[64];
    1.88  
    1.89 @@ -6592,47 +6593,36 @@ int main(int argc, char **argv)
    1.90  
    1.91      xc_handle = xc_interface_open();
    1.92  
    1.93 -    nr_pages = ram_size/PAGE_SIZE;
    1.94 -    tmp_nr_pages = nr_pages;
    1.95 -
    1.96  #if defined(__i386__) || defined(__x86_64__)
    1.97 -    if (ram_size > HVM_BELOW_4G_RAM_END) {
    1.98 -        tmp_nr_pages += HVM_BELOW_4G_MMIO_LENGTH >> PAGE_SHIFT;
    1.99 -        shared_page_nr = (HVM_BELOW_4G_RAM_END >> PAGE_SHIFT) - 1;
   1.100 -    } else
   1.101 -        shared_page_nr = nr_pages - 1;
   1.102 -#endif
   1.103 -
   1.104 -#if defined(__i386__) || defined(__x86_64__)
   1.105 -
   1.106 -    if ( qemu_map_cache_init(tmp_nr_pages) )
   1.107 -    {
   1.108 +
   1.109 +    if (qemu_map_cache_init()) {
   1.110          fprintf(logfile, "qemu_map_cache_init returned: error %d\n", errno);
   1.111          exit(-1);
   1.112      }
   1.113  
   1.114 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
   1.115 +    fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
   1.116      shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   1.117 -                                       PROT_READ|PROT_WRITE, shared_page_nr);
   1.118 +                                       PROT_READ|PROT_WRITE, ioreq_pfn);
   1.119      if (shared_page == NULL) {
   1.120          fprintf(logfile, "map shared IO page returned error %d\n", errno);
   1.121          exit(-1);
   1.122      }
   1.123  
   1.124 -    fprintf(logfile, "shared page at pfn:%lx\n", shared_page_nr);
   1.125 -
   1.126 +    xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
   1.127 +    fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
   1.128      buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   1.129 -                                            PROT_READ|PROT_WRITE,
   1.130 -                                            shared_page_nr - 2);
   1.131 +                                            PROT_READ|PROT_WRITE, ioreq_pfn);
   1.132      if (buffered_io_page == NULL) {
   1.133          fprintf(logfile, "map buffered IO page returned error %d\n", errno);
   1.134          exit(-1);
   1.135      }
   1.136  
   1.137 -    fprintf(logfile, "buffered io page at pfn:%lx\n", shared_page_nr - 2);
   1.138 -
   1.139  #elif defined(__ia64__)
   1.140  
   1.141 -    page_array = (xen_pfn_t *)malloc(tmp_nr_pages * sizeof(xen_pfn_t));
   1.142 +    nr_pages = ram_size/PAGE_SIZE;
   1.143 +
   1.144 +    page_array = (xen_pfn_t *)malloc(nr_pages * sizeof(xen_pfn_t));
   1.145      if (page_array == NULL) {
   1.146          fprintf(logfile, "malloc returned error %d\n", errno);
   1.147          exit(-1);
   1.148 @@ -6650,7 +6640,7 @@ int main(int argc, char **argv)
   1.149                                         PROT_READ|PROT_WRITE,
   1.150                                         BUFFER_PIO_PAGE_START >> PAGE_SHIFT);
   1.151  
   1.152 -    for (i = 0; i < tmp_nr_pages; i++)
   1.153 +    for (i = 0; i < nr_pages; i++)
   1.154          page_array[i] = i;
   1.155  	
   1.156      /* VTI will not use memory between 3G~4G, so we just pass a legal pfn