linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2
@ 2019-12-02  3:07 Jordan Niethe
  2019-12-04  1:32 ` Oliver O'Halloran
  0 siblings, 1 reply; 2+ messages in thread
From: Jordan Niethe @ 2019-12-02  3:07 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: 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 <jniethe5@gmail.com>
---
 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
+	srwi	r6, 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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2
  2019-12-02  3:07 [PATCH] powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2 Jordan Niethe
@ 2019-12-04  1:32 ` Oliver O'Halloran
  0 siblings, 0 replies; 2+ messages in thread
From: Oliver O'Halloran @ 2019-12-04  1:32 UTC (permalink / raw)
  To: Jordan Niethe; +Cc: Paul Mackerras, linuxppc-dev, Nicholas Piggin

On Mon, Dec 2, 2019 at 2:08 PM Jordan Niethe <jniethe5@gmail.com> 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 <jniethe5@gmail.com>
> ---
>  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
> +       srwi    r6, 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
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-12-04  1:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-02  3:07 [PATCH] powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2 Jordan Niethe
2019-12-04  1:32 ` Oliver O'Halloran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).