Skip to content

Commit 5e36c31

Browse files
committed
Automatic merge of 'fixes-test' into merge-test (2023-09-14 23:55)
2 parents cf3f655 + 2ca9ece commit 5e36c31

File tree

4 files changed

+58
-23
lines changed

4 files changed

+58
-23
lines changed

arch/powerpc/kernel/hw_breakpoint.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
230230
struct arch_hw_breakpoint *info;
231231
int i;
232232

233+
preempt_disable();
234+
233235
for (i = 0; i < nr_wp_slots(); i++) {
234236
struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);
235237

236238
if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))
237239
goto reset;
238240
}
239-
return;
241+
goto out;
240242

241243
reset:
242244
regs_set_return_msr(regs, regs->msr & ~MSR_SE);
@@ -245,6 +247,9 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
245247
__set_breakpoint(i, info);
246248
info->perf_single_step = false;
247249
}
250+
251+
out:
252+
preempt_enable();
248253
}
249254

250255
static bool is_larx_stcx_instr(int type)
@@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp,
363368
}
364369
}
365370

371+
/*
372+
* Handle a DABR or DAWR exception.
373+
*
374+
* Called in atomic context.
375+
*/
366376
int hw_breakpoint_handler(struct die_args *args)
367377
{
368378
bool err = false;
@@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);
490500

491501
/*
492502
* Handle single-step exceptions following a DABR hit.
503+
*
504+
* Called in atomic context.
493505
*/
494506
static int single_step_dabr_instruction(struct die_args *args)
495507
{
@@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);
541553

542554
/*
543555
* Handle debug exception notifications.
556+
*
557+
* Called in atomic context.
544558
*/
545559
int hw_breakpoint_exceptions_notify(
546560
struct notifier_block *unused, unsigned long val, void *data)

arch/powerpc/kernel/hw_breakpoint_constraints.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
131131
int *type, int *size, unsigned long *ea)
132132
{
133133
struct instruction_op op;
134+
int err;
134135

135-
if (__get_user_instr(*instr, (void __user *)regs->nip))
136+
pagefault_disable();
137+
err = __get_user_instr(*instr, (void __user *)regs->nip);
138+
pagefault_enable();
139+
140+
if (err)
136141
return;
137142

138143
analyse_instr(&op, regs, *instr);

arch/powerpc/kernel/traps.c

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,23 +1512,11 @@ static void do_program_check(struct pt_regs *regs)
15121512
return;
15131513
}
15141514

1515-
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) {
1516-
ppc_inst_t insn;
1517-
1518-
if (get_user_instr(insn, (void __user *)regs->nip)) {
1519-
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
1520-
return;
1521-
}
1522-
1523-
if (ppc_inst_primary_opcode(insn) == 31 &&
1524-
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
1525-
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
1526-
return;
1527-
}
1515+
/* User mode considers other cases after enabling IRQs */
1516+
if (!user_mode(regs)) {
1517+
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
1518+
return;
15281519
}
1529-
1530-
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
1531-
return;
15321520
}
15331521
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
15341522
if (reason & REASON_TM) {
@@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs)
15611549

15621550
/*
15631551
* If we took the program check in the kernel skip down to sending a
1564-
* SIGILL. The subsequent cases all relate to emulating instructions
1565-
* which we should only do for userspace. We also do not want to enable
1566-
* interrupts for kernel faults because that might lead to further
1567-
* faults, and loose the context of the original exception.
1552+
* SIGILL. The subsequent cases all relate to user space, such as
1553+
* emulating instructions which we should only do for user space. We
1554+
* also do not want to enable interrupts for kernel faults because that
1555+
* might lead to further faults, and loose the context of the original
1556+
* exception.
15681557
*/
15691558
if (!user_mode(regs))
15701559
goto sigill;
15711560

15721561
interrupt_cond_local_irq_enable(regs);
15731562

1563+
/*
1564+
* (reason & REASON_TRAP) is mostly handled before enabling IRQs,
1565+
* except get_user_instr() can sleep so we cannot reliably inspect the
1566+
* current instruction in that context. Now that we know we are
1567+
* handling a user space trap and can sleep, we can check if the trap
1568+
* was a hashchk failure.
1569+
*/
1570+
if (reason & REASON_TRAP) {
1571+
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) {
1572+
ppc_inst_t insn;
1573+
1574+
if (get_user_instr(insn, (void __user *)regs->nip)) {
1575+
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
1576+
return;
1577+
}
1578+
1579+
if (ppc_inst_primary_opcode(insn) == 31 &&
1580+
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
1581+
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
1582+
return;
1583+
}
1584+
}
1585+
1586+
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
1587+
return;
1588+
}
1589+
15741590
/* (reason & REASON_ILLEGAL) would be the obvious thing here,
15751591
* but there seems to be a hardware bug on the 405GP (RevD)
15761592
* that means ESR is sometimes set incorrectly - either to

arch/powerpc/perf/hv-24x7.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event)
14181418
}
14191419

14201420
domain = event_get_domain(event);
1421-
if (domain >= HV_PERF_DOMAIN_MAX) {
1421+
if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) {
14221422
pr_devel("invalid domain %d\n", domain);
14231423
return -EINVAL;
14241424
}

0 commit comments

Comments
 (0)