git: 0ccf063e075a - stable/13 - powerpc64: fix radix on pseries TLB invalidation

From: Leandro Lupori <luporl_at_FreeBSD.org>
Date: Tue, 04 Oct 2022 16:29:40 UTC
The branch stable/13 has been updated by luporl:

URL: https://cgit.FreeBSD.org/src/commit/?id=0ccf063e075ac02d3b487b3f51f001e8f4151f24

commit 0ccf063e075ac02d3b487b3f51f001e8f4151f24
Author:     Leandro Lupori <luporl@FreeBSD.org>
AuthorDate: 2021-09-08 11:37:11 +0000
Commit:     Leandro Lupori <luporl@FreeBSD.org>
CommitDate: 2022-10-04 16:24:14 +0000

    powerpc64: fix radix on pseries TLB invalidation
    
    When running in a virtualized environment, TLB invalidations can only
    be performed on process scope, as only the hypervisor is allowed to
    invalidate a global scope, or else a Program Interrupt is triggered.
    
    Since we are here, also make sure that the register process table
    hypercall returns success.
    
    Reviewed by:            jhibbits
    Sponsored by:           Instituto de Pesquisas Eldorado (eldorado.org.br)
    Differential Revision:  https://reviews.freebsd.org/D31775
    
    (cherry picked from commit 4f7c436548ea1cc935c4f4b237693fbe8ed7939a)
---
 sys/powerpc/aim/mmu_radix.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/sys/powerpc/aim/mmu_radix.c b/sys/powerpc/aim/mmu_radix.c
index f77c1f5c8da4..34736d5031bd 100644
--- a/sys/powerpc/aim/mmu_radix.c
+++ b/sys/powerpc/aim/mmu_radix.c
@@ -656,10 +656,10 @@ extern void bs_remap_earlyboot(void);
 #define PARTTAB_HR		(1UL << 63) /* host uses radix */
 #define PARTTAB_GR		(1UL << 63) /* guest uses radix must match host */
 
-/* TLB flush actions. Used as argument to tlbiel_all() */
+/* TLB flush actions. Used as argument to tlbiel_flush() */
 enum {
-	TLB_INVAL_SCOPE_LPID = 0,	/* invalidate TLBs for current LPID */
-	TLB_INVAL_SCOPE_GLOBAL = 1,	/* invalidate all TLBs */
+	TLB_INVAL_SCOPE_LPID = 2,	/* invalidate TLBs for current LPID */
+	TLB_INVAL_SCOPE_GLOBAL = 3,	/* invalidate all TLBs */
 };
 
 #define	NPV_LIST_LOCKS	MAXCPU
@@ -757,9 +757,11 @@ tlbiel_flush_isa3(uint32_t num_sets, uint32_t is)
 	 * and partition table entries. Then flush the remaining sets of the
 	 * TLB.
 	 */
-	tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0);
-	for (set = 1; set < num_sets; set++)
-		tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0);
+	if (is == TLB_INVAL_SCOPE_GLOBAL) {
+		tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 0);
+		for (set = 1; set < num_sets; set++)
+			tlbiel_radix_set_isa300(set, is, 0, RIC_FLUSH_TLB, 0);
+	}
 
 	/* Do the same for process scoped entries. */
 	tlbiel_radix_set_isa300(0, is, 0, RIC_FLUSH_ALL, 1);
@@ -772,13 +774,10 @@ tlbiel_flush_isa3(uint32_t num_sets, uint32_t is)
 static void
 mmu_radix_tlbiel_flush(int scope)
 {
-	int is;
-
 	MPASS(scope == TLB_INVAL_SCOPE_LPID ||
 		  scope == TLB_INVAL_SCOPE_GLOBAL);
-	is = scope + 2;
 
-	tlbiel_flush_isa3(POWER9_TLB_SETS_RADIX, is);
+	tlbiel_flush_isa3(POWER9_TLB_SETS_RADIX, scope);
 	__asm __volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
 }
 
@@ -2191,9 +2190,15 @@ mmu_radix_proctab_init(void)
 		__asm __volatile("eieio; tlbsync; ptesync" : : : "memory");
 #ifdef PSERIES
 	} else {
-		phyp_hcall(H_REGISTER_PROC_TBL,
+		int64_t rc;
+
+		rc = phyp_hcall(H_REGISTER_PROC_TBL,
 		    PROC_TABLE_NEW | PROC_TABLE_RADIX | PROC_TABLE_GTSE,
 		    proctab0pa, 0, PROCTAB_SIZE_SHIFT - 12);
+		if (rc != H_SUCCESS)
+			panic("mmu_radix_proctab_init: "
+				"failed to register process table: rc=%jd",
+				(intmax_t)rc);
 #endif
 	}