diff options
author | Jimi Xenidis <jimix@pobox.com> | 2011-09-29 10:55:14 +0000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-11-25 14:11:28 +1100 |
commit | c3dcf53a3fcb01f1d98f6b0cf440bb781dbcbc34 (patch) | |
tree | 8b0271a59dc103db39b3e8259419b9b549c89eae /arch/powerpc/mm/fault.c | |
parent | fac26ad4f9cb794c9d1032f55f40a31cb55be09a (diff) | |
download | talos-op-linux-c3dcf53a3fcb01f1d98f6b0cf440bb781dbcbc34.tar.gz talos-op-linux-c3dcf53a3fcb01f1d98f6b0cf440bb781dbcbc34.zip |
powerpc/icswx: Simple ACOP fault handler
This patch adds a fault handler that responds to illegal Coprocessor
types. Currently all CTs are treated and illegal. There are two ways
to report the fault back to the application. If the application used
the record form ("icswx.") then the architected "reject" is emulated.
If the application did not used the record form ("icswx") then it is
selectable by config whether the failure is silent (as architected) or
a SIGILL is generated.
In all cases pr_warn() is used to log the bad CT.
Signed-off-by: Jimi Xenidis <jimix@pobox.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm/fault.c')
-rw-r--r-- | arch/powerpc/mm/fault.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 5efe8c96d37f..2f0d1b032a89 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -44,6 +44,8 @@ #include <asm/siginfo.h> #include <mm/mmu_decl.h> +#include "icswx.h" + #ifdef CONFIG_KPROBES static inline int notify_page_fault(struct pt_regs *regs) { @@ -143,6 +145,21 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code & ESR_DST; #endif /* CONFIG_4xx || CONFIG_BOOKE */ +#ifdef CONFIG_PPC_ICSWX + /* + * we need to do this early because this "data storage + * interrupt" does not update the DAR/DEAR so we don't want to + * look at it + */ + if (error_code & ICSWX_DSI_UCT) { + int ret; + + ret = acop_handle_fault(regs, address, error_code); + if (ret) + return ret; + } +#endif + if (notify_page_fault(regs)) return 0; |