Use setjmp() instead of the identical-except-for-having-a-wrong-prototype

setfault() when testing for faults. This should also help the compiler
do the right thing with this complicated-to-optimize function.
This commit is contained in:
Nathan Whitehorn 2016-01-10 16:42:14 +00:00
parent cf45f1240d
commit a18c313e4a
7 changed files with 60 additions and 47 deletions

View File

@ -35,7 +35,7 @@
#ifndef _MACHINE_PCB_H_
#define _MACHINE_PCB_H_
typedef register_t faultbuf[25];
#include <machine/setjmp.h>
struct pcb {
register_t pcb_context[20]; /* non-volatile r14-r31 */
@ -44,7 +44,7 @@ struct pcb {
register_t pcb_toc; /* toc pointer */
register_t pcb_lr; /* link register */
struct pmap *pcb_pm; /* pmap of our vmspace */
faultbuf *pcb_onfault; /* For use during
jmp_buf *pcb_onfault; /* For use during
copyin/copyout */
int pcb_flags;
#define PCB_FPU 1 /* Process uses FPU */

View File

@ -8,7 +8,11 @@
#include <sys/cdefs.h>
#ifdef _KERNEL
#define _JBLEN 25 /* Kernel doesn't save FP and Altivec regs */
#else
#define _JBLEN 100
#endif
/*
* jmp_buf and sigjmp_buf are encapsulated in different structs to force

View File

@ -62,8 +62,6 @@ int rtascall(vm_offset_t callbuffer, uintptr_t rtas_privdat);
extern uintptr_t rtas_entry;
extern register_t rtasmsr;
int setfault(faultbuf); /* defined in locore.S */
/*
* After the VM is up, allocate RTAS memory and instantiate it
*/
@ -203,7 +201,7 @@ int
rtas_call_method(cell_t token, int nargs, int nreturns, ...)
{
vm_offset_t argsptr;
faultbuf env, *oldfaultbuf;
jmp_buf env, *oldfaultbuf;
va_list ap;
struct {
cell_t token;
@ -233,7 +231,8 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...)
/* Get rid of any stale machine checks that have been waiting. */
__asm __volatile ("sync; isync");
oldfaultbuf = curthread->td_pcb->pcb_onfault;
if (!setfault(env)) {
curthread->td_pcb->pcb_onfault = &env;
if (!setjmp(env)) {
__asm __volatile ("sync");
result = rtascall(argsptr, rtas_private_data);
__asm __volatile ("sync; isync");

View File

@ -82,8 +82,6 @@ static int grackle_enable_config(struct grackle_softc *, u_int,
static void grackle_disable_config(struct grackle_softc *);
static int badaddr(void *, size_t);
int setfault(faultbuf); /* defined in locore.S */
/*
* Driver methods.
*/
@ -244,7 +242,7 @@ static int
badaddr(void *addr, size_t size)
{
struct thread *td;
faultbuf env, *oldfaultbuf;
jmp_buf env, *oldfaultbuf;
int x;
/* Get rid of any stale machine checks that have been waiting. */
@ -253,7 +251,8 @@ badaddr(void *addr, size_t size)
td = curthread;
oldfaultbuf = td->td_pcb->pcb_onfault;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = oldfaultbuf;
__asm __volatile ("sync");
return 1;

View File

@ -71,8 +71,6 @@ __FBSDID("$FreeBSD$");
#include <machine/slb.h>
#include <machine/vmparam.h>
int setfault(faultbuf); /* defined in locore.S */
#ifdef AIM
/*
* Makes sure that the right segment of userspace is mapped in.
@ -176,7 +174,7 @@ copyout(const void *kaddr, void *udaddr, size_t len)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
const char *kp;
char *up, *p;
size_t l;
@ -184,7 +182,8 @@ copyout(const void *kaddr, void *udaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@ -214,7 +213,7 @@ copyin(const void *udaddr, void *kaddr, size_t len)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
const char *up;
char *kp, *p;
size_t l;
@ -222,7 +221,8 @@ copyin(const void *udaddr, void *kaddr, size_t len)
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (EFAULT);
}
@ -285,13 +285,14 @@ subyte(volatile void *addr, int byte)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
char *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -313,13 +314,14 @@ suword32(volatile void *addr, int word)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
int *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -341,13 +343,14 @@ suword(volatile void *addr, long word)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -382,14 +385,15 @@ fubyte(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
u_char *p;
int val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -410,13 +414,14 @@ fuword16(volatile const void *addr)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
uint16_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -437,13 +442,14 @@ fueword32(volatile const void *addr, int32_t *val)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
int32_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -465,13 +471,14 @@ fueword64(volatile const void *addr, int64_t *val)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
int64_t *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -493,13 +500,14 @@ fueword(volatile const void *addr, long *val)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
long *p;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -521,13 +529,14 @@ casueword32(volatile uint32_t *addr, uint32_t old, uint32_t *oldvalp,
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
uint32_t *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}
@ -572,13 +581,14 @@ casueword(volatile u_long *addr, u_long old, u_long *oldvalp, u_long new)
{
struct thread *td;
pmap_t pm;
faultbuf env;
jmp_buf env;
u_long *p, val;
td = curthread;
pm = &td->td_proc->p_vmspace->vm_pmap;
if (setfault(env)) {
td->td_pcb->pcb_onfault = &env;
if (setjmp(env)) {
td->td_pcb->pcb_onfault = NULL;
return (-1);
}

View File

@ -67,7 +67,6 @@ volatile static u_quad_t ap_timebase;
static u_int ipi_msg_cnt[32];
static struct mtx ap_boot_mtx;
struct pcb stoppcbs[MAXCPU];
int longfault(faultbuf, int);
void
machdep_ap_bootstrap(void)

View File

@ -74,11 +74,12 @@ __FBSDID("$FreeBSD$");
#include <machine/spr.h>
#include <machine/sr.h>
#define FAULTBUF_LR 0
/* Below matches setjmp.S */
#define FAULTBUF_LR 21
#define FAULTBUF_R1 1
#define FAULTBUF_R2 2
#define FAULTBUF_CR 3
#define FAULTBUF_R13 4
#define FAULTBUF_CR 22
#define FAULTBUF_R14 3
static void trap_fatal(struct trapframe *frame);
static void printtrap(u_int vector, struct trapframe *frame, int isfatal,
@ -462,18 +463,19 @@ static int
handle_onfault(struct trapframe *frame)
{
struct thread *td;
faultbuf *fb;
jmp_buf *fb;
td = curthread;
fb = td->td_pcb->pcb_onfault;
if (fb != NULL) {
frame->srr0 = (*fb)[FAULTBUF_LR];
frame->fixreg[1] = (*fb)[FAULTBUF_R1];
frame->fixreg[2] = (*fb)[FAULTBUF_R2];
frame->srr0 = (*fb)->_jb[FAULTBUF_LR];
frame->fixreg[1] = (*fb)->_jb[FAULTBUF_R1];
frame->fixreg[2] = (*fb)->_jb[FAULTBUF_R2];
frame->fixreg[3] = 1;
frame->cr = (*fb)[FAULTBUF_CR];
bcopy(&(*fb)[FAULTBUF_R13], &frame->fixreg[13],
19 * sizeof(register_t));
frame->cr = (*fb)->_jb[FAULTBUF_CR];
bcopy(&(*fb)->_jb[FAULTBUF_R14], &frame->fixreg[14],
18 * sizeof(register_t));
td->td_pcb->pcb_onfault = NULL; /* Returns twice, not thrice */
return (1);
}
return (0);