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
This commit is contained in:
parent
de8bfff6c9
commit
474dee38bf
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user