svn commit: r361317 - in head/sys/powerpc: aim include powerpc
Justin Hibbits
jhibbits at FreeBSD.org
Thu May 21 03:33:22 UTC 2020
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.
More information about the svn-src-head
mailing list