Skip to content

Commit

Permalink
Automatic merge of 'fixes-test' into merge-test (2023-09-14 23:55)
Browse files Browse the repository at this point in the history
  • Loading branch information
mpe committed Sep 14, 2023
2 parents cf3f655 + 2ca9ece commit 5e36c31
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 23 deletions.
16 changes: 15 additions & 1 deletion arch/powerpc/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
struct arch_hw_breakpoint *info;
int i;

preempt_disable();

for (i = 0; i < nr_wp_slots(); i++) {
struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);

if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))
goto reset;
}
return;
goto out;

reset:
regs_set_return_msr(regs, regs->msr & ~MSR_SE);
Expand All @@ -245,6 +247,9 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
__set_breakpoint(i, info);
info->perf_single_step = false;
}

out:
preempt_enable();
}

static bool is_larx_stcx_instr(int type)
Expand Down Expand Up @@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp,
}
}

/*
* Handle a DABR or DAWR exception.
*
* Called in atomic context.
*/
int hw_breakpoint_handler(struct die_args *args)
{
bool err = false;
Expand Down Expand Up @@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);

/*
* Handle single-step exceptions following a DABR hit.
*
* Called in atomic context.
*/
static int single_step_dabr_instruction(struct die_args *args)
{
Expand Down Expand Up @@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);

/*
* Handle debug exception notifications.
*
* Called in atomic context.
*/
int hw_breakpoint_exceptions_notify(
struct notifier_block *unused, unsigned long val, void *data)
Expand Down
7 changes: 6 additions & 1 deletion arch/powerpc/kernel/hw_breakpoint_constraints.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
int *type, int *size, unsigned long *ea)
{
struct instruction_op op;
int err;

if (__get_user_instr(*instr, (void __user *)regs->nip))
pagefault_disable();
err = __get_user_instr(*instr, (void __user *)regs->nip);
pagefault_enable();

if (err)
return;

analyse_instr(&op, regs, *instr);
Expand Down
56 changes: 36 additions & 20 deletions arch/powerpc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -1512,23 +1512,11 @@ static void do_program_check(struct pt_regs *regs)
return;
}

if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) {
ppc_inst_t insn;

if (get_user_instr(insn, (void __user *)regs->nip)) {
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
return;
}

if (ppc_inst_primary_opcode(insn) == 31 &&
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
return;
}
/* User mode considers other cases after enabling IRQs */
if (!user_mode(regs)) {
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
return;
}

_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
return;
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (reason & REASON_TM) {
Expand Down Expand Up @@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs)

/*
* If we took the program check in the kernel skip down to sending a
* SIGILL. The subsequent cases all relate to emulating instructions
* which we should only do for userspace. We also do not want to enable
* interrupts for kernel faults because that might lead to further
* faults, and loose the context of the original exception.
* SIGILL. The subsequent cases all relate to user space, such as
* emulating instructions which we should only do for user space. We
* also do not want to enable interrupts for kernel faults because that
* might lead to further faults, and loose the context of the original
* exception.
*/
if (!user_mode(regs))
goto sigill;

interrupt_cond_local_irq_enable(regs);

/*
* (reason & REASON_TRAP) is mostly handled before enabling IRQs,
* except get_user_instr() can sleep so we cannot reliably inspect the
* current instruction in that context. Now that we know we are
* handling a user space trap and can sleep, we can check if the trap
* was a hashchk failure.
*/
if (reason & REASON_TRAP) {
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE)) {
ppc_inst_t insn;

if (get_user_instr(insn, (void __user *)regs->nip)) {
_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
return;
}

if (ppc_inst_primary_opcode(insn) == 31 &&
get_xop(ppc_inst_val(insn)) == OP_31_XOP_HASHCHK) {
_exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
return;
}
}

_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
return;
}

/* (reason & REASON_ILLEGAL) would be the obvious thing here,
* but there seems to be a hardware bug on the 405GP (RevD)
* that means ESR is sometimes set incorrectly - either to
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/perf/hv-24x7.c
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event)
}

domain = event_get_domain(event);
if (domain >= HV_PERF_DOMAIN_MAX) {
if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) {
pr_devel("invalid domain %d\n", domain);
return -EINVAL;
}
Expand Down

0 comments on commit 5e36c31

Please sign in to comment.