KVM: PPC: Book3S HV: Use msgsnd for IPIs to other cores on POWER9
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 17 Nov 2016 21:47:08 +0000 (08:47 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Wed, 23 Nov 2016 22:24:23 +0000 (09:24 +1100)
On POWER9, the msgsnd instruction is able to send interrupts to
other cores, as well as other threads on the local core.  Since
msgsnd is generally simpler and faster than sending an IPI via the
XICS, we use msgsnd for all IPIs sent by KVM on POWER9.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_builtin.c

index 0a90fa44f555aedb530d7455ac53efc039ad4a07..7a6a00a41b127da42d644639148059fca584f2af 100644 (file)
@@ -147,12 +147,21 @@ static inline struct kvm_vcpu *next_runnable_thread(struct kvmppc_vcore *vc,
 
 static bool kvmppc_ipi_thread(int cpu)
 {
+       unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
+
+       /* On POWER9 we can use msgsnd to IPI any cpu */
+       if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+               msg |= get_hard_smp_processor_id(cpu);
+               smp_mb();
+               __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+               return true;
+       }
+
        /* On POWER8 for IPIs to threads in the same core, use msgsnd */
        if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
                preempt_disable();
                if (cpu_first_thread_sibling(cpu) ==
                    cpu_first_thread_sibling(smp_processor_id())) {
-                       unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
                        msg |= cpu_thread_in_core(cpu);
                        smp_mb();
                        __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
index 90a0b274e699e4859466a23e008d62b405e4dada..e1e1ead1abb523146efc0f1d9fb323c22ded80ec 100644 (file)
@@ -206,12 +206,18 @@ static inline void rm_writeb(unsigned long paddr, u8 val)
 void kvmhv_rm_send_ipi(int cpu)
 {
        unsigned long xics_phys;
+       unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
 
-       /* On POWER8 for IPIs to threads in the same core, use msgsnd */
+       /* On POWER9 we can use msgsnd for any destination cpu. */
+       if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+               msg |= get_hard_smp_processor_id(cpu);
+               __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+               return;
+       }
+       /* On POWER8 for IPIs to threads in the same core, use msgsnd. */
        if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
            cpu_first_thread_sibling(cpu) ==
            cpu_first_thread_sibling(raw_smp_processor_id())) {
-               unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
                msg |= cpu_thread_in_core(cpu);
                __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
                return;