Send the correct signal when vm_fault fails. While here also set the code

and address fields.

Sponsored by:	ABT Systems Ltd
This commit is contained in:
andrew 2015-07-08 12:42:44 +00:00
parent 0e59e469d5
commit 44c69163d2

View File

@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
#include <machine/frame.h>
@ -79,13 +80,14 @@ void do_el0_error(struct trapframe *);
int (*dtrace_invop_jump_addr)(struct trapframe *);
static __inline void
call_trapsignal(struct thread *td, int sig, u_long code)
call_trapsignal(struct thread *td, int sig, int code, void *addr)
{
ksiginfo_t ksi;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = sig;
ksi.ksi_code = (int)code;
ksi.ksi_code = code;
ksi.ksi_addr = addr;
trapsignal(td, &ksi);
}
@ -151,7 +153,7 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower)
vm_prot_t ftype;
vm_offset_t va;
uint64_t far;
int error, sig;
int error, sig, ucode;
td = curthread;
pcb = td->td_pcb;
@ -204,13 +206,14 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower)
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
}
if (error != 0) {
if (error != KERN_SUCCESS) {
if (lower) {
if (error == ENOMEM)
sig = SIGKILL;
sig = SIGSEGV;
if (error == KERN_PROTECTION_FAILURE)
ucode = SEGV_ACCERR;
else
sig = SIGSEGV;
call_trapsignal(td, sig, 0);
ucode = SEGV_MAPERR;
call_trapsignal(td, sig, ucode, (void *)far);
} else {
if (td->td_intr_nesting_level == 0 &&
pcb->pcb_onfault != 0) {