diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c index 2479d87972..1855042fa0 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c @@ -359,7 +359,8 @@ static void __init probe_roms(void) shared_info_t *HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page; EXPORT_SYMBOL(HYPERVISOR_shared_info); -unsigned long *phys_to_machine_mapping, *pfn_to_mfn_frame_list; +unsigned long *phys_to_machine_mapping; +unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[16]; EXPORT_SYMBOL(phys_to_machine_mapping); /* Raw start-of-day parameters from the hypervisor. */ @@ -1519,7 +1520,7 @@ static void set_mca_bus(int x) { } */ void __init setup_arch(char **cmdline_p) { - int i, j; + int i, j, k, fpp; physdev_op_t op; unsigned long max_low_pfn; @@ -1669,14 +1670,31 @@ void __init setup_arch(char **cmdline_p) sizeof(unsigned long)))); } - pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE); - for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ ) - { - pfn_to_mfn_frame_list[j] = - virt_to_mfn(&phys_to_machine_mapping[i]); + + /* + * Initialise the list of the frames that specify the list of + * frames that make up the p2m table. Used by save/restore + */ + pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE); + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = + virt_to_mfn(pfn_to_mfn_frame_list_list); + + fpp = PAGE_SIZE/sizeof(unsigned long); + for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ ) + { + if ( (j % fpp) == 0 ) + { + k++; + BUG_ON(k>=16); + pfn_to_mfn_frame_list[k] = alloc_bootmem_low_pages(PAGE_SIZE); + pfn_to_mfn_frame_list_list[k] = + virt_to_mfn(pfn_to_mfn_frame_list[k]); + j=0; + } + pfn_to_mfn_frame_list[k][j] = + virt_to_mfn(&phys_to_machine_mapping[i]); } - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list = - virt_to_mfn(pfn_to_mfn_frame_list); + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; /* * NOTE: at this point the bootmem allocator is fully available. diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index 50e645a69f..87eb53bebb 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -67,7 +67,7 @@ static int shutting_down = SHUTDOWN_INVALID; static int __do_suspend(void *ignore) { - int i, j; + int i, j, k, fpp; #ifdef CONFIG_XEN_USB_FRONTEND extern void usbif_resume(); @@ -81,7 +81,7 @@ static int __do_suspend(void *ignore) extern void time_suspend(void); extern void time_resume(void); extern unsigned long max_pfn; - extern unsigned long *pfn_to_mfn_frame_list; + extern unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[]; #ifdef CONFIG_SMP extern void smp_suspend(void); @@ -191,14 +191,24 @@ static int __do_suspend(void *ignore) HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO); memset(empty_zero_page, 0, PAGE_SIZE); - - for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ ) + + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = + virt_to_mfn(pfn_to_mfn_frame_list_list); + + fpp = PAGE_SIZE/sizeof(unsigned long); + for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ ) { - pfn_to_mfn_frame_list[j] = - virt_to_mfn(&phys_to_machine_mapping[i]); + if ( (j % fpp) == 0 ) + { + k++; + pfn_to_mfn_frame_list_list[k] = + virt_to_mfn(pfn_to_mfn_frame_list[k]); + j=0; + } + pfn_to_mfn_frame_list[k][j] = + virt_to_mfn(&phys_to_machine_mapping[i]); } - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list = - virt_to_mfn(pfn_to_mfn_frame_list); + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; gnttab_resume(); diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c index 05dab06d4a..9b3d47b29c 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c @@ -76,7 +76,8 @@ EXPORT_SYMBOL(HYPERVISOR_shared_info); /* Allows setting of maximum possible memory size */ unsigned long xen_override_max_pfn; -unsigned long *phys_to_machine_mapping, *pfn_to_mfn_frame_list; +unsigned long *phys_to_machine_mapping; +unsigned long *pfn_to_mfn_frame_list_list, *pfn_to_mfn_frame_list[512]; EXPORT_SYMBOL(phys_to_machine_mapping); @@ -730,7 +731,7 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_XEN { - int i, j; + int i, j, k, fpp; /* Make sure we have a large enough P->M table. */ if (end_pfn > xen_start_info->nr_pages) { phys_to_machine_mapping = alloc_bootmem( @@ -746,11 +747,35 @@ void __init setup_arch(char **cmdline_p) sizeof(unsigned long)))); } - pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE); - - for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ ) - pfn_to_mfn_frame_list[j] = + /* + * Initialise the list of the frames that specify the list of + * frames that make up the p2m table. Used by save/restore + */ + pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE); + HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = + virt_to_mfn(pfn_to_mfn_frame_list_list); + + fpp = PAGE_SIZE/sizeof(unsigned long); + for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ ) + { + if ( (j % fpp) == 0 ) + { + k++; + BUG_ON(k>=fpp); + pfn_to_mfn_frame_list[k] = alloc_bootmem(PAGE_SIZE); + pfn_to_mfn_frame_list_list[k] = + virt_to_mfn(pfn_to_mfn_frame_list[k]); + j=0; + } + pfn_to_mfn_frame_list[k][j] = virt_to_mfn(&phys_to_machine_mapping[i]); + } + HYPERVISOR_shared_info->arch.max_pfn = max_pfn; + + + + + } #endif diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index c9af7b0d3b..af32db7791 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -419,6 +419,7 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters, unsigned long page[1024]; /* A copy of the pfn-to-mfn table frame list. */ + unsigned long *live_pfn_to_mfn_frame_list_list = NULL; unsigned long *live_pfn_to_mfn_frame_list = NULL; unsigned long pfn_to_mfn_frame_list[1024]; @@ -506,11 +507,20 @@ int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters, goto out; } - /* the pfn_to_mfn_frame_list fits in a single page */ + live_pfn_to_mfn_frame_list_list = xc_map_foreign_range(xc_handle, dom, + PAGE_SIZE, PROT_READ, + live_shinfo->arch.pfn_to_mfn_frame_list_list); + + if (!live_pfn_to_mfn_frame_list_list){ + ERR("Couldn't map pfn_to_mfn_frame_list_list"); + goto out; + } + live_pfn_to_mfn_frame_list = - xc_map_foreign_range(xc_handle, dom, - PAGE_SIZE, PROT_READ, - live_shinfo->arch.pfn_to_mfn_frame_list ); + xc_map_foreign_batch(xc_handle, dom, + PROT_READ, + live_pfn_to_mfn_frame_list_list, + (nr_pfns+(1024*1024)-1)/(1024*1024) ); if (!live_pfn_to_mfn_frame_list){ ERR("Couldn't map pfn_to_mfn_frame_list"); diff --git a/tools/libxc/xc_load_aout9.c b/tools/libxc/xc_load_aout9.c index 93ec251cc4..bc76bae3b2 100644 --- a/tools/libxc/xc_load_aout9.c +++ b/tools/libxc/xc_load_aout9.c @@ -14,7 +14,6 @@ #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) -#define round_pgdown(_p) ((_p)&PAGE_MASK) #define KZERO 0x80000000 #define KOFFSET(_p) ((_p)&~KZERO) @@ -49,7 +48,7 @@ parseaout9image( struct domain_setup_info *dsi) { struct Exec ehdr; - unsigned long start, txtsz, end; + unsigned long start, dstart, end; if (!get_header(image, image_size, &ehdr)) { ERROR("Kernel image does not have a a.out9 header."); @@ -61,9 +60,9 @@ parseaout9image( return -EINVAL; } - start = round_pgdown(ehdr.entry); - txtsz = round_pgup(ehdr.text); - end = start + txtsz + ehdr.data + ehdr.bss; + start = ehdr.entry; + dstart = round_pgup(start + ehdr.text); + end = dstart + ehdr.data + ehdr.bss; dsi->v_start = KZERO; dsi->v_kernstart = start; @@ -85,19 +84,18 @@ loadaout9image( struct domain_setup_info *dsi) { struct Exec ehdr; - unsigned long start, txtsz; + unsigned long start, dstart; if (!get_header(image, image_size, &ehdr)) { ERROR("Kernel image does not have a a.out9 header."); return -EINVAL; } - start = round_pgdown(ehdr.entry); - txtsz = round_pgup(ehdr.text); - copyout(xch, dom, parray, - start, image, sizeof ehdr + ehdr.text); - copyout(xch, dom, parray, - start+txtsz, image + sizeof ehdr + ehdr.text, ehdr.data); + start = ehdr.entry; + dstart = round_pgup(start + ehdr.text); + copyout(xch, dom, parray, start, image + sizeof ehdr, ehdr.text); + copyout(xch, dom, parray, dstart, + image + sizeof ehdr + ehdr.text, ehdr.data); /* XXX load symbols */ diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index b7101d1a61..8944bfa4cc 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -15,6 +15,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Copyright (C) 2005 Mike Wray Hewlett-Packard + * Copyright (C) 2005 Christian Limpach * */ diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 81100e7a1c..7e972bea94 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -791,6 +791,13 @@ static void local_time_calibration(void *unused) stime_elapsed64 = curr_master_stime - prev_master_stime; tsc_elapsed64 = curr_tsc - prev_tsc; + /* + * Weirdness can happen if we lose sync with the platform timer. + * We could be smarter here: resync platform timer with local timer? + */ + if ( ((s64)stime_elapsed64 < (EPOCH / 2)) ) + goto out; + /* * Calculate error-correction factor. This only slows down a fast local * clock (slow clocks are warped forwards). The scale factor is clamped @@ -854,6 +861,7 @@ static void local_time_calibration(void *unused) cpu_time[cpu].stime_local_stamp = curr_local_stime; cpu_time[cpu].stime_master_stamp = curr_master_stime; + out: set_ac_timer(&cpu_time[cpu].calibration_timer, NOW() + EPOCH); if ( cpu == 0 ) diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index cf0a43c50c..f6c3ea9246 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -128,8 +128,11 @@ typedef struct vcpu_guest_context { } vcpu_guest_context_t; typedef struct arch_shared_info { - /* MFN of a table of MFNs that make up p2m table */ - u64 pfn_to_mfn_frame_list; + unsigned long max_pfn; /* max pfn that appears in table */ + unsigned long pfn_to_mfn_frame_list_list; + /* frame containing list of mfns + containing list of mfns + containing the p2m table. */ } arch_shared_info_t; #endif diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 81b1ecd6fd..3cb8a2a785 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -186,8 +186,11 @@ typedef struct vcpu_guest_context { } vcpu_guest_context_t; typedef struct arch_shared_info { - /* MFN of a table of MFNs that make up p2m table */ - u64 pfn_to_mfn_frame_list; + unsigned long max_pfn; /* max pfn that appears in table */ + unsigned long pfn_to_mfn_frame_list_list; + /* frame containing list of mfns + containing list of mfns + containing the p2m table. */ } arch_shared_info_t; #endif /* !__ASSEMBLY__ */