aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-08-18 08:57:29 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-06 12:30:25 -0400
commit9a20ea4b4c34764416e935090d6e5ede02d1bada (patch)
tree913ee443b564815b42c683592c599d431b01c201
parente8483b578b229774382a95891439b2ebd9c92fc5 (diff)
x86/kvm: Convert to hotplug state machine
Install the callbacks via the state machine. The online & down callbacks are invoked on the target CPU so we can avoid using smp_call_function_single(). local_irq_disable() is used because smp_call_function_single() used to invoke the function with interrupts disabled. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Cc: kvm@vger.kernel.org Cc: Peter Zijlstra <peterz@infradead.org> Cc: Gleb Natapov <gleb@kernel.org> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160818125731.27256-15-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/kernel/kvm.c43
1 files changed, 16 insertions, 27 deletions
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 1726c4c12336..1f431f362dd5 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -423,12 +423,7 @@ static void __init kvm_smp_prepare_boot_cpu(void)
423 kvm_spinlock_init(); 423 kvm_spinlock_init();
424} 424}
425 425
426static void kvm_guest_cpu_online(void *dummy) 426static void kvm_guest_cpu_offline(void)
427{
428 kvm_guest_cpu_init();
429}
430
431static void kvm_guest_cpu_offline(void *dummy)
432{ 427{
433 kvm_disable_steal_time(); 428 kvm_disable_steal_time();
434 if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) 429 if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
@@ -437,29 +432,21 @@ static void kvm_guest_cpu_offline(void *dummy)
437 apf_task_wake_all(); 432 apf_task_wake_all();
438} 433}
439 434
440static int kvm_cpu_notify(struct notifier_block *self, unsigned long action, 435static int kvm_cpu_online(unsigned int cpu)
441 void *hcpu)
442{ 436{
443 int cpu = (unsigned long)hcpu; 437 local_irq_disable();
444 switch (action) { 438 kvm_guest_cpu_init();
445 case CPU_ONLINE: 439 local_irq_enable();
446 case CPU_DOWN_FAILED: 440 return 0;
447 case CPU_ONLINE_FROZEN:
448 smp_call_function_single(cpu, kvm_guest_cpu_online, NULL, 0);
449 break;
450 case CPU_DOWN_PREPARE:
451 case CPU_DOWN_PREPARE_FROZEN:
452 smp_call_function_single(cpu, kvm_guest_cpu_offline, NULL, 1);
453 break;
454 default:
455 break;
456 }
457 return NOTIFY_OK;
458} 441}
459 442
460static struct notifier_block kvm_cpu_notifier = { 443static int kvm_cpu_down_prepare(unsigned int cpu)
461 .notifier_call = kvm_cpu_notify, 444{
462}; 445 local_irq_disable();
446 kvm_guest_cpu_offline();
447 local_irq_enable();
448 return 0;
449}
463#endif 450#endif
464 451
465static void __init kvm_apf_trap_init(void) 452static void __init kvm_apf_trap_init(void)
@@ -494,7 +481,9 @@ void __init kvm_guest_init(void)
494 481
495#ifdef CONFIG_SMP 482#ifdef CONFIG_SMP
496 smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; 483 smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
497 register_cpu_notifier(&kvm_cpu_notifier); 484 if (cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/kvm:online",
485 kvm_cpu_online, kvm_cpu_down_prepare) < 0)
486 pr_err("kvm_guest: Failed to install cpu hotplug callbacks\n");
498#else 487#else
499 kvm_guest_cpu_init(); 488 kvm_guest_cpu_init();
500#endif 489#endif