Commit 736bcdd3 authored by Jordan Niethe's avatar Jordan Niethe Committed by Michael Ellerman
Browse files

powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2



Commit a25bd72b ("powerpc/mm/radix: Workaround prefetch issue with
KVM") introduced a number of workarounds as coming out of a guest with
the mmu enabled would make the cpu would start running in hypervisor
state with the PID value from the guest. The cpu will then start
prefetching for the hypervisor with that PID value.

In Power9 DD2.2 the cpu behaviour was modified to fix this. When
accessing Quadrant 0 in hypervisor mode with LPID != 0 prefetching will
not be performed. This means that we can get rid of the workarounds for
Power9 DD2.2 and later revisions. Add a new cpu feature
CPU_FTR_P9_RADIX_PREFETCH_BUG to indicate if the workarounds are needed.

Signed-off-by: default avatarJordan Niethe <jniethe5@gmail.com>
Acked-by: default avatarPaul Mackerras <paulus@ozlabs.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20191206031722.25781-1-jniethe5@gmail.com
parent 5649607a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ static inline void cpu_feature_keys_init(void) { }
#define CPU_FTR_P9_TLBIE_STQ_BUG	LONG_ASM_CONST(0x0000400000000000)
#define CPU_FTR_P9_TIDR			LONG_ASM_CONST(0x0000800000000000)
#define CPU_FTR_P9_TLBIE_ERAT_BUG	LONG_ASM_CONST(0x0001000000000000)
#define CPU_FTR_P9_RADIX_PREFETCH_BUG	LONG_ASM_CONST(0x0002000000000000)

#ifndef __ASSEMBLY__

@@ -459,8 +460,10 @@ static inline void cpu_feature_keys_init(void) { }
	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
	    CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
	    CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TLBIE_ERAT_BUG | CPU_FTR_P9_TIDR)
#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_0 (CPU_FTRS_POWER9 | CPU_FTR_P9_RADIX_PREFETCH_BUG)
#define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | \
			       CPU_FTR_P9_RADIX_PREFETCH_BUG | \
			       CPU_FTR_POWER9_DD2_1)
#define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
			       CPU_FTR_P9_TM_HV_ASSIST | \
			       CPU_FTR_P9_TM_XER_SO_BUG)
+8 −5
Original line number Diff line number Diff line
@@ -727,17 +727,20 @@ static __init void cpufeatures_cpu_quirks(void)
	/*
	 * Not all quirks can be derived from the cpufeatures device tree.
	 */
	if ((version & 0xffffefff) == 0x004e0200)
		; /* DD2.0 has no feature flag */
	else if ((version & 0xffffefff) == 0x004e0201)
	if ((version & 0xffffefff) == 0x004e0200) {
		/* DD2.0 has no feature flag */
		cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
	} 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_RADIX_PREFETCH_BUG;
	} else if ((version & 0xffffefff) == 0x004e0202) {
		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
		cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
	} else if ((version & 0xffff0000) == 0x004e0000)
	} else if ((version & 0xffff0000) == 0x004e0000) {
		/* DD2.1 and up have DD2_1 */
		cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
	}

	if ((version & 0xffff0000) == 0x004e0000) {
		cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
+2 −0
Original line number Diff line number Diff line
@@ -1801,6 +1801,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
	tlbsync
	ptesync

BEGIN_FTR_SECTION
	/* Radix: Handle the case where the guest used an illegal PID */
	LOAD_REG_ADDR(r4, mmu_base_pid)
	lwz	r3, VCPU_GUEST_PID(r9)
@@ -1830,6 +1831,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
	addi	r7,r7,0x1000
	bdnz	1b
	ptesync
END_FTR_SECTION_IFSET(CPU_FTR_P9_RADIX_PREFETCH_BUG)

2:
#endif /* CONFIG_PPC_RADIX_MMU */
+5 −1
Original line number Diff line number Diff line
@@ -337,7 +337,11 @@ static void __init radix_init_pgtable(void)
	}

	/* Find out how many PID bits are supported */
	if (cpu_has_feature(CPU_FTR_HVMODE)) {
	if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
		if (!mmu_pid_bits)
			mmu_pid_bits = 20;
		mmu_base_pid = 1;
	} else if (cpu_has_feature(CPU_FTR_HVMODE)) {
		if (!mmu_pid_bits)
			mmu_pid_bits = 20;
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+3 −0
Original line number Diff line number Diff line
@@ -1161,6 +1161,9 @@ extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
	if (unlikely(pid == MMU_NO_CONTEXT))
		return;

	if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG))
		return;

	/*
	 * If this context hasn't run on that CPU before and KVM is
	 * around, there's a slim chance that the guest on another