xen: save/restore bugfixes
Subsystems (3)
PATCH 1/1 xen: save/restore bugfixes
Hi Ingo,
Here's some bugfix patches for Xen save/restore.
Thanks,
J
PATCH 1/1 xen: restore vcpu_info mapping
If we're using vcpu_info mapping, then make sure its restored on all processors before relasing them from stop_machine.
The only complication is that if this fails, we can't continue because we've already made assumptions that the mapping is available (baked in calls to the _direct versions of the functions, for example).
Fortunately this can only happen with a 32-bit hypervisor, which may possibly run out of mapping space. On a 64-bit hypervisor, this is a non-issue.
--- arch/x86/xen/enlighten.c | 30 +++++++++++++++++++++++++++++- arch/x86/xen/suspend.c | 4 +++- arch/x86/xen/xen-ops.h | 1 + 3 files changed, 33 insertions(+), 2 deletions(-)
arch/x86/xen/enlighten.c +29 -1
@@ -98,7 +98,7 @@*/ static int have_vcpu_info_placement =1 ; -static void __init xen_vcpu_setup (int cpu) +static void xen_vcpu_setup (int cpu) {struct vcpu_register_vcpu_info info;int err;
@@ -133,6 +133,34 @@printk (KERN_DEBUG "cpu %d using vcpu_info at %p\n" , cpu, vcpup); + } +} + +/* +* On restore, set the vcpu placement up again. +* If it fails, then we're in a bad state, since +* we can't back out from using it... +*/ +void xen_vcpu_restore (void ) +{ +if (have_vcpu_info_placement) { +int cpu; + +for_each_online_cpu (cpu) { +bool other_cpu = (cpu !=smp_processor_id ()); + +if (other_cpu && +HYPERVISOR_vcpu_op (VCPUOP_down, cpu,NULL )) +BUG (); + +xen_vcpu_setup (cpu); + +if (other_cpu && +HYPERVISOR_vcpu_op (VCPUOP_up, cpu,NULL )) +BUG (); + } + +BUG_ON (!have_vcpu_info_placement); } }
arch/x86/xen/suspend.c +3 -1
@@ -26,6 +26,8 @@void xen_post_suspend (int suspend_cancelled) { +xen_setup_shared_info (); +if (suspend_cancelled) { xen_start_info->store_mfn =pfn_to_mfn (xen_start_info->store_mfn);
@@ -35,8 +37,8 @@#ifdef CONFIG_SMP xen_cpu_initialized_map = cpu_online_map;#endif +xen_vcpu_restore (); } -xen_setup_shared_info (); }
arch/x86/xen/xen-ops.h +1 -0
@@ -26,6 +26,7 @@void __init xen_arch_setup (void );void __init xen_init_IRQ (void );void xen_enable_sysenter (void ); +void xen_vcpu_restore (void );void __init xen_build_dynamic_phys_to_machine (void );
PATCH 1/1 xen: resume timers on all vcpus
In reply to Jeremy FitzhardingeOn resume, the vcpu timer modes will not be restored. The timer infrastructure doesn't do this for us, since it assumes the cpus are offline. We can just poke the other vcpus into the right mode directly though.
--- arch/x86/xen/suspend.c | 1 + arch/x86/xen/time.c | 13 +++++++++++++ arch/x86/xen/xen-ops.h | 1 + 3 files changed, 15 insertions(+)
arch/x86/xen/suspend.c +1 -0
@@ -38,6 +38,7 @@ xen_cpu_initialized_map = cpu_online_map;#endif xen_vcpu_restore (); +xen_timer_resume (); } }
arch/x86/xen/time.c +13 -0
@@ -565,6 +565,19 @@clockevents_register_device (&__get_cpu_var (xen_clock_events)); } +void xen_timer_resume (void ) +{ +int cpu; + +if (xen_clockevent != &xen_vcpuop_clockevent) +return ; + +for_each_online_cpu (cpu) { +if (HYPERVISOR_vcpu_op (VCPUOP_stop_periodic_timer, cpu,NULL )) +BUG (); + } +} +__init void xen_time_init (void ) {int cpu =smp_processor_id ();
arch/x86/xen/xen-ops.h +1 -0
@@ -37,6 +37,7 @@unsigned long xen_get_wallclock (void );int xen_set_wallclock (unsigned long time);unsigned long long xen_sched_clock (void ); +void xen_timer_resume (void );irqreturn_t xen_debug_interrupt (int irq,void *dev_id);
PATCH 1/1 xen: add new Xen elfnote types and use them appropriately
In reply to Jeremy FitzhardingeDefine recently added XEN_ELFNOTEs, and use them appropriately. Most significantly, this enables domain checkpointing (xm save -c).
--- arch/x86/xen/xen-head.S | 5 +++++ include/xen/interface/elfnote.h | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+)
arch/x86/xen/xen-head.S +5 -0
@@ -7,6 +7,7 @@ #include <linux/init.h> #include <asm/boot.h> #include <xen/interface/elfnote.h> +#include <asm/xen/interface.h> __INIT ENTRY(startup_xen)
@@ -32,5 +33,9 @@ ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz "!writable_page_tables|pae_pgdir_above_4gb") ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") + ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID, + .quad _PAGE_PRESENT; .quad _PAGE_PRESENT) + ELFNOTE(Xen, XEN_ELFNOTE_SUSPEND_CANCEL, .long 1) + ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long __HYPERVISOR_VIRT_START) #endif /*CONFIG_XEN */
include/xen/interface/elfnote.h +20 -0
@@ -120,6 +120,26 @@*/ #define XEN_ELFNOTE_BSD_SYMTAB 11 +/* +* The lowest address the hypervisor hole can begin at (numeric). +* +* This must not be set higher than HYPERVISOR_VIRT_START. Its presence +* also indicates to the hypervisor that the kernel can deal with the +* hole starting at a higher address. +*/ +#define XEN_ELFNOTE_HV_START_LOW 12 + +/* +* List of maddr_t-sized mask/value pairs describing how to recognize +* (non-present) L1 page table entries carrying valid MFNs (numeric). +*/ +#define XEN_ELFNOTE_L1_MFN_VALID 13 + +/* +* Whether or not the guest supports cooperative suspend cancellation. +*/ +#define XEN_ELFNOTE_SUSPEND_CANCEL 14 +#endif /* __XEN_PUBLIC_ELFNOTE_H__ */ /*
Ingo Molnar
AppliedQuoted 3 lines · Jeremy Fitzhardinge
Hi Ingo,
Here's some bugfix patches for Xen save/restore.
applied to tip/x86/xen. Thanks,
Ingo