Add compat support for struct reg on arm64
The size of the spsr field in struct reg has changed. Mask the bits that userspace doesn't know about out as they may be invalid. While here add a comment why we don't need compat support in set_regs. Sponsored by: Arm Ltd
This commit is contained in:
parent
76d8efc2b5
commit
032a1ed4bc
@ -125,6 +125,13 @@ set_regs(struct thread *td, struct reg *regs)
|
||||
#endif
|
||||
{
|
||||
frame->tf_elr = regs->elr;
|
||||
/*
|
||||
* frame->tf_spsr and regs->spsr on FreeBSD 13 was 32-bit
|
||||
* where from 14 they are 64 bit. As PSR_SETTABLE_64 clears
|
||||
* the upper 32 bits no compatibility handling is needed,
|
||||
* however if this is ever not the case we will need to add
|
||||
* these, similar to how it is done in set_mcontext.
|
||||
*/
|
||||
frame->tf_spsr &= ~PSR_SETTABLE_64;
|
||||
frame->tf_spsr |= regs->spsr & PSR_SETTABLE_64;
|
||||
/* Enable single stepping if userspace asked fot it */
|
||||
@ -456,10 +463,22 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
|
||||
int
|
||||
set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
{
|
||||
#define PSR_13_MASK 0xfffffffful
|
||||
struct trapframe *tf = td->td_frame;
|
||||
uint64_t spsr;
|
||||
|
||||
spsr = mcp->mc_gpregs.gp_spsr;
|
||||
#ifdef COMPAT_FREEBSD13
|
||||
if (td->td_proc->p_osrel < P_OSREL_ARM64_SPSR) {
|
||||
/*
|
||||
* Before FreeBSD 14 gp_spsr was 32 bit. The size of mc_gpregs
|
||||
* was identical because of padding so mask of the upper bits
|
||||
* that may be invalid on earlier releases.
|
||||
*/
|
||||
spsr &= PSR_13_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((spsr & PSR_M_MASK) != PSR_M_EL0t ||
|
||||
(spsr & PSR_AARCH32) != 0 ||
|
||||
(spsr & PSR_DAIF) != (td->td_frame->tf_spsr & PSR_DAIF))
|
||||
@ -470,7 +489,14 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
tf->tf_sp = mcp->mc_gpregs.gp_sp;
|
||||
tf->tf_lr = mcp->mc_gpregs.gp_lr;
|
||||
tf->tf_elr = mcp->mc_gpregs.gp_elr;
|
||||
tf->tf_spsr = mcp->mc_gpregs.gp_spsr;
|
||||
#ifdef COMPAT_FREEBSD13
|
||||
if (td->td_proc->p_osrel < P_OSREL_ARM64_SPSR) {
|
||||
/* Keep the upper 32 bits of spsr on older releases */
|
||||
tf->tf_spsr &= ~PSR_13_MASK;
|
||||
tf->tf_spsr |= spsr;
|
||||
} else
|
||||
#endif
|
||||
tf->tf_spsr = spsr;
|
||||
if ((tf->tf_spsr & PSR_SS) != 0) {
|
||||
td->td_pcb->pcb_flags |= PCB_SINGLE_STEP;
|
||||
|
||||
@ -481,6 +507,7 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
set_fpcontext(td, mcp);
|
||||
|
||||
return (0);
|
||||
#undef PSR_13_MASK
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -108,6 +108,7 @@
|
||||
#define P_OSREL_CK_INODE 1300005
|
||||
#define P_OSREL_POWERPC_NEW_AUX_ARGS 1300070
|
||||
#define P_OSREL_TIDPID 1400079
|
||||
#define P_OSREL_ARM64_SPSR 1400084
|
||||
|
||||
#define P_OSREL_MAJOR(x) ((x) / 100000)
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user