Arvind M | 8e87d85 | 2018-01-29 00:04:29 -0800 | [diff] [blame] | 1 | From 3ac5ae9729d00da7089ecf595d867c4c1fc25841 Mon Sep 17 00:00:00 2001 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 2 | From: "Yadi.hu" <yadi.hu@windriver.com> |
| 3 | Date: Wed, 10 Dec 2014 10:32:09 +0800 |
Arvind M | 10268e7 | 2017-12-04 22:18:06 -0800 | [diff] [blame] | 4 | Subject: [PATCH 192/366] ARM: enable irq in translation/section permission |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 5 | fault handlers |
| 6 | MIME-Version: 1.0 |
| 7 | Content-Type: text/plain; charset=UTF-8 |
| 8 | Content-Transfer-Encoding: 8bit |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 9 | |
| 10 | Probably happens on all ARM, with |
| 11 | CONFIG_PREEMPT_RT_FULL |
| 12 | CONFIG_DEBUG_ATOMIC_SLEEP |
| 13 | |
| 14 | This simple program.... |
| 15 | |
| 16 | int main() { |
| 17 | *((char*)0xc0001000) = 0; |
| 18 | }; |
| 19 | |
| 20 | [ 512.742724] BUG: sleeping function called from invalid context at kernel/rtmutex.c:658 |
| 21 | [ 512.743000] in_atomic(): 0, irqs_disabled(): 128, pid: 994, name: a |
| 22 | [ 512.743217] INFO: lockdep is turned off. |
| 23 | [ 512.743360] irq event stamp: 0 |
| 24 | [ 512.743482] hardirqs last enabled at (0): [< (null)>] (null) |
| 25 | [ 512.743714] hardirqs last disabled at (0): [<c0426370>] copy_process+0x3b0/0x11c0 |
| 26 | [ 512.744013] softirqs last enabled at (0): [<c0426370>] copy_process+0x3b0/0x11c0 |
| 27 | [ 512.744303] softirqs last disabled at (0): [< (null)>] (null) |
| 28 | [ 512.744631] [<c041872c>] (unwind_backtrace+0x0/0x104) |
| 29 | [ 512.745001] [<c09af0c4>] (dump_stack+0x20/0x24) |
| 30 | [ 512.745355] [<c0462490>] (__might_sleep+0x1dc/0x1e0) |
| 31 | [ 512.745717] [<c09b6770>] (rt_spin_lock+0x34/0x6c) |
| 32 | [ 512.746073] [<c0441bf0>] (do_force_sig_info+0x34/0xf0) |
| 33 | [ 512.746457] [<c0442668>] (force_sig_info+0x18/0x1c) |
| 34 | [ 512.746829] [<c041d880>] (__do_user_fault+0x9c/0xd8) |
| 35 | [ 512.747185] [<c041d938>] (do_bad_area+0x7c/0x94) |
| 36 | [ 512.747536] [<c041d990>] (do_sect_fault+0x40/0x48) |
| 37 | [ 512.747898] [<c040841c>] (do_DataAbort+0x40/0xa0) |
| 38 | [ 512.748181] Exception stack(0xecaa1fb0 to 0xecaa1ff8) |
| 39 | |
| 40 | Oxc0000000 belongs to kernel address space, user task can not be |
| 41 | allowed to access it. For above condition, correct result is that |
| 42 | test case should receive a “segment fault” and exits but not stacks. |
| 43 | |
| 44 | the root cause is commit 02fe2845d6a8 ("avoid enabling interrupts in |
| 45 | prefetch/data abort handlers"),it deletes irq enable block in Data |
| 46 | abort assemble code and move them into page/breakpiont/alignment fault |
| 47 | handlers instead. But author does not enable irq in translation/section |
| 48 | permission fault handlers. ARM disables irq when it enters exception/ |
| 49 | interrupt mode, if kernel doesn't enable irq, it would be still disabled |
| 50 | during translation/section permission fault. |
| 51 | |
| 52 | We see the above splat because do_force_sig_info is still called with |
| 53 | IRQs off, and that code eventually does a: |
| 54 | |
| 55 | spin_lock_irqsave(&t->sighand->siglock, flags); |
| 56 | |
| 57 | As this is architecture independent code, and we've not seen any other |
| 58 | need for other arch to have the siglock converted to raw lock, we can |
| 59 | conclude that we should enable irq for ARM translation/section |
| 60 | permission exception. |
| 61 | |
| 62 | Signed-off-by: Yadi.hu <yadi.hu@windriver.com> |
| 63 | Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 64 | --- |
| 65 | arch/arm/mm/fault.c | 6 ++++++ |
| 66 | 1 file changed, 6 insertions(+) |
| 67 | |
| 68 | diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c |
Ishan Mittal | b799826 | 2017-01-17 16:11:50 +0530 | [diff] [blame] | 69 | index 506c225..e3355a8 100644 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 70 | --- a/arch/arm/mm/fault.c |
| 71 | +++ b/arch/arm/mm/fault.c |
| 72 | @@ -430,6 +430,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, |
| 73 | if (addr < TASK_SIZE) |
| 74 | return do_page_fault(addr, fsr, regs); |
| 75 | |
| 76 | + if (interrupts_enabled(regs)) |
| 77 | + local_irq_enable(); |
| 78 | + |
| 79 | if (user_mode(regs)) |
| 80 | goto bad_area; |
| 81 | |
| 82 | @@ -497,6 +500,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, |
| 83 | static int |
| 84 | do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
| 85 | { |
| 86 | + if (interrupts_enabled(regs)) |
| 87 | + local_irq_enable(); |
| 88 | + |
| 89 | do_bad_area(addr, fsr, regs); |
| 90 | return 0; |
| 91 | } |
| 92 | -- |
Arvind M | 10268e7 | 2017-12-04 22:18:06 -0800 | [diff] [blame] | 93 | 1.9.1 |
Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame] | 94 | |