From dfdcf34031db02eb8d81dd3b1c3415ec900c40bb Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 11 Jan 2018 13:25:31 +0000 Subject: linux-user: Add support for big-endian aarch64 Enable big-endian mode for data accesses on aarch64 for big-endian linux user mode. Activate it for all exception levels as documented by ARM: Set the SCTLR EE bit for ELs 1 through 3. Additionally set bit E0E in EL1 to enable it in EL0 as well. Signed-off-by: Michael Weiser Reviewed-by: Richard Henderson Message-id: 20171220212308.12614-2-michael.weiser@gmx.de Signed-off-by: Peter Maydell --- linux-user/main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'linux-user') diff --git a/linux-user/main.c b/linux-user/main.c index 99a551b..450eb3c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4629,6 +4629,12 @@ int main(int argc, char **argv, char **envp) } env->pc = regs->pc; env->xregs[31] = regs->sp; +#ifdef TARGET_WORDS_BIGENDIAN + env->cp15.sctlr_el[1] |= SCTLR_E0E; + for (i = 1; i < 4; ++i) { + env->cp15.sctlr_el[i] |= SCTLR_EE; + } +#endif } #elif defined(TARGET_ARM) { -- cgit v1.1 From cb3aa5fea19cdc108baf6c3aff2e768bf9475b50 Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 11 Jan 2018 13:25:31 +0000 Subject: linux-user: Add separate aarch64_be uname Make big-endian aarch64 systems identify as aarch64_be as expected by big-endian userland and toolchains. Signed-off-by: Michael Weiser Reviewed-by: Richard Henderson Reviewed-by: Laurent Vivier Message-id: 20171220212308.12614-3-michael.weiser@gmx.de Signed-off-by: Peter Maydell --- linux-user/aarch64/target_syscall.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'linux-user') diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h index 1b62953..604ab99 100644 --- a/linux-user/aarch64/target_syscall.h +++ b/linux-user/aarch64/target_syscall.h @@ -8,7 +8,11 @@ struct target_pt_regs { uint64_t pstate; }; +#if defined(TARGET_WORDS_BIGENDIAN) +#define UNAME_MACHINE "aarch64_be" +#else #define UNAME_MACHINE "aarch64" +#endif #define UNAME_MINIMUM_RELEASE "3.8.0" #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 -- cgit v1.1 From 50f22fa60d95c04a179e2cbf4b5f58d1f6068b61 Mon Sep 17 00:00:00 2001 From: Michael Weiser Date: Thu, 11 Jan 2018 13:25:31 +0000 Subject: linux-user: Fix endianess of aarch64 signal trampoline Since for aarch64 the signal trampoline is synthesized directly into the signal frame we need to make sure the instructions end up little-endian. Otherwise the wrong endianness will cause a SIGILL upon return from the signal handler on big-endian targets. Signed-off-by: Michael Weiser Reviewed-by: Richard Henderson Message-id: 20171220212308.12614-4-michael.weiser@gmx.de Signed-off-by: Peter Maydell --- linux-user/signal.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'linux-user') diff --git a/linux-user/signal.c b/linux-user/signal.c index 74fa03f..f85f0dd 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1599,9 +1599,13 @@ static void target_setup_frame(int usig, struct target_sigaction *ka, if (ka->sa_flags & TARGET_SA_RESTORER) { return_addr = ka->sa_restorer; } else { - /* mov x8,#__NR_rt_sigreturn; svc #0 */ - __put_user(0xd2801168, &frame->tramp[0]); - __put_user(0xd4000001, &frame->tramp[1]); + /* + * mov x8,#__NR_rt_sigreturn; svc #0 + * Since these are instructions they need to be put as little-endian + * regardless of target default or current CPU endianness. + */ + __put_user_e(0xd2801168, &frame->tramp[0], le); + __put_user_e(0xd4000001, &frame->tramp[1], le); return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp); } env->xregs[0] = usig; -- cgit v1.1 From 579648554acbd6c22d5cc2f03cf77cfc25332650 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 11 Jan 2018 13:25:39 +0000 Subject: linux-user/arm/nwfpe: Check coprocessor number for FPA emulation Our copy of the nwfpe code for emulating of the old FPA11 floating point unit doesn't check the coprocessor number in the instruction when it emulates it. This means that we might treat some instructions which should really UNDEF as being FPA11 instructions by accident. The kernel's copy of the nwfpe code doesn't make this error; I suspect the bug was noticed and fixed as part of the process of mainlining the nwfpe code more than a decade ago. Add a check that the coprocessor number (which is always in bits [11:8] of the instruction) is either 1 or 2, which is where the FPA11 lives. Reported-by: Richard Henderson Signed-off-by: Peter Maydell --- linux-user/arm/nwfpe/fpa11.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'linux-user') diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c index 441e3b1..f6f8163 100644 --- a/linux-user/arm/nwfpe/fpa11.c +++ b/linux-user/arm/nwfpe/fpa11.c @@ -137,8 +137,17 @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs) unsigned int nRc = 0; // unsigned long flags; FPA11 *fpa11; + unsigned int cp; // save_flags(flags); sti(); + /* Check that this is really an FPA11 instruction: the coprocessor + * field in bits [11:8] must be 1 or 2. + */ + cp = (opcode >> 8) & 0xf; + if (cp != 1 && cp != 2) { + return 0; + } + qemufpa=qfpa; user_registers=qregs; -- cgit v1.1