Commit 7153d4bf authored by Xiongwei Song's avatar Xiongwei Song Committed by Michael Ellerman

powerpc/traps: Enhance readability for trap types

Define macros to list ppc interrupt types in interttupt.h, replace the
reference of the trap hex values with these macros.

Referred the hex numbers in arch/powerpc/kernel/exceptions-64e.S,
arch/powerpc/kernel/exceptions-64s.S, arch/powerpc/kernel/head_*.S,
arch/powerpc/kernel/head_booke.h and arch/powerpc/include/asm/kvm_asm.h.
Signed-off-by: default avatarXiongwei Song <sxwjean@gmail.com>
[mpe: Resolve conflicts in nmi_disables_ftrace(), fix 40x build]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1618398033-13025-1-git-send-email-sxwjean@me.com
parent 7de21e67
...@@ -9,6 +9,50 @@ ...@@ -9,6 +9,50 @@
#include <asm/kprobes.h> #include <asm/kprobes.h>
#include <asm/runlatch.h> #include <asm/runlatch.h>
/* BookE/4xx */
#define INTERRUPT_CRITICAL_INPUT 0x100
/* BookE */
#define INTERRUPT_DEBUG 0xd00
#ifdef CONFIG_BOOKE
#define INTERRUPT_PERFMON 0x260
#define INTERRUPT_DOORBELL 0x280
#endif
/* BookS/4xx/8xx */
#define INTERRUPT_MACHINE_CHECK 0x200
/* BookS/8xx */
#define INTERRUPT_SYSTEM_RESET 0x100
/* BookS */
#define INTERRUPT_DATA_SEGMENT 0x380
#define INTERRUPT_INST_SEGMENT 0x480
#define INTERRUPT_TRACE 0xd00
#define INTERRUPT_H_DATA_STORAGE 0xe00
#define INTERRUPT_H_FAC_UNAVAIL 0xf80
#ifdef CONFIG_PPC_BOOK3S
#define INTERRUPT_DOORBELL 0xa00
#define INTERRUPT_PERFMON 0xf00
#endif
/* BookE/BookS/4xx/8xx */
#define INTERRUPT_DATA_STORAGE 0x300
#define INTERRUPT_INST_STORAGE 0x400
#define INTERRUPT_ALIGNMENT 0x600
#define INTERRUPT_PROGRAM 0x700
#define INTERRUPT_SYSCALL 0xc00
/* BookE/BookS/44x */
#define INTERRUPT_FP_UNAVAIL 0x800
/* BookE/BookS/44x/8xx */
#define INTERRUPT_DECREMENTER 0x900
#ifndef INTERRUPT_PERFMON
#define INTERRUPT_PERFMON 0x0
#endif
static inline void nap_adjust_return(struct pt_regs *regs) static inline void nap_adjust_return(struct pt_regs *regs)
{ {
#ifdef CONFIG_PPC_970_NAP #ifdef CONFIG_PPC_970_NAP
...@@ -65,7 +109,7 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup ...@@ -65,7 +109,7 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup
* CT_WARN_ON comes here via program_check_exception, * CT_WARN_ON comes here via program_check_exception,
* so avoid recursion. * so avoid recursion.
*/ */
if (TRAP(regs) != 0x700) if (TRAP(regs) != INTERRUPT_PROGRAM)
CT_WARN_ON(ct_state() != CONTEXT_KERNEL); CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
} }
#endif #endif
...@@ -131,13 +175,13 @@ static inline bool nmi_disables_ftrace(struct pt_regs *regs) ...@@ -131,13 +175,13 @@ static inline bool nmi_disables_ftrace(struct pt_regs *regs)
{ {
/* Allow DEC and PMI to be traced when they are soft-NMI */ /* Allow DEC and PMI to be traced when they are soft-NMI */
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) { if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
if (TRAP(regs) == 0x900) if (TRAP(regs) == INTERRUPT_DECREMENTER)
return false; return false;
if (TRAP(regs) == 0xf00) if (TRAP(regs) == INTERRUPT_PERFMON)
return false; return false;
} }
if (IS_ENABLED(CONFIG_PPC_BOOK3E)) { if (IS_ENABLED(CONFIG_PPC_BOOK3E)) {
if (TRAP(regs) == 0x260) if (TRAP(regs) == INTERRUPT_PERFMON)
return false; return false;
} }
......
...@@ -728,7 +728,7 @@ void crash_fadump(struct pt_regs *regs, const char *str) ...@@ -728,7 +728,7 @@ void crash_fadump(struct pt_regs *regs, const char *str)
* If we came in via system reset, wait a while for the secondary * If we came in via system reset, wait a while for the secondary
* CPUs to enter. * CPUs to enter.
*/ */
if (TRAP(&(fdh->regs)) == 0x100) { if (TRAP(&(fdh->regs)) == INTERRUPT_SYSTEM_RESET) {
msecs = CRASH_TIMEOUT; msecs = CRASH_TIMEOUT;
while ((atomic_read(&cpus_in_fadump) < ncpus) && (--msecs > 0)) while ((atomic_read(&cpus_in_fadump) < ncpus) && (--msecs > 0))
mdelay(1); mdelay(1);
......
...@@ -447,7 +447,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign ...@@ -447,7 +447,7 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign
* CT_WARN_ON comes here via program_check_exception, * CT_WARN_ON comes here via program_check_exception,
* so avoid recursion. * so avoid recursion.
*/ */
if (TRAP(regs) != 0x700) if (TRAP(regs) != INTERRUPT_PROGRAM)
CT_WARN_ON(ct_state() == CONTEXT_USER); CT_WARN_ON(ct_state() == CONTEXT_USER);
kuap = kuap_get_and_assert_locked(); kuap = kuap_get_and_assert_locked();
......
...@@ -1467,7 +1467,9 @@ static void __show_regs(struct pt_regs *regs) ...@@ -1467,7 +1467,9 @@ static void __show_regs(struct pt_regs *regs)
trap = TRAP(regs); trap = TRAP(regs);
if (!trap_is_syscall(regs) && cpu_has_feature(CPU_FTR_CFAR)) if (!trap_is_syscall(regs) && cpu_has_feature(CPU_FTR_CFAR))
pr_cont("CFAR: "REG" ", regs->orig_gpr3); pr_cont("CFAR: "REG" ", regs->orig_gpr3);
if (trap == 0x200 || trap == 0x300 || trap == 0x600) { if (trap == INTERRUPT_MACHINE_CHECK ||
trap == INTERRUPT_DATA_STORAGE ||
trap == INTERRUPT_ALIGNMENT) {
if (IS_ENABLED(CONFIG_4xx) || IS_ENABLED(CONFIG_BOOKE)) if (IS_ENABLED(CONFIG_4xx) || IS_ENABLED(CONFIG_BOOKE))
pr_cont("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr); pr_cont("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr);
else else
......
...@@ -221,7 +221,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, ...@@ -221,7 +221,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs,
/* /*
* system_reset_excption handles debugger, crash dump, panic, for 0x100 * system_reset_excption handles debugger, crash dump, panic, for 0x100
*/ */
if (TRAP(regs) == 0x100) if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
return; return;
crash_fadump(regs, "die oops"); crash_fadump(regs, "die oops");
...@@ -289,7 +289,7 @@ void die(const char *str, struct pt_regs *regs, long err) ...@@ -289,7 +289,7 @@ void die(const char *str, struct pt_regs *regs, long err)
/* /*
* system_reset_excption handles debugger, crash dump, panic, for 0x100 * system_reset_excption handles debugger, crash dump, panic, for 0x100
*/ */
if (TRAP(regs) != 0x100) { if (TRAP(regs) != INTERRUPT_SYSTEM_RESET) {
if (debugger(regs)) if (debugger(regs))
return; return;
} }
...@@ -1691,7 +1691,7 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception) ...@@ -1691,7 +1691,7 @@ DEFINE_INTERRUPT_HANDLER(facility_unavailable_exception)
u8 status; u8 status;
bool hv; bool hv;
hv = (TRAP(regs) == 0xf80); hv = (TRAP(regs) == INTERRUPT_H_FAC_UNAVAIL);
if (hv) if (hv)
value = mfspr(SPRN_HFSCR); value = mfspr(SPRN_HFSCR);
else else
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/setjmp.h> #include <asm/setjmp.h>
#include <asm/debug.h> #include <asm/debug.h>
#include <asm/interrupt.h>
/* /*
* The primary CPU waits a while for all secondary CPUs to enter. This is to * The primary CPU waits a while for all secondary CPUs to enter. This is to
...@@ -336,7 +337,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) ...@@ -336,7 +337,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
* If we came in via system reset, wait a while for the secondary * If we came in via system reset, wait a while for the secondary
* CPUs to enter. * CPUs to enter.
*/ */
if (TRAP(regs) == 0x100) if (TRAP(regs) == INTERRUPT_SYSTEM_RESET)
mdelay(PRIMARY_TIMEOUT); mdelay(PRIMARY_TIMEOUT);
crash_kexec_prepare_cpus(crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu);
......
...@@ -1156,7 +1156,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) ...@@ -1156,7 +1156,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
/* page is dirty */ /* page is dirty */
if (!test_bit(PG_dcache_clean, &page->flags) && !PageReserved(page)) { if (!test_bit(PG_dcache_clean, &page->flags) && !PageReserved(page)) {
if (trap == 0x400) { if (trap == INTERRUPT_INST_STORAGE) {
flush_dcache_icache_page(page); flush_dcache_icache_page(page);
set_bit(PG_dcache_clean, &page->flags); set_bit(PG_dcache_clean, &page->flags);
} else } else
...@@ -1556,7 +1556,7 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault) ...@@ -1556,7 +1556,7 @@ DEFINE_INTERRUPT_HANDLER_RET(__do_hash_fault)
if (user_mode(regs) || (region_id == USER_REGION_ID)) if (user_mode(regs) || (region_id == USER_REGION_ID))
access &= ~_PAGE_PRIVILEGED; access &= ~_PAGE_PRIVILEGED;
if (TRAP(regs) == 0x400) if (TRAP(regs) == INTERRUPT_INST_STORAGE)
access |= _PAGE_EXEC; access |= _PAGE_EXEC;
err = hash_page_mm(mm, ea, access, TRAP(regs), flags); err = hash_page_mm(mm, ea, access, TRAP(regs), flags);
......
...@@ -197,7 +197,7 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, ...@@ -197,7 +197,7 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr,
static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code, static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code,
unsigned long address, bool is_write) unsigned long address, bool is_write)
{ {
int is_exec = TRAP(regs) == 0x400; int is_exec = TRAP(regs) == INTERRUPT_INST_STORAGE;
/* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */ /* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */
if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT | if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT |
...@@ -391,7 +391,7 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -391,7 +391,7 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
struct vm_area_struct * vma; struct vm_area_struct * vma;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned int flags = FAULT_FLAG_DEFAULT; unsigned int flags = FAULT_FLAG_DEFAULT;
int is_exec = TRAP(regs) == 0x400; int is_exec = TRAP(regs) == INTERRUPT_INST_STORAGE;
int is_user = user_mode(regs); int is_user = user_mode(regs);
int is_write = page_fault_is_write(error_code); int is_write = page_fault_is_write(error_code);
vm_fault_t fault, major = 0; vm_fault_t fault, major = 0;
...@@ -574,20 +574,20 @@ static void __bad_page_fault(struct pt_regs *regs, int sig) ...@@ -574,20 +574,20 @@ static void __bad_page_fault(struct pt_regs *regs, int sig)
/* kernel has accessed a bad area */ /* kernel has accessed a bad area */
switch (TRAP(regs)) { switch (TRAP(regs)) {
case 0x300: case INTERRUPT_DATA_STORAGE:
case 0x380: case INTERRUPT_DATA_SEGMENT:
case 0xe00: case INTERRUPT_H_DATA_STORAGE:
pr_alert("BUG: %s on %s at 0x%08lx\n", pr_alert("BUG: %s on %s at 0x%08lx\n",
regs->dar < PAGE_SIZE ? "Kernel NULL pointer dereference" : regs->dar < PAGE_SIZE ? "Kernel NULL pointer dereference" :
"Unable to handle kernel data access", "Unable to handle kernel data access",
is_write ? "write" : "read", regs->dar); is_write ? "write" : "read", regs->dar);
break; break;
case 0x400: case INTERRUPT_INST_STORAGE:
case 0x480: case INTERRUPT_INST_SEGMENT:
pr_alert("BUG: Unable to handle kernel instruction fetch%s", pr_alert("BUG: Unable to handle kernel instruction fetch%s",
regs->nip < PAGE_SIZE ? " (NULL pointer?)\n" : "\n"); regs->nip < PAGE_SIZE ? " (NULL pointer?)\n" : "\n");
break; break;
case 0x600: case INTERRUPT_ALIGNMENT:
pr_alert("BUG: Unable to handle kernel unaligned access at 0x%08lx\n", pr_alert("BUG: Unable to handle kernel unaligned access at 0x%08lx\n",
regs->dar); regs->dar);
break; break;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/code-patching.h> #include <asm/code-patching.h>
#include <asm/interrupt.h>
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#include "internal.h" #include "internal.h"
...@@ -168,7 +169,7 @@ static bool regs_use_siar(struct pt_regs *regs) ...@@ -168,7 +169,7 @@ static bool regs_use_siar(struct pt_regs *regs)
* they have not been setup using perf_read_regs() and so regs->result * they have not been setup using perf_read_regs() and so regs->result
* is something random. * is something random.
*/ */
return ((TRAP(regs) == 0xf00) && regs->result); return ((TRAP(regs) == INTERRUPT_PERFMON) && regs->result);
} }
/* /*
...@@ -347,7 +348,7 @@ static inline void perf_read_regs(struct pt_regs *regs) ...@@ -347,7 +348,7 @@ static inline void perf_read_regs(struct pt_regs *regs)
* hypervisor samples as well as samples in the kernel with * hypervisor samples as well as samples in the kernel with
* interrupts off hence the userspace check. * interrupts off hence the userspace check.
*/ */
if (TRAP(regs) != 0xf00) if (TRAP(regs) != INTERRUPT_PERFMON)
use_siar = 0; use_siar = 0;
else if ((ppmu->flags & PPMU_NO_SIAR)) else if ((ppmu->flags & PPMU_NO_SIAR))
use_siar = 0; use_siar = 0;
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include <asm/code-patching.h> #include <asm/code-patching.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/inst.h> #include <asm/inst.h>
#include <asm/interrupt.h>
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#include <asm/hvcall.h> #include <asm/hvcall.h>
...@@ -605,7 +606,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) ...@@ -605,7 +606,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
* debugger break (IPI). This is similar to * debugger break (IPI). This is similar to
* crash_kexec_secondary(). * crash_kexec_secondary().
*/ */
if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus)) if (TRAP(regs) != INTERRUPT_SYSTEM_RESET || !wait_for_other_cpus(ncpus))
smp_send_debugger_break(); smp_send_debugger_break();
wait_for_other_cpus(ncpus); wait_for_other_cpus(ncpus);
...@@ -615,7 +616,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) ...@@ -615,7 +616,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
if (!locked_down) { if (!locked_down) {
/* for breakpoint or single step, print curr insn */ /* for breakpoint or single step, print curr insn */
if (bp || TRAP(regs) == 0xd00) if (bp || TRAP(regs) == INTERRUPT_TRACE)
ppc_inst_dump(regs->nip, 1, 0); ppc_inst_dump(regs->nip, 1, 0);
printf("enter ? for help\n"); printf("enter ? for help\n");
} }
...@@ -684,7 +685,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) ...@@ -684,7 +685,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
disable_surveillance(); disable_surveillance();
if (!locked_down) { if (!locked_down) {
/* for breakpoint or single step, print current insn */ /* for breakpoint or single step, print current insn */
if (bp || TRAP(regs) == 0xd00) if (bp || TRAP(regs) == INTERRUPT_TRACE)
ppc_inst_dump(regs->nip, 1, 0); ppc_inst_dump(regs->nip, 1, 0);
printf("enter ? for help\n"); printf("enter ? for help\n");
} }
...@@ -1769,9 +1770,12 @@ static void excprint(struct pt_regs *fp) ...@@ -1769,9 +1770,12 @@ static void excprint(struct pt_regs *fp)
printf(" sp: %lx\n", fp->gpr[1]); printf(" sp: %lx\n", fp->gpr[1]);
printf(" msr: %lx\n", fp->msr); printf(" msr: %lx\n", fp->msr);
if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) { if (trap == INTERRUPT_DATA_STORAGE ||
trap == INTERRUPT_DATA_SEGMENT ||
trap == INTERRUPT_ALIGNMENT ||
trap == INTERRUPT_MACHINE_CHECK) {
printf(" dar: %lx\n", fp->dar); printf(" dar: %lx\n", fp->dar);
if (trap != 0x380) if (trap != INTERRUPT_DATA_SEGMENT)
printf(" dsisr: %lx\n", fp->dsisr); printf(" dsisr: %lx\n", fp->dsisr);
} }
...@@ -1785,7 +1789,7 @@ static void excprint(struct pt_regs *fp) ...@@ -1785,7 +1789,7 @@ static void excprint(struct pt_regs *fp)
current->pid, current->comm); current->pid, current->comm);
} }
if (trap == 0x700) if (trap == INTERRUPT_PROGRAM)
print_bug_trap(fp); print_bug_trap(fp);
printf(linux_banner); printf(linux_banner);
...@@ -1837,7 +1841,9 @@ static void prregs(struct pt_regs *fp) ...@@ -1837,7 +1841,9 @@ static void prregs(struct pt_regs *fp)
printf("ctr = "REG" xer = "REG" trap = %4lx\n", printf("ctr = "REG" xer = "REG" trap = %4lx\n",
fp->ctr, fp->xer, fp->trap); fp->ctr, fp->xer, fp->trap);
trap = TRAP(fp); trap = TRAP(fp);
if (trap == 0x300 || trap == 0x380 || trap == 0x600) if (trap == INTERRUPT_DATA_STORAGE ||
trap == INTERRUPT_DATA_SEGMENT ||
trap == INTERRUPT_ALIGNMENT)
printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
} }
......
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