big-endian patch series
Subsystems (9)
This is the latest of the big-endian core updates for ARM. It is currently pushed to the following location:
git://git.baserock.org/delta/linux.git baserock/311-rc7/be/core-v2
It is now well reviewed and has been tested by a number of people including Thomas Petazzoni and Victor Kamensky (who have both contributed to getting this series sorted).
Russell, would this be something that you would accept a pull request for? If so, can I leave the highbank, vexpress and mvebu in the series?
Changes since previous version:
- Updated patches reviewed by Dave Martin
- Fixed message in alignment trap handler (Sergei Shtylov)
- Fixed ordering in highbank (Rob Herring)
- Added Victor Kamensy's signal handling patch
There are a few small outstanding issues to deal with, but those are not directly related to the functionality of this patch series. They are as follows
- KGDB should be disbaled or fixed for THUMB kernels
- The kprobes test suite does not currently work with BE8 properly
- Modules may need 'be8' adding to the vermagic.
PATCH 1/20 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN
The Kconfig for arch/arm/mach-ixp4xx has a local definition of ARCH_SUPPORTS_BIG_ENDIAN which could be used elsewhere. This means that if IXP4xx is selected and this symbol is selected eleswhere then an warning is produced.
Clean the following error up by making the symbol be selected by the main ARCH_IXP4XX definition and have a common definition in arch/arm/mm/Kconfig
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
--- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/Kconfig | 4 ---- arch/arm/mm/Kconfig | 6 ++++++ 3 files changed, 7 insertions(+), 4 deletions(-)
arch/arm/Kconfig +1 -0
@@ -480,6 +480,7 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select ARCH_HAS_DMA_SET_COHERENT_MASK + select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_REQUIRE_GPIOLIB select CLKSRC_MMIO select CPU_XSCALE
arch/arm/mach-ixp4xx/Kconfig +0 -4
@@ -1,9 +1,5 @@ if ARCH_IXP4XX -config ARCH_SUPPORTS_BIG_ENDIAN - bool - default y - menu "Intel IXP4xx Implementation Options" comment "IXP4xx Platforms"
arch/arm/mm/Kconfig +6 -0
@@ -952,3 +952,9 @@ config ARCH_HAS_BARRIERS help This option allows the use of custom mandatory barriers included via the mach/barriers.h file. + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + help + This option specifies the architecture can support big endian + operation.
Signature · 1 line
1.7.10.4
PATCH 2/20 ARM: asm: Add ARM_BE8() assembly helper
In reply to Ben DooksAdd ARM_BE8() helper to wrap any code conditional on being compile when CONFIG_ARM_ENDIAN_BE8 is selected and convert existing places where this is to use it.
--- arch/arm/boot/compressed/head.S | 8 ++------ arch/arm/include/asm/assembler.h | 7 +++++++ arch/arm/kernel/entry-armv.S | 5 ++--- arch/arm/kernel/entry-common.S | 4 +--- arch/arm/mm/abort-ev6.S | 5 ++--- arch/arm/mm/proc-v6.S | 4 +--- arch/arm/mm/proc-v7.S | 4 +--- 7 files changed, 16 insertions(+), 21 deletions(-)
arch/arm/boot/compressed/head.S +2 -6
@@ -699,9 +699,7 @@ __armv4_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x0030 -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r0, r0, #1 << 25 @ big-endian page tables -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables bl __common_mmu_cache_on mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
@@ -728,9 +726,7 @@ __armv7_mmu_cache_on: orr r0, r0, #1 << 22 @ U (v6 unaligned access model) @ (needed for ARM1176) #ifdef CONFIG_MMU -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r0, r0, #1 << 25 @ big-endian page tables -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg orrne r0, r0, #1 @ MMU enabled movne r1, #0xfffffffd @ domain 0 = client
arch/arm/include/asm/assembler.h +7 -0
@@ -53,6 +53,13 @@#define put_byte_3 lsl #0#endif +/* Select code for any configuration running in BE8 mode */ +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define ARM_BE8(code...) code +#else +#define ARM_BE8(code...) +#endif +/* * Data preload for architectures that support it */
arch/arm/kernel/entry-armv.S +2 -3
@@ -416,9 +416,8 @@ __und_usr: bne __und_usr_thumb sub r4, r2, #4 @ ARM instr@LR - 4 1: ldrt r0, [r4] -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r0, r0 @ little endian instruction -#endif + ARM_BE8(rev r0, r0) @ little endian instruction + @ r0 = 32-bit ARM instruction which caused the exception @ r2 = PC value for the following instruction (:= regs->ARM_pc) @ r4 = PC value for the faulting instruction
arch/arm/kernel/entry-common.S +1 -3
@@ -393,9 +393,7 @@ ENTRY(vector_swi) #else USER( ldr r10, [lr, #-4] ) @ get SWI instruction #endif -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r10, r10 @ little endian instruction -#endif + ARM_BE8(rev r10, r10) @ little endian instruction #elif defined(CONFIG_AEABI)
arch/arm/mm/abort-ev6.S +2 -3
@@ -38,9 +38,8 @@ ENTRY(v6_early_abort) bne do_DataAbort bic r1, r1, #1 << 11 @ clear bit 11 of FSR ldr r3, [r4] @ read aborted ARM instruction -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r3, r3 -#endif + ARM_BE8(rev r3, r3) + do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes.
arch/arm/mm/proc-v6.S +1 -3
@@ -220,9 +220,7 @@ __v6_setup: #endif /* CONFIG_MMU */ adr r5, v6_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them
arch/arm/mm/proc-v7.S +1 -3
@@ -355,9 +355,7 @@ __v7_setup: #endif adr r5, v7_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables #ifdef CONFIG_SWP_EMULATE orr r5, r5, #(1 << 10) @ set SW bit in "clear" bic r6, r6, #(1 << 10) @ clear it in "mmuset"
Signature · 1 line
1.7.10.4
PATCH 3/20 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
In reply to Ben DooksThe fixup_pv_table assumes that the instructions are in the same endian configuration as the data, but when the CPU is running in BE8 the instructions stay in little-endian format.
Make sure if CONFIG_CPU_ENDIAN_BE8 is set that we do all the alterations to the instructions taking in to account the LDR/STR will be swapping the data endian-ness.
Since the code is only modifying a byte, we avoid dual-swapping the data, and just change the bits we clear and ORR in (in the case where the code is not thumb2).
For thumb2, we add the necessary rev16 instructions to ensure that the instructions are processed in the correct format, as it was easier than re-writing the code to contain a mask and shift.
--- arch/arm/kernel/head.S | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/kernel/head.S +8 -0
@@ -582,8 +582,10 @@ __fixup_a_pv_table: b 2f 1: add r7, r3 ldrh ip, [r7, #2] +ARM_BE8(rev16 ip, ip) and ip, 0x8f00 orr ip, r6 @ mask in offset bits 31-24 +ARM_BE8(rev16 ip, ip) strh ip, [r7, #2] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot
@@ -592,8 +594,14 @@ __fixup_a_pv_table: #else b 2f 1: ldr ip, [r7, r3] +#ifdef CONFIG_CPU_ENDIAN_BE8 + @ in BE8, we load data in BE, but instructions still in LE + bic ip, ip, #0xff000000 + orr ip, ip, r6, lsl#24 +#else bic ip, ip, #0x000000ff orr ip, ip, r6 @ mask in offset bits 31-24 +#endif str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot
Signature · 1 line
1.7.10.4
PATCH 4/20 ARM: set BE8 if LE in head code
In reply to Ben DooksIf we are booting in LE and compiled for BE8, then add code to set the state to bE8. Since the instruction stream is always LE, we do not need to do anything special to the instruction.
Also ensure that the secondary processors are started in the same mode.
Note, we do add about 20 bytes to the kernel image, but it seems easier to do this than adding another configuration to change.
--- arch/arm/boot/compressed/head.S | 1 + arch/arm/kernel/head.S | 4 ++++ arch/arm/kernel/sleep.S | 1 + 3 files changed, 6 insertions(+)
arch/arm/boot/compressed/head.S +1 -0
@@ -135,6 +135,7 @@ start: .word _edata @ zImage end address THUMB( .thumb ) 1: + ARM_BE8( setend be ) @ go BE8 if compiled for BE8 mrs r9, cpsr #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install @ get into SVC mode, reversibly
arch/arm/kernel/head.S +4 -0
@@ -77,6 +77,7 @@ __HEAD ENTRY(stext) + ARM_BE8(setend be ) @ ensure we are in BE8 mode THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
@@ -352,6 +353,9 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ + + ARM_BE8(setend be) @ ensure we are in BE8 mode + #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install_secondary #endif
arch/arm/kernel/sleep.S +1 -0
@@ -130,6 +130,7 @@ ENDPROC(cpu_resume_after_mmu) .data .align ENTRY(cpu_resume) +ARM_BE8(setend be) @ ensure we are in BE mode mov r1, #0 ALT_SMP(mrc p15, 0, r0, c0, c0, 5) ALT_UP_B(1f)
Signature · 1 line
1.7.10.4
PATCH 5/20 ARM: pl01x debug code endian fix
In reply to Ben DooksThe PL01X debug code needs to take into account which endian mode the processor is running in. If it is big-endian, ensure the data is swapped appropriately.
Note, we could do this slightly more efficiently if we have an macro to do the necessary swap for the bits used by test.
--- arch/arm/include/asm/hardware/debug-pl01x.S | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/include/asm/hardware/debug-pl01x.S +2 -0
@@ -18,12 +18,14 @@ .macro waituart,rd,rx 1001: ldr \rd, [\rx, #UART01x_FR] + ARM_BE8( rev \rd, \rd ) tst \rd, #UART01x_FR_TXFF bne 1001b .endm .macro busyuart,rd,rx 1001: ldr \rd, [\rx, #UART01x_FR] + ARM_BE8( rev \rd, \rd ) tst \rd, #UART01x_FR_BUSY bne 1001b .endm
Signature · 1 line
1.7.10.4
PATCH 6/20 ARM: twd: data endian fix
In reply to Ben DooksEnsure the twd driver uses the correct calls to access the hardware to ensure that we do not end up with data in the wrong endian format.
--- arch/arm/kernel/smp_twd.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm/kernel/smp_twd.c +12 -12
@@ -45,7 +45,7 @@ static void twd_set_mode(enum clock_event_mode mode,case CLOCK_EVT_MODE_PERIODIC : ctrl =TWD_TIMER_CONTROL_ENABLE |TWD_TIMER_CONTROL_IT_ENABLE |TWD_TIMER_CONTROL_PERIODIC ; -__raw_writel (DIV_ROUND_CLOSEST (twd_timer_rate,HZ ), +writel_relaxed (DIV_ROUND_CLOSEST (twd_timer_rate,HZ ), twd_base +TWD_TIMER_LOAD );break ;case CLOCK_EVT_MODE_ONESHOT :
@@ -58,18 +58,18 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl =0 ; } -__raw_writel (ctrl, twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (ctrl, twd_base +TWD_TIMER_CONTROL ); }static int twd_set_next_event (unsigned long evt,struct clock_event_device *unused) { -unsigned long ctrl =__raw_readl (twd_base +TWD_TIMER_CONTROL ); +unsigned long ctrl =readl_relaxed (twd_base +TWD_TIMER_CONTROL ); ctrl |=TWD_TIMER_CONTROL_ENABLE ; -__raw_writel (evt, twd_base +TWD_TIMER_COUNTER ); -__raw_writel (ctrl, twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (evt, twd_base +TWD_TIMER_COUNTER ); +writel_relaxed (ctrl, twd_base +TWD_TIMER_CONTROL );return 0 ; }
@@ -82,8 +82,8 @@ static int twd_set_next_event(unsigned long evt,*/ static int twd_timer_ack (void ) { -if (__raw_readl (twd_base +TWD_TIMER_INTSTAT )) { -__raw_writel (1 , twd_base +TWD_TIMER_INTSTAT ); +if (readl_relaxed (twd_base +TWD_TIMER_INTSTAT )) { +writel_relaxed (1 , twd_base +TWD_TIMER_INTSTAT );return 1 ; }
@@ -209,15 +209,15 @@ static void twd_calibrate_rate(void) waitjiffies +=5 ;/* enable, no interrupt or reload */ -__raw_writel (0x1 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0x1 , twd_base +TWD_TIMER_CONTROL );/* maximum value */ -__raw_writel (0xFFFFFFFFU , twd_base +TWD_TIMER_COUNTER ); +writel_relaxed (0xFFFFFFFFU , twd_base +TWD_TIMER_COUNTER );while (get_jiffies_64 () < waitjiffies)udelay (10 ); - count =__raw_readl (twd_base +TWD_TIMER_COUNTER ); + count =readl_relaxed (twd_base +TWD_TIMER_COUNTER ); twd_timer_rate = (0xFFFFFFFFU - count) * (HZ /5 );
@@ -275,7 +275,7 @@ static int twd_timer_setup(struct clock_event_device *clk)* bother with the below. */ if (per_cpu (percpu_setup_called, cpu)) { -__raw_writel (0 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0 , twd_base +TWD_TIMER_CONTROL );clockevents_register_device (*__this_cpu_ptr (twd_evt));enable_percpu_irq (clk->irq,0 );return 0 ;
@@ -288,7 +288,7 @@ static int twd_timer_setup(struct clock_event_device *clk)* The following is done once per CPU the first time .setup() is * called. */ -__raw_writel (0 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0 , twd_base +TWD_TIMER_CONTROL ); clk->name ="local_timer" ; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
Signature · 1 line
1.7.10.4
PATCH 7/20 ARM: smp_scu: data endian fixes
In reply to Ben DooksThe smp_scu driver needs to use the relaxed readl/write accessors to avoid any issues with the endian mode the processor core is in.
--- arch/arm/kernel/smp_scu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
arch/arm/kernel/smp_scu.c +7 -7
@@ -28,7 +28,7 @@*/ unsigned int __init scu_get_core_count (void __iomem *scu_base) { -unsigned int ncores =__raw_readl (scu_base +SCU_CONFIG ); +unsigned int ncores =readl_relaxed (scu_base +SCU_CONFIG );return (ncores &0x03 ) +1 ; }
@@ -42,19 +42,19 @@ void scu_enable(void __iomem *scu_base)#ifdef CONFIG_ARM_ERRATA_764369 /* Cortex-A9 only */ if ((read_cpuid_id () &0xff0ffff0 ) ==0x410fc090 ) { - scu_ctrl =__raw_readl (scu_base +0x30 ); + scu_ctrl =readl_relaxed (scu_base +0x30 );if (!(scu_ctrl &1 )) -__raw_writel (scu_ctrl |0x1 , scu_base +0x30 ); +writel_relaxed (scu_ctrl |0x1 , scu_base +0x30 ); }#endif - scu_ctrl =__raw_readl (scu_base +SCU_CTRL ); + scu_ctrl =readl_relaxed (scu_base +SCU_CTRL );/* already enabled? */ if (scu_ctrl &1 )return ; scu_ctrl |=1 ; -__raw_writel (scu_ctrl, scu_base +SCU_CTRL ); +writel_relaxed (scu_ctrl, scu_base +SCU_CTRL );/* * Ensure that the data accessed by CPU0 before the SCU was
@@ -80,9 +80,9 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode)if (mode >3 || mode ==1 || cpu >3 )return -EINVAL ; - val =__raw_readb (scu_base +SCU_CPU_STATUS + cpu) & ~0x03 ; + val =readb_relaxed (scu_base +SCU_CPU_STATUS + cpu) & ~0x03 ; val |= mode; -__raw_writeb (val, scu_base +SCU_CPU_STATUS + cpu); +writeb_relaxed (val, scu_base +SCU_CPU_STATUS + cpu);return 0 ; }
Signature · 1 line
1.7.10.4
PATCH 8/20 highbank: enable big-endian
In reply to Ben DooksApart from a xgmac driver issue, the highbank seems to work correctly in big-endian mode. Allow the selection of big-endian in the system.
--- arch/arm/mach-highbank/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mach-highbank/Kconfig +2 -0
@@ -2,6 +2,7 @@ config ARCH_HIGHBANK bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7 select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP + select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_AMBA select ARM_GIC
@@ -18,3 +19,4 @@ config ARCH_HIGHBANK select PL320_MBOX select SPARSE_IRQ select USE_OF +
Signature · 1 line
1.7.10.4
PATCH 8/20 highbank: enable big-endian
Quoted 4 lines · Ben Dooks
Apart from a xgmac driver issue, the highbank seems to work correctly in big-endian mode. Allow the selection of big-endian in the system.
Signed-off-by Ben Dooks <[email protected]>
Rob
PATCH 8/20 highbank: enable big-endian
In reply to Ben DooksHello.
Quoted 12 lines · Ben Dooks
Apart from a xgmac driver issue, the highbank seems to work correctly in big-endian mode. Allow the selection of big-endian in the system.
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/mach-highbank/Kconfig | 2 ++ 1 file changed, 2 insertions(+)arch/arm/mach-highbank/Kconfig +0
-0
[...]
arch/arm/mach-highbank/Kconfig config ARCH_HIGHBANK · line 22
Quoted 5 lines
arch/arm/mach-highbank/Kconfig +1
-0@@ -18,3 +19,4 @@ config ARCH_HIGHBANK select PL320_MBOX select SPARSE_IRQ select USE_OF +
I don't think you really intended to add this line at end of file.
WBR, Sergei
PATCH 9/20 mvebu: support running big-endian
In reply to Ben DooksAdd indication we can run these cores in BE mode, and ensure that the secondary CPU is set to big-endian mode in the initialisation code as the initial code runs little-endian.
--- arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/coherency_ll.S | 3 +++ arch/arm/mach-mvebu/headsmp.S | 4 ++++ 3 files changed, 8 insertions(+)
arch/arm/mach-mvebu/Kconfig +1 -0
@@ -1,5 +1,6 @@ config ARCH_MVEBU bool "Marvell SOCs with Device Tree support" if ARCH_MULTI_V7 + select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_MMIO select COMMON_CLK select GENERIC_CLOCKEVENTS
arch/arm/mach-mvebu/coherency_ll.S +3 -0
@@ -20,6 +20,8 @@ #define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0 #define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4 +#include <asm/assembler.h> + .text /* * r0: Coherency fabric base register address
@@ -29,6 +31,7 @@ ENTRY(ll_set_cpu_coherent) /* Create bit by cpu index */ mov r3, #(1 << 24) lsl r1, r3, r1 +ARM_BE8(rev r1, r1) /* Add CPU to SMP group - Atomic */ add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
arch/arm/mach-mvebu/headsmp.S +4 -0
@@ -21,12 +21,16 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> + /* * Armada XP specific entry point for secondary CPUs. * We add the CPU to the coherency fabric and then jump to secondary * startup */ ENTRY(armada_xp_secondary_startup) + ARM_BE8(setend be ) @ go BE8 if entered LE + /* Get coherency fabric base physical address */ adr r0, 1f ldr r1, [r0]
Signature · 1 line
1.7.10.4
PATCH 10/20 vexpress: add big endian support
In reply to Ben DooksAdd support for the versatile express systems to boot big-endian.
--- arch/arm/mach-vexpress/Kconfig | 1 + arch/arm/plat-versatile/headsmp.S | 2 ++ 2 files changed, 3 insertions(+)
arch/arm/mach-vexpress/Kconfig +1 -0
@@ -1,6 +1,7 @@ config ARCH_VEXPRESS bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 select ARCH_REQUIRE_GPIOLIB + select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804
arch/arm/plat-versatile/headsmp.S +2 -0
@@ -10,6 +10,7 @@ */ #include <linux/linkage.h> #include <linux/init.h> +#include <asm/assembler.h> /* * Realview/Versatile Express specific entry point for secondary CPUs.
@@ -17,6 +18,7 @@ * until we're ready for them to initialise. */ ENTRY(versatile_secondary_startup) + ARM_BE8(setend be) mrc p15, 0, r0, c0, c0, 5 bic r0, #0xff000000 adr r4, 1f
Signature · 1 line
1.7.10.4
PATCH 11/20 ARM: alignment: correctly decode instructions in BE8 mode.
In reply to Ben DooksIf we are in BE8 mode, we must deal with the instruction stream being in LE order when data is being loaded in BE order. Ensure the data is swapped before processing to avoid thre following:
Change to using <asm/opcodes.h> to provide the necessary conversion functions to change the byte ordering.
This stops the following warning messages from the kernel on a fault:
Unhandled fault: alignment exception (0x001) at 0xbfa09567 Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
--- arch/arm/mm/alignment.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/arm/mm/alignment.c +7 -2
@@ -25,6 +25,7 @@#include <asm/cp15.h> #include <asm/system_info.h> #include <asm/unaligned.h> +#include <asm/opcodes.h> #include "fault.h"
@@ -762,21 +763,25 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if (thumb_mode (regs)) {u16 *ptr = (u16 *)(instrptr & ~1 ); fault =probe_kernel_address (ptr, tinstr); + tinstr =__mem_to_opcode_thumb16 (tinstr);if (!fault) {if (cpu_architecture () >= CPU_ARCH_ARMv7 &&IS_T32 (tinstr)) {/* Thumb-2 32-bit */ u16 tinst2 =0 ; fault =probe_kernel_address (ptr +1 , tinst2); - instr = (tinstr <<16 ) | tinst2; + tinst2 =__mem_to_opcode_thumb16 (tinst2); + instr =__opcode_thumb32_compose (tinstr, tinst2); thumb2_32b =1 ; }else { isize =2 ; instr =thumb2arm (tinstr); } } - }else + }else { fault =probe_kernel_address (instrptr, instr); + instr =__mem_to_opcode_arm (instr); + }if (fault) { type =TYPE_FAULT ;
Signature · 1 line
1.7.10.4
PATCH 12/20 ARM: traps: use <asm/opcodes.h> to get correct instruction order
In reply to Ben DooksThe trap handler needs to take into account the endian configuration of the system when loading instructions. Use <asm/opcodes.h> to provide the necessary conversion functions.
--- arch/arm/kernel/traps.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
arch/arm/kernel/traps.c +10 -6
@@ -34,6 +34,7 @@#include <asm/unwind.h> #include <asm/tls.h> #include <asm/system_misc.h> +#include <asm/opcodes.h> static const char *handler[]= {"prefetch abort" ,"data abort" ,"address exception" ,"interrupt" };
@@ -402,25 +403,28 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)if (processor_mode (regs) ==SVC_MODE ) {#ifdef CONFIG_THUMB2_KERNEL if (thumb_mode (regs)) { - instr = ((u16 *)pc)[0 ]; + instr =__mem_to_opcode_thumb16 (((u16 *)pc)[0 ]);if (is_wide_instruction (instr)) { - instr <<=16 ; - instr |= ((u16 *)pc)[1 ]; +u16 inst2; + instr2 =__mem_to_opcode_thumb16 (((u16 *)pc)[1 ]); + instr =__opcode_thumb32_compose (instr, instr2); } } else#endif - instr = *(u32 *) pc; + instr =__mem_to_opcode_arm (*(u32 *) pc); }else if (thumb_mode (regs)) {if (get_user (instr, (u16 __user *)pc)) goto die_sig; + instr =__mem_to_opcode_thumb16 (instr);if (is_wide_instruction (instr)) {unsigned int instr2;if (get_user (instr2, (u16 __user *)pc+1 )) goto die_sig; - instr <<=16 ; - instr |= instr2; + instr2 =__mem_to_opcode_thumb16 (instr2); + instr =__opcode_thumb32_compose (instr, instr2); } }else if (get_user (instr, (u32 __user *)pc)) { + instr =__mem_to_opcode_arm (instr); goto die_sig; }
Signature · 1 line
1.7.10.4
PATCH 13/20 ARM: module: correctly relocate instructions in BE8
In reply to Ben DooksWhen in BE8 mode, our instructions are not in the same ordering as the data, so use <asm/opcodes.h> to take this into account.
Note, also requires modules to be built --be8
--- arch/arm/kernel/module.c | 57 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-)
arch/arm/kernel/module.c +34 -23
@@ -24,6 +24,7 @@#include <asm/sections.h> #include <asm/smp_plat.h> #include <asm/unwind.h> +#include <asm/opcodes.h> #ifdef CONFIG_XIP_KERNEL /*
@@ -60,6 +61,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,Elf32_Sym *sym;const char *symname;s32 offset; +u32 tmp;#ifdef CONFIG_THUMB2_KERNEL u32 upper, lower, sign, j1, j2;#endif
@@ -95,7 +97,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,case R_ARM_PC24 :case R_ARM_CALL :case R_ARM_JUMP24 : - offset = (*(u32 *)loc &0x00ffffff ) <<2 ; + offset =__mem_to_opcode_arm (*(u32 *)loc); + offset = (offset &0x00ffffff ) <<2 ;if (offset &0x02000000 ) offset -=0x04000000 ;
@@ -111,9 +114,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, } offset >>=2 ; + offset &=0x00ffffff ; - *(u32 *)loc &=0xff000000 ; - *(u32 *)loc |= offset &0x00ffffff ; + *(u32 *)loc &=__opcode_to_mem_arm (0xff000000 ); + *(u32 *)loc |=__opcode_to_mem_arm (offset);break ;case R_ARM_V4BX :
@@ -121,8 +125,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,* other bits to re-code instruction as * MOV PC,Rm. */ - *(u32 *)loc &=0xf000000f ; - *(u32 *)loc |=0x01a0f000 ; + *(u32 *)loc &=__opcode_to_mem_arm (0xf000000f ); + *(u32 *)loc |=__opcode_to_mem_arm (0x01a0f000 );break ;case R_ARM_PREL31 :
@@ -132,7 +136,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,case R_ARM_MOVW_ABS_NC :case R_ARM_MOVT_ABS : - offset = *(u32 *)loc; + offset = tmp =__mem_to_opcode_arm (*(u32 *)loc); offset = ((offset &0xf0000 ) >>4 ) | (offset &0xfff ); offset = (offset ^0x8000 ) -0x8000 ;
@@ -140,16 +144,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,if (ELF32_R_TYPE (rel->r_info) ==R_ARM_MOVT_ABS ) offset >>=16 ; - *(u32 *)loc &=0xfff0f000 ; - *(u32 *)loc |= ((offset &0xf000 ) <<4 ) | - (offset &0x0fff ); + tmp &=0xfff0f000 ; + tmp |= ((offset &0xf000 ) <<4 ) | + (offset &0x0fff ); + + *(u32 *)loc =__opcode_to_mem_arm (tmp);break ;#ifdef CONFIG_THUMB2_KERNEL case R_ARM_THM_CALL :case R_ARM_THM_JUMP24 : - upper = *(u16 *)loc; - lower = *(u16 *)(loc +2 ); + upper =__mem_to_opcode_thumb16 (*(u16 *)loc); + lower =__mem_to_opcode_thumb16 (*(u16 *)(loc +2 ));/* * 25 bit signed address range (Thumb-2 BL and B.W
@@ -198,17 +204,20 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sign = (offset >>24 ) &1 ; j1 = sign ^ (~(offset >>23 ) &1 ); j2 = sign ^ (~(offset >>22 ) &1 ); - *(u16 *)loc = (u16)((upper &0xf800 ) | (sign <<10 ) | + upper = (u16)((upper &0xf800 ) | (sign <<10 ) | ((offset >>12 ) &0x03ff )); - *(u16 *)(loc +2 ) = (u16)((lower &0xd000 ) | - (j1 <<13 ) | (j2 <<11 ) | - ((offset >>1 ) &0x07ff )); + lower = (u16)((lower &0xd000 ) | + (j1 <<13 ) | (j2 <<11 ) | + ((offset >>1 ) &0x07ff )); + + *(u16 *)loc =__opcode_to_mem_thumb16 (upper); + *(u16 *)(loc +2 ) =__opcode_to_mem_thumb16 (lower);break ;case R_ARM_THM_MOVW_ABS_NC :case R_ARM_THM_MOVT_ABS : - upper = *(u16 *)loc; - lower = *(u16 *)(loc +2 ); + upper =__mem_to_opcode_thumb16 (*(u16 *)loc); + lower =__mem_to_opcode_thumb16 (*(u16 *)(loc +2 ));/* * MOVT/MOVW instructions encoding in Thumb-2:
@@ -229,12 +238,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,if (ELF32_R_TYPE (rel->r_info) ==R_ARM_THM_MOVT_ABS ) offset >>=16 ; - *(u16 *)loc = (u16)((upper &0xfbf0 ) | - ((offset &0xf000 ) >>12 ) | - ((offset &0x0800 ) >>1 )); - *(u16 *)(loc +2 ) = (u16)((lower &0x8f00 ) | - ((offset &0x0700 ) <<4 ) | - (offset &0x00ff )); + upper = (u16)((upper &0xfbf0 ) | + ((offset &0xf000 ) >>12 ) | + ((offset &0x0800 ) >>1 )); + lower = (u16)((lower &0x8f00 ) | + ((offset &0x0700 ) <<4 ) | + (offset &0x00ff )); + *(u16 *)loc =__opcode_to_mem_thumb16 (upper); + *(u16 *)(loc +2 ) =__opcode_to_mem_thumb16 (lower);break ;#endif
Signature · 1 line
1.7.10.4
PATCH 14/20 ARM: set --be8 when linking modules
In reply to Ben DooksTo avoid having to make every text section swap the instruction order of all instructions, make sure modules are built also built with --be8 (as is the current kernel final link).
If we do not do this, we would end up having to swap all instructions when loading a module, instead of just the instructions that we are applying ELF relocations to.
--- arch/arm/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/arm/Makefile +1 -0
@@ -16,6 +16,7 @@ LDFLAGS := LDFLAGS_vmlinux :=-p --no-undefined -X ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 +LDFLAGS_MODULE += --be8 endif OBJCOPYFLAGS :=-O binary -R .comment -S
Signature · 1 line
1.7.10.4
PATCH 15/20 ARM: hardware: fix endian-ness in <hardware/coresight.h>
In reply to Ben DooksThe <hardware/coresight.h> needs to take into account the endian-ness of the processor when reading and writing data, so change to using the readl/writel relaxed variants from the raw ones.
--- arch/arm/include/asm/hardware/coresight.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/include/asm/hardware/coresight.h +4 -4
@@ -24,8 +24,8 @@#define TRACER_TIMEOUT 10000#define etm_writel (t, v, x) \ - (__raw_writel((v), (t)->etm_regs + (x))) -#define etm_readl (t, x) (__raw_readl((t)->etm_regs + (x))) + (writel_relaxed((v), (t)->etm_regs + (x))) +#define etm_readl (t, x) (readl_relaxed((t)->etm_regs + (x)))/* CoreSight Management Registers */ #define CSMR_LOCKACCESS 0xfb0
@@ -142,8 +142,8 @@#define ETBFF_TRIGFL BIT(10)#define etb_writel (t, v, x) \ - (__raw_writel((v), (t)->etb_regs + (x))) -#define etb_readl (t, x) (__raw_readl((t)->etb_regs + (x))) + (writel_relaxed((v), (t)->etb_regs + (x))) +#define etb_readl (t, x) (readl_relaxed((t)->etb_regs + (x)))#define etm_lock (t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)#define etm_unlock (t) \
Signature · 1 line
1.7.10.4
PATCH 16/20 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c
In reply to Ben DooksUse <asm/opcodes.h> to correctly transform instruction byte ordering into in-memory ordering.
--- arch/arm/net/bpf_jit_32.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/net/bpf_jit_32.c +5 -1
@@ -19,6 +19,7 @@#include <linux/if_vlan.h> #include <asm/cacheflush.h> #include <asm/hwcap.h> +#include <asm/opcodes.h> #include "bpf_jit_32.h"
@@ -113,8 +114,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor)static inline void _emit (int cond,u32 inst,struct jit_ctx *ctx) { + inst |= (cond <<28 ); + inst =__opcode_to_mem_arm (inst); +if (ctx->target !=NULL ) - ctx->target[ctx->idx] = inst | (cond <<28 ); + ctx->target[ctx->idx] = inst; ctx->idx++; }
Signature · 1 line
1.7.10.4
PATCH 17/20 ARM: Correct BUG() assembly to ensure it is endian-agnostic
In reply to Ben DooksCurrently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text. This means that the BUG() macro does not get trapped properly.
Change to using <asm/opcodes.h> to provide the necessary ARM instruction building as we cannot rely on gcc/gas having the .inst instructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).
--- arch/arm/include/asm/bug.h | 10 ++++++---- arch/arm/kernel/traps.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
@@ -2,6 +2,8 @@#define _ASMARM_BUG_H#include <linux/linkage.h> +#include <linux/types.h> +#include <asm/opcodes.h> #ifdef CONFIG_BUG
@@ -12,10 +14,10 @@*/ #ifdef CONFIG_THUMB2_KERNEL #define BUG_INSTR_VALUE 0xde02 -#define BUG_INSTR_TYPE ".hword " +#define BUG_INSTR (__value) __inst_thumb16(__value)#else #define BUG_INSTR_VALUE 0xe7f001f2 -#define BUG_INSTR_TYPE ".word " +#define BUG_INSTR (__value) __inst_arm(__value)#endif
@@ -33,7 +35,7 @@#define __BUG (__file, __line, __value) \ do { \ - asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n" \ + asm volatile("1:\t" BUG_INSTR(__value) "\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ "2:\t.asciz " #__file "\n" \ ".popsection\n" \
@@ -48,7 +50,7 @@ do { \#define __BUG (__file, __line, __value) \ do { \ - asm volatile(BUG_INSTR_TYPE #__value); \ + asm volatile(BUG_INSTR(__value) "\n"); \ unreachable(); \ } while (0)#endif /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
@@ -342,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,int is_valid_bugaddr (unsigned long pc) {#ifdef CONFIG_THUMB2_KERNEL -unsigned short bkpt; +u16 bkpt; +u16 insn =__opcode_to_mem_thumb16 (BUG_INSTR_VALUE );#else -unsigned long bkpt; +u32 bkpt; +u32 insn =__opcode_to_mem_arm (BUG_INSTR_VALUE );#endif if (probe_kernel_address ((unsigned *)pc, bkpt))return 0 ; -return bkpt ==BUG_INSTR_VALUE ; +return bkpt == insn; }#endif
Signature · 1 line
1.7.10.4
PATCH 18/20 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
In reply to Ben DooksThe arch_kgdb_breakpoint() function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.
As noted, this code means that kgdb is really only usable on arm32 kernels, and should be made dependant on not being a thumb2 kernel until fixed. However this is not something to be added to this patch.
--- arch/arm/include/asm/kgdb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
@@ -11,6 +11,7 @@#define __ARM_KGDB_H__#include <linux/ptrace.h> +#include <asm/opcodes.h> /* * GDB assumes that we're a user process being debugged, so
@@ -41,7 +42,7 @@static inline void arch_kgdb_breakpoint (void ) { - asm(".word 0xe7ffdeff" ); + asm(__inst_arm(0xe7ffdeff)); }extern void kgdb_handle_bus_error (void );
Signature · 1 line
1.7.10.4
PATCH 19/20 ARM: atomic64: fix endian-ness in atomic.h
In reply to Ben DooksFrom: Victor Kamensky <[email protected]>
Fix inline asm for atomic64_xxx functions in arm atomic.h. Instead of %H operand specifiers code should use %Q for least significant part of the value, and %R for the most significant part of the value. %H always returns the higher of the two register numbers, and therefore it is not endian neutral. %H should be used with ldrexd and strexd instructions.
--- arch/arm/include/asm/atomic.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
arch/arm/include/asm/atomic.h +13 -13
@@ -301,8 +301,8 @@ static inline void atomic64_add(u64 i, atomic64_t *v) __asm__ __volatile__("@ atomic64_add\n" "1: ldrexd %0, %H0, [%3]\n" -" adds %0, %0, %4\n" -" adc %H0, %H0, %H4\n" +" adds %Q0, %Q0, %Q4\n" +" adc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b"
@@ -320,8 +320,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) __asm__ __volatile__("@ atomic64_add_return\n" "1: ldrexd %0, %H0, [%3]\n" -" adds %0, %0, %4\n" -" adc %H0, %H0, %H4\n" +" adds %Q0, %Q0, %Q4\n" +" adc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b"
@@ -341,8 +341,8 @@ static inline void atomic64_sub(u64 i, atomic64_t *v) __asm__ __volatile__("@ atomic64_sub\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, %4\n" -" sbc %H0, %H0, %H4\n" +" subs %Q0, %Q0, %Q4\n" +" sbc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b"
@@ -360,8 +360,8 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v) __asm__ __volatile__("@ atomic64_sub_return\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, %4\n" -" sbc %H0, %H0, %H4\n" +" subs %Q0, %Q0, %Q4\n" +" sbc %R0, %R0, %R4\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n" " bne 1b"
@@ -428,9 +428,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v) __asm__ __volatile__("@ atomic64_dec_if_positive\n" "1: ldrexd %0, %H0, [%3]\n" -" subs %0, %0, #1\n" -" sbc %H0, %H0, #0\n" -" teq %H0, #0\n" +" subs %Q0, %Q0, #1\n" +" sbc %R0, %R0, #0\n" +" teq %R0, #0\n" " bmi 2f\n" " strexd %1, %0, %H0, [%3]\n" " teq %1, #0\n"
@@ -459,8 +459,8 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)" teqeq %H0, %H5\n" " moveq %1, #0\n" " beq 2f\n" -" adds %0, %0, %6\n" -" adc %H0, %H0, %H6\n" +" adds %Q0, %Q0, %Q6\n" +" adc %R0, %R0, %R6\n" " strexd %2, %0, %H0, [%4]\n" " teq %2, #0\n" " bne 1b\n"
Signature · 1 line
1.7.10.4
PATCH 20/20 ARM: signal: sigreturn_codes should be endian neutral to work in BE8
In reply to Ben DooksFrom: Victor Kamensky <[email protected]>
In case of BE8 kernel data is in BE order whereas code stays in LE order. Move sigreturn_codes to separate .S file and use proper assembler mnemonics for these code snippets. In this case compiler will take care of proper instructions byteswaps for BE8 case. Change assumes that sufficiently Thumb-capable tools are used to build kernel.
Problem was discovered during ltp testing of BE system: all rt_sig* tests failed. Tested against the same tests in both BE and LE modes.
--- arch/arm/kernel/Makefile | 3 +- arch/arm/kernel/signal.c | 24 +------------ arch/arm/kernel/sigreturn_codes.S | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 24 deletions(-) create mode 100644 arch/arm/kernel/sigreturn_codes.S
arch/arm/kernel/Makefile +2 -1
@@ -17,7 +17,8 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o \ - setup.o signal.o stacktrace.o sys_arm.o time.o traps.o + setup.o signal.o sigreturn_codes.o \ + stacktrace.o sys_arm.o time.o traps.o obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
arch/arm/kernel/signal.c +1 -23
@@ -21,29 +21,7 @@#include <asm/unistd.h> #include <asm/vfp.h> -/* -* For ARM syscalls, we encode the syscall number into the instruction. -*/ -#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) -#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) - -/* -* With EABI, the syscall number has to be loaded into r7. -*/ -#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE)) -#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) - -/* -* For Thumb syscalls, we pass the syscall number via r7. We therefore -* need two 16-bit instructions. -*/ -#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) -#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) - -static const unsigned long sigreturn_codes[7 ] = { -MOV_R7_NR_SIGRETURN ,SWI_SYS_SIGRETURN ,SWI_THUMB_SIGRETURN , -MOV_R7_NR_RT_SIGRETURN ,SWI_SYS_RT_SIGRETURN ,SWI_THUMB_RT_SIGRETURN , -}; +extern const unsigned long sigreturn_codes[7 ];static unsigned long signal_return_offset;
arch/arm/kernel/sigreturn_codes.S new file +69 -0
69 lines not on this page · raw message
Signature · 1 line
1.7.10.4