direct-io.hg
changeset 14717:171fba41a44e
hvm ioemu x86: Avoid assumptions about memory map.
Signed-off-by: Keir Fraser <keir@xensource.com>
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