All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] AArch64 BE Support
@ 2013-10-11 13:52 Matthew Leach
  2013-10-11 13:52 ` [PATCH 01/14] Docs: arm64: booting: clarify boot requirements Matthew Leach
                   ` (13 more replies)
  0 siblings, 14 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch series adds big-endian support to the arm64 kernel. It has
been tested successfully with LTP on both AArch32 and AArch64
userspace configurations. There were no regressions reported over a
little-endian system.

The first patch (from Mark Rutland) clarifies the booting
requirements, which is needed for a big-endian kernel boot. The bulk
of the patches fix up issues in the architectural port, with the last
patch fixing an endianness assumption in the smc91x network driver.

Whilst there is another series of BE patches currently on the list:

  http://lists.infradead.org/pipermail/linux-arm-kernel/2013-October/204031.html

we believe that our work is both more complete and has been subjected
to substantial testing effort.

All comments welcome,

Matt

Mark Rutland (1):
  Docs: arm64: booting: clarify boot requirements

Matthew Leach (6):
  arm64: compat: correct register concatenation for syscall wrappers
  arm64: big-endian: don't treat code as data when copying sigret code
  arm64: asm: add CPU_LE & CPU_BE assembler helpers
  arm64: head: create a new function for setting the boot_cpu_mode flag
  arm64: big-endian: set correct endianess on kernel entry
  arm64: big-endian: write CPU holding pen address as LE

Will Deacon (7):
  arm64: big-endian: add big-endian support to top-level arch Makefile
  arm64: big-endian: fix byteorder include
  arm64: ELF: add support for big-endian executables
  arm64: setup: report ELF_PLATFORM as the machine for utsname
  arm64: compat: add support for big-endian (BE8) AArch32 binaries
  arm64: kconfig: allow CPU_BIG_ENDIAN to be selected
  net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data

 Documentation/arm64/booting.txt         |   45 +++++++++++++++++++---------
 arch/arm64/Kconfig                      |    5 ++++
 arch/arm64/Makefile                     |    6 ++++
 arch/arm64/include/asm/assembler.h      |   31 +++++++++++++++++++
 arch/arm64/include/asm/compat.h         |   14 +++++++++
 arch/arm64/include/asm/elf.h            |   18 ++++++++++++
 arch/arm64/include/asm/processor.h      |    5 ++++
 arch/arm64/include/asm/ptrace.h         |    1 +
 arch/arm64/include/asm/virt.h           |    3 +-
 arch/arm64/include/uapi/asm/byteorder.h |    4 +++
 arch/arm64/kernel/Makefile              |    2 +-
 arch/arm64/kernel/head.S                |   49 ++++++++++++++++++++++++-------
 arch/arm64/kernel/kuser32.S             |   42 ++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c               |    2 +-
 arch/arm64/kernel/signal32.c            |   28 ------------------
 arch/arm64/kernel/smp_spin_table.c      |   11 ++++++-
 arch/arm64/kernel/sys32.S               |   22 +++++++-------
 arch/arm64/kernel/vdso.c                |    5 +++-
 arch/arm64/mm/proc.S                    |    4 +--
 drivers/net/ethernet/smsc/smc91x.h      |    6 ++--
 20 files changed, 228 insertions(+), 75 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 01/14] Docs: arm64: booting: clarify boot requirements
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 02/14] arm64: big-endian: add big-endian support to top-level arch Makefile Matthew Leach
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Mark Rutland <mark.rutland@arm.com>

There are a few points in the arm64 booting document which are unclear
(such as the initial state of secondary CPUs), and/or have not been
documented (PSCI is a supported mechanism for booting secondary CPUs).

This patch amends the arm64 boot document to better express the
(existing) requirements, and to describe PSCI as a supported booting
mechanism.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dave Martin <dave.martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Fu Wei <tekkamanninja@gmail.com>
---
 Documentation/arm64/booting.txt |   45 +++++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt
index 98df4a0..a9691cc 100644
--- a/Documentation/arm64/booting.txt
+++ b/Documentation/arm64/booting.txt
@@ -115,9 +115,10 @@ Before jumping into the kernel, the following conditions must be met:
   External caches (if present) must be configured and disabled.
 
 - Architected timers
-  CNTFRQ must be programmed with the timer frequency.
-  If entering the kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0)
-  set where available.
+  CNTFRQ must be programmed with the timer frequency and CNTVOFF must
+  be programmed with a consistent value on all CPUs.  If entering the
+  kernel at EL1, CNTHCTL_EL2 must have EL1PCTEN (bit 0) set where
+  available.
 
 - Coherency
   All CPUs to be booted by the kernel must be part of the same coherency
@@ -130,30 +131,46 @@ Before jumping into the kernel, the following conditions must be met:
   the kernel image will be entered must be initialised by software at a
   higher exception level to prevent execution in an UNKNOWN state.
 
+The requirements described above for CPU mode, caches, MMUs, architected
+timers, coherency and system registers apply to all CPUs.  All CPUs must
+enter the kernel in the same exception level.
+
 The boot loader is expected to enter the kernel on each CPU in the
 following manner:
 
 - The primary CPU must jump directly to the first instruction of the
   kernel image.  The device tree blob passed by this CPU must contain
-  for each CPU node:
-
-    1. An 'enable-method' property. Currently, the only supported value
-       for this field is the string "spin-table".
-
-    2. A 'cpu-release-addr' property identifying a 64-bit,
-       zero-initialised memory location.
+  an 'enable-method' property for each cpu node.  The supported
+  enable-methods are described below.
 
   It is expected that the bootloader will generate these device tree
   properties and insert them into the blob prior to kernel entry.
 
-- Any secondary CPUs must spin outside of the kernel in a reserved area
-  of memory (communicated to the kernel by a /memreserve/ region in the
+- CPUs with a "spin-table" enable-method must have a 'cpu-release-addr'
+  property in their cpu node.  This property identifies a
+  naturally-aligned 64-bit zero-initalised memory location.
+
+  These CPUs should spin outside of the kernel in a reserved area of
+  memory (communicated to the kernel by a /memreserve/ region in the
   device tree) polling their cpu-release-addr location, which must be
   contained in the reserved region.  A wfe instruction may be inserted
   to reduce the overhead of the busy-loop and a sev will be issued by
   the primary CPU.  When a read of the location pointed to by the
-  cpu-release-addr returns a non-zero value, the CPU must jump directly
-  to this value.
+  cpu-release-addr returns a non-zero value, the CPU must jump to this
+  value.  The value will be written as a single 64-bit little-endian
+  value, so CPUs must convert the read value to their native endianness
+  before jumping to it.
+
+- CPUs with a "psci" enable method should remain outside of
+  the kernel (i.e. outside of the regions of memory described to the
+  kernel in the memory node, or in a reserved area of memory described
+  to the kernel by a /memreserve/ region in the device tree).  The
+  kernel will issue CPU_ON calls as described in ARM document number ARM
+  DEN 0022A ("Power State Coordination Interface System Software on ARM
+  processors") to bring CPUs into the kernel.
+
+  The device tree should contain a 'psci' node, as described in
+  Documentation/devicetree/bindings/arm/psci.txt.
 
 - Secondary CPU general-purpose register settings
   x0 = 0 (reserved for future use)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 02/14] arm64: big-endian: add big-endian support to top-level arch Makefile
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
  2013-10-11 13:52 ` [PATCH 01/14] Docs: arm64: booting: clarify boot requirements Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 03/14] arm64: big-endian: fix byteorder include Matthew Leach
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch adds big-endian support to the AArch64 top-level Makefile.
This currently just passes the relevant flags to the toolchain and is
predicated on a Kconfig option that will be introduced later on.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Makefile |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index d90cf79..2fceb71 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -20,9 +20,15 @@ LIBGCC 		:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 KBUILD_DEFCONFIG := defconfig
 
 KBUILD_CFLAGS	+= -mgeneral-regs-only
+ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
+KBUILD_CPPFLAGS	+= -mbig-endian
+AS		+= -EB
+LD		+= -EB
+else
 KBUILD_CPPFLAGS	+= -mlittle-endian
 AS		+= -EL
 LD		+= -EL
+endif
 
 comma = ,
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 03/14] arm64: big-endian: fix byteorder include
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
  2013-10-11 13:52 ` [PATCH 01/14] Docs: arm64: booting: clarify boot requirements Matthew Leach
  2013-10-11 13:52 ` [PATCH 02/14] arm64: big-endian: add big-endian support to top-level arch Makefile Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 04/14] arm64: ELF: add support for big-endian executables Matthew Leach
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

For big-endian processors, we must include
linux/byteorder/big_endian.h to get the relevant definitions for
swabbing between CPU order and a defined endianness.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/uapi/asm/byteorder.h |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/byteorder.h b/arch/arm64/include/uapi/asm/byteorder.h
index 2b92046..dc19e95 100644
--- a/arch/arm64/include/uapi/asm/byteorder.h
+++ b/arch/arm64/include/uapi/asm/byteorder.h
@@ -16,6 +16,10 @@
 #ifndef __ASM_BYTEORDER_H
 #define __ASM_BYTEORDER_H
 
+#ifdef __AARCH64EB__
+#include <linux/byteorder/big_endian.h>
+#else
 #include <linux/byteorder/little_endian.h>
+#endif
 
 #endif	/* __ASM_BYTEORDER_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 04/14] arm64: ELF: add support for big-endian executables
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (2 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 03/14] arm64: big-endian: fix byteorder include Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 05/14] arm64: setup: report ELF_PLATFORM as the machine for utsname Matthew Leach
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch adds support for the aarch64_be ELF format to the AArch64 ELF
loader.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/elf.h |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index e7fa87f..a3e4a55 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -90,11 +90,24 @@ typedef struct user_fpsimd_state elf_fpregset_t;
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS	ELFCLASS64
+#ifdef __AARCH64EB__
+#define ELF_DATA	ELFDATA2MSB
+#else
 #define ELF_DATA	ELFDATA2LSB
+#endif
 #define ELF_ARCH	EM_AARCH64
 
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ */
 #define ELF_PLATFORM_SIZE	16
+#ifdef __AARCH64EB__
+#define ELF_PLATFORM		("aarch64_be")
+#else
 #define ELF_PLATFORM		("aarch64")
+#endif
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 05/14] arm64: setup: report ELF_PLATFORM as the machine for utsname
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (3 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 04/14] arm64: ELF: add support for big-endian executables Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries Matthew Leach
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

uname -m reports the machine field from the current utsname, which should
reflect the endianness of the system.

This patch reports ELF_PLATFORM for the field, so that everything appears
consistent from userspace.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/setup.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 055cfb8..df9ccb3 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -118,7 +118,7 @@ static void __init setup_processor(void)
 	printk("CPU: %s [%08x] revision %d\n",
 	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15);
 
-	sprintf(init_utsname()->machine, "aarch64");
+	sprintf(init_utsname()->machine, ELF_PLATFORM);
 	elf_hwcap = 0;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (4 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 05/14] arm64: setup: report ELF_PLATFORM as the machine for utsname Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 14:36   ` Mark Rutland
  2013-10-11 13:52 ` [PATCH 07/14] arm64: compat: correct register concatenation for syscall wrappers Matthew Leach
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch adds support for BE8 AArch32 tasks to the compat layer.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/compat.h    |   14 ++++++++++++++
 arch/arm64/include/asm/elf.h       |    5 +++++
 arch/arm64/include/asm/processor.h |    5 +++++
 arch/arm64/include/asm/ptrace.h    |    1 +
 4 files changed, 25 insertions(+)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 899af80..93bd6b7 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -26,7 +26,11 @@
 #include <linux/ptrace.h>
 
 #define COMPAT_USER_HZ		100
+#ifdef __AARCH64EB__
+#define COMPAT_UTS_MACHINE      "armv8b\0\0"
+#else
 #define COMPAT_UTS_MACHINE	"armv8l\0\0"
+#endif
 
 typedef u32		compat_size_t;
 typedef s32		compat_ssize_t;
@@ -73,13 +77,23 @@ struct compat_timeval {
 };
 
 struct compat_stat {
+#ifdef __AARCH64EB__
+	short		st_dev;
+	short		__pad1;
+#else
 	compat_dev_t	st_dev;
+#endif
 	compat_ino_t	st_ino;
 	compat_mode_t	st_mode;
 	compat_ushort_t	st_nlink;
 	__compat_uid16_t	st_uid;
 	__compat_gid16_t	st_gid;
+#ifdef __AARCH64EB__
+	short		st_rdev;
+	short		__pad2;
+#else
 	compat_dev_t	st_rdev;
+#endif
 	compat_off_t	st_size;
 	compat_off_t	st_blksize;
 	compat_off_t	st_blocks;
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index a3e4a55..d42b82f 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -162,7 +162,12 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
 #ifdef CONFIG_COMPAT
+
+#ifdef __AARCH64EB__
+#define COMPAT_ELF_PLATFORM             ("v8b")
+#else
 #define COMPAT_ELF_PLATFORM		("v8l")
+#endif
 
 #define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index ab239b2..4ad8fec 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -107,6 +107,11 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
 	regs->pstate = COMPAT_PSR_MODE_USR;
 	if (pc & 1)
 		regs->pstate |= COMPAT_PSR_T_BIT;
+
+#ifdef __AARCH64EB__
+        regs->pstate |= COMPAT_PSR_E_BIT;
+#endif
+
 	regs->compat_sp = sp;
 }
 #endif
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0dacbbf..0e7fa49 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -42,6 +42,7 @@
 #define COMPAT_PSR_MODE_UND	0x0000001b
 #define COMPAT_PSR_MODE_SYS	0x0000001f
 #define COMPAT_PSR_T_BIT	0x00000020
+#define COMPAT_PSR_E_BIT	0x00000200
 #define COMPAT_PSR_F_BIT	0x00000040
 #define COMPAT_PSR_I_BIT	0x00000080
 #define COMPAT_PSR_A_BIT	0x00000100
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 07/14] arm64: compat: correct register concatenation for syscall wrappers
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (5 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 08/14] arm64: big-endian: don't treat code as data when copying sigret code Matthew Leach
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

The arm64 port contains wrappers for arm32 syscalls that pass 64-bit
values. These wrappers concatenate the two registers to hold a 64-bit
value in a single X register. On BE, however, the lower and higher
words are swapped.

Create a new assembler macro, regs_to_64, that when on BE systems
swaps the registers in the orr instruction.

Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/include/asm/assembler.h |   12 ++++++++++++
 arch/arm64/kernel/sys32.S          |   22 +++++++++++-----------
 2 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 5aceb83..381b935 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -115,3 +115,15 @@ lr	.req	x30		// link register
 	.align	7
 	b	\label
 	.endm
+/*
+ * Define a macro that constructs a 64-bit value by concatenating two
+ * 32-bit registers. Note that on big endian systems the order of the
+ * registers is swapped.
+ */
+#ifndef CONFIG_CPU_BIG_ENDIAN
+	.macro	regs_to_64, rd, lbits, hbits
+#else
+	.macro	regs_to_64, rd, hbits, lbits
+#endif
+	orr	\rd, \lbits, \hbits, lsl #32
+	.endm
diff --git a/arch/arm64/kernel/sys32.S b/arch/arm64/kernel/sys32.S
index a1b19ed..423a5b3 100644
--- a/arch/arm64/kernel/sys32.S
+++ b/arch/arm64/kernel/sys32.S
@@ -59,48 +59,48 @@ ENDPROC(compat_sys_fstatfs64_wrapper)
  * extension.
  */
 compat_sys_pread64_wrapper:
-	orr	x3, x4, x5, lsl #32
+	regs_to_64	x3, x4, x5
 	b	sys_pread64
 ENDPROC(compat_sys_pread64_wrapper)
 
 compat_sys_pwrite64_wrapper:
-	orr	x3, x4, x5, lsl #32
+	regs_to_64	x3, x4, x5
 	b	sys_pwrite64
 ENDPROC(compat_sys_pwrite64_wrapper)
 
 compat_sys_truncate64_wrapper:
-	orr	x1, x2, x3, lsl #32
+	regs_to_64	x1, x2, x3
 	b	sys_truncate
 ENDPROC(compat_sys_truncate64_wrapper)
 
 compat_sys_ftruncate64_wrapper:
-	orr	x1, x2, x3, lsl #32
+	regs_to_64	x1, x2, x3
 	b	sys_ftruncate
 ENDPROC(compat_sys_ftruncate64_wrapper)
 
 compat_sys_readahead_wrapper:
-	orr	x1, x2, x3, lsl #32
+	regs_to_64	x1, x2, x3
 	mov	w2, w4
 	b	sys_readahead
 ENDPROC(compat_sys_readahead_wrapper)
 
 compat_sys_fadvise64_64_wrapper:
 	mov	w6, w1
-	orr	x1, x2, x3, lsl #32
-	orr	x2, x4, x5, lsl #32
+	regs_to_64	x1, x2, x3
+	regs_to_64	x2, x4, x5
 	mov	w3, w6
 	b	sys_fadvise64_64
 ENDPROC(compat_sys_fadvise64_64_wrapper)
 
 compat_sys_sync_file_range2_wrapper:
-	orr	x2, x2, x3, lsl #32
-	orr	x3, x4, x5, lsl #32
+	regs_to_64	x2, x2, x3
+	regs_to_64	x3, x4, x5
 	b	sys_sync_file_range2
 ENDPROC(compat_sys_sync_file_range2_wrapper)
 
 compat_sys_fallocate_wrapper:
-	orr	x2, x2, x3, lsl #32
-	orr	x3, x4, x5, lsl #32
+	regs_to_64	x2, x2, x3
+	regs_to_64	x3, x4, x5
 	b	sys_fallocate
 ENDPROC(compat_sys_fallocate_wrapper)
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 08/14] arm64: big-endian: don't treat code as data when copying sigret code
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (6 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 07/14] arm64: compat: correct register concatenation for syscall wrappers Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 09/14] arm64: asm: add CPU_LE & CPU_BE assembler helpers Matthew Leach
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

Currently the sigreturn compat code is copied to an offset in the
vectors table. When using a BE kernel this data will be stored in the
wrong endianess so when returning from a signal on a 32-bit BE system,
arbitrary code will be executed.

Instead of declaring the code inside a struct and copying that, use
the assembler's .byte directives to store the code in the correct
endianess regardless of platform endianess.

Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/kernel/Makefile   |    2 +-
 arch/arm64/kernel/kuser32.S  |   42 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/signal32.c |   28 ----------------------------
 arch/arm64/kernel/vdso.c     |    5 ++++-
 4 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 7b4b564..7d45ad7 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -11,7 +11,7 @@ arm64-obj-y		:= cputable.o debug-monitors.o entry.o irq.o fpsimd.o	\
 			   sys.o stacktrace.o time.o traps.o io.o vdso.o	\
 			   hyp-stub.o psci.o
 
-arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o 	\
+arm64-obj-$(CONFIG_COMPAT)		+= sys32.o kuser32.o signal32.o  	\
 					   sys_compat.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_SMP)			+= smp.o smp_spin_table.o smp_psci.o
diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S
index 8b69ecb..1e4905d 100644
--- a/arch/arm64/kernel/kuser32.S
+++ b/arch/arm64/kernel/kuser32.S
@@ -27,6 +27,9 @@
  *
  * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
  */
+
+#include <asm/unistd32.h>
+
 	.align	5
 	.globl	__kuser_helper_start
 __kuser_helper_start:
@@ -75,3 +78,42 @@ __kuser_helper_version:			// 0xffff0ffc
 	.word	((__kuser_helper_end - __kuser_helper_start) >> 5)
 	.globl	__kuser_helper_end
 __kuser_helper_end:
+
+/*
+ * AArch32 sigreturn code
+ *
+ * For ARM syscalls, the syscall number has to be loaded into r7.
+ * We do not support an OABI userspace.
+ *
+ * For Thumb syscalls, we also pass the syscall number via r7. We therefore
+ * need two 16-bit instructions.
+ */
+	.globl __aarch32_sigret_code_start
+__aarch32_sigret_code_start:
+
+	/*
+	 * ARM Code
+	 */
+	.byte	__NR_compat_sigreturn, 0x70, 0xa0, 0xe3	// mov	r7, #__NR_compat_sigreturn
+	.byte	__NR_compat_sigreturn, 0x00, 0x00, 0xef	// svc	#__NR_compat_sigreturn
+
+	/*
+	 * Thumb code
+	 */
+	.byte	__NR_compat_sigreturn, 0x27			// svc	#__NR_compat_sigreturn
+	.byte	__NR_compat_sigreturn, 0xdf			// mov	r7, #__NR_compat_sigreturn
+
+	/*
+	 * ARM code
+	 */
+	.byte	__NR_compat_rt_sigreturn, 0x70, 0xa0, 0xe3	// mov	r7, #__NR_compat_rt_sigreturn
+	.byte	__NR_compat_rt_sigreturn, 0x00, 0x00, 0xef	// svc	#__NR_compat_rt_sigreturn
+
+	/*
+	 * Thumb code
+	 */
+	.byte	__NR_compat_rt_sigreturn, 0x27			// svc	#__NR_compat_rt_sigreturn
+	.byte	__NR_compat_rt_sigreturn, 0xdf			// mov	r7, #__NR_compat_rt_sigreturn
+
+        .globl __aarch32_sigret_code_end
+__aarch32_sigret_code_end:
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index e393174..e8772c0 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -100,34 +100,6 @@ struct compat_rt_sigframe {
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-/*
- * For ARM syscalls, the syscall number has to be loaded into r7.
- * We do not support an OABI userspace.
- */
-#define MOV_R7_NR_SIGRETURN	(0xe3a07000 | __NR_compat_sigreturn)
-#define SVC_SYS_SIGRETURN	(0xef000000 | __NR_compat_sigreturn)
-#define MOV_R7_NR_RT_SIGRETURN	(0xe3a07000 | __NR_compat_rt_sigreturn)
-#define SVC_SYS_RT_SIGRETURN	(0xef000000 | __NR_compat_rt_sigreturn)
-
-/*
- * For Thumb syscalls, we also pass the syscall number via r7. We therefore
- * need two 16-bit instructions.
- */
-#define SVC_THUMB_SIGRETURN	(((0xdf00 | __NR_compat_sigreturn) << 16) | \
-				   0x2700 | __NR_compat_sigreturn)
-#define SVC_THUMB_RT_SIGRETURN	(((0xdf00 | __NR_compat_rt_sigreturn) << 16) | \
-				   0x2700 | __NR_compat_rt_sigreturn)
-
-const compat_ulong_t aarch32_sigret_code[6] = {
-	/*
-	 * AArch32 sigreturn code.
-	 * We don't construct an OABI SWI - instead we just set the imm24 field
-	 * to the EABI syscall number so that we create a sane disassembly.
-	 */
-	MOV_R7_NR_SIGRETURN,    SVC_SYS_SIGRETURN,    SVC_THUMB_SIGRETURN,
-	MOV_R7_NR_RT_SIGRETURN, SVC_SYS_RT_SIGRETURN, SVC_THUMB_RT_SIGRETURN,
-};
-
 static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
 {
 	compat_sigset_t	cset;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 6a389dc..65d40cf 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -58,7 +58,10 @@ static struct page *vectors_page[1];
 static int alloc_vectors_page(void)
 {
 	extern char __kuser_helper_start[], __kuser_helper_end[];
+	extern char __aarch32_sigret_code_start[], __aarch32_sigret_code_end[];
+
 	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+	int sigret_sz = __aarch32_sigret_code_end - __aarch32_sigret_code_start;
 	unsigned long vpage;
 
 	vpage = get_zeroed_page(GFP_ATOMIC);
@@ -72,7 +75,7 @@ static int alloc_vectors_page(void)
 
 	/* sigreturn code */
 	memcpy((void *)vpage + AARCH32_KERN_SIGRET_CODE_OFFSET,
-		aarch32_sigret_code, sizeof(aarch32_sigret_code));
+               __aarch32_sigret_code_start, sigret_sz);
 
 	flush_icache_range(vpage, vpage + PAGE_SIZE);
 	vectors_page[0] = virt_to_page(vpage);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 09/14] arm64: asm: add CPU_LE & CPU_BE assembler helpers
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (7 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 08/14] arm64: big-endian: don't treat code as data when copying sigret code Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 10/14] arm64: head: create a new function for setting the boot_cpu_mode flag Matthew Leach
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add CPU_LE and CPU_BE to select assembler code in little and big
endian configurations respectively.

Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/include/asm/assembler.h |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 381b935..fd3e392 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -115,6 +115,25 @@ lr	.req	x30		// link register
 	.align	7
 	b	\label
 	.endm
+
+/*
+ * Select code when configured for BE.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CPU_BE(code...) code
+#else
+#define CPU_BE(code...)
+#endif
+
+/*
+ * Select code when configured for LE.
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define CPU_LE(code...)
+#else
+#define CPU_LE(code...) code
+#endif
+
 /*
  * Define a macro that constructs a 64-bit value by concatenating two
  * 32-bit registers. Note that on big endian systems the order of the
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 10/14] arm64: head: create a new function for setting the boot_cpu_mode flag
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (8 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 09/14] arm64: asm: add CPU_LE & CPU_BE assembler helpers Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry Matthew Leach
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, the code for setting the __cpu_boot_mode flag is munged in
with el2_setup. This makes things difficult on a BE bringup as a
memory access has to have occurred before el2_setup which is the place
that we'd like to set the endianess on the current EL.

Create a new function for setting __cpu_boot_mode and have el2_setup
return the mode the CPU. Also define a new constant in virt.h,
BOOT_CPU_MODE_EL1, for readability.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/include/asm/virt.h |    3 ++-
 arch/arm64/kernel/head.S      |   34 +++++++++++++++++++++++++---------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 26e310c..130e2be 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -18,7 +18,8 @@
 #ifndef __ASM__VIRT_H
 #define __ASM__VIRT_H
 
-#define BOOT_CPU_MODE_EL2	(0x0e12b007)
+#define BOOT_CPU_MODE_EL1	(0xe11)
+#define BOOT_CPU_MODE_EL2	(0xe12)
 
 #ifndef __ASSEMBLY__
 #include <asm/cacheflush.h>
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7090c12..b3fcdf4 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -123,8 +123,9 @@
 
 ENTRY(stext)
 	mov	x21, x0				// x21=FDT
+	bl	el2_setup			// Drop to EL1, w20=cpu_boot_mode
 	bl	__calc_phys_offset		// x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
-	bl	el2_setup			// Drop to EL1
+	bl	set_cpu_boot_mode_flag
 	mrs	x22, midr_el1			// x22=cpuid
 	mov	x0, x22
 	bl	lookup_processor_type
@@ -150,21 +151,20 @@ ENDPROC(stext)
 /*
  * If we're fortunate enough to boot at EL2, ensure that the world is
  * sane before dropping to EL1.
+ *
+ * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x20 if
+ * booted in EL1 or EL2 respectively.
  */
 ENTRY(el2_setup)
 	mrs	x0, CurrentEL
 	cmp	x0, #PSR_MODE_EL2t
 	ccmp	x0, #PSR_MODE_EL2h, #0x4, ne
-	ldr	x0, =__boot_cpu_mode		// Compute __boot_cpu_mode
-	add	x0, x0, x28
 	b.eq	1f
-	str	wzr, [x0]			// Remember we don't have EL2...
+	mov	w20, #BOOT_CPU_MODE_EL1		// This cpu booted in EL1
 	ret
 
 	/* Hyp configuration. */
-1:	ldr	w1, =BOOT_CPU_MODE_EL2
-	str	w1, [x0, #4]			// This CPU has EL2
-	mov	x0, #(1 << 31)			// 64-bit EL1
+1:	mov	x0, #(1 << 31)			// 64-bit EL1
 	msr	hcr_el2, x0
 
 	/* Generic timers. */
@@ -204,10 +204,25 @@ ENTRY(el2_setup)
 		      PSR_MODE_EL1h)
 	msr	spsr_el2, x0
 	msr	elr_el2, lr
+	mov	w20, #BOOT_CPU_MODE_EL2		// This CPU booted in EL2
 	eret
 ENDPROC(el2_setup)
 
 /*
+ * Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
+ * in x20. See arch/arm64/include/asm/virt.h for more info.
+ */
+ENTRY(set_cpu_boot_mode_flag)
+	ldr	x1, =__boot_cpu_mode		// Compute __boot_cpu_mode
+	add	x1, x1, x28
+	cmp	w20, #BOOT_CPU_MODE_EL2
+	b.ne	1f
+	add	x1, x1, #4
+1:	str	w20, [x1]			// This CPU has booted in EL1
+	ret
+ENDPROC(set_cpu_boot_mode_flag)
+
+/*
  * We need to find out the CPU boot mode long after boot, so we need to
  * store it in a writable variable.
  *
@@ -235,8 +250,9 @@ ENTRY(__boot_cpu_mode)
 	 * cores are held until we're ready for them to initialise.
 	 */
 ENTRY(secondary_holding_pen)
-	bl	__calc_phys_offset		// x24=phys offset
-	bl	el2_setup			// Drop to EL1
+	bl	el2_setup			// Drop to EL1, w20=cpu_boot_mode
+	bl	__calc_phys_offset		// x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
+	bl	set_cpu_boot_mode_flag
 	mrs	x0, mpidr_el1
 	ldr     x1, =MPIDR_HWID_BITMASK
 	and	x0, x0, x1
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (9 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 10/14] arm64: head: create a new function for setting the boot_cpu_mode flag Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-15 18:46   ` Christopher Covington
  2013-10-24 15:46   ` Catalin Marinas
  2013-10-11 13:52 ` [PATCH 12/14] arm64: big-endian: write CPU holding pen address as LE Matthew Leach
                   ` (2 subsequent siblings)
  13 siblings, 2 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

The endianness of memory accesses at EL2 and EL1 are configured by
SCTLR_EL2.EE and SCTLR_EL1.EE respectively. When the kernel is booted,
the state of SCTLR_EL{2,1}.EE is unknown, and thus the kernel must
ensure that they are set before performing any memory accesses.

This patch ensures that SCTLR_EL{2,1} are configured appropriately at
boot for kernels of either endianness.

Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/kernel/head.S |   17 ++++++++++++++---
 arch/arm64/mm/proc.S     |    4 ++--
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b3fcdf4..cd0ecb1 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -159,12 +159,22 @@ ENTRY(el2_setup)
 	mrs	x0, CurrentEL
 	cmp	x0, #PSR_MODE_EL2t
 	ccmp	x0, #PSR_MODE_EL2h, #0x4, ne
-	b.eq	1f
+	b.ne	1f
+	mrs	x0, sctlr_el2
+CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
+CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
+	msr	sctlr_el2, x0
+	b	2f
+1:	mrs	x0, sctlr_el1
+CPU_BE(	orr	x0, x0, #(2 << 24)	)	// Set the EE and E0E bits for EL1
+CPU_LE(	bic	x0, x0, #(2 << 24)	)	// Clear the EE and E0E bits for EL1
+	msr	sctlr_el1, x0
 	mov	w20, #BOOT_CPU_MODE_EL1		// This cpu booted in EL1
+	isb
 	ret
 
 	/* Hyp configuration. */
-1:	mov	x0, #(1 << 31)			// 64-bit EL1
+2:	mov	x0, #(1 << 31)			// 64-bit EL1
 	msr	hcr_el2, x0
 
 	/* Generic timers. */
@@ -181,7 +191,8 @@ ENTRY(el2_setup)
 
 	/* sctlr_el1 */
 	mov	x0, #0x0800			// Set/clear RES{1,0} bits
-	movk	x0, #0x30d0, lsl #16
+CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
+CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
 	msr	sctlr_el1, x0
 
 	/* Coprocessor traps. */
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index b1b31bb..421b99f 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -162,9 +162,9 @@ ENDPROC(__cpu_setup)
 	 *       CE0      XWHW CZ     ME TEEA S
 	 * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
 	 * 0011 0... 1101 ..0. ..0. 10.. .... .... < hardware reserved
-	 * .... .100 .... 01.1 11.1 ..01 0001 1101 < software settings
+	 * .... .1.. .... 01.1 11.1 ..01 0001 1101 < software settings
 	 */
 	.type	crval, #object
 crval:
-	.word	0x030802e2			// clear
+	.word	0x000802e2			// clear
 	.word	0x0405d11d			// set
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 12/14] arm64: big-endian: write CPU holding pen address as LE
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (10 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 13/14] arm64: kconfig: allow CPU_BIG_ENDIAN to be selected Matthew Leach
  2013-10-11 13:52   ` Matthew Leach
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

Currently when CPUs are brought online via a spin-table, the address
they should jump to is written to the cpu-release-addr in the kernel's
native endianness. As the kernel may switch endianness, secondaries
might read the value byte-reversed from what was intended, and they
would jump to the wrong address.

As the only current arm64 spin-table implementations are
little-endian, stricten up the arm64 spin-table definition such that
the value written to cpu-release-addr is _always_ little-endian
regardless of the endianness of any CPU. If a spinning CPU is
operating big-endian, it must byte-reverse the value before jumping to
handle this.

Signed-off-by: Matthew Leach <matthew.leach@arm.com>
---
 arch/arm64/kernel/smp_spin_table.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index 7c35fa6..c0bc097 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -48,7 +48,16 @@ static int __init smp_spin_table_prepare_cpu(int cpu)
 		return -ENODEV;
 
 	release_addr = __va(cpu_release_addr[cpu]);
-	release_addr[0] = (void *)__pa(secondary_holding_pen);
+
+	/*
+	 * We write the release address as LE regardless of the native
+	 * endianess of the kernel. Therefore, any boot-loaders that
+	 * read this address need to convert this address to the
+	 * boot-loader's endianess before jumping. This is mandated by
+	 * the boot protocol.
+	 */
+	release_addr[0] = (void *) cpu_to_le64(__pa(secondary_holding_pen));
+
 	__flush_dcache_area(release_addr, sizeof(release_addr[0]));
 
 	/*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 13/14] arm64: kconfig: allow CPU_BIG_ENDIAN to be selected
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
                   ` (11 preceding siblings ...)
  2013-10-11 13:52 ` [PATCH 12/14] arm64: big-endian: write CPU holding pen address as LE Matthew Leach
@ 2013-10-11 13:52 ` Matthew Leach
  2013-10-11 13:52   ` Matthew Leach
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

This patch wires up CONFIG_CPU_BIG_ENDIAN for the AArch64 kernel
configuration.

Selecting this option builds a big-endian kernel which can boot into a
big-endian userspace.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c044548..95d6cb9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -138,6 +138,11 @@ config ARM64_64K_PAGES
 	  look-up. AArch32 emulation is not available when this feature
 	  is enabled.
 
+config CPU_BIG_ENDIAN
+       bool "Build big-endian kernel"
+       help
+         Say Y if you plan on running a kernel in big-endian mode.
+
 config SMP
 	bool "Symmetric Multi-Processing"
 	select USE_GENERIC_SMP_HELPERS
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
  2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
@ 2013-10-11 13:52   ` Matthew Leach
  2013-10-11 13:52 ` [PATCH 02/14] arm64: big-endian: add big-endian support to top-level arch Makefile Matthew Leach
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: ankit.jindal, steve.mcintyre, tushar.jagad, will.deacon,
	catalin.marinas, netdev, Nicolas Pitre, David S. Miller

From: Will Deacon <will.deacon@arm.com>

SMC_outw invokes an endian-aware I/O accessor, which may change the data
endianness before writing to the device. This is not suitable for data
transfers where the memory buffer is simply a string of bytes that does
not require any byte-swapping.

This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
string I/O accessor for outputting the leading or trailing halfwords on
halfword-aligned buffers.

Cc: <netdev@vger.kernel.org>
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 drivers/net/ethernet/smsc/smc91x.h |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index 5730fe2..98eedb9 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -1124,8 +1124,7 @@ static const char * chip_ids[ 16 ] =  {
 			void __iomem *__ioaddr = ioaddr;		\
 			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
 				__len -= 2;				\
-				SMC_outw(*(u16 *)__ptr, ioaddr,		\
-					DATA_REG(lp));		\
+				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
 				__ptr += 2;				\
 			}						\
 			if (SMC_CAN_USE_DATACS && lp->datacs)		\
@@ -1133,8 +1132,7 @@ static const char * chip_ids[ 16 ] =  {
 			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
 			if (__len & 2) {				\
 				__ptr += (__len & ~3);			\
-				SMC_outw(*((u16 *)__ptr), ioaddr,	\
-					 DATA_REG(lp));		\
+				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
 			}						\
 		} else if (SMC_16BIT(lp))				\
 			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
@ 2013-10-11 13:52   ` Matthew Leach
  0 siblings, 0 replies; 23+ messages in thread
From: Matthew Leach @ 2013-10-11 13:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Will Deacon <will.deacon@arm.com>

SMC_outw invokes an endian-aware I/O accessor, which may change the data
endianness before writing to the device. This is not suitable for data
transfers where the memory buffer is simply a string of bytes that does
not require any byte-swapping.

This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
string I/O accessor for outputting the leading or trailing halfwords on
halfword-aligned buffers.

Cc: <netdev@vger.kernel.org>
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 drivers/net/ethernet/smsc/smc91x.h |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index 5730fe2..98eedb9 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -1124,8 +1124,7 @@ static const char * chip_ids[ 16 ] =  {
 			void __iomem *__ioaddr = ioaddr;		\
 			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
 				__len -= 2;				\
-				SMC_outw(*(u16 *)__ptr, ioaddr,		\
-					DATA_REG(lp));		\
+				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
 				__ptr += 2;				\
 			}						\
 			if (SMC_CAN_USE_DATACS && lp->datacs)		\
@@ -1133,8 +1132,7 @@ static const char * chip_ids[ 16 ] =  {
 			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
 			if (__len & 2) {				\
 				__ptr += (__len & ~3);			\
-				SMC_outw(*((u16 *)__ptr), ioaddr,	\
-					 DATA_REG(lp));		\
+				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
 			}						\
 		} else if (SMC_16BIT(lp))				\
 			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries
  2013-10-11 13:52 ` [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries Matthew Leach
@ 2013-10-11 14:36   ` Mark Rutland
  0 siblings, 0 replies; 23+ messages in thread
From: Mark Rutland @ 2013-10-11 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Matt, Will,

On Fri, Oct 11, 2013 at 02:52:12PM +0100, Matthew Leach wrote:
> From: Will Deacon <will.deacon@arm.com>
> 
> This patch adds support for BE8 AArch32 tasks to the compat layer.
> 
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  arch/arm64/include/asm/compat.h    |   14 ++++++++++++++
>  arch/arm64/include/asm/elf.h       |    5 +++++
>  arch/arm64/include/asm/processor.h |    5 +++++
>  arch/arm64/include/asm/ptrace.h    |    1 +
>  4 files changed, 25 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index 899af80..93bd6b7 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -26,7 +26,11 @@
>  #include <linux/ptrace.h>
>  
>  #define COMPAT_USER_HZ		100
> +#ifdef __AARCH64EB__
> +#define COMPAT_UTS_MACHINE      "armv8b\0\0"

There's space damage here    ^

> +#else
>  #define COMPAT_UTS_MACHINE	"armv8l\0\0"
> +#endif
>  
>  typedef u32		compat_size_t;
>  typedef s32		compat_ssize_t;
> @@ -73,13 +77,23 @@ struct compat_timeval {
>  };
>  
>  struct compat_stat {
> +#ifdef __AARCH64EB__
> +	short		st_dev;
> +	short		__pad1;
> +#else
>  	compat_dev_t	st_dev;
> +#endif

I was going to ask why this was different across BE and LE, but I see it
matches arch/arm/include/uapi/asm/stat.h.

> diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
> index a3e4a55..d42b82f 100644
> --- a/arch/arm64/include/asm/elf.h
> +++ b/arch/arm64/include/asm/elf.h
> @@ -162,7 +162,12 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
>  #define arch_randomize_brk arch_randomize_brk
>  
>  #ifdef CONFIG_COMPAT
> +
> +#ifdef __AARCH64EB__
> +#define COMPAT_ELF_PLATFORM             ("v8b")

Space damage here too         ^

> +#else
>  #define COMPAT_ELF_PLATFORM		("v8l")
> +#endif
>  
>  #define COMPAT_ELF_ET_DYN_BASE		(randomize_et_dyn(2 * TASK_SIZE_32 / 3))
>  
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index ab239b2..4ad8fec 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -107,6 +107,11 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
>  	regs->pstate = COMPAT_PSR_MODE_USR;
>  	if (pc & 1)
>  		regs->pstate |= COMPAT_PSR_T_BIT;
> +
> +#ifdef __AARCH64EB__
> +        regs->pstate |= COMPAT_PSR_E_BIT;

   ^ More space damage.

Cheers,
Mark.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
  2013-10-11 13:52   ` Matthew Leach
@ 2013-10-11 20:41     ` Nicolas Pitre
  -1 siblings, 0 replies; 23+ messages in thread
From: Nicolas Pitre @ 2013-10-11 20:41 UTC (permalink / raw)
  To: Matthew Leach
  Cc: linux-arm-kernel, ankit.jindal, steve.mcintyre, tushar.jagad,
	will.deacon, catalin.marinas, netdev, David S. Miller

On Fri, 11 Oct 2013, Matthew Leach wrote:

> From: Will Deacon <will.deacon@arm.com>
> 
> SMC_outw invokes an endian-aware I/O accessor, which may change the data
> endianness before writing to the device. This is not suitable for data
> transfers where the memory buffer is simply a string of bytes that does
> not require any byte-swapping.
> 
> This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
> string I/O accessor for outputting the leading or trailing halfwords on
> halfword-aligned buffers.

Acked-by: Nicolas Pitre <nico@linaro.org>

> 
> Cc: <netdev@vger.kernel.org>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  drivers/net/ethernet/smsc/smc91x.h |    6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
> index 5730fe2..98eedb9 100644
> --- a/drivers/net/ethernet/smsc/smc91x.h
> +++ b/drivers/net/ethernet/smsc/smc91x.h
> @@ -1124,8 +1124,7 @@ static const char * chip_ids[ 16 ] =  {
>  			void __iomem *__ioaddr = ioaddr;		\
>  			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
>  				__len -= 2;				\
> -				SMC_outw(*(u16 *)__ptr, ioaddr,		\
> -					DATA_REG(lp));		\
> +				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
>  				__ptr += 2;				\
>  			}						\
>  			if (SMC_CAN_USE_DATACS && lp->datacs)		\
> @@ -1133,8 +1132,7 @@ static const char * chip_ids[ 16 ] =  {
>  			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
>  			if (__len & 2) {				\
>  				__ptr += (__len & ~3);			\
> -				SMC_outw(*((u16 *)__ptr), ioaddr,	\
> -					 DATA_REG(lp));		\
> +				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
>  			}						\
>  		} else if (SMC_16BIT(lp))				\
>  			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
@ 2013-10-11 20:41     ` Nicolas Pitre
  0 siblings, 0 replies; 23+ messages in thread
From: Nicolas Pitre @ 2013-10-11 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 11 Oct 2013, Matthew Leach wrote:

> From: Will Deacon <will.deacon@arm.com>
> 
> SMC_outw invokes an endian-aware I/O accessor, which may change the data
> endianness before writing to the device. This is not suitable for data
> transfers where the memory buffer is simply a string of bytes that does
> not require any byte-swapping.
> 
> This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
> string I/O accessor for outputting the leading or trailing halfwords on
> halfword-aligned buffers.

Acked-by: Nicolas Pitre <nico@linaro.org>

> 
> Cc: <netdev@vger.kernel.org>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  drivers/net/ethernet/smsc/smc91x.h |    6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
> index 5730fe2..98eedb9 100644
> --- a/drivers/net/ethernet/smsc/smc91x.h
> +++ b/drivers/net/ethernet/smsc/smc91x.h
> @@ -1124,8 +1124,7 @@ static const char * chip_ids[ 16 ] =  {
>  			void __iomem *__ioaddr = ioaddr;		\
>  			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
>  				__len -= 2;				\
> -				SMC_outw(*(u16 *)__ptr, ioaddr,		\
> -					DATA_REG(lp));		\
> +				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
>  				__ptr += 2;				\
>  			}						\
>  			if (SMC_CAN_USE_DATACS && lp->datacs)		\
> @@ -1133,8 +1132,7 @@ static const char * chip_ids[ 16 ] =  {
>  			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
>  			if (__len & 2) {				\
>  				__ptr += (__len & ~3);			\
> -				SMC_outw(*((u16 *)__ptr), ioaddr,	\
> -					 DATA_REG(lp));		\
> +				SMC_outsw(ioaddr, DATA_REG(lp), __ptr, 1); \
>  			}						\
>  		} else if (SMC_16BIT(lp))				\
>  			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
  2013-10-11 13:52   ` Matthew Leach
@ 2013-10-11 21:56     ` David Miller
  -1 siblings, 0 replies; 23+ messages in thread
From: David Miller @ 2013-10-11 21:56 UTC (permalink / raw)
  To: matthew.leach
  Cc: linux-arm-kernel, ankit.jindal, steve.mcintyre, tushar.jagad,
	will.deacon, catalin.marinas, netdev, nico

From: Matthew Leach <matthew.leach@arm.com>
Date: Fri, 11 Oct 2013 14:52:20 +0100

> From: Will Deacon <will.deacon@arm.com>
> 
> SMC_outw invokes an endian-aware I/O accessor, which may change the data
> endianness before writing to the device. This is not suitable for data
> transfers where the memory buffer is simply a string of bytes that does
> not require any byte-swapping.
> 
> This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
> string I/O accessor for outputting the leading or trailing halfwords on
> halfword-aligned buffers.
> 
> Cc: <netdev@vger.kernel.org>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Will Deacon <will.deacon@arm.com>

Applied.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data
@ 2013-10-11 21:56     ` David Miller
  0 siblings, 0 replies; 23+ messages in thread
From: David Miller @ 2013-10-11 21:56 UTC (permalink / raw)
  To: linux-arm-kernel

From: Matthew Leach <matthew.leach@arm.com>
Date: Fri, 11 Oct 2013 14:52:20 +0100

> From: Will Deacon <will.deacon@arm.com>
> 
> SMC_outw invokes an endian-aware I/O accessor, which may change the data
> endianness before writing to the device. This is not suitable for data
> transfers where the memory buffer is simply a string of bytes that does
> not require any byte-swapping.
> 
> This patches fixes the smc91x SMC_PUSH_DATA macro so that it uses the
> string I/O accessor for outputting the leading or trailing halfwords on
> halfword-aligned buffers.
> 
> Cc: <netdev@vger.kernel.org>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Will Deacon <will.deacon@arm.com>

Applied.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry
  2013-10-11 13:52 ` [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry Matthew Leach
@ 2013-10-15 18:46   ` Christopher Covington
  2013-10-24 15:46   ` Catalin Marinas
  1 sibling, 0 replies; 23+ messages in thread
From: Christopher Covington @ 2013-10-15 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Matthew,

On 10/11/2013 09:52 AM, Matthew Leach wrote:
> The endianness of memory accesses at EL2 and EL1 are configured by
> SCTLR_EL2.EE and SCTLR_EL1.EE respectively. When the kernel is booted,
> the state of SCTLR_EL{2,1}.EE is unknown, and thus the kernel must
> ensure that they are set before performing any memory accesses.
> 
> This patch ensures that SCTLR_EL{2,1} are configured appropriately at
> boot for kernels of either endianness.
[...]
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -159,12 +159,22 @@ ENTRY(el2_setup)
>  	mrs	x0, CurrentEL
>  	cmp	x0, #PSR_MODE_EL2t
>  	ccmp	x0, #PSR_MODE_EL2h, #0x4, ne
> -	b.eq	1f
> +	b.ne	1f
> +	mrs	x0, sctlr_el2
> +CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
> +CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
> +	msr	sctlr_el2, x0
> +	b	2f
> +1:	mrs	x0, sctlr_el1
> +CPU_BE(	orr	x0, x0, #(2 << 24)	)	// Set the EE and E0E bits for EL1
> +CPU_LE(	bic	x0, x0, #(2 << 24)	)	// Clear the EE and E0E bits for EL1
> +	msr	sctlr_el1, x0
>  	mov	w20, #BOOT_CPU_MODE_EL1		// This cpu booted in EL1
> +	isb

Could you please comment on why this barrier is necessary?

>  	ret
>  
>  	/* Hyp configuration. */
> -1:	mov	x0, #(1 << 31)			// 64-bit EL1
> +2:	mov	x0, #(1 << 31)			// 64-bit EL1
>  	msr	hcr_el2, x0
>  
>  	/* Generic timers. */
> @@ -181,7 +191,8 @@ ENTRY(el2_setup)
>  
>  	/* sctlr_el1 */
>  	mov	x0, #0x0800			// Set/clear RES{1,0} bits
> -	movk	x0, #0x30d0, lsl #16
> +CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
> +CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems

Although the CPU_[BL]E macros make the ifdef'ery here and above prettier than
they would be otherwise, I wonder if making the set and clear operations and
this magic number macros instead could improve readability and fall more in
line with the "#ifdefs are ugly" guideline in Documentation/SubmittingPatches.

>  	msr	sctlr_el1, x0
>  
>  	/* Coprocessor traps. */

[...]

Thanks,
Christopher

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry
  2013-10-11 13:52 ` [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry Matthew Leach
  2013-10-15 18:46   ` Christopher Covington
@ 2013-10-24 15:46   ` Catalin Marinas
  1 sibling, 0 replies; 23+ messages in thread
From: Catalin Marinas @ 2013-10-24 15:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2013-10-11 at 14:52 +0100, Matthew Leach wrote:
> The endianness of memory accesses at EL2 and EL1 are configured by
> SCTLR_EL2.EE and SCTLR_EL1.EE respectively. When the kernel is booted,
> the state of SCTLR_EL{2,1}.EE is unknown, and thus the kernel must
> ensure that they are set before performing any memory accesses.
> 
> This patch ensures that SCTLR_EL{2,1} are configured appropriately at
> boot for kernels of either endianness.
> 
> Acked-by: Will Deacon <will.deacon@arm.com>
> Signed-off-by: Matthew Leach <matthew.leach@arm.com>
> ---
>  arch/arm64/kernel/head.S |   17 ++++++++++++++---
>  arch/arm64/mm/proc.S     |    4 ++--
>  2 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index b3fcdf4..cd0ecb1 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -159,12 +159,22 @@ ENTRY(el2_setup)
>  	mrs	x0, CurrentEL
>  	cmp	x0, #PSR_MODE_EL2t
>  	ccmp	x0, #PSR_MODE_EL2h, #0x4, ne
> -	b.eq	1f
> +	b.ne	1f
> +	mrs	x0, sctlr_el2
> +CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
> +CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
> +	msr	sctlr_el2, x0
> +	b	2f
> +1:	mrs	x0, sctlr_el1
> +CPU_BE(	orr	x0, x0, #(2 << 24)	)	// Set the EE and E0E bits for EL1
> +CPU_LE(	bic	x0, x0, #(2 << 24)	)	// Clear the EE and E0E bits for EL1

Shouldn't this be (3 << 24)?

-- 
Catalin

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2013-10-24 15:46 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-11 13:52 [PATCH 00/14] AArch64 BE Support Matthew Leach
2013-10-11 13:52 ` [PATCH 01/14] Docs: arm64: booting: clarify boot requirements Matthew Leach
2013-10-11 13:52 ` [PATCH 02/14] arm64: big-endian: add big-endian support to top-level arch Makefile Matthew Leach
2013-10-11 13:52 ` [PATCH 03/14] arm64: big-endian: fix byteorder include Matthew Leach
2013-10-11 13:52 ` [PATCH 04/14] arm64: ELF: add support for big-endian executables Matthew Leach
2013-10-11 13:52 ` [PATCH 05/14] arm64: setup: report ELF_PLATFORM as the machine for utsname Matthew Leach
2013-10-11 13:52 ` [PATCH 06/14] arm64: compat: add support for big-endian (BE8) AArch32 binaries Matthew Leach
2013-10-11 14:36   ` Mark Rutland
2013-10-11 13:52 ` [PATCH 07/14] arm64: compat: correct register concatenation for syscall wrappers Matthew Leach
2013-10-11 13:52 ` [PATCH 08/14] arm64: big-endian: don't treat code as data when copying sigret code Matthew Leach
2013-10-11 13:52 ` [PATCH 09/14] arm64: asm: add CPU_LE & CPU_BE assembler helpers Matthew Leach
2013-10-11 13:52 ` [PATCH 10/14] arm64: head: create a new function for setting the boot_cpu_mode flag Matthew Leach
2013-10-11 13:52 ` [PATCH 11/14] arm64: big-endian: set correct endianess on kernel entry Matthew Leach
2013-10-15 18:46   ` Christopher Covington
2013-10-24 15:46   ` Catalin Marinas
2013-10-11 13:52 ` [PATCH 12/14] arm64: big-endian: write CPU holding pen address as LE Matthew Leach
2013-10-11 13:52 ` [PATCH 13/14] arm64: kconfig: allow CPU_BIG_ENDIAN to be selected Matthew Leach
2013-10-11 13:52 ` [PATCH 14/14] net: smc91x: dont't use SMC_outw for fixing up halfword-aligned data Matthew Leach
2013-10-11 13:52   ` Matthew Leach
2013-10-11 20:41   ` Nicolas Pitre
2013-10-11 20:41     ` Nicolas Pitre
2013-10-11 21:56   ` David Miller
2013-10-11 21:56     ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.