Page MenuHomeFreeBSD

D21566.1785210581.diff
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

D21566.1785210581.diff

Index: sys/amd64/amd64/trap.c
===================================================================
--- sys/amd64/amd64/trap.c
+++ sys/amd64/amd64/trap.c
@@ -111,7 +111,7 @@
void trap_check(struct trapframe *frame);
void dblfault_handler(struct trapframe *frame);
-static int trap_pfault(struct trapframe *, int);
+static int trap_pfault(struct trapframe *, bool, int *, int *);
static void trap_fatal(struct trapframe *, vm_offset_t);
#ifdef KDTRACE_HOOKS
static bool trap_user_dtrace(struct trapframe *,
@@ -352,40 +352,11 @@
return;
addr = frame->tf_addr;
- signo = trap_pfault(frame, TRUE);
+ trap_pfault(frame, true, &signo, &ucode);
if (signo == -1)
return;
if (signo == 0)
goto userret;
- if (signo == SIGSEGV) {
- ucode = SEGV_MAPERR;
- } else if (prot_fault_translation == 0) {
- /*
- * Autodetect. This check also covers
- * the images without the ABI-tag ELF
- * note.
- */
- if (SV_CURPROC_ABI() == SV_ABI_FREEBSD &&
- p->p_osrel >= P_OSREL_SIGSEGV) {
- signo = SIGSEGV;
- ucode = SEGV_ACCERR;
- } else {
- signo = SIGBUS;
- ucode = T_PAGEFLT;
- }
- } else if (prot_fault_translation == 1) {
- /*
- * Always compat mode.
- */
- signo = SIGBUS;
- ucode = T_PAGEFLT;
- } else {
- /*
- * Always SIGSEGV mode.
- */
- signo = SIGSEGV;
- ucode = SEGV_ACCERR;
- }
break;
case T_DIVIDE: /* integer divide fault */
@@ -440,7 +411,7 @@
("kernel trap doesn't have ucred"));
switch (type) {
case T_PAGEFLT: /* page fault */
- (void) trap_pfault(frame, FALSE);
+ (void) trap_pfault(frame, false, NULL, NULL);
return;
case T_DNA:
@@ -713,7 +684,7 @@
}
static int
-trap_pfault(struct trapframe *frame, int usermode)
+trap_pfault(struct trapframe *frame, bool usermode, int *signo, int *ucode)
{
struct thread *td;
struct proc *p;
@@ -776,8 +747,11 @@
/*
* Don't allow user-mode faults in kernel address space.
*/
- if (usermode)
- return (SIGSEGV);
+ if (usermode) {
+ *signo = SIGSEGV;
+ *ucode = SEGV_ACCERR;
+ return (1);
+ }
map = kernel_map;
} else {
@@ -868,7 +842,37 @@
trap_fatal(frame, eva);
return (-1);
}
- return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+
+ if (rv == KERN_FAILURE || rv == KERN_RESOURCE_SHORTAGE) {
+ *signo = SIGSEGV;
+ *ucode = SEGV_MAPERR;
+ } else if (rv == KERN_INVALID_ADDRESS) {
+ *signo = SIGBUS;
+ *ucode = BUS_OBJERR;
+ } else if (prot_fault_translation == 0) {
+ /*
+ * Autodetect. This check also covers
+ * the images without the ABI-tag ELF
+ * note.
+ */
+ if (SV_CURPROC_ABI() == SV_ABI_FREEBSD &&
+ p->p_osrel >= P_OSREL_SIGSEGV) {
+ *signo = SIGSEGV;
+ *ucode = SEGV_ACCERR;
+ } else {
+ *signo = SIGBUS;
+ *ucode = T_PAGEFLT;
+ }
+ } else if (prot_fault_translation == 1) {
+ /* Always compat mode. */
+ *signo = SIGBUS;
+ *ucode = T_PAGEFLT;
+ } else {
+ /* Always SIGSEGV mode. */
+ *signo = SIGSEGV;
+ *ucode = SEGV_ACCERR;
+ }
+ return (1);
}
static void
Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ sys/vm/vm_fault.c
@@ -562,6 +562,11 @@
#endif
result = vm_fault_hold(map, trunc_page(vaddr), fault_type, fault_flags,
NULL);
+ KASSERT(result == KERN_SUCCESS || result == KERN_FAILURE ||
+ result == KERN_INVALID_ADDRESS ||
+ result == KERN_RESOURCE_SHORTAGE ||
+ result == KERN_PROTECTION_FAILURE,
+ ("Unknown Mach error %d from vm_fault_hold()", result));
#ifdef KTRACE
if (map != kernel_map && KTRPOINT(td, KTR_FAULTEND))
ktrfaultend(result);
@@ -787,7 +792,7 @@
fs.object == fs.first_object) {
if (fs.pindex >= fs.object->size) {
unlock_and_deallocate(&fs);
- return (KERN_PROTECTION_FAILURE);
+ return (KERN_INVALID_ADDRESS);
}
if (fs.object == fs.first_object &&

File Metadata

Mime Type
text/plain
Expires
Tue, Jul 28, 3:49 AM (9 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29286241
Default Alt Text
D21566.1785210581.diff (3 KB)

Event Timeline