Commit 7bdfc1af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:

 - A fix for breakpoint handling which was using get_user() while atomic

 - Fix the Power10 HASHCHK handler which was using get_user() while
   atomic

 - A few build fixes for issues caused by recent changes

Thanks to Benjamin Gray, Christophe Leroy, Kajol Jain, and Naveen N Rao.

* tag 'powerpc-6.6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/dexcr: Move HASHCHK trap handler
  powerpc/82xx: Select FSL_SOC
  powerpc: Fix build issue with LD_DEAD_CODE_DATA_ELIMINATION and FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY
  powerpc/watchpoints: Annotate atomic context in more places
  powerpc/watchpoint: Disable pagefaults when getting user instruction
  powerpc/watchpoints: Disable preemption in thread_change_pc()
  powerpc/perf/hv-24x7: Update domain value check
parents 88a174a9 c3f43096
...@@ -255,7 +255,7 @@ config PPC ...@@ -255,7 +255,7 @@ config PPC
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES select HAVE_KRETPROBES
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if HAVE_OBJTOOL_MCOUNT && (!ARCH_USING_PATCHABLE_FUNCTION_ENTRY || (!CC_IS_GCC || GCC_VERSION >= 110100))
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
select HAVE_MOD_ARCH_SPECIFIC select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S)
......
...@@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) ...@@ -230,13 +230,15 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
struct arch_hw_breakpoint *info; struct arch_hw_breakpoint *info;
int i; int i;
preempt_disable();
for (i = 0; i < nr_wp_slots(); i++) { for (i = 0; i < nr_wp_slots(); i++) {
struct perf_event *bp = __this_cpu_read(bp_per_reg[i]); struct perf_event *bp = __this_cpu_read(bp_per_reg[i]);
if (unlikely(bp && counter_arch_bp(bp)->perf_single_step)) if (unlikely(bp && counter_arch_bp(bp)->perf_single_step))
goto reset; goto reset;
} }
return; goto out;
reset: reset:
regs_set_return_msr(regs, regs->msr & ~MSR_SE); 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) ...@@ -245,6 +247,9 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
__set_breakpoint(i, info); __set_breakpoint(i, info);
info->perf_single_step = false; info->perf_single_step = false;
} }
out:
preempt_enable();
} }
static bool is_larx_stcx_instr(int type) static bool is_larx_stcx_instr(int type)
...@@ -363,6 +368,11 @@ static void handle_p10dd1_spurious_exception(struct perf_event **bp, ...@@ -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) int hw_breakpoint_handler(struct die_args *args)
{ {
bool err = false; bool err = false;
...@@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler); ...@@ -490,6 +500,8 @@ NOKPROBE_SYMBOL(hw_breakpoint_handler);
/* /*
* Handle single-step exceptions following a DABR hit. * Handle single-step exceptions following a DABR hit.
*
* Called in atomic context.
*/ */
static int single_step_dabr_instruction(struct die_args *args) static int single_step_dabr_instruction(struct die_args *args)
{ {
...@@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction); ...@@ -541,6 +553,8 @@ NOKPROBE_SYMBOL(single_step_dabr_instruction);
/* /*
* Handle debug exception notifications. * Handle debug exception notifications.
*
* Called in atomic context.
*/ */
int hw_breakpoint_exceptions_notify( int hw_breakpoint_exceptions_notify(
struct notifier_block *unused, unsigned long val, void *data) struct notifier_block *unused, unsigned long val, void *data)
......
...@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr, ...@@ -131,8 +131,13 @@ void wp_get_instr_detail(struct pt_regs *regs, ppc_inst_t *instr,
int *type, int *size, unsigned long *ea) int *type, int *size, unsigned long *ea)
{ {
struct instruction_op op; 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; return;
analyse_instr(&op, regs, *instr); analyse_instr(&op, regs, *instr);
......
...@@ -1512,24 +1512,12 @@ static void do_program_check(struct pt_regs *regs) ...@@ -1512,24 +1512,12 @@ static void do_program_check(struct pt_regs *regs)
return; return;
} }
if (cpu_has_feature(CPU_FTR_DEXCR_NPHIE) && user_mode(regs)) { /* User mode considers other cases after enabling IRQs */
ppc_inst_t insn; if (!user_mode(regs)) {
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); _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
return; return;
} }
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (reason & REASON_TM) { if (reason & REASON_TM) {
/* This is a TM "Bad Thing Exception" program check. /* This is a TM "Bad Thing Exception" program check.
...@@ -1561,16 +1549,44 @@ static void do_program_check(struct pt_regs *regs) ...@@ -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 * If we took the program check in the kernel skip down to sending a
* SIGILL. The subsequent cases all relate to emulating instructions * SIGILL. The subsequent cases all relate to user space, such as
* which we should only do for userspace. We also do not want to enable * emulating instructions which we should only do for user space. We
* interrupts for kernel faults because that might lead to further * also do not want to enable interrupts for kernel faults because that
* faults, and loose the context of the original exception. * might lead to further faults, and loose the context of the original
* exception.
*/ */
if (!user_mode(regs)) if (!user_mode(regs))
goto sigill; goto sigill;
interrupt_cond_local_irq_enable(regs); 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, /* (reason & REASON_ILLEGAL) would be the obvious thing here,
* but there seems to be a hardware bug on the 405GP (RevD) * but there seems to be a hardware bug on the 405GP (RevD)
* that means ESR is sometimes set incorrectly - either to * that means ESR is sometimes set incorrectly - either to
......
...@@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event) ...@@ -1418,7 +1418,7 @@ static int h_24x7_event_init(struct perf_event *event)
} }
domain = event_get_domain(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); pr_devel("invalid domain %d\n", domain);
return -EINVAL; return -EINVAL;
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
menuconfig PPC_82xx menuconfig PPC_82xx
bool "82xx-based boards (PQ II)" bool "82xx-based boards (PQ II)"
depends on PPC_BOOK3S_32 depends on PPC_BOOK3S_32
select FSL_SOC
if PPC_82xx if PPC_82xx
...@@ -9,7 +10,6 @@ config EP8248E ...@@ -9,7 +10,6 @@ config EP8248E
bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)" bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)"
select CPM2 select CPM2
select PPC_INDIRECT_PCI if PCI select PPC_INDIRECT_PCI if PCI
select FSL_SOC
select PHYLIB if NETDEVICES select PHYLIB if NETDEVICES
select MDIO_BITBANG if PHYLIB select MDIO_BITBANG if PHYLIB
help help
...@@ -22,7 +22,6 @@ config MGCOGE ...@@ -22,7 +22,6 @@ config MGCOGE
bool "Keymile MGCOGE" bool "Keymile MGCOGE"
select CPM2 select CPM2
select PPC_INDIRECT_PCI if PCI select PPC_INDIRECT_PCI if PCI
select FSL_SOC
help help
This enables support for the Keymile MGCOGE board. This enables support for the Keymile MGCOGE board.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment