aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2014-05-23 04:15:25 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-05-27 23:35:34 -0400
commit441c19c8a290f5f1e1b263691641124c84232b6e (patch)
treea9541511426e26fc3a654d04fb38d2132ada9415 /arch/powerpc
parent64bb80d87f01ec01c76863b61b457e0904387f2f (diff)
powerpc/kvm/book3s_hv: Rework the secondary inhibit code
As part of the support for split core on POWER8, we want to be able to block splitting of the core while KVM VMs are active. The logic to do that would be exactly the same as the code we currently have for inhibiting onlining of secondaries. Instead of adding an identical mechanism to block split core, rework the secondary inhibit code to be a "HV KVM is active" check. We can then use that in both the cpu hotplug code and the upcoming split core code. Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Michael Neuling <mikey@neuling.org> Acked-by: Alexander Graf <agraf@suse.de> Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h7
-rw-r--r--arch/powerpc/include/asm/smp.h8
-rw-r--r--arch/powerpc/kernel/smp.c34
-rw-r--r--arch/powerpc/kvm/book3s_hv.c8
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c31
5 files changed, 45 insertions, 43 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 4096f16502a9..2c8e39951ab5 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -337,6 +337,10 @@ static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu)
337 vcpu->kvm->arch.kvm_ops->fast_vcpu_kick(vcpu); 337 vcpu->kvm->arch.kvm_ops->fast_vcpu_kick(vcpu);
338} 338}
339 339
340extern void kvm_hv_vm_activated(void);
341extern void kvm_hv_vm_deactivated(void);
342extern bool kvm_hv_mode_active(void);
343
340#else 344#else
341static inline void __init kvm_cma_reserve(void) 345static inline void __init kvm_cma_reserve(void)
342{} 346{}
@@ -356,6 +360,9 @@ static inline void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu)
356{ 360{
357 kvm_vcpu_kick(vcpu); 361 kvm_vcpu_kick(vcpu);
358} 362}
363
364static inline bool kvm_hv_mode_active(void) { return false; }
365
359#endif 366#endif
360 367
361#ifdef CONFIG_KVM_XICS 368#ifdef CONFIG_KVM_XICS
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index ff51046b6466..5a6614a7f0b2 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -68,14 +68,6 @@ void generic_mach_cpu_die(void);
68void generic_set_cpu_dead(unsigned int cpu); 68void generic_set_cpu_dead(unsigned int cpu);
69void generic_set_cpu_up(unsigned int cpu); 69void generic_set_cpu_up(unsigned int cpu);
70int generic_check_cpu_restart(unsigned int cpu); 70int generic_check_cpu_restart(unsigned int cpu);
71
72extern void inhibit_secondary_onlining(void);
73extern void uninhibit_secondary_onlining(void);
74
75#else /* HOTPLUG_CPU */
76static inline void inhibit_secondary_onlining(void) {}
77static inline void uninhibit_secondary_onlining(void) {}
78
79#endif 71#endif
80 72
81#ifdef CONFIG_PPC64 73#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 4863ea14f270..5cdd9eb3b24c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -36,6 +36,7 @@
36#include <linux/atomic.h> 36#include <linux/atomic.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/hw_irq.h> 38#include <asm/hw_irq.h>
39#include <asm/kvm_ppc.h>
39#include <asm/page.h> 40#include <asm/page.h>
40#include <asm/pgtable.h> 41#include <asm/pgtable.h>
41#include <asm/prom.h> 42#include <asm/prom.h>
@@ -458,38 +459,9 @@ int generic_check_cpu_restart(unsigned int cpu)
458 return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; 459 return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
459} 460}
460 461
461static atomic_t secondary_inhibit_count; 462static bool secondaries_inhibited(void)
462
463/*
464 * Don't allow secondary CPU threads to come online
465 */
466void inhibit_secondary_onlining(void)
467{
468 /*
469 * This makes secondary_inhibit_count stable during cpu
470 * online/offline operations.
471 */
472 get_online_cpus();
473
474 atomic_inc(&secondary_inhibit_count);
475 put_online_cpus();
476}
477EXPORT_SYMBOL_GPL(inhibit_secondary_onlining);
478
479/*
480 * Allow secondary CPU threads to come online again
481 */
482void uninhibit_secondary_onlining(void)
483{
484 get_online_cpus();
485 atomic_dec(&secondary_inhibit_count);
486 put_online_cpus();
487}
488EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining);
489
490static int secondaries_inhibited(void)
491{ 463{
492 return atomic_read(&secondary_inhibit_count); 464 return kvm_hv_mode_active();
493} 465}
494 466
495#else /* HOTPLUG_CPU */ 467#else /* HOTPLUG_CPU */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 8227dba5af0f..d7b74f888ad8 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -2317,10 +2317,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm)
2317 spin_lock_init(&kvm->arch.slot_phys_lock); 2317 spin_lock_init(&kvm->arch.slot_phys_lock);
2318 2318
2319 /* 2319 /*
2320 * Don't allow secondary CPU threads to come online 2320 * Track that we now have a HV mode VM active. This blocks secondary
2321 * while any KVM VMs exist. 2321 * CPU threads from coming online.
2322 */ 2322 */
2323 inhibit_secondary_onlining(); 2323 kvm_hv_vm_activated();
2324 2324
2325 return 0; 2325 return 0;
2326} 2326}
@@ -2336,7 +2336,7 @@ static void kvmppc_free_vcores(struct kvm *kvm)
2336 2336
2337static void kvmppc_core_destroy_vm_hv(struct kvm *kvm) 2337static void kvmppc_core_destroy_vm_hv(struct kvm *kvm)
2338{ 2338{
2339 uninhibit_secondary_onlining(); 2339 kvm_hv_vm_deactivated();
2340 2340
2341 kvmppc_free_vcores(kvm); 2341 kvmppc_free_vcores(kvm);
2342 if (kvm->arch.rma) { 2342 if (kvm->arch.rma) {
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 8cd0daebb82d..7cde8a665205 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -6,6 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <linux/cpu.h>
9#include <linux/kvm_host.h> 10#include <linux/kvm_host.h>
10#include <linux/preempt.h> 11#include <linux/preempt.h>
11#include <linux/export.h> 12#include <linux/export.h>
@@ -181,3 +182,33 @@ void __init kvm_cma_reserve(void)
181 kvm_cma_declare_contiguous(selected_size, align_size); 182 kvm_cma_declare_contiguous(selected_size, align_size);
182 } 183 }
183} 184}
185
186/*
187 * When running HV mode KVM we need to block certain operations while KVM VMs
188 * exist in the system. We use a counter of VMs to track this.
189 *
190 * One of the operations we need to block is onlining of secondaries, so we
191 * protect hv_vm_count with get/put_online_cpus().
192 */
193static atomic_t hv_vm_count;
194
195void kvm_hv_vm_activated(void)
196{
197 get_online_cpus();
198 atomic_inc(&hv_vm_count);
199 put_online_cpus();
200}
201EXPORT_SYMBOL_GPL(kvm_hv_vm_activated);
202
203void kvm_hv_vm_deactivated(void)
204{
205 get_online_cpus();
206 atomic_dec(&hv_vm_count);
207 put_online_cpus();
208}
209EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated);
210
211bool kvm_hv_mode_active(void)
212{
213 return atomic_read(&hv_vm_count) != 0;
214}