Re: [PATCH] powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2

2019-12-03 Thread Oliver O'Halloran
On Mon, Dec 2, 2019 at 2:08 PM Jordan Niethe  wrote:
>
> Commit a25bd72badfa ("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.
>
> Signed-off-by: Jordan Niethe 
> ---
>  arch/powerpc/kvm/book3s_hv_rmhandlers.S  |  9 +
>  arch/powerpc/mm/book3s64/radix_pgtable.c | 18 --
>  arch/powerpc/mm/book3s64/radix_tlb.c |  5 +
>  3 files changed, 26 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index faebcbb8c4db..6bbc5fbc7ea9 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -1793,6 +1793,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
> tlbsync
> ptesync
>
> +   /* We do not need this work around from POWER9 DD2.2 and onwards */
> +   mfspr   r3, SPRN_PVR
> +   srwir6, r3, 16
> +   cmpwi   cr0, r6, PVR_POWER9
> +   bne cr0, 2f
> +   andi.   r3, r3, 0xfff
> +   cmpwi   cr0, r3, 0x202
> +   bge cr0, 2f

This seems like the sort of thing we'd want to use a CPU_FTR_SECTION()
for. We probably want to have a CPU_FTR for this anyway so we're not
open-coding the PVR check all over the place.

> +
> /* Radix: Handle the case where the guest used an illegal PID */
> LOAD_REG_ADDR(r4, mmu_base_pid)
> lwz r3, VCPU_GUEST_PID(r9)
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
> b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index 6ee17d09649c..1f280124994e 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -312,6 +312,7 @@ static void __init radix_init_pgtable(void)
>  {
> unsigned long rts_field;
> struct memblock_region *reg;
> +   unsigned int pvr;
>
> /* We don't support slb for radix */
> mmu_slb_size = 0;
> @@ -336,24 +337,29 @@ static void __init radix_init_pgtable(void)
> }
>
> /* Find out how many PID bits are supported */
> +   pvr = mfspr(SPRN_PVR);
> if (cpu_has_feature(CPU_FTR_HVMODE)) {
> if (!mmu_pid_bits)
> mmu_pid_bits = 20;
>  #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
> /*
> -* When KVM is possible, we only use the top half of the
> -* PID space to avoid collisions between host and guest PIDs
> -* which can cause problems due to prefetch when exiting the
> -* guest with AIL=3
> +* Before Power9 DD2.2, when KVM is possible, we only use the
> +* top half of the PID space to avoid collisions between host
> +* and guest PIDs which can cause problems due to prefetch 
> when
> +* exiting the guest with AIL=3
>  */
> -   mmu_base_pid = 1 << (mmu_pid_bits - 1);
> +   if (PVR_VER(pvr) == PVR_POWER9 && ((0xfff & pvr) < 0x202))
> +   mmu_base_pid = 1;
> +   else
> +   mmu_base_pid = 1 << (mmu_pid_bits - 1);
>  #else
> mmu_base_pid = 1;
>  #endif
> } else {
> /* The guest uses the bottom half of the PID space */
> if (!mmu_pid_bits)
> -   mmu_pid_bits = 19;
> +   mmu_pid_bits = (PVR_VER(pvr) == PVR_POWER9 &&
> +   ((0xfff & pvr) < 0x202)) ? 19 : 20;
> mmu_base_pid = 1;
> }
>
> diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c 
> b/arch/powerpc/mm/book3s64/radix_tlb.c
> index 67af871190c6..cc86d8a88b86 100644
> --- a/arch/powerpc/mm/book3s64/radix_tlb.c
> +++ b/arch/powerpc/mm/book3s64/radix_tlb.c
> @@ -1217,10 +1217,15 @@ void radix__flush_tlb_all(void)
>  extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
>  {
> unsigned long pid = mm->context.id;
> +   unsigned int pvr;
>
> if (unlikely(pid == MMU_NO_CONTEXT))
> return;
>
> +   pvr = mfspr(SPRN_PVR);
> +   if (PVR_VER(pvr) != PVR_POWER9 || ((0xfff & pvr) >= 0x202))
> +   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
> --
> 2.20.1
>


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

2019-12-01 Thread Jordan Niethe
Commit a25bd72badfa ("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.

Signed-off-by: Jordan Niethe 
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S  |  9 +
 arch/powerpc/mm/book3s64/radix_pgtable.c | 18 --
 arch/powerpc/mm/book3s64/radix_tlb.c |  5 +
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index faebcbb8c4db..6bbc5fbc7ea9 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1793,6 +1793,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
tlbsync
ptesync
 
+   /* We do not need this work around from POWER9 DD2.2 and onwards */
+   mfspr   r3, SPRN_PVR
+   srwir6, r3, 16
+   cmpwi   cr0, r6, PVR_POWER9
+   bne cr0, 2f
+   andi.   r3, r3, 0xfff
+   cmpwi   cr0, r3, 0x202
+   bge cr0, 2f
+
/* Radix: Handle the case where the guest used an illegal PID */
LOAD_REG_ADDR(r4, mmu_base_pid)
lwz r3, VCPU_GUEST_PID(r9)
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 6ee17d09649c..1f280124994e 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -312,6 +312,7 @@ static void __init radix_init_pgtable(void)
 {
unsigned long rts_field;
struct memblock_region *reg;
+   unsigned int pvr;
 
/* We don't support slb for radix */
mmu_slb_size = 0;
@@ -336,24 +337,29 @@ static void __init radix_init_pgtable(void)
}
 
/* Find out how many PID bits are supported */
+   pvr = mfspr(SPRN_PVR);
if (cpu_has_feature(CPU_FTR_HVMODE)) {
if (!mmu_pid_bits)
mmu_pid_bits = 20;
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
/*
-* When KVM is possible, we only use the top half of the
-* PID space to avoid collisions between host and guest PIDs
-* which can cause problems due to prefetch when exiting the
-* guest with AIL=3
+* Before Power9 DD2.2, when KVM is possible, we only use the
+* top half of the PID space to avoid collisions between host
+* and guest PIDs which can cause problems due to prefetch when
+* exiting the guest with AIL=3
 */
-   mmu_base_pid = 1 << (mmu_pid_bits - 1);
+   if (PVR_VER(pvr) == PVR_POWER9 && ((0xfff & pvr) < 0x202))
+   mmu_base_pid = 1;
+   else
+   mmu_base_pid = 1 << (mmu_pid_bits - 1);
 #else
mmu_base_pid = 1;
 #endif
} else {
/* The guest uses the bottom half of the PID space */
if (!mmu_pid_bits)
-   mmu_pid_bits = 19;
+   mmu_pid_bits = (PVR_VER(pvr) == PVR_POWER9 &&
+   ((0xfff & pvr) < 0x202)) ? 19 : 20;
mmu_base_pid = 1;
}
 
diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c 
b/arch/powerpc/mm/book3s64/radix_tlb.c
index 67af871190c6..cc86d8a88b86 100644
--- a/arch/powerpc/mm/book3s64/radix_tlb.c
+++ b/arch/powerpc/mm/book3s64/radix_tlb.c
@@ -1217,10 +1217,15 @@ void radix__flush_tlb_all(void)
 extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
 {
unsigned long pid = mm->context.id;
+   unsigned int pvr;
 
if (unlikely(pid == MMU_NO_CONTEXT))
return;
 
+   pvr = mfspr(SPRN_PVR);
+   if (PVR_VER(pvr) != PVR_POWER9 || ((0xfff & pvr) >= 0x202))
+   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
-- 
2.20.1