Module Name: src
Committed By: rin
Date: Fri Dec 15 09:31:03 UTC 2023
Modified Files:
src/sys/arch/powerpc/powerpc: trap.c
Log Message:
powerpc/oea: trap: pmap_{pte,ste}_spill() even in the interrupt context
Page table for oea is something like L2 TLB on memory; kernel and
processes share its entries, and process entries can be spilled out.
As done for MMU based on software-managed TLB, we need to restore
such entries even in the interrupt context.
Note that pmap_pte_spill() require no resouce to restore entries.
Still-not-implemented pmap_ste_spill() for OEA64 should also.
Part of PR kern/57621
To generate a diff of this commit:
cvs rdiff -u -r1.164 -r1.165 src/sys/arch/powerpc/powerpc/trap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/powerpc/powerpc/trap.c
diff -u src/sys/arch/powerpc/powerpc/trap.c:1.164 src/sys/arch/powerpc/powerpc/trap.c:1.165
--- src/sys/arch/powerpc/powerpc/trap.c:1.164 Thu Oct 5 19:41:05 2023
+++ src/sys/arch/powerpc/powerpc/trap.c Fri Dec 15 09:31:02 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.164 2023/10/05 19:41:05 ad Exp $ */
+/* $NetBSD: trap.c,v 1.165 2023/12/15 09:31:02 rin Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -35,7 +35,7 @@
#define __UCAS_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.164 2023/10/05 19:41:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.165 2023/12/15 09:31:02 rin Exp $");
#ifdef _KERNEL_OPT
#include "opt_altivec.h"
@@ -136,42 +136,40 @@ trap(struct trapframe *tf)
ci->ci_ev_kdsi.ev_count++;
- /*
- * Only query UVM if no interrupts are active.
- */
- if (ci->ci_idepth < 0) {
- if ((va >> ADDR_SR_SHFT) == pcb->pcb_kmapsr) {
- va &= ADDR_PIDX | ADDR_POFF;
- va |= pcb->pcb_umapsr << ADDR_SR_SHFT;
- map = &p->p_vmspace->vm_map;
-#ifdef PPC_OEA64
- if ((tf->tf_dsisr & DSISR_NOTFOUND) &&
- vm_map_pmap(map)->pm_ste_evictions > 0 &&
- pmap_ste_spill(vm_map_pmap(map),
- trunc_page(va), false)) {
- return;
- }
+ if ((va >> ADDR_SR_SHFT) == pcb->pcb_kmapsr) {
+ va &= ADDR_PIDX | ADDR_POFF;
+ va |= pcb->pcb_umapsr << ADDR_SR_SHFT;
+ map = &p->p_vmspace->vm_map;
+ }
+#if defined(DIAGNOSTIC) && !defined(PPC_OEA64)
+ else if (__predict_false((va >> ADDR_SR_SHFT) == USER_SR)) {
+ printf("trap: kernel %s DSI trap @ %#lx by %#lx"
+ " (DSISR %#x): USER_SR unset\n",
+ (tf->tf_dsisr & DSISR_STORE)
+ ? "write" : "read",
+ va, tf->tf_srr0, tf->tf_dsisr);
+ goto brain_damage2;
+ }
#endif
+ else {
+ map = kernel_map;
+ }
- if ((tf->tf_dsisr & DSISR_NOTFOUND) &&
- vm_map_pmap(map)->pm_evictions > 0 &&
- pmap_pte_spill(vm_map_pmap(map),
- trunc_page(va), false)) {
- return;
- }
-#if defined(DIAGNOSTIC) && !defined(PPC_OEA64)
- } else if ((va >> ADDR_SR_SHFT) == USER_SR) {
- printf("trap: kernel %s DSI trap @ %#lx by %#lx"
- " (DSISR %#x): USER_SR unset\n",
- (tf->tf_dsisr & DSISR_STORE)
- ? "write" : "read",
- va, tf->tf_srr0, tf->tf_dsisr);
- goto brain_damage2;
+#ifdef PPC_OEA64
+ if ((tf->tf_dsisr & DSISR_NOTFOUND) &&
+ vm_map_pmap(map)->pm_ste_evictions > 0 &&
+ pmap_ste_spill(vm_map_pmap(map), trunc_page(va), false))
+ return;
#endif
- } else {
- map = kernel_map;
- }
+ if ((tf->tf_dsisr & DSISR_NOTFOUND) &&
+ vm_map_pmap(map)->pm_evictions > 0 &&
+ pmap_pte_spill(vm_map_pmap(map), trunc_page(va), false))
+ return;
+ /*
+ * Only query UVM if no interrupts are active.
+ */
+ if (ci->ci_idepth < 0) {
if (tf->tf_dsisr & DSISR_STORE)
ftype = VM_PROT_WRITE;
else