mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 12:14:01 +08:00
powerpc: remove partial register save logic
All subarchitectures always save all GPRs to pt_regs interrupt frames now. Remove FULL_REGS and associated bits. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210316104206.407354-11-npiggin@gmail.com
This commit is contained in:
parent
c45ba4f44f
commit
8dc7f0229b
@ -188,29 +188,16 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
|
||||
#ifdef __powerpc64__
|
||||
#define TRAP_FLAGS_MASK 0x10
|
||||
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
||||
#define FULL_REGS(regs) true
|
||||
#define SET_FULL_REGS(regs) do { } while (0)
|
||||
#define CHECK_FULL_REGS(regs) do { } while (0)
|
||||
#define NV_REG_POISON 0xdeadbeefdeadbeefUL
|
||||
#else
|
||||
/*
|
||||
* We use the least-significant bit of the trap field to indicate
|
||||
* whether we have saved the full set of registers, or only a
|
||||
* partial set. A 1 there means the partial set.
|
||||
* On 4xx we use the next bit to indicate whether the exception
|
||||
* On 4xx we use bit 1 in the trap word to indicate whether the exception
|
||||
* is a critical exception (1 means it is).
|
||||
*/
|
||||
#define TRAP_FLAGS_MASK 0x1F
|
||||
#define TRAP_FLAGS_MASK 0x1E
|
||||
#define TRAP(regs) ((regs)->trap & ~TRAP_FLAGS_MASK)
|
||||
#define FULL_REGS(regs) true
|
||||
#define SET_FULL_REGS(regs) do { } while (0)
|
||||
#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0)
|
||||
#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0)
|
||||
#define IS_DEBUG_EXC(regs) (((regs)->trap & 8) != 0)
|
||||
#define NV_REG_POISON 0xdeadbeef
|
||||
#define CHECK_FULL_REGS(regs) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
static __always_inline void set_trap(struct pt_regs *regs, unsigned long val)
|
||||
|
@ -304,12 +304,6 @@ int fix_alignment(struct pt_regs *regs)
|
||||
struct instruction_op op;
|
||||
int r, type;
|
||||
|
||||
/*
|
||||
* We require a complete register set, if not, then our assembly
|
||||
* is broken
|
||||
*/
|
||||
CHECK_FULL_REGS(regs);
|
||||
|
||||
if (is_kernel_addr(regs->nip))
|
||||
r = probe_kernel_read_inst(&instr, (void *)regs->nip);
|
||||
else
|
||||
|
@ -51,7 +51,6 @@ notrace long system_call_exception(long r3, long r4, long r5,
|
||||
if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x))
|
||||
BUG_ON(!(regs->msr & MSR_RI));
|
||||
BUG_ON(!(regs->msr & MSR_PR));
|
||||
BUG_ON(!FULL_REGS(regs));
|
||||
BUG_ON(arch_irq_disabled_regs(regs));
|
||||
|
||||
#ifdef CONFIG_PPC_PKEY
|
||||
@ -365,7 +364,6 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned
|
||||
if (!IS_ENABLED(CONFIG_BOOKE) && !IS_ENABLED(CONFIG_40x))
|
||||
BUG_ON(!(regs->msr & MSR_RI));
|
||||
BUG_ON(!(regs->msr & MSR_PR));
|
||||
BUG_ON(!FULL_REGS(regs));
|
||||
BUG_ON(arch_irq_disabled_regs(regs));
|
||||
CT_WARN_ON(ct_state() == CONTEXT_USER);
|
||||
|
||||
@ -445,7 +443,6 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign
|
||||
unlikely(!(regs->msr & MSR_RI)))
|
||||
unrecoverable_exception(regs);
|
||||
BUG_ON(regs->msr & MSR_PR);
|
||||
BUG_ON(!FULL_REGS(regs));
|
||||
/*
|
||||
* CT_WARN_ON comes here via program_check_exception,
|
||||
* so avoid recursion.
|
||||
|
@ -1448,11 +1448,9 @@ static void print_msr_bits(unsigned long val)
|
||||
#ifdef CONFIG_PPC64
|
||||
#define REG "%016lx"
|
||||
#define REGS_PER_LINE 4
|
||||
#define LAST_VOLATILE 13
|
||||
#else
|
||||
#define REG "%08lx"
|
||||
#define REGS_PER_LINE 8
|
||||
#define LAST_VOLATILE 12
|
||||
#endif
|
||||
|
||||
static void __show_regs(struct pt_regs *regs)
|
||||
@ -1488,8 +1486,6 @@ static void __show_regs(struct pt_regs *regs)
|
||||
if ((i % REGS_PER_LINE) == 0)
|
||||
pr_cont("\nGPR%02d: ", i);
|
||||
pr_cont(REG " ", regs->gpr[i]);
|
||||
if (i == LAST_VOLATILE && !FULL_REGS(regs))
|
||||
break;
|
||||
}
|
||||
pr_cont("\n");
|
||||
/*
|
||||
@ -1692,7 +1688,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
} else {
|
||||
/* user thread */
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
CHECK_FULL_REGS(regs);
|
||||
*childregs = *regs;
|
||||
if (usp)
|
||||
childregs->gpr[1] = usp;
|
||||
@ -1797,13 +1792,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
||||
regs->ccr = 0;
|
||||
regs->gpr[1] = sp;
|
||||
|
||||
/*
|
||||
* We have just cleared all the nonvolatile GPRs, so make
|
||||
* FULL_REGS(regs) return true. This is necessary to allow
|
||||
* ptrace to examine the thread immediately after exec.
|
||||
*/
|
||||
SET_FULL_REGS(regs);
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
regs->mq = 0;
|
||||
regs->nip = start;
|
||||
|
@ -221,17 +221,9 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset,
|
||||
#ifdef CONFIG_PPC64
|
||||
struct membuf to_softe = membuf_at(&to, offsetof(struct pt_regs, softe));
|
||||
#endif
|
||||
int i;
|
||||
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (!FULL_REGS(target->thread.regs)) {
|
||||
/* We have a partial register set. Fill 14-31 with bogus values */
|
||||
for (i = 14; i < 32; i++)
|
||||
target->thread.regs->gpr[i] = NV_REG_POISON;
|
||||
}
|
||||
|
||||
membuf_write(&to, target->thread.regs, sizeof(struct user_pt_regs));
|
||||
|
||||
membuf_store(&to_msr, get_user_msr(target));
|
||||
@ -252,8 +244,6 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
CHECK_FULL_REGS(target->thread.regs);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
target->thread.regs,
|
||||
0, PT_MSR * sizeof(reg));
|
||||
@ -729,19 +719,9 @@ static int gpr32_get(struct task_struct *target,
|
||||
const struct user_regset *regset,
|
||||
struct membuf to)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
if (!FULL_REGS(target->thread.regs)) {
|
||||
/*
|
||||
* We have a partial register set.
|
||||
* Fill 14-31 with bogus values.
|
||||
*/
|
||||
for (i = 14; i < 32; i++)
|
||||
target->thread.regs->gpr[i] = NV_REG_POISON;
|
||||
}
|
||||
return gpr32_get_common(target, regset, to,
|
||||
&target->thread.regs->gpr[0]);
|
||||
}
|
||||
@ -754,7 +734,6 @@ static int gpr32_set(struct task_struct *target,
|
||||
if (target->thread.regs == NULL)
|
||||
return -EIO;
|
||||
|
||||
CHECK_FULL_REGS(target->thread.regs);
|
||||
return gpr32_set_common(target, regset, pos, count, kbuf, ubuf,
|
||||
&target->thread.regs->gpr[0]);
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0)
|
||||
ret = ptrace_get_reg(child, (int) index, &tmp);
|
||||
else
|
||||
@ -81,7 +80,6 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0)
|
||||
ret = ptrace_put_reg(child, index, data);
|
||||
else
|
||||
|
@ -83,7 +83,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
if ((addr & 3) || (index > PT_FPSCR32))
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0) {
|
||||
ret = ptrace_get_reg(child, index, &tmp);
|
||||
if (ret)
|
||||
@ -133,7 +132,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
if ((addr & 3) || numReg > PT_FPSCR)
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (numReg >= PT_FPR0) {
|
||||
flush_fp_to_thread(child);
|
||||
/* get 64 bit FPR */
|
||||
@ -187,7 +185,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
if ((addr & 3) || (index > PT_FPSCR32))
|
||||
break;
|
||||
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (index < PT_FPR0) {
|
||||
ret = ptrace_put_reg(child, index, data);
|
||||
} else {
|
||||
@ -226,7 +223,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||
*/
|
||||
if ((addr & 3) || (numReg > PT_FPSCR))
|
||||
break;
|
||||
CHECK_FULL_REGS(child->thread.regs);
|
||||
if (numReg < PT_FPR0) {
|
||||
unsigned long freg;
|
||||
ret = ptrace_get_reg(child, numReg, &freg);
|
||||
|
@ -94,8 +94,6 @@ __unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
|
||||
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
|
||||
int val, i;
|
||||
|
||||
WARN_ON(!FULL_REGS(regs));
|
||||
|
||||
for (i = 0; i <= PT_RESULT; i ++) {
|
||||
/* Force usr to alway see softe as 1 (interrupts enabled) */
|
||||
if (i == PT_SOFTE)
|
||||
@ -147,7 +145,6 @@ failed:
|
||||
static __always_inline int
|
||||
__unsafe_save_general_regs(struct pt_regs *regs, struct mcontext __user *frame)
|
||||
{
|
||||
WARN_ON(!FULL_REGS(regs));
|
||||
unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed);
|
||||
return 0;
|
||||
|
||||
|
@ -172,7 +172,6 @@ static long notrace __unsafe_setup_sigcontext(struct sigcontext __user *sc,
|
||||
}
|
||||
#endif /* CONFIG_VSX */
|
||||
unsafe_put_user(&sc->gp_regs, &sc->regs, efault_out);
|
||||
WARN_ON(!FULL_REGS(regs));
|
||||
unsafe_copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE, efault_out);
|
||||
unsafe_put_user(msr, &sc->gp_regs[PT_MSR], efault_out);
|
||||
unsafe_put_user(softe, &sc->gp_regs[PT_SOFTE], efault_out);
|
||||
@ -309,7 +308,6 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
|
||||
|
||||
err |= __put_user(&sc->gp_regs, &sc->regs);
|
||||
err |= __put_user(&tm_sc->gp_regs, &tm_sc->regs);
|
||||
WARN_ON(!FULL_REGS(regs));
|
||||
err |= __copy_to_user(&tm_sc->gp_regs, regs, GP_REGS_SIZE);
|
||||
err |= __copy_to_user(&sc->gp_regs,
|
||||
&tsk->thread.ckpt_regs, GP_REGS_SIZE);
|
||||
|
@ -1318,7 +1318,6 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
|
||||
if (!user_mode(regs))
|
||||
return -EINVAL;
|
||||
CHECK_FULL_REGS(regs);
|
||||
|
||||
if (get_user(instword, (u32 __user *)(regs->nip)))
|
||||
return -EFAULT;
|
||||
|
@ -1401,10 +1401,6 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Following cases refer to regs->gpr[], so we need all regs */
|
||||
if (!FULL_REGS(regs))
|
||||
return -1;
|
||||
|
||||
rd = (word >> 21) & 0x1f;
|
||||
ra = (word >> 16) & 0x1f;
|
||||
rb = (word >> 11) & 0x1f;
|
||||
|
@ -1815,25 +1815,16 @@ static void prregs(struct pt_regs *fp)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
if (FULL_REGS(fp)) {
|
||||
for (n = 0; n < 16; ++n)
|
||||
printf("R%.2d = "REG" R%.2d = "REG"\n",
|
||||
n, fp->gpr[n], n+16, fp->gpr[n+16]);
|
||||
} else {
|
||||
for (n = 0; n < 7; ++n)
|
||||
printf("R%.2d = "REG" R%.2d = "REG"\n",
|
||||
n, fp->gpr[n], n+7, fp->gpr[n+7]);
|
||||
}
|
||||
#define R_PER_LINE 2
|
||||
#else
|
||||
for (n = 0; n < 32; ++n) {
|
||||
printf("R%.2d = %.8lx%s", n, fp->gpr[n],
|
||||
(n & 3) == 3? "\n": " ");
|
||||
if (n == 12 && !FULL_REGS(fp)) {
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#define R_PER_LINE 4
|
||||
#endif
|
||||
|
||||
for (n = 0; n < 32; ++n) {
|
||||
printf("R%.2d = "REG"%s", n, fp->gpr[n],
|
||||
(n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : " ");
|
||||
}
|
||||
|
||||
printf("pc = ");
|
||||
xmon_print_symbol(fp->nip, " ", "\n");
|
||||
if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
|
||||
|
Loading…
Reference in New Issue
Block a user