Skip to content

Commit 01af50a

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas: - arm64 stacktrace: address some fallout from the recent changes to unwinding across exception boundaries - Ensure the arm64 signal delivery failure is recoverable - only override the return registers after all the user accesses took place - Fix the arm64 kselftest access to SVCR - only when SME is detected * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: kselftest/arm64: abi: fix SVCR detection arm64: signal: Ensure signal delivery failure is recoverable arm64: stacktrace: Don't WARN when unwinding other tasks arm64: stacktrace: Skip reporting LR at exception boundaries
2 parents a5b3d5d + ce03573 commit 01af50a

File tree

3 files changed

+55
-57
lines changed

3 files changed

+55
-57
lines changed

arch/arm64/kernel/signal.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,10 +1462,33 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
14621462
struct rt_sigframe_user_layout *user, int usig)
14631463
{
14641464
__sigrestore_t sigtramp;
1465+
int err;
1466+
1467+
if (ksig->ka.sa.sa_flags & SA_RESTORER)
1468+
sigtramp = ksig->ka.sa.sa_restorer;
1469+
else
1470+
sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
1471+
1472+
err = gcs_signal_entry(sigtramp, ksig);
1473+
if (err)
1474+
return err;
1475+
1476+
/*
1477+
* We must not fail from this point onwards. We are going to update
1478+
* registers, including SP, in order to invoke the signal handler. If
1479+
* we failed and attempted to deliver a nested SIGSEGV to a handler
1480+
* after that point, the subsequent sigreturn would end up restoring
1481+
* the (partial) state for the original signal handler.
1482+
*/
14651483

14661484
regs->regs[0] = usig;
1485+
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
1486+
regs->regs[1] = (unsigned long)&user->sigframe->info;
1487+
regs->regs[2] = (unsigned long)&user->sigframe->uc;
1488+
}
14671489
regs->sp = (unsigned long)user->sigframe;
14681490
regs->regs[29] = (unsigned long)&user->next_frame->fp;
1491+
regs->regs[30] = (unsigned long)sigtramp;
14691492
regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
14701493

14711494
/*
@@ -1506,14 +1529,7 @@ static int setup_return(struct pt_regs *regs, struct ksignal *ksig,
15061529
sme_smstop();
15071530
}
15081531

1509-
if (ksig->ka.sa.sa_flags & SA_RESTORER)
1510-
sigtramp = ksig->ka.sa.sa_restorer;
1511-
else
1512-
sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
1513-
1514-
regs->regs[30] = (unsigned long)sigtramp;
1515-
1516-
return gcs_signal_entry(sigtramp, ksig);
1532+
return 0;
15171533
}
15181534

15191535
static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
@@ -1537,14 +1553,16 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
15371553

15381554
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
15391555
err |= setup_sigframe(&user, regs, set, &ua_state);
1540-
if (err == 0) {
1556+
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
1557+
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
1558+
1559+
if (err == 0)
15411560
err = setup_return(regs, ksig, &user, usig);
1542-
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
1543-
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
1544-
regs->regs[1] = (unsigned long)&frame->info;
1545-
regs->regs[2] = (unsigned long)&frame->uc;
1546-
}
1547-
}
1561+
1562+
/*
1563+
* We must not fail if setup_return() succeeded - see comment at the
1564+
* beginning of setup_return().
1565+
*/
15481566

15491567
if (err == 0)
15501568
set_handler_user_access_state();

arch/arm64/kernel/stacktrace.c

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ enum kunwind_source {
2626
KUNWIND_SOURCE_CALLER,
2727
KUNWIND_SOURCE_TASK,
2828
KUNWIND_SOURCE_REGS_PC,
29-
KUNWIND_SOURCE_REGS_LR,
3029
};
3130

3231
union unwind_flags {
@@ -138,8 +137,10 @@ kunwind_recover_return_address(struct kunwind_state *state)
138137
orig_pc = ftrace_graph_ret_addr(state->task, &state->graph_idx,
139138
state->common.pc,
140139
(void *)state->common.fp);
141-
if (WARN_ON_ONCE(state->common.pc == orig_pc))
140+
if (state->common.pc == orig_pc) {
141+
WARN_ON_ONCE(state->task == current);
142142
return -EINVAL;
143+
}
143144
state->common.pc = orig_pc;
144145
state->flags.fgraph = 1;
145146
}
@@ -178,23 +179,8 @@ int kunwind_next_regs_pc(struct kunwind_state *state)
178179
state->regs = regs;
179180
state->common.pc = regs->pc;
180181
state->common.fp = regs->regs[29];
181-
state->source = KUNWIND_SOURCE_REGS_PC;
182-
return 0;
183-
}
184-
185-
static __always_inline int
186-
kunwind_next_regs_lr(struct kunwind_state *state)
187-
{
188-
/*
189-
* The stack for the regs was consumed by kunwind_next_regs_pc(), so we
190-
* cannot consume that again here, but we know the regs are safe to
191-
* access.
192-
*/
193-
state->common.pc = state->regs->regs[30];
194-
state->common.fp = state->regs->regs[29];
195182
state->regs = NULL;
196-
state->source = KUNWIND_SOURCE_REGS_LR;
197-
183+
state->source = KUNWIND_SOURCE_REGS_PC;
198184
return 0;
199185
}
200186

@@ -215,12 +201,12 @@ kunwind_next_frame_record_meta(struct kunwind_state *state)
215201
case FRAME_META_TYPE_FINAL:
216202
if (meta == &task_pt_regs(tsk)->stackframe)
217203
return -ENOENT;
218-
WARN_ON_ONCE(1);
204+
WARN_ON_ONCE(tsk == current);
219205
return -EINVAL;
220206
case FRAME_META_TYPE_PT_REGS:
221207
return kunwind_next_regs_pc(state);
222208
default:
223-
WARN_ON_ONCE(1);
209+
WARN_ON_ONCE(tsk == current);
224210
return -EINVAL;
225211
}
226212
}
@@ -274,11 +260,8 @@ kunwind_next(struct kunwind_state *state)
274260
case KUNWIND_SOURCE_FRAME:
275261
case KUNWIND_SOURCE_CALLER:
276262
case KUNWIND_SOURCE_TASK:
277-
case KUNWIND_SOURCE_REGS_LR:
278-
err = kunwind_next_frame_record(state);
279-
break;
280263
case KUNWIND_SOURCE_REGS_PC:
281-
err = kunwind_next_regs_lr(state);
264+
err = kunwind_next_frame_record(state);
282265
break;
283266
default:
284267
err = -EINVAL;
@@ -436,7 +419,6 @@ static const char *state_source_string(const struct kunwind_state *state)
436419
case KUNWIND_SOURCE_CALLER: return "C";
437420
case KUNWIND_SOURCE_TASK: return "T";
438421
case KUNWIND_SOURCE_REGS_PC: return "P";
439-
case KUNWIND_SOURCE_REGS_LR: return "L";
440422
default: return "U";
441423
}
442424
}

tools/testing/selftests/arm64/abi/syscall-abi-asm.S

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,31 @@ do_syscall:
8181
stp x27, x28, [sp, #96]
8282

8383
// Set SVCR if we're doing SME
84-
cbz x1, 1f
84+
cbz x1, load_gpr
8585
adrp x2, svcr_in
8686
ldr x2, [x2, :lo12:svcr_in]
8787
msr S3_3_C4_C2_2, x2
88-
1:
8988

9089
// Load ZA and ZT0 if enabled - uses x12 as scratch due to SME LDR
91-
tbz x2, #SVCR_ZA_SHIFT, 1f
90+
tbz x2, #SVCR_ZA_SHIFT, load_gpr
9291
mov w12, #0
9392
ldr x2, =za_in
94-
2: _ldr_za 12, 2
93+
1: _ldr_za 12, 2
9594
add x2, x2, x1
9695
add x12, x12, #1
9796
cmp x1, x12
98-
bne 2b
97+
bne 1b
9998

10099
// ZT0
101100
mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1
102101
ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
103102
#ID_AA64SMFR0_EL1_SMEver_WIDTH
104-
cbz x2, 1f
103+
cbz x2, load_gpr
105104
adrp x2, zt_in
106105
add x2, x2, :lo12:zt_in
107106
_ldr_zt 2
108-
1:
109107

108+
load_gpr:
110109
// Load GPRs x8-x28, and save our SP/FP for later comparison
111110
ldr x2, =gpr_in
112111
add x2, x2, #64
@@ -125,9 +124,9 @@ do_syscall:
125124
str x30, [x2], #8 // LR
126125

127126
// Load FPRs if we're not doing neither SVE nor streaming SVE
128-
cbnz x0, 1f
127+
cbnz x0, check_sve_in
129128
ldr x2, =svcr_in
130-
tbnz x2, #SVCR_SM_SHIFT, 1f
129+
tbnz x2, #SVCR_SM_SHIFT, check_sve_in
131130

132131
ldr x2, =fpr_in
133132
ldp q0, q1, [x2]
@@ -148,8 +147,8 @@ do_syscall:
148147
ldp q30, q31, [x2, #16 * 30]
149148

150149
b 2f
151-
1:
152150

151+
check_sve_in:
153152
// Load the SVE registers if we're doing SVE/SME
154153

155154
ldr x2, =z_in
@@ -256,32 +255,31 @@ do_syscall:
256255
stp q30, q31, [x2, #16 * 30]
257256

258257
// Save SVCR if we're doing SME
259-
cbz x1, 1f
258+
cbz x1, check_sve_out
260259
mrs x2, S3_3_C4_C2_2
261260
adrp x3, svcr_out
262261
str x2, [x3, :lo12:svcr_out]
263-
1:
264262

265263
// Save ZA if it's enabled - uses x12 as scratch due to SME STR
266-
tbz x2, #SVCR_ZA_SHIFT, 1f
264+
tbz x2, #SVCR_ZA_SHIFT, check_sve_out
267265
mov w12, #0
268266
ldr x2, =za_out
269-
2: _str_za 12, 2
267+
1: _str_za 12, 2
270268
add x2, x2, x1
271269
add x12, x12, #1
272270
cmp x1, x12
273-
bne 2b
271+
bne 1b
274272

275273
// ZT0
276274
mrs x2, S3_0_C0_C4_5 // ID_AA64SMFR0_EL1
277275
ubfx x2, x2, #ID_AA64SMFR0_EL1_SMEver_SHIFT, \
278276
#ID_AA64SMFR0_EL1_SMEver_WIDTH
279-
cbz x2, 1f
277+
cbz x2, check_sve_out
280278
adrp x2, zt_out
281279
add x2, x2, :lo12:zt_out
282280
_str_zt 2
283-
1:
284281

282+
check_sve_out:
285283
// Save the SVE state if we have some
286284
cbz x0, 1f
287285

0 commit comments

Comments
 (0)