]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: compat: map SPSR_ELx<->PSR for signals
authorMark Rutland <mark.rutland@arm.com>
Thu, 5 Jul 2018 14:16:50 +0000 (15:16 +0100)
committerWill Deacon <will.deacon@arm.com>
Thu, 5 Jul 2018 16:24:13 +0000 (17:24 +0100)
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: Mark Rutland <mark.rutland@arm.com>
Fixes: 7206dc93a58fb764 ("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: Will Deacon <will.deacon@arm.com>
arch/arm64/kernel/signal32.c

index 77b91f478995fd3b0a881bfa80511337d9bc33b5..12aec0a6637696c15bb8b57035e8b15cf2b33dad 100644 (file)
@@ -243,6 +243,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
        int err;
        sigset_t set;
        struct compat_aux_sigframe __user *aux;
+       unsigned long psr;
 
        err = get_sigset_t(&set, &sf->uc.uc_sigmask);
        if (err == 0) {
@@ -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_lr, &sf->uc.uc_mcontext.arm_lr, 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.
@@ -414,6 +417,7 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
                                 struct pt_regs *regs, sigset_t *set)
 {
        struct compat_aux_sigframe __user *aux;
+       unsigned long psr = pstate_to_compat_psr(regs->pstate);
        int err = 0;
 
        __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,
        __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->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);
        /* set the compat FSR WnR */