From: Nicholas Piggin Date: Mon, 29 May 2017 14:54:34 +0000 (-0300) Subject: powerpc/powernv: POWER9 support for msgsnd/doorbell IPI X-Git-Tag: Ubuntu-4.10.0-25.29~140 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=cd450c6ddc7432284d4195993b1dbebc4f2ac91a;p=mirror_ubuntu-zesty-kernel.git powerpc/powernv: POWER9 support for msgsnd/doorbell IPI 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 [mpe: Drop no longer needed asm feature macro changes] Signed-off-by: Michael Ellerman (cherry picked from commit 6b3edefefa6752df57ad636f26baa1b0a502ddab) Signed-off-by: Gustavo Walbon Acked-by: Stefan Bader Acked-by: Seth Forshee Signed-off-by: Kleber Sacilotto de Souza --- diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h index 040944659a20..f70cbfe0ec04 100644 --- a/arch/powerpc/include/asm/dbell.h +++ b/arch/powerpc/include/asm/dbell.h @@ -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 */ diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index d99bd442aacb..9b7e9b9dee34 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -161,6 +161,7 @@ #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 @@ -338,6 +339,7 @@ ___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 | \ diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 6001504ea3c3..21c2d2a235be 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -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; }