Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/aarch64 PR port-arm/54702
details: https://anonhg.NetBSD.org/src/rev/18ee1e5b5500
branches: trunk
changeset: 465478:18ee1e5b5500
user: rin <rin%NetBSD.org@localhost>
date: Sun Nov 24 04:08:36 2019 +0000
description:
PR port-arm/54702
Add support for earmv6hf binaries on COMPAT_NETBSD32 for aarch64:
- Emulate ARMv6 instructions with cache operations register (c7), that
are deprecated since ARMv7, and disabled on ARMv8 with LP64 kernel.
- ep_machine_arch (default: earmv7hf) is copied from executables, as we
do for mips64. "uname -p" reports earmv6hf if compiled for earmv6hf;
configure scripts etc can determine the appropriate architecture.
Many thanks to ryo@ for helping me to add support of Thumb-mode,
as well as providing exhaustive test cases:
https://github.com/ryo/mcr_test/
We've confirmed:
- Emulation works in Thumb-mode.
- T32 16-bit length illegal instruction results in SIGILL, even if
it is located nearby a boundary b/w mapped and unmapped pages.
- T32 32-bit instruction results in SIGSEGV if it is located across
a boundary b/w mapped and unmapped pages.
XXX
pullup to netbsd-9
diffstat:
sys/arch/aarch64/aarch64/exec_machdep.c | 11 ++-
sys/arch/aarch64/aarch64/netbsd32_machdep.c | 10 +-
sys/arch/aarch64/aarch64/trap.c | 108 +++++++++++++++++++++++++++-
sys/arch/aarch64/include/netbsd32_machdep.h | 5 +-
sys/arch/aarch64/include/param.h | 12 ++-
sys/arch/aarch64/include/proc.h | 13 +++-
6 files changed, 145 insertions(+), 14 deletions(-)
diffs (truncated from 301 to 300 lines):
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/aarch64/exec_machdep.c
--- a/sys/arch/aarch64/aarch64/exec_machdep.c Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/aarch64/exec_machdep.c Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_machdep.c,v 1.4 2018/11/28 08:12:15 ryo Exp $ */
+/* $NetBSD: exec_machdep.c,v 1.5 2019/11/24 04:08:36 rin Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_machdep.c,v 1.4 2018/11/28 08:12:15 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_machdep.c,v 1.5 2019/11/24 04:08:36 rin Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_netbsd32.h"
@@ -83,6 +83,13 @@
ID_AA64PFR0_EL1_EL0_64_32)
return ENOEXEC;
+ /*
+ * Copy (if any) the machine_arch of the executable to the proc.
+ */
+ if (epp->ep_machine_arch[0] != 0)
+ strlcpy(l->l_proc->p_md.md_march32, epp->ep_machine_arch,
+ sizeof(l->l_proc->p_md.md_march32));
+
return 0;
}
#endif
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/aarch64/netbsd32_machdep.c
--- a/sys/arch/aarch64/aarch64/netbsd32_machdep.c Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/aarch64/netbsd32_machdep.c Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.c,v 1.8 2019/11/20 19:37:51 pgoyette Exp $ */
+/* $NetBSD: netbsd32_machdep.c,v 1.9 2019/11/24 04:08:36 rin Exp $ */
/*
* Copyright (c) 2018 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.8 2019/11/20 19:37:51 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.9 2019/11/24 04:08:36 rin Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -55,11 +55,7 @@
#include <aarch64/userret.h>
const char machine32[] = MACHINE;
-#ifdef __AARCH64EB__
-const char machine_arch32[] = "earmv7hfeb";
-#else
-const char machine_arch32[] = "earmv7hf";
-#endif
+const char machine_arch32[] = MACHINE32_ARCH;
void
netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/aarch64/trap.c
--- a/sys/arch/aarch64/aarch64/trap.c Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/aarch64/trap.c Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.20 2019/11/21 19:23:58 ad Exp $ */
+/* $NetBSD: trap.c,v 1.21 2019/11/24 04:08:36 rin Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.20 2019/11/21 19:23:58 ad Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.21 2019/11/24 04:08:36 rin Exp $");
#include "opt_arm_intr_impl.h"
#include "opt_compat_netbsd32.h"
@@ -321,6 +321,103 @@
cpu_dosoftints();
}
+#ifdef COMPAT_NETBSD32
+
+/*
+ * 32-bit length Thumb instruction. See ARMv7 DDI0406A A6.3.
+ */
+#define THUMB_32BIT(hi) (((hi) & 0xe000) == 0xe000 && ((hi) & 0x1800))
+
+static int
+fetch_arm_insn(struct trapframe *tf, uint32_t *insn)
+{
+
+ /* THUMB? */
+ if (tf->tf_spsr & SPSR_A32_T) {
+ uint16_t *pc = (uint16_t *)(tf->tf_pc & ~1UL); /* XXX */
+ uint16_t hi, lo;
+
+ hi = *pc;
+ if (!THUMB_32BIT(hi)) {
+ /* 16-bit Thumb instruction */
+ *insn = hi;
+ return 2;
+ }
+
+ /*
+ * 32-bit Thumb instruction:
+ * We can safely retrieve the lower-half word without
+ * consideration of a page fault; If present, it must
+ * have occurred already in the decode stage.
+ */
+ lo = *(pc + 1);
+
+ *insn = ((uint32_t)hi << 16) | lo;
+ return 4;
+ }
+
+ *insn = *(uint32_t *)tf->tf_pc;
+ return 4;
+}
+
+static int
+emul_arm_insn(struct trapframe *tf)
+{
+ uint32_t insn;
+ int insn_size;
+
+ insn_size = fetch_arm_insn(tf, &insn);
+
+ switch (insn_size) {
+ case 2:
+ /* T32-16bit instruction */
+
+ /* XXX: some T32 IT instruction deprecated should be emulated */
+ break;
+ case 4:
+ /* T32-32bit instruction, or A32 instruction */
+
+ /*
+ * Emulate ARMv6 instructions with cache operations
+ * register (c7), that can be used in user mode.
+ */
+ switch (insn & 0x0fff0fff) {
+ case 0x0e070f95:
+ /*
+ * mcr p15, 0, <Rd>, c7, c5, 4
+ * (flush prefetch buffer)
+ */
+ __asm __volatile("isb sy" ::: "memory");
+ goto emulated;
+ case 0x0e070f9a:
+ /*
+ * mcr p15, 0, <Rd>, c7, c10, 4
+ * (data synchronization barrier)
+ */
+ __asm __volatile("dsb sy" ::: "memory");
+ goto emulated;
+ case 0x0e070fba:
+ /*
+ * mcr p15, 0, <Rd>, c7, c10, 5
+ * (data memory barrier)
+ */
+ __asm __volatile("dmb sy" ::: "memory");
+ goto emulated;
+ default:
+ break;
+ }
+ break;
+ }
+
+ /* unknown, or unsupported instruction */
+ return 1;
+
+ emulated:
+ tf->tf_pc += insn_size;
+ return 0;
+}
+#endif /* COMPAT_NETBSD32 */
+
void
trap_el0_32sync(struct trapframe *tf)
{
@@ -371,11 +468,18 @@
userret(l);
break;
+ case ESR_EC_UNKNOWN:
+ if (emul_arm_insn(tf))
+ goto unknown;
+ userret(l);
+ break;
+
case ESR_EC_CP15_RT:
case ESR_EC_CP15_RRT:
case ESR_EC_CP14_RT:
case ESR_EC_CP14_DT:
case ESR_EC_CP14_RRT:
+unknown:
#endif /* COMPAT_NETBSD32 */
default:
#ifdef DDB
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/include/netbsd32_machdep.h
--- a/sys/arch/aarch64/include/netbsd32_machdep.h Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/include/netbsd32_machdep.h Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.h,v 1.2 2018/10/12 01:28:58 ryo Exp $ */
+/* $NetBSD: netbsd32_machdep.h,v 1.3 2019/11/24 04:08:36 rin Exp $ */
#ifndef _MACHINE_NETBSD32_H_
#define _MACHINE_NETBSD32_H_
@@ -107,4 +107,7 @@
netbsd32_size_t len; /* Region size */
};
+/* Support varying ABI names for netbsd32 */
+#define PROC_MACHINE_ARCH32(P) ((P)->p_md.md_march32)
+
#endif /* _MACHINE_NETBSD32_H_ */
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/include/param.h
--- a/sys/arch/aarch64/include/param.h Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/include/param.h Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.12 2019/10/19 18:04:26 jmcneill Exp $ */
+/* $NetBSD: param.h,v 1.13 2019/11/24 04:08:36 rin Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -59,9 +59,13 @@
# ifdef __AARCH64EB__
# define _MACHINE_ARCH aarch64eb
# define MACHINE_ARCH "aarch64eb"
+# define _MACHINE32_ARCH earmv7hfeb
+# define MACHINE32_ARCH "earmv7hfeb"
# else
# define _MACHINE_ARCH aarch64
# define MACHINE_ARCH "aarch64"
+# define _MACHINE32_ARCH earmv7hf
+# define MACHINE32_ARCH "earmv7hf"
# endif /* __AARCH64EB__ */
# endif /* MACHINE_ARCH */
#else
@@ -69,14 +73,20 @@
# undef MACHINE
# undef _MACHINE_ARCH
# undef MACHINE_ARCH
+# undef _MACHINE32_ARCH
+# undef MACHINE32_ARCH
# define _MACHINE aarch64
# define MACHINE "aarch64"
# ifdef __AARCH64EB__
# define _MACHINE_ARCH aarch64eb
# define MACHINE_ARCH "aarch64eb"
+# define _MACHINE32_ARCH earmv7hfeb
+# define MACHINE32_ARCH "earmv7hfeb"
# else
# define _MACHINE_ARCH aarch64
# define MACHINE_ARCH "aarch64"
+# define _MACHINE32_ARCH earmv7hf
+# define MACHINE32_ARCH "earmv7hf"
# endif /* __AARCH64EB__ */
#endif /* !_KERNEL */
diff -r 5435147e92c4 -r 18ee1e5b5500 sys/arch/aarch64/include/proc.h
--- a/sys/arch/aarch64/include/proc.h Sun Nov 24 02:06:16 2019 +0000
+++ b/sys/arch/aarch64/include/proc.h Sun Nov 24 04:08:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.3 2018/12/27 09:55:27 mrg Exp $ */
+/* $NetBSD: proc.h,v 1.4 2019/11/24 04:08:36 rin Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,6 +34,10 @@
#ifdef __aarch64__
+#ifdef _KERNEL_OPT
+#include "opt_compat_netbsd32.h"
+#endif
+
struct mdlwp {
void *md_onfault;
struct trapframe *md_utf;
@@ -43,8 +47,15 @@
struct mdproc {
void (*md_syscall)(struct trapframe *);
+#ifdef COMPAT_NETBSD32
+ char md_march32[12]; /* machine arch of executable */
+#endif
};
+#ifdef COMPAT_NETBSD32
+#define PROC0_MD_INITIALIZERS .p_md = { .md_march32 = MACHINE32_ARCH },
+#endif
+
#elif defined(__arm__)
Home |
Main Index |
Thread Index |
Old Index