Subject: mips handling of SIGSEGV and SIGBUS.
To: None <port-mips@netbsd.org>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 09/23/2000 11:32:45
so, while looking at some unrelated code, i noticed what i'd call a
couple of quirks in the mips trap.c w.r.t. signal delivery because of
failing user-mode accesses.
For misaligned or kseg accesses, and for accesses which cause the cpu
to be signaled with a bus error, the user process is given a SIGSEGV.
For TLB misses (other than those which resolve to
KERN_RESOURCE_SHORTAGE and get the process killed), if
KERN_PROTECTION_FAILURE then a SIGBUS is given, otherwise a SIGSEGV is
given.
I checked some other ports: sparc, alpha, i386. On each:
* for misaligned accesses, SIGBUS is given.
* for accesses that result in calls to uvm_fault (which aren't
resolved w/o error, and which don't get the process killed), SIGSEGV
is always returned.
I'd say that MIPS should be consistent. Specifically, that means the
diff below. (I've lumped kseg accesses into the buserr case, because
that's not a valid access ever.)
Any comments?
chris
===================================================================
Index: trap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/trap.c,v
retrieving revision 1.148
diff -c -r1.148 trap.c
*** trap.c 2000/09/21 20:59:58 1.148
--- trap.c 2000/09/23 18:31:57
***************
*** 544,551 ****
p->p_ucred->cr_uid : -1);
sig = SIGKILL;
} else {
! sig = (rv == KERN_PROTECTION_FAILURE) ?
! SIGBUS : SIGSEGV;
}
ucode = vaddr;
break; /* SIGNAL */
--- 544,550 ----
p->p_ucred->cr_uid : -1);
sig = SIGKILL;
} else {
! sig = SIGSEGV;
}
ucode = vaddr;
break; /* SIGNAL */
***************
*** 574,580 ****
case T_ADDR_ERR_ST+T_USER: /* misaligned or kseg access */
case T_BUS_ERR_IFETCH+T_USER: /* BERR asserted to cpu */
case T_BUS_ERR_LD_ST+T_USER: /* BERR asserted to cpu */
! sig = SIGSEGV;
ucode = vaddr;
break; /* SIGNAL */
--- 573,579 ----
case T_ADDR_ERR_ST+T_USER: /* misaligned or kseg access */
case T_BUS_ERR_IFETCH+T_USER: /* BERR asserted to cpu */
case T_BUS_ERR_LD_ST+T_USER: /* BERR asserted to cpu */
! sig = SIGBUS;
ucode = vaddr;
break; /* SIGNAL */