Merge tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
[linux-2.6-block.git] / arch / powerpc / platforms / powernv / smp.c
index 273d7b46f72ac22ff238cd10dc978eaf8610d32b..8f70ba681a78b91e6755e3e123c3dc784857e3c6 100644 (file)
@@ -32,6 +32,8 @@
 #include <asm/runlatch.h>
 #include <asm/code-patching.h>
 #include <asm/dbell.h>
+#include <asm/kvm_ppc.h>
+#include <asm/ppc-opcode.h>
 
 #include "powernv.h"
 
@@ -148,7 +150,7 @@ static int pnv_smp_cpu_disable(void)
 static void pnv_smp_cpu_kill_self(void)
 {
        unsigned int cpu;
-       unsigned long srr1;
+       unsigned long srr1, wmask;
        u32 idle_states;
 
        /* Standard hot unplug procedure */
@@ -160,6 +162,10 @@ static void pnv_smp_cpu_kill_self(void)
        generic_set_cpu_dead(cpu);
        smp_wmb();
 
+       wmask = SRR1_WAKEMASK;
+       if (cpu_has_feature(CPU_FTR_ARCH_207S))
+               wmask = SRR1_WAKEMASK_P8;
+
        idle_states = pnv_get_supported_cpuidle_states();
        /* We don't want to take decrementer interrupts while we are offline,
         * so clear LPCR:PECE1. We keep PECE2 enabled.
@@ -190,10 +196,14 @@ static void pnv_smp_cpu_kill_self(void)
                 * having finished executing in a KVM guest, then srr1
                 * contains 0.
                 */
-               if ((srr1 & SRR1_WAKEMASK) == SRR1_WAKEEE) {
+               if ((srr1 & wmask) == SRR1_WAKEEE) {
                        icp_native_flush_interrupt();
                        local_paca->irq_happened &= PACA_IRQ_HARD_DIS;
                        smp_mb();
+               } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) {
+                       unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
+                       asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
+                       kvmppc_set_host_ipi(cpu, 0);
                }
 
                if (cpu_core_split_required())