Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 May 2020 03:33:20 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r361317 - in head/sys/powerpc: aim include powerpc
Message-ID:  <202005210333.04L3XKSK023931@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Thu May 21 03:33:20 2020
New Revision: 361317
URL: https://svnweb.freebsd.org/changeset/base/361317

Log:
  powerpc: Handle machine checks caused by D-ERAT multihit
  
  Instead of crashing the user process when a D-ERAT multihit is detected, try
  to flush the ERAT, and continue.  This machine check indicates a likely PMAP
  invalidation shortcoming that will need to be addressed, but it's
  recoverable, so just recover.  The recovery is pmap-specific to flush the
  ERAT, so add a pmap function to do so, currently only implemented by the
  POWER9 radix pmap.

Modified:
  head/sys/powerpc/aim/aim_machdep.c
  head/sys/powerpc/aim/mmu_radix.c
  head/sys/powerpc/include/pmap.h
  head/sys/powerpc/powerpc/mmu_if.m
  head/sys/powerpc/powerpc/pmap_dispatch.c

Modified: head/sys/powerpc/aim/aim_machdep.c
==============================================================================
--- head/sys/powerpc/aim/aim_machdep.c	Thu May 21 02:10:45 2020	(r361316)
+++ head/sys/powerpc/aim/aim_machdep.c	Thu May 21 03:33:20 2020	(r361317)
@@ -539,6 +539,10 @@ cpu_machine_check(struct thread *td, struct trapframe 
 		/* SLB multi-hit is recoverable. */
 		if ((frame->cpu.aim.dsisr & DSISR_MC_SLB_MULTIHIT) != 0)
 			return (0);
+		if ((frame->cpu.aim.dsisr & DSISR_MC_DERAT_MULTIHIT) != 0) {
+			pmap_tlbie_all();
+			return (0);
+		}
 		/* TODO: Add other machine check recovery procedures. */
 	} else {
 		if ((frame->srr1 & SRR1_MCHK_IFETCH_M) == SRR1_MCHK_IFETCH_SLBMH)

Modified: head/sys/powerpc/aim/mmu_radix.c
==============================================================================
--- head/sys/powerpc/aim/mmu_radix.c	Thu May 21 02:10:45 2020	(r361316)
+++ head/sys/powerpc/aim/mmu_radix.c	Thu May 21 03:33:20 2020	(r361317)
@@ -482,6 +482,7 @@ static void mmu_radix_dumpsys_map(mmu_t mmu, vm_paddr_
     void **va);
 static void mmu_radix_scan_init(mmu_t mmu);
 static void	mmu_radix_cpu_bootstrap(mmu_t, int ap);
+static void	mmu_radix_tlbie_all(mmu_t);
 
 static mmu_method_t mmu_radix_methods[] = {
 	MMUMETHOD(mmu_bootstrap,	mmu_radix_bootstrap),
@@ -543,6 +544,8 @@ static mmu_method_t mmu_radix_methods[] = {
 	MMUMETHOD(mmu_change_attr,	mmu_radix_change_attr),
 	MMUMETHOD(mmu_map_user_ptr,	mmu_radix_map_user_ptr),
 	MMUMETHOD(mmu_decode_kernel_ptr, mmu_radix_decode_kernel_ptr),
+
+	MMUMETHOD(mmu_tlbie_all,	mmu_radix_tlbie_all),
 	{ 0, 0 }
 };
 
@@ -772,6 +775,13 @@ mmu_radix_tlbiel_flush(int scope)
 
 	tlbiel_flush_isa3(POWER9_TLB_SETS_RADIX, is);
 	__asm __volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
+}
+
+static void
+mmu_radix_tlbie_all(mmu_t __unused mmu)
+{
+	/* TODO: LPID invalidate */
+	mmu_radix_tlbiel_flush(TLB_INVAL_SCOPE_GLOBAL);
 }
 
 static void

Modified: head/sys/powerpc/include/pmap.h
==============================================================================
--- head/sys/powerpc/include/pmap.h	Thu May 21 02:10:45 2020	(r361316)
+++ head/sys/powerpc/include/pmap.h	Thu May 21 03:33:20 2020	(r361317)
@@ -341,6 +341,7 @@ vm_offset_t pmap_early_io_map(vm_paddr_t pa, vm_size_t
 void pmap_early_io_unmap(vm_offset_t va, vm_size_t size);
 void pmap_track_page(pmap_t pmap, vm_offset_t va);
 void pmap_page_print_mappings(vm_page_t m);
+void pmap_tlbie_all(void);
 
 static inline int
 pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)

Modified: head/sys/powerpc/powerpc/mmu_if.m
==============================================================================
--- head/sys/powerpc/powerpc/mmu_if.m	Thu May 21 02:10:45 2020	(r361316)
+++ head/sys/powerpc/powerpc/mmu_if.m	Thu May 21 03:33:20 2020	(r361317)
@@ -1100,3 +1100,11 @@ METHOD boolean_t ps_enabled {
 	mmu_t		_mmu;
 	pmap_t		_pmap;
 } DEFAULT mmu_null_ps_enabled;
+
+
+/**
+ * @brief Flush the TLB (used by machine check handler).
+ */
+METHOD void tlbie_all {
+	mmu_t		_mmu;
+};

Modified: head/sys/powerpc/powerpc/pmap_dispatch.c
==============================================================================
--- head/sys/powerpc/powerpc/pmap_dispatch.c	Thu May 21 02:10:45 2020	(r361316)
+++ head/sys/powerpc/powerpc/pmap_dispatch.c	Thu May 21 03:33:20 2020	(r361317)
@@ -631,6 +631,13 @@ pmap_ps_enabled(pmap_t pmap)
 	return (MMU_PS_ENABLED(mmu_obj, pmap));
 }
 
+void
+pmap_tlbie_all(void)
+{
+	CTR1(KTR_PMAP, "%s()", __func__);
+	return (MMU_TLBIE_ALL(mmu_obj));
+}
+
 /*
  * MMU install routines. Highest priority wins, equal priority also
  * overrides allowing last-set to win.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005210333.04L3XKSK023931>