Commit 25dc2c80 authored by Mark Rutland's avatar Mark Rutland Committed by Will Deacon

arm64: compat: map SPSR_ELx<->PSR for signals

The SPSR_ELx format for exceptions taken from AArch32 differs from the
AArch32 PSR format. Thus, we must translate between the two when setting
up a compat sigframe, or restoring context from a compat sigframe.
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Fixes: 7206dc93 ("arm64: Expose Arm v8.4 features")
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Suzuki Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 12651321
...@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs, ...@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
int err; int err;
sigset_t set; sigset_t set;
struct compat_aux_sigframe __user *aux; struct compat_aux_sigframe __user *aux;
unsigned long psr;
err = get_sigset_t(&set, &sf->uc.uc_sigmask); err = get_sigset_t(&set, &sf->uc.uc_sigmask);
if (err == 0) { if (err == 0) {
...@@ -266,7 +267,9 @@ static int compat_restore_sigframe(struct pt_regs *regs, ...@@ -266,7 +267,9 @@ static int compat_restore_sigframe(struct pt_regs *regs,
__get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); __get_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
__get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); __get_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
__get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); __get_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
__get_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); __get_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
regs->pstate = compat_psr_to_pstate(psr);
/* /*
* Avoid compat_sys_sigreturn() restarting. * Avoid compat_sys_sigreturn() restarting.
...@@ -414,6 +417,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf, ...@@ -414,6 +417,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
struct pt_regs *regs, sigset_t *set) struct pt_regs *regs, sigset_t *set)
{ {
struct compat_aux_sigframe __user *aux; struct compat_aux_sigframe __user *aux;
unsigned long psr = pstate_to_compat_psr(regs->pstate);
int err = 0; int err = 0;
__put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err); __put_user_error(regs->regs[0], &sf->uc.uc_mcontext.arm_r0, err);
...@@ -432,7 +436,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf, ...@@ -432,7 +436,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
__put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err); __put_user_error(regs->compat_sp, &sf->uc.uc_mcontext.arm_sp, err);
__put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err); __put_user_error(regs->compat_lr, &sf->uc.uc_mcontext.arm_lr, err);
__put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err); __put_user_error(regs->pc, &sf->uc.uc_mcontext.arm_pc, err);
__put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); __put_user_error(psr, &sf->uc.uc_mcontext.arm_cpsr, err);
__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
/* set the compat FSR WnR */ /* set the compat FSR WnR */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment