Skip to content

Commit 3618250

Browse files
chleroympe
authored andcommitted
powerpc/ptrace: Don't return error when getting/setting FP regs without CONFIG_PPC_FPU_REGS
An #ifdef CONFIG_PPC_FPU_REGS is missing in arch_ptrace() leading to the following Oops because [REGSET_FPR] entry is not initialised in native_regsets[]. [ 41.917608] BUG: Unable to handle kernel instruction fetch [ 41.922849] Faulting instruction address: 0xff8fd228 [ 41.927760] Oops: Kernel access of bad area, sig: 11 [Rust-for-Linux#1] [ 41.933089] BE PAGE_SIZE=4K PREEMPT CMPC885 [ 41.940753] Modules linked in: [ 41.943768] CPU: 0 PID: 366 Comm: gdb Not tainted 5.12.0-rc5-s3k-dev-01666-g7aac86a0f057-dirty #4835 [ 41.952800] NIP: ff8fd228 LR: c004d9e0 CTR: ff8fd228 [ 41.957790] REGS: caae9df0 TRAP: 0400 Not tainted (5.12.0-rc5-s3k-dev-01666-g7aac86a0f057-dirty) [ 41.966741] MSR: 40009032 <EE,ME,IR,DR,RI> CR: 82004248 XER: 20000000 [ 41.973540] [ 41.973540] GPR00: c004d9b4 caae9eb0 c1b64f60 c1b64520 c0713cd4 caae9eb c1bacdfc 00000004 [ 41.973540] GPR08: 00000200 ff8fd228 c1bac700 00001032 28004242 1061aaf4 00000001 106d64a0 [ 41.973540] GPR16: 00000000 00000000 7fa0a774 10610000 7fa0aef9 00000000 10610000 7fa0a538 [ 41.973540] GPR24: 7fa0a580 7fa0a570 c1bacc00 c1b64520 c1bacc00 caae9ee8 00000108 c0713cd4 [ 42.009685] NIP [ff8fd228] 0xff8fd228 [ 42.013300] LR [c004d9e0] __regset_get+0x100/0x124 [ 42.018036] Call Trace: [ 42.020443] [caae9eb0] [c004d9b4] __regset_get+0xd4/0x124 (unreliable) [ 42.026899] [caae9ee0] [c004da94] copy_regset_to_user+0x5c/0xb0 [ 42.032751] [caae9f10] [c002f640] sys_ptrace+0xe4/0x588 [ 42.037915] [caae9f30] [c0011010] ret_from_syscall+0x0/0x28 [ 42.043422] --- interrupt: c00 at 0xfd1f8e4 [ 42.047553] NIP: 0fd1f8e4 LR: 1004a688 CTR: 00000000 [ 42.052544] REGS: caae9f40 TRAP: 0c00 Not tainted (5.12.0-rc5-s3k-dev-01666-g7aac86a0f057-dirty) [ 42.061494] MSR: 0000d032 <EE,PR,ME,IR,DR,RI> CR: 48004442 XER: 00000000 [ 42.068551] [ 42.068551] GPR00: 0000001a 7fa0a040 77dad7e0 0000000 00000170 00000000 7fa0a078 00000004 [ 42.068551] GPR08: 00000000 108deb88 108dda40 106d6010 44004442 1061aaf4 00000001 106d64a0 [ 42.068551] GPR16: 00000000 00000000 7fa0a774 10610000 7fa0aef9 00000000 10610000 7fa0a538 [ 42.068551] GPR24: 7fa0a580 7fa0a570 1078fe00 1078fd70 1078fd70 00000170 0fdd3244 0000000d [ 42.104696] NIP [0fd1f8e4] 0xfd1f8e4 [ 42.108225] LR [1004a688] 0x1004a688 [ 42.111753] --- interrupt: c00 [ 42.114768] Instruction dump: [ 42.117698] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX [ 42.125443] XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX [ 42.133195] ---[ end trace d35616f22ab2100c ]--- Adding the missing #ifdef is not good because gdb doesn't like getting an error when getting registers. Instead, make ptrace return 0s when CONFIG_PPC_FPU_REGS is not set. Fixes: b6254ce ("powerpc/signal: Don't manage floating point regs when no FPU") Cc: [email protected] Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/9121a44a2d50ba1af18d8aa5ada06c9a3bea8afd.1617200085.git.christophe.leroy@csgroup.eu
1 parent 53f1d31 commit 3618250

File tree

5 files changed

+20
-18
lines changed

5 files changed

+20
-18
lines changed

arch/powerpc/kernel/ptrace/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
77

88
obj-y += ptrace.o ptrace-view.o
9-
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o
9+
obj-y += ptrace-fpu.o
1010
obj-$(CONFIG_COMPAT) += ptrace32.o
1111
obj-$(CONFIG_VSX) += ptrace-vsx.o
1212
ifneq ($(CONFIG_VSX),y)
13-
obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o
13+
obj-y += ptrace-novsx.o
1414
endif
1515
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
1616
obj-$(CONFIG_SPE) += ptrace-spe.o

arch/powerpc/kernel/ptrace/ptrace-decl.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,22 +165,8 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
165165
extern const struct user_regset_view user_ppc_native_view;
166166

167167
/* ptrace-fpu */
168-
#ifdef CONFIG_PPC_FPU_REGS
169168
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
170169
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
171-
#else
172-
static inline int
173-
ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
174-
{
175-
return -EIO;
176-
}
177-
178-
static inline int
179-
ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
180-
{
181-
return -EIO;
182-
}
183-
#endif
184170

185171
/* ptrace-(no)adv */
186172
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);

arch/powerpc/kernel/ptrace/ptrace-fpu.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,42 @@
88

99
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
1010
{
11+
#ifdef CONFIG_PPC_FPU_REGS
1112
unsigned int fpidx = index - PT_FPR0;
13+
#endif
1214

1315
if (index > PT_FPSCR)
1416
return -EIO;
1517

18+
#ifdef CONFIG_PPC_FPU_REGS
1619
flush_fp_to_thread(child);
1720
if (fpidx < (PT_FPSCR - PT_FPR0))
1821
memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
1922
else
2023
*data = child->thread.fp_state.fpscr;
24+
#else
25+
*data = 0;
26+
#endif
2127

2228
return 0;
2329
}
2430

2531
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
2632
{
33+
#ifdef CONFIG_PPC_FPU_REGS
2734
unsigned int fpidx = index - PT_FPR0;
35+
#endif
2836

2937
if (index > PT_FPSCR)
3038
return -EIO;
3139

40+
#ifdef CONFIG_PPC_FPU_REGS
3241
flush_fp_to_thread(child);
3342
if (fpidx < (PT_FPSCR - PT_FPR0))
3443
memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
3544
else
3645
child->thread.fp_state.fpscr = data;
46+
#endif
3747

3848
return 0;
3949
}

arch/powerpc/kernel/ptrace/ptrace-novsx.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@
2121
int fpr_get(struct task_struct *target, const struct user_regset *regset,
2222
struct membuf to)
2323
{
24+
#ifdef CONFIG_PPC_FPU_REGS
2425
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
2526
offsetof(struct thread_fp_state, fpr[32]));
2627

2728
flush_fp_to_thread(target);
2829

2930
return membuf_write(&to, &target->thread.fp_state, 33 * sizeof(u64));
31+
#else
32+
return membuf_write(&to, &empty_zero_page, 33 * sizeof(u64));
33+
#endif
3034
}
3135

3236
/*
@@ -46,11 +50,15 @@ int fpr_set(struct task_struct *target, const struct user_regset *regset,
4650
unsigned int pos, unsigned int count,
4751
const void *kbuf, const void __user *ubuf)
4852
{
53+
#ifdef CONFIG_PPC_FPU_REGS
4954
BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
5055
offsetof(struct thread_fp_state, fpr[32]));
5156

5257
flush_fp_to_thread(target);
5358

5459
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
5560
&target->thread.fp_state, 0, -1);
61+
#else
62+
return 0;
63+
#endif
5664
}

arch/powerpc/kernel/ptrace/ptrace-view.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,13 +522,11 @@ static const struct user_regset native_regsets[] = {
522522
.size = sizeof(long), .align = sizeof(long),
523523
.regset_get = gpr_get, .set = gpr_set
524524
},
525-
#ifdef CONFIG_PPC_FPU_REGS
526525
[REGSET_FPR] = {
527526
.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
528527
.size = sizeof(double), .align = sizeof(double),
529528
.regset_get = fpr_get, .set = fpr_set
530529
},
531-
#endif
532530
#ifdef CONFIG_ALTIVEC
533531
[REGSET_VMX] = {
534532
.core_note_type = NT_PPC_VMX, .n = 34,

0 commit comments

Comments
 (0)