diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2014-04-06 18:04:12 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-05-09 10:47:47 -0400 |
commit | 9141300a5884b57cea6d32c4e3fd16a337cfc99a (patch) | |
tree | d717d0ae66c7458c922b885c689b9c192b0f4083 /arch/arm64/mm/fault.c | |
parent | 6400111399e16a535231ebd76389c894ea1837ff (diff) |
arm64: Provide read/write fault information in compat signal handlers
For AArch32, bit 11 (WnR) of the FSR/ESR register is set when the fault
was caused by a write access and applications like Qemu rely on such
information being provided in sigcontext. This patch introduces the
ESR_EL1 tracking for the arm64 kernel faults and sets bit 11 accordingly
in compat sigcontext.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/mm/fault.c')
-rw-r--r-- | arch/arm64/mm/fault.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index c23751b06120..bcc965e2cce1 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <asm/exception.h> | 33 | #include <asm/exception.h> |
34 | #include <asm/debug-monitors.h> | 34 | #include <asm/debug-monitors.h> |
35 | #include <asm/esr.h> | ||
35 | #include <asm/system_misc.h> | 36 | #include <asm/system_misc.h> |
36 | #include <asm/pgtable.h> | 37 | #include <asm/pgtable.h> |
37 | #include <asm/tlbflush.h> | 38 | #include <asm/tlbflush.h> |
@@ -123,6 +124,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, | |||
123 | } | 124 | } |
124 | 125 | ||
125 | tsk->thread.fault_address = addr; | 126 | tsk->thread.fault_address = addr; |
127 | tsk->thread.fault_code = esr; | ||
126 | si.si_signo = sig; | 128 | si.si_signo = sig; |
127 | si.si_errno = 0; | 129 | si.si_errno = 0; |
128 | si.si_code = code; | 130 | si.si_code = code; |
@@ -148,8 +150,6 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re | |||
148 | #define VM_FAULT_BADMAP 0x010000 | 150 | #define VM_FAULT_BADMAP 0x010000 |
149 | #define VM_FAULT_BADACCESS 0x020000 | 151 | #define VM_FAULT_BADACCESS 0x020000 |
150 | 152 | ||
151 | #define ESR_WRITE (1 << 6) | ||
152 | #define ESR_CM (1 << 8) | ||
153 | #define ESR_LNX_EXEC (1 << 24) | 153 | #define ESR_LNX_EXEC (1 << 24) |
154 | 154 | ||
155 | static int __do_page_fault(struct mm_struct *mm, unsigned long addr, | 155 | static int __do_page_fault(struct mm_struct *mm, unsigned long addr, |
@@ -218,7 +218,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, | |||
218 | 218 | ||
219 | if (esr & ESR_LNX_EXEC) { | 219 | if (esr & ESR_LNX_EXEC) { |
220 | vm_flags = VM_EXEC; | 220 | vm_flags = VM_EXEC; |
221 | } else if ((esr & ESR_WRITE) && !(esr & ESR_CM)) { | 221 | } else if ((esr & ESR_EL1_WRITE) && !(esr & ESR_EL1_CM)) { |
222 | vm_flags = VM_WRITE; | 222 | vm_flags = VM_WRITE; |
223 | mm_flags |= FAULT_FLAG_WRITE; | 223 | mm_flags |= FAULT_FLAG_WRITE; |
224 | } | 224 | } |
@@ -525,7 +525,7 @@ asmlinkage int __exception do_debug_exception(unsigned long addr, | |||
525 | info.si_errno = 0; | 525 | info.si_errno = 0; |
526 | info.si_code = inf->code; | 526 | info.si_code = inf->code; |
527 | info.si_addr = (void __user *)addr; | 527 | info.si_addr = (void __user *)addr; |
528 | arm64_notify_die("", regs, &info, esr); | 528 | arm64_notify_die("", regs, &info, 0); |
529 | 529 | ||
530 | return 0; | 530 | return 0; |
531 | } | 531 | } |