mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
powerpc fixes for 5.12 #6
Fix an oops triggered by ptrace when CONFIG_PPC_FPU_REGS=n. Fix an oops on sigreturn when the VDSO is unmapped on 32-bit. Fix vdso_wrapper.o not being rebuilt everytime vdso.so is rebuilt. Thanks to Christophe Leroy. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmBxsh4THG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgBzUD/9XtNJDggNNOYgS10ICO7MgzRsUoTH3 U7Y7ZkgD/tDou5ZJ+YD5amJgQ4UFpAPHF/cvvrFVk0MND2TyRp2SXpAiCSELwh/w k24WPxszQzs8Z8m9/GTonNxF10g05kcGzZJLqlCiXuSuH2R8sGDCGqWuls+hJHSv ZSQkG3mVfqnNqgueDSERwcpr+ReS7Elsa3qZTAhGtllRvSlC/xZaB4KOIu7oLU9u YTYnoPvbQZOv37zDTDqd5VF+kwNW4rcMG0E2hwmsqJwUE9Etf2g9L0VNATbSZZSb ooBkWpwonmCeis1ttUFS3mVVJm3C9YNhT7/b08n4dlyc2cO/H6dXWfmeEDkstCQ1 KgCEzuRR1+ZZqX795mwxzzjwp3GTBTRlcTd4CfruMdp5cytHl6cOWl2+awsv1nZM VHnoRpV9Uozx+zNIJAASCLZsTouyp37cNSuLWd0TTgPTXkm6NqlqJpNTA4zgeZh6 BvI9NNX0LYiaiofIUsBxxQhJ6JFhjDh0gTt2rHKLP/lMy2iNhh0EoxlByA7lNU/K fR6uS2NsqABafzlNaW/0DF3n31UzPP5oCUjEw3vzaSyO9qx3SRNiatpHwbvBfp0Y SJLZy/MALAIV8pq0pgI8G/8EJqpPHK/nKJvjsK6SMoV6udWWE5+KsiR9AD/rMVNS wMeaz9+TkQVFUQ== =gIsc -----END PGP SIGNATURE----- Merge tag 'powerpc-5.12-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fixes from Michael Ellerman: "Some some more powerpc fixes for 5.12: - Fix an oops triggered by ptrace when CONFIG_PPC_FPU_REGS=n - Fix an oops on sigreturn when the VDSO is unmapped on 32-bit - Fix vdso_wrapper.o not being rebuilt everytime vdso.so is rebuilt Thanks to Christophe Leroy" * tag 'powerpc-5.12-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/vdso: Make sure vdso_wrapper.o is rebuilt everytime vdso.so is rebuilt powerpc/signal32: Fix Oops on sigreturn with unmapped VDSO powerpc/ptrace: Don't return error when getting/setting FP regs without CONFIG_PPC_FPU_REGS
This commit is contained in:
commit
95c7b07551
7 changed files with 32 additions and 30 deletions
|
@ -191,3 +191,7 @@ $(obj)/prom_init_check: $(src)/prom_init_check.sh $(obj)/prom_init.o FORCE
|
|||
targets += prom_init_check
|
||||
|
||||
clean-files := vmlinux.lds
|
||||
|
||||
# Force dependency (incbin is bad)
|
||||
$(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg
|
||||
$(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
obj-y += ptrace.o ptrace-view.o
|
||||
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o
|
||||
obj-y += ptrace-fpu.o
|
||||
obj-$(CONFIG_COMPAT) += ptrace32.o
|
||||
obj-$(CONFIG_VSX) += ptrace-vsx.o
|
||||
ifneq ($(CONFIG_VSX),y)
|
||||
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o
|
||||
obj-y += ptrace-novsx.o
|
||||
endif
|
||||
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
|
||||
obj-$(CONFIG_SPE) += ptrace-spe.o
|
||||
|
|
|
@ -165,22 +165,8 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
|
|||
extern const struct user_regset_view user_ppc_native_view;
|
||||
|
||||
/* ptrace-fpu */
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
|
||||
#else
|
||||
static inline int
|
||||
ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ptrace-(no)adv */
|
||||
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
|
||||
|
|
|
@ -8,32 +8,42 @@
|
|||
|
||||
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
#endif
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
|
||||
else
|
||||
*data = child->thread.fp_state.fpscr;
|
||||
#else
|
||||
*data = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
unsigned int fpidx = index - PT_FPR0;
|
||||
#endif
|
||||
|
||||
if (index > PT_FPSCR)
|
||||
return -EIO;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
flush_fp_to_thread(child);
|
||||
if (fpidx < (PT_FPSCR - PT_FPR0))
|
||||
memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
|
||||
else
|
||||
child->thread.fp_state.fpscr = data;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
int fpr_get(struct task_struct *target, const struct user_regset *regset,
|
||||
struct membuf to)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
|
||||
offsetof(struct thread_fp_state, fpr[32]));
|
||||
|
||||
flush_fp_to_thread(target);
|
||||
|
||||
return membuf_write(&to, &target->thread.fp_state, 33 * sizeof(u64));
|
||||
#else
|
||||
return membuf_write(&to, &empty_zero_page, 33 * sizeof(u64));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -46,6 +50,7 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
|
|||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
|
||||
offsetof(struct thread_fp_state, fpr[32]));
|
||||
|
||||
|
@ -53,4 +58,7 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
|
|||
|
||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.fp_state, 0, -1);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -522,13 +522,11 @@ static const struct user_regset native_regsets[] = {
|
|||
.size = sizeof(long), .align = sizeof(long),
|
||||
.regset_get = gpr_get, .set = gpr_set
|
||||
},
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
[REGSET_FPR] = {
|
||||
.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
|
||||
.size = sizeof(double), .align = sizeof(double),
|
||||
.regset_get = fpr_get, .set = fpr_set
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
[REGSET_VMX] = {
|
||||
.core_note_type = NT_PPC_VMX, .n = 34,
|
||||
|
|
|
@ -775,7 +775,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
else
|
||||
prepare_save_user_regs(1);
|
||||
|
||||
if (!user_write_access_begin(frame, sizeof(*frame)))
|
||||
if (!user_access_begin(frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
||||
/* Put the siginfo & fill in most of the ucontext */
|
||||
|
@ -809,17 +809,15 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
unsafe_put_user(PPC_INST_ADDI + __NR_rt_sigreturn, &mctx->mc_pad[0],
|
||||
failed);
|
||||
unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
|
||||
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
|
||||
}
|
||||
unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed);
|
||||
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
if (copy_siginfo_to_user(&frame->info, &ksig->info))
|
||||
goto badframe;
|
||||
|
||||
if (tramp == (unsigned long)mctx->mc_pad)
|
||||
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||
|
||||
regs->link = tramp;
|
||||
|
||||
#ifdef CONFIG_PPC_FPU_REGS
|
||||
|
@ -844,7 +842,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
badframe:
|
||||
signal_fault(tsk, regs, "handle_rt_signal32", frame);
|
||||
|
@ -879,7 +877,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
else
|
||||
prepare_save_user_regs(1);
|
||||
|
||||
if (!user_write_access_begin(frame, sizeof(*frame)))
|
||||
if (!user_access_begin(frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
sc = (struct sigcontext __user *) &frame->sctx;
|
||||
|
||||
|
@ -908,11 +906,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
/* Set up the sigreturn trampoline: li r0,sigret; sc */
|
||||
unsafe_put_user(PPC_INST_ADDI + __NR_sigreturn, &mctx->mc_pad[0], failed);
|
||||
unsafe_put_user(PPC_INST_SC, &mctx->mc_pad[1], failed);
|
||||
asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0]));
|
||||
}
|
||||
user_write_access_end();
|
||||
|
||||
if (tramp == (unsigned long)mctx->mc_pad)
|
||||
flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
|
||||
user_access_end();
|
||||
|
||||
regs->link = tramp;
|
||||
|
||||
|
@ -935,7 +931,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
user_write_access_end();
|
||||
user_access_end();
|
||||
|
||||
badframe:
|
||||
signal_fault(tsk, regs, "handle_signal32", frame);
|
||||
|
|
Loading…
Reference in a new issue