From 1b38e07f98241d7eb7901f9cbc40dded7ccc5bb4 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 27 Jun 2014 10:47:24 -0400 Subject: [PATCH 2/2] RFC: VCPU_reset_cpu_info Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/xen/enlighten.c | 29 ++++++++++++++++++++++++++++- arch/x86/xen/smp.c | 26 +++++++++++++++++++++++++- arch/x86/xen/smp.h | 1 + arch/x86/xen/xen-ops.h | 1 + include/xen/interface/vcpu.h | 2 ++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 7e1b951..303883e 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -215,6 +215,11 @@ static void xen_vcpu_setup(int cpu) hypervisor has no unregister variant and this hypercall does not allow to over-write info.mfn and info.offset. */ + err = HYPERVISOR_vcpu_op(VCPUOP_reset_vcpu_info, cpu, NULL); + if (err) + printk(KERN_DEBUG "%s: VCPUOP_reset_vcpu_info for CPU%d failed: %d\n", + __func__, cpu, err); + err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); if (err) { @@ -228,6 +233,21 @@ static void xen_vcpu_setup(int cpu) } } +void xen_teardown_vcpu_setup(int cpu) +{ + int err; + + if (!have_vcpu_info_placement) + return; + + err = HYPERVISOR_vcpu_op(VCPUOP_reset_vcpu_info, cpu, NULL); + if (err) { + xen_raw_printk("%s: VCPUOP_reset_vcpu_info rc: %d\n", __func__, err); + return; + } + if (cpu < MAX_VIRT_CPUS) + per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; +} /* * On restore, set the vcpu placement up again. * If it fails, then we're in a bad state, since @@ -1828,7 +1848,11 @@ static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action, static struct notifier_block xen_hvm_cpu_notifier = { .notifier_call = xen_hvm_cpu_notify, }; - +static void xen_pvhvm_kexec_shutdown(void) +{ + xen_kexec_shutdown(); + native_machine_shutdown(); +} static void __init xen_hvm_guest_init(void) { init_hvm_pv_info(); @@ -1845,6 +1869,9 @@ static void __init xen_hvm_guest_init(void) x86_init.irqs.intr_init = xen_init_IRQ; xen_hvm_init_time_ops(); xen_hvm_init_mmu_ops(); +#ifdef CONFIG_KEXEC + machine_ops.shutdown = xen_pvhvm_kexec_shutdown; +#endif } static uint32_t __init xen_hvm_platform(void) diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 7005974..984a955 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -494,7 +495,6 @@ static int xen_cpu_disable(void) load_cr3(swapper_pg_dir); return 0; } - static void xen_cpu_die(unsigned int cpu) { while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { @@ -504,6 +504,8 @@ static void xen_cpu_die(unsigned int cpu) xen_smp_intr_free(cpu); xen_uninit_lock_cpu(cpu); xen_teardown_timer(cpu); + + xen_teardown_vcpu_setup(cpu); } static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ @@ -762,6 +764,28 @@ static void xen_hvm_cpu_die(unsigned int cpu) native_cpu_die(cpu); } +void xen_kexec_shutdown(void) +{ +#ifdef CONFIG_KEXEC + int cpu; + + if (!kexec_in_progress) + return; + + cpu = smp_processor_id(); + + gnttab_suspend(); + xen_arch_pre_suspend(); + + /* Stop all CPUs... */ + disable_nonboot_cpus(); + + /* Bring down the IPIs, PIRQs, on the BSP. */ + xen_raw_printk("CPU0 down.\n"); + xen_cpu_die(cpu); + xen_raw_printk("CPU0 down done.\n"); +#endif +} void __init xen_hvm_smp_init(void) { if (!xen_have_vector_callback) diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h index c7c2d89..1af0493 100644 --- a/arch/x86/xen/smp.h +++ b/arch/x86/xen/smp.h @@ -8,4 +8,5 @@ extern void xen_send_IPI_allbutself(int vector); extern void xen_send_IPI_all(int vector); extern void xen_send_IPI_self(int vector); +extern void xen_kexec_shutdown(void); #endif diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 002c3e9..978b79b 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h @@ -50,6 +50,7 @@ void xen_init_irq_ops(void); void xen_setup_timer(int cpu); void xen_setup_runstate_info(int cpu); void xen_teardown_timer(int cpu); +void xen_teardown_vcpu_setup(int cpu); cycle_t xen_clocksource_read(void); void xen_setup_cpu_clockevents(void); void __init xen_init_time_ops(void); diff --git a/include/xen/interface/vcpu.h b/include/xen/interface/vcpu.h index b05288c..3e5e6e9 100644 --- a/include/xen/interface/vcpu.h +++ b/include/xen/interface/vcpu.h @@ -172,4 +172,6 @@ DEFINE_GUEST_HANDLE_STRUCT(vcpu_register_vcpu_info); /* Send an NMI to the specified VCPU. @extra_arg == NULL. */ #define VCPUOP_send_nmi 11 + +#define VCPUOP_reset_vcpu_info 14 #endif /* __XEN_PUBLIC_VCPU_H__ */ -- 1.7.7.6