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:
peter 2003-10-15 02:04:52 +00:00
parent e6f87cb811
commit 7b395bcd75
5 changed files with 17 additions and 5 deletions

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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 */

View File

@ -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_ */