From 9b55613f42e8d40d5c9ccb8970bde6af4764b2ab Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 11 Sep 2015 16:44:02 +0100 Subject: ARM: fix Thumb2 signal handling when ARMv6 is enabled When a kernel is built covering ARMv6 to ARMv7, we omit to clear the IT state when entering a signal handler. This can cause the first few instructions to be conditionally executed depending on the parent context. In any case, the original test for >= ARMv7 is broken - ARMv6 can have Thumb-2 support as well, and an ARMv6T2 specific build would omit this code too. Relax the test back to ARMv6 or greater. This results in us always clearing the IT state bits in the PSR, even on CPUs where these bits are reserved. However, they're reserved for the IT state, so this should cause no harm. Cc: Fixes: d71e1352e240 ("Clear the IT state when invoking a Thumb-2 signal handler") Acked-by: Tony Lindgren Tested-by: H. Nikolaus Schaller Tested-by: Grazvydas Ignotas Signed-off-by: Russell King --- arch/arm/kernel/signal.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 423663e23791..586eef26203d 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -343,12 +343,17 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, */ thumb = handler & 1; -#if __LINUX_ARM_ARCH__ >= 7 +#if __LINUX_ARM_ARCH__ >= 6 /* - * Clear the If-Then Thumb-2 execution state - * ARM spec requires this to be all 000s in ARM mode - * Snapdragon S4/Krait misbehaves on a Thumb=>ARM - * signal transition without this. + * Clear the If-Then Thumb-2 execution state. ARM spec + * requires this to be all 000s in ARM mode. Snapdragon + * S4/Krait misbehaves on a Thumb=>ARM signal transition + * without this. + * + * We must do this whenever we are running on a Thumb-2 + * capable CPU, which includes ARMv6T2. However, we elect + * to do this whenever we're on an ARMv6 or later CPU for + * simplicity. */ cpsr &= ~PSR_IT_MASK; #endif -- cgit v1.2.3 From 12fc7306e6ffae4e86680892f2286063d7d6eae7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 16 Sep 2015 11:08:49 +0100 Subject: ARM: get rid of needless #if in signal handling code Remove the #if statement which caused trouble for kernels that support both ARMv6 and ARMv7. Older architectures do not implement these bits, so it should be safe to always clear them. Signed-off-by: Russell King --- arch/arm/kernel/signal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 586eef26203d..29e5dc70bb41 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -343,7 +343,6 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, */ thumb = handler & 1; -#if __LINUX_ARM_ARCH__ >= 6 /* * Clear the If-Then Thumb-2 execution state. ARM spec * requires this to be all 000s in ARM mode. Snapdragon @@ -352,11 +351,10 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, * * We must do this whenever we are running on a Thumb-2 * capable CPU, which includes ARMv6T2. However, we elect - * to do this whenever we're on an ARMv6 or later CPU for - * simplicity. + * to always do this to simplify the code; this field is + * marked UNK/SBZP for older architectures. */ cpsr &= ~PSR_IT_MASK; -#endif if (thumb) { cpsr |= PSR_T_BIT; -- cgit v1.2.3 From 90cde5584a34e210850728bebee4c6fb1a7124ba Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 14 Sep 2015 17:49:02 +0100 Subject: ARM: 8437/1: dma-mapping: fix build warning with new DMA_ERROR_CODE definition Commit 96231b2686b5: ("ARM: 8419/1: dma-mapping: harmonize definition of DMA_ERROR_CODE") changed the definition of DMA_ERROR_CODE to use dma_addr_t, which makes the compiler barf on assigning this to an "int" variable on ARM with LPAE enabled: ************* In file included from /src/linux/include/linux/dma-mapping.h:86:0, from /src/linux/arch/arm/mm/dma-mapping.c:21: /src/linux/arch/arm/mm/dma-mapping.c: In function '__iommu_create_mapping': /src/linux/arch/arm/include/asm/dma-mapping.h:16:24: warning: overflow in implicit constant conversion [-Woverflow] #define DMA_ERROR_CODE (~(dma_addr_t)0x0) ^ /src/linux/arch/arm/mm/dma-mapping.c:1252:15: note: in expansion of macro DMA_ERROR_CODE' int i, ret = DMA_ERROR_CODE; ^ ************* Remove the actually unneeded initialization of "ret" in __iommu_create_mapping() and move the variable declaration inside the for-loop to make the scope of this variable more clear. Signed-off-by: Andre Przywara Signed-off-by: Russell King --- arch/arm/mm/dma-mapping.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index cba12f34ff77..3594543a4e9d 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1257,7 +1257,7 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size) struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; dma_addr_t dma_addr, iova; - int i, ret = DMA_ERROR_CODE; + int i; dma_addr = __alloc_iova(mapping, size); if (dma_addr == DMA_ERROR_CODE) @@ -1265,6 +1265,8 @@ __iommu_create_mapping(struct device *dev, struct page **pages, size_t size) iova = dma_addr; for (i = 0; i < count; ) { + int ret; + unsigned int next_pfn = page_to_pfn(pages[i]) + 1; phys_addr_t phys = page_to_phys(pages[i]); unsigned int len, j; -- cgit v1.2.3 From 7ae85dc7687c7e7119053d83d02c560ea217b772 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 26 Aug 2015 18:26:49 +0100 Subject: ARM: 8425/1: kgdb: Don't try to stop the machine when setting breakpoints In (23a4e40 arm: kgdb: Handle read-only text / modules) we moved to using patch_text() to set breakpoints so that we could handle the case when we had CONFIG_DEBUG_RODATA. That patch used patch_text(). Unfortunately, patch_text() assumes that we're not in atomic context when it runs since it needs to grab a mutex and also wait for other CPUs to stop (which it does with a completion). This would result in a stack crawl if you had CONFIG_DEBUG_ATOMIC_SLEEP and tried to set a breakpoint in kgdb. The crawl looked something like: BUG: scheduling while atomic: swapper/0/0/0x00010007 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-00133-geb63b34 #1073 Hardware name: Rockchip (Device Tree) (unwind_backtrace) from [] (show_stack+0x20/0x24) (show_stack) from [] (dump_stack+0x84/0xb8) (dump_stack) from [] (__schedule_bug+0x54/0x6c) (__schedule_bug) from [] (__schedule+0x80/0x668) (__schedule) from [] (schedule+0xb8/0xd4) (schedule) from [] (schedule_timeout+0x2c/0x234) (schedule_timeout) from [] (wait_for_common+0xf4/0x188) (wait_for_common) from [] (wait_for_completion+0x20/0x24) (wait_for_completion) from [] (__stop_cpus+0x58/0x70) (__stop_cpus) from [] (stop_cpus+0x3c/0x54) (stop_cpus) from [] (__stop_machine+0xcc/0xe8) (__stop_machine) from [] (stop_machine+0x34/0x44) (stop_machine) from [] (patch_text+0x28/0x34) (patch_text) from [] (kgdb_arch_set_breakpoint+0x40/0x4c) (kgdb_arch_set_breakpoint) from [] (kgdb_validate_break_address+0x2c/0x60) (kgdb_validate_break_address) from [] (dbg_set_sw_break+0x1c/0xdc) (dbg_set_sw_break) from [] (gdb_serial_stub+0x9c4/0xba4) (gdb_serial_stub) from [] (kgdb_cpu_enter+0x1f8/0x60c) (kgdb_cpu_enter) from [] (kgdb_handle_exception+0x19c/0x1d0) (kgdb_handle_exception) from [] (kgdb_compiled_brk_fn+0x30/0x3c) (kgdb_compiled_brk_fn) from [] (do_undefinstr+0x1a4/0x20c) (do_undefinstr) from [] (__und_svc_finish+0x0/0x34) It turns out that when we're in kgdb all the CPUs are stopped anyway so there's no reason we should be calling patch_text(). We can instead directly call __patch_text() which assumes that CPUs have already been stopped. Fixes: 23a4e4050ba9 ("arm: kgdb: Handle read-only text / modules") Reported-by: Aapo Vienamo Signed-off-by: Douglas Anderson Reviewed-by: Stephen Boyd Acked-by: Kees Cook Signed-off-by: Russell King --- arch/arm/kernel/kgdb.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index a6ad93c9bce3..fd9eefce0a7b 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -259,15 +259,17 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) if (err) return err; - patch_text((void *)bpt->bpt_addr, - *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr); + /* Machine is already stopped, so we can use __patch_text() directly */ + __patch_text((void *)bpt->bpt_addr, + *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr); return err; } int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) { - patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr); + /* Machine is already stopped, so we can use __patch_text() directly */ + __patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr); return 0; } -- cgit v1.2.3