]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
powerpc/powernv: POWER9 support for msgsnd/doorbell IPI
authorNicholas Piggin <npiggin@gmail.com>
Mon, 29 May 2017 14:54:34 +0000 (11:54 -0300)
committerStefan Bader <stefan.bader@canonical.com>
Tue, 20 Jun 2017 08:49:48 +0000 (10:49 +0200)
BugLink: http://bugs.launchpad.net/bugs/1691973
POWER9 requires msgsync for receiver-side synchronization, and a DD1
workaround restricts IPIs to core-local.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Drop no longer needed asm feature macro changes]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
(cherry picked from commit 6b3edefefa6752df57ad636f26baa1b0a502ddab)
Signed-off-by: Gustavo Walbon <gwalbon@linux.vnet.ibm.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
arch/powerpc/include/asm/dbell.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/platforms/powernv/smp.c

index 040944659a202430c30dfd6a0c17969a02af3f4f..f70cbfe0ec045d54b90fbbe121dd5c395ad233da 100644 (file)
@@ -51,6 +51,9 @@ static inline void ppc_msgsnd_sync(void)
 /* sync after taking message interrupt */
 static inline void ppc_msgsync(void)
 {
+       /* sync is not required when taking messages from the same core */
+       __asm__ __volatile__ (ASM_FTR_IFSET(PPC_MSGSYNC " ; lwsync", "", %0)
+                               : : "i" (CPU_FTR_HVMODE|CPU_FTR_ARCH_300));
 }
 
 #else /* CONFIG_PPC_BOOK3S */
index d99bd442aacbe5747f605cd356de6aa3ae58e53a..9b7e9b9dee3477d38a0ae6e95900e5d4803ae6b7 100644 (file)
 #define PPC_INST_MFTMR                 0x7c0002dc
 #define PPC_INST_MSGSND                        0x7c00019c
 #define PPC_INST_MSGCLR                        0x7c0001dc
+#define PPC_INST_MSGSYNC               0x7c0006ec
 #define PPC_INST_MSGSNDP               0x7c00011c
 #define PPC_INST_MTTMR                 0x7c0003dc
 #define PPC_INST_NOP                   0x60000000
                                        ___PPC_RB(b) | __PPC_EH(eh))
 #define PPC_MSGSND(b)          stringify_in_c(.long PPC_INST_MSGSND | \
                                        ___PPC_RB(b))
+#define PPC_MSGSYNC            stringify_in_c(.long PPC_INST_MSGSYNC)
 #define PPC_MSGCLR(b)          stringify_in_c(.long PPC_INST_MSGCLR | \
                                        ___PPC_RB(b))
 #define PPC_MSGSNDP(b)         stringify_in_c(.long PPC_INST_MSGSNDP | \
index 6001504ea3c30692f6c062df63e68cad4300a93a..21c2d2a235be8f7c520533abcefdb8fccfa0e1d7 100644 (file)
@@ -256,6 +256,23 @@ static void pnv_cause_ipi(int cpu)
        icp_ops->cause_ipi(cpu);
 }
 
+static void pnv_p9_dd1_cause_ipi(int cpu)
+{
+       int this_cpu = get_cpu();
+
+       /*
+        * POWER9 DD1 has a global addressed msgsnd, but for now we restrict
+        * IPIs to same core, because it requires additional synchronization
+        * for inter-core doorbells which we do not implement.
+        */
+       if (cpumask_test_cpu(cpu, cpu_sibling_mask(this_cpu)))
+               doorbell_global_ipi(cpu);
+       else
+               icp_ops->cause_ipi(cpu);
+
+       put_cpu();
+}
+
 static void __init pnv_smp_probe(void)
 {
        if (xive_enabled())
@@ -263,8 +280,15 @@ static void __init pnv_smp_probe(void)
        else
                xics_smp_probe();
 
-       if (cpu_has_feature(CPU_FTR_DBELL) && !cpu_has_feature(CPU_FTR_ARCH_300)) {
-               smp_ops->cause_ipi = pnv_cause_ipi;
+       if (cpu_has_feature(CPU_FTR_DBELL)) {
+               if (cpu_has_feature(CPU_FTR_ARCH_300)) {
+                       if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+                               smp_ops->cause_ipi = pnv_p9_dd1_cause_ipi;
+                       else
+                               smp_ops->cause_ipi = doorbell_global_ipi;
+               } else {
+                       smp_ops->cause_ipi = pnv_cause_ipi;
+               }
        } else {
                smp_ops->cause_ipi = icp_ops->cause_ipi;
        }