powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2
authorPaul Mackerras <paulus@ozlabs.org>
Wed, 21 Mar 2018 10:31:59 +0000 (21:31 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 23 Mar 2018 13:39:09 +0000 (00:39 +1100)
This adds a CPU feature bit which is set for POWER9 "Nimbus" DD2.2
processors which will be used to enable the hypervisor to assist
hardware with the handling of checkpointed register values while the
CPU is in suspend state, in order to work around hardware bugs.  The
hardware assistance for these workarounds introduced a new hardware
bug relating to the XER[SO] bit.  We add a separate feature bit for
this bug in case future chips fix it while still requiring the
hypervisor assistance with suspend state.

When the dt_cpu_ftrs subsystem is in use, the software assistance can
be enabled using a "tm-suspend-hypervisor-assist" node in the device
tree, and a "tm-suspend-xer-so-bug" node enables the workarounds for
the XER[SO] bug.  In the absence of such nodes, a quirk enables both
for POWER9 "Nimbus" DD2.2 processors.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/cputable.h
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/dt_cpu_ftrs.c

index 49fd0676b6e5a56726fe649178a293afc0025b88..ecee84dea7e7644cf8599a0b59e1f7afdf123d07 100644 (file)
@@ -213,6 +213,8 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_PMAO_BUG               LONG_ASM_CONST(0x0000020000000000)
 #define CPU_FTR_POWER9_DD1             LONG_ASM_CONST(0x0000040000000000)
 #define CPU_FTR_POWER9_DD2_1           LONG_ASM_CONST(0x0000080000000000)
+#define CPU_FTR_P9_TM_HV_ASSIST                LONG_ASM_CONST(0x0000100000000000)
+#define CPU_FTR_P9_TM_XER_SO_BUG       LONG_ASM_CONST(0x0000200000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -469,6 +471,8 @@ static inline void cpu_feature_keys_init(void) { }
                             (~CPU_FTR_SAO))
 #define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
 #define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
+#define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_P9_TM_HV_ASSIST | \
+                              CPU_FTR_P9_TM_XER_SO_BUG)
 #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -488,7 +492,8 @@ static inline void cpu_feature_keys_init(void) { }
             CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
             CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \
             CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9 | \
-            CPU_FTRS_POWER9_DD1 | CPU_FTRS_POWER9_DD2_1)
+            CPU_FTRS_POWER9_DD1 | CPU_FTRS_POWER9_DD2_1 | \
+            CPU_FTRS_POWER9_DD2_2)
 #endif
 #else
 enum {
index c40a9fc1e5d1270e4bbe75507819e0aa6ed74abe..68052eacb82736950b2e931d65982eea21a01e19 100644 (file)
@@ -553,11 +553,31 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check_early    = __machine_check_early_realmode_p9,
                .platform               = "power9",
        },
-       {       /* Power9 DD 2.1 or later (see DD2.0 above) */
+       {       /* Power9 DD 2.1 */
+               .pvr_mask               = 0xffffefff,
+               .pvr_value              = 0x004e0201,
+               .cpu_name               = "POWER9 (raw)",
+               .cpu_features           = CPU_FTRS_POWER9_DD2_1,
+               .cpu_user_features      = COMMON_USER_POWER9,
+               .cpu_user_features2     = COMMON_USER2_POWER9,
+               .mmu_features           = MMU_FTRS_POWER9,
+               .icache_bsize           = 128,
+               .dcache_bsize           = 128,
+               .num_pmcs               = 6,
+               .pmc_type               = PPC_PMC_IBM,
+               .oprofile_cpu_type      = "ppc64/power9",
+               .oprofile_type          = PPC_OPROFILE_INVALID,
+               .cpu_setup              = __setup_cpu_power9,
+               .cpu_restore            = __restore_cpu_power9,
+               .flush_tlb              = __flush_tlb_power9,
+               .machine_check_early    = __machine_check_early_realmode_p9,
+               .platform               = "power9",
+       },
+       {       /* Power9 DD2.2 or later */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x004e0000,
                .cpu_name               = "POWER9 (raw)",
-               .cpu_features           = CPU_FTRS_POWER9_DD2_1,
+               .cpu_features           = CPU_FTRS_POWER9_DD2_2,
                .cpu_user_features      = COMMON_USER_POWER9,
                .cpu_user_features2     = COMMON_USER2_POWER9,
                .mmu_features           = MMU_FTRS_POWER9,
index ee562ffb00c0f7e19f9ea8279291dbd145706225..0a0c601c6ade59aaf743a9bd7cf6a760c9860932 100644 (file)
@@ -589,6 +589,8 @@ static struct dt_cpu_feature_match __initdata
        {"virtual-page-class-key-protection", feat_enable, 0},
        {"transactional-memory", feat_enable_tm, CPU_FTR_TM},
        {"transactional-memory-v3", feat_enable_tm, 0},
+       {"tm-suspend-hypervisor-assist", feat_enable, CPU_FTR_P9_TM_HV_ASSIST},
+       {"tm-suspend-xer-so-bug", feat_enable, CPU_FTR_P9_TM_XER_SO_BUG},
        {"idle-nap", feat_enable_idle_nap, 0},
        {"alignment-interrupt-dsisr", feat_enable_align_dsisr, 0},
        {"idle-stop", feat_enable_idle_stop, 0},
@@ -708,6 +710,9 @@ static __init void cpufeatures_cpu_quirks(void)
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD1;
        else if ((version & 0xffffefff) == 0x004e0201)
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
+       else if ((version & 0xffffefff) == 0x004e0202)
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST |
+                       CPU_FTR_P9_TM_XER_SO_BUG;
 }
 
 static void __init cpufeatures_setup_finished(void)