Pull the tier-2 card one last time and break the get/setcontext and
sigreturn() ABI and the signal context on the stack. Make the trapframe (and its shadows in the ucontext and sigframe etc) 8 bytes larger in order to preserve 16 byte stack alignment for the following C code calls. I could have done some padding after the trapframe was saved, but some of the C code still expects an argument of 'struct trapframe'. Anyway, this gives me a spare field that can be used to store things like 'partial trapframe' status or something else in the future. The runtime impact is fairly small, *except* for threaded apps and things that decode contexts and the signal stack (eg: cvsup binary). Signal delivery isn't too badly affected because the kernel generates the sigframe that sigreturn uses after the handler has been called. The size of mcontext_t and struct sigframe hasn't changed. Only the last few fields (sc_eip etc) got moved a little and I eliminated a spare field. mc_len/sc_len did change location though so the sanity checks there will still trap it.
This commit is contained in:
parent
6f366f87e6
commit
19acc770c2
@ -228,7 +228,7 @@ IDTVEC(fast_syscall)
|
||||
movq %rsp,PCPU(SCRATCH_RSP)
|
||||
movq common_tss+COMMON_TSS_RSP0,%rsp
|
||||
/* Now emulate a trapframe. Make the 8 byte alignment odd for call. */
|
||||
subq $TF_SIZE+8,%rsp
|
||||
subq $TF_SIZE,%rsp
|
||||
/* defer TF_RSP till we have a spare register */
|
||||
movq %r11,TF_RFLAGS(%rsp)
|
||||
movq %rcx,TF_RIP(%rsp) /* %rcx original value is in %r10 */
|
||||
|
@ -258,6 +258,9 @@ trap(frame)
|
||||
default:
|
||||
ucode = code + BUS_SEGM_FAULT ;
|
||||
i = SIGBUS;
|
||||
printf("trap %d: pid %d err %p eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", type, p->p_pid, (void *)frame.tf_err,
|
||||
(void *)frame.tf_addr, (void *)frame.tf_rip, (void *)frame.tf_rax, (void *)frame.tf_rbx, (void *)frame.tf_rcx, (void *)frame.tf_rdx, (void *)frame.tf_rsp, (void *)frame.tf_rbp, (void *)frame.tf_rsi, (void *)frame.tf_rdi);
|
||||
|
||||
break;
|
||||
|
||||
case T_PAGEFLT: /* page fault */
|
||||
@ -542,6 +545,12 @@ trap_pfault(frame, usermode)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
printf("trap_pfault: pid %d %s %s %s eva %p, rip %p, rax %p, rbx %p, rcx %p, rdx %p, rsp %p, rbp %p, rsi %p, rdi %p\n", p->p_pid,
|
||||
frame->tf_err & PGEX_U ? "user" : "supervisor",
|
||||
frame->tf_err & PGEX_W ? "write" : "read",
|
||||
frame->tf_err & PGEX_P ? "protection violation" : "page not present",
|
||||
(void *)eva, (void *)frame->tf_rip, (void *)frame->tf_rax, (void *)frame->tf_rbx, (void *)frame->tf_rcx, (void *)frame->tf_rdx, (void *)frame->tf_rsp, (void *)frame->tf_rbp, (void *)frame->tf_rsi, (void *)frame->tf_rdi);
|
||||
|
||||
return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ struct trapframe {
|
||||
register_t tf_r15;
|
||||
register_t tf_trapno;
|
||||
register_t tf_addr;
|
||||
register_t tf_flags;
|
||||
/* below portion defined in hardware */
|
||||
register_t tf_err;
|
||||
register_t tf_rip;
|
||||
@ -98,6 +99,7 @@ struct intrframe {
|
||||
register_t if_r15;
|
||||
register_t :64; /* compat with trap frame - trapno */
|
||||
register_t :64; /* compat with trap frame - addr */
|
||||
register_t :64; /* compat with trap frame - flags */
|
||||
register_t :64; /* compat with trap frame - err */
|
||||
/* below portion defined in hardware */
|
||||
register_t if_rip;
|
||||
@ -127,6 +129,7 @@ struct clockframe {
|
||||
register_t cf_r15;
|
||||
register_t :64; /* compat with trap frame - trapno */
|
||||
register_t :64; /* compat with trap frame - addr */
|
||||
register_t :64; /* compat with trap frame - flags */
|
||||
register_t :64; /* compat with trap frame - err */
|
||||
/* below portion defined in hardware */
|
||||
register_t cf_rip;
|
||||
|
@ -91,6 +91,7 @@ struct sigcontext {
|
||||
long sc_r15;
|
||||
long sc_trapno;
|
||||
long sc_addr;
|
||||
long sc_flags;
|
||||
long sc_err;
|
||||
long sc_rip;
|
||||
long sc_cs;
|
||||
@ -104,9 +105,8 @@ struct sigcontext {
|
||||
*/
|
||||
long sc_fpformat;
|
||||
long sc_ownedfp;
|
||||
long sc_spare1[1];
|
||||
long sc_fpstate[64] __aligned(16);
|
||||
long sc_spare2[8];
|
||||
long sc_spare[8];
|
||||
};
|
||||
#endif /* __BSD_VISIBLE */
|
||||
|
||||
|
@ -55,6 +55,7 @@ typedef struct __mcontext {
|
||||
__register_t mc_r15;
|
||||
__register_t mc_trapno;
|
||||
__register_t mc_addr;
|
||||
__register_t mc_flags;
|
||||
__register_t mc_err;
|
||||
__register_t mc_rip;
|
||||
__register_t mc_cs;
|
||||
@ -70,12 +71,11 @@ typedef struct __mcontext {
|
||||
#define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */
|
||||
#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */
|
||||
long mc_ownedfp;
|
||||
long mc_spare1[1]; /* align mc_fpstate to 16 bytes */
|
||||
/*
|
||||
* See <machine/npx.h> for the internals of mc_fpstate[].
|
||||
*/
|
||||
long mc_fpstate[64] __aligned(16);
|
||||
long mc_spare2[8];
|
||||
long mc_spare[8];
|
||||
} mcontext_t;
|
||||
|
||||
#endif /* !_MACHINE_UCONTEXT_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user