summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2008-08-24 20:53:36 +0000
committermarius <marius@FreeBSD.org>2008-08-24 20:53:36 +0000
commite95621f381ab930a1b7f2be1bfe3259ead616346 (patch)
treebaad18f409365a13a826cc143643e2ac67e5282b /sys/sparc64
parent4561fa447ef579c8b93b84878af6c7d4e401e68c (diff)
downloadFreeBSD-src-e95621f381ab930a1b7f2be1bfe3259ead616346.zip
FreeBSD-src-e95621f381ab930a1b7f2be1bfe3259ead616346.tar.gz
There's a race in kmem(4) between checking whether a page is resident
in the kernel and copying it out, causing a panic when faulting on a nofault entry. Handle this case gracefully by letting the kernel copy functions return EFAULT instead. As such this change addresses the same problem as r154721 does for i386. MFC after: 3 days
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/sparc64/trap.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 44eed95..c1a81cd 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -388,6 +388,7 @@ trap_pfault(struct thread *td, struct trapframe *tf)
struct proc *p;
vm_offset_t va;
vm_prot_t prot;
+ vm_map_entry_t entry;
u_long ctx;
int flags;
int type;
@@ -461,6 +462,19 @@ trap_pfault(struct thread *td, struct trapframe *tf)
KASSERT(tf->tf_tstate & TSTATE_PRIV,
("trap_pfault: fault on nucleus context from user mode"));
+ if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
+ tf->tf_tpc <= (u_long)copy_nofault_end) {
+ vm_map_lock_read(kernel_map);
+ if (vm_map_lookup_entry(kernel_map, va, &entry) &&
+ (entry->eflags & MAP_ENTRY_NOFAULT) != 0) {
+ tf->tf_tpc = (u_long)copy_fault;
+ tf->tf_tnpc = tf->tf_tpc + 4;
+ vm_map_unlock_read(kernel_map);
+ return (0);
+ }
+ vm_map_unlock_read(kernel_map);
+ }
+
/*
* We don't have to worry about process locking or stacks in
* the kernel.
OpenPOWER on IntegriCloud