ARMv8.1 introduced PAN (Priviliged Access Never) which prevents the kernel from accessing userland data. This can be bypassed by using special instructions which we already use in copyin(9) and friends. So we can simply turn this feature on if the CPU supports it.
Tested on an Odroid-C4 which has Cortex-A55 cores that have PAN support. ok? Index: arch/arm64/arm64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v retrieving revision 1.38 diff -u -p -r1.38 cpu.c --- arch/arm64/arm64/cpu.c 4 Jun 2020 21:18:16 -0000 1.38 +++ arch/arm64/arm64/cpu.c 13 Aug 2020 19:12:30 -0000 @@ -321,6 +321,7 @@ cpu_attach(struct device *parent, struct struct fdt_attach_args *faa = aux; struct cpu_info *ci; uint64_t mpidr = READ_SPECIALREG(mpidr_el1); + uint64_t id_aa64mmfr1, sctlr; uint32_t opp; KASSERT(faa->fa_nreg > 0); @@ -393,6 +394,14 @@ cpu_attach(struct device *parent, struct cpu_cpuspeed = cpu_clockspeed; } + /* Enable PAN. */ + id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); + if (ID_AA64MMFR1_PAN(id_aa64mmfr1) != ID_AA64MMFR1_PAN_NONE) { + sctlr = READ_SPECIALREG(sctlr_el1); + sctlr &= ~SCTLR_SPAN; + WRITE_SPECIALREG(sctlr_el1, sctlr); + } + /* Initialize debug registers. */ WRITE_SPECIALREG(mdscr_el1, DBG_MDSCR_TDCC); WRITE_SPECIALREG(oslar_el1, 0); @@ -522,6 +531,7 @@ cpu_boot_secondary(struct cpu_info *ci) void cpu_start_secondary(struct cpu_info *ci) { + uint64_t id_aa64mmfr1, sctlr; uint64_t tcr; int s; @@ -543,6 +553,14 @@ cpu_start_secondary(struct cpu_info *ci) tcr |= TCR_T0SZ(64 - USER_SPACE_BITS); tcr |= TCR_A1; WRITE_SPECIALREG(tcr_el1, tcr); + + /* Enable PAN. */ + id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); + if (ID_AA64MMFR1_PAN(id_aa64mmfr1) != ID_AA64MMFR1_PAN_NONE) { + sctlr = READ_SPECIALREG(sctlr_el1); + sctlr &= ~SCTLR_SPAN; + WRITE_SPECIALREG(sctlr_el1, sctlr); + } /* Initialize debug registers. */ WRITE_SPECIALREG(mdscr_el1, DBG_MDSCR_TDCC); Index: arch/arm64/include/armreg.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/armreg.h,v retrieving revision 1.11 diff -u -p -r1.11 armreg.h --- arch/arm64/include/armreg.h 5 Jun 2020 22:14:25 -0000 1.11 +++ arch/arm64/include/armreg.h 13 Aug 2020 19:12:30 -0000 @@ -451,6 +451,7 @@ #define SCTLR_nTWI 0x00010000 #define SCTLR_nTWE 0x00040000 #define SCTLR_WXN 0x00080000 +#define SCTLR_SPAN 0x00800000 #define SCTLR_EOE 0x01000000 #define SCTLR_EE 0x02000000 #define SCTLR_UCI 0x04000000 @@ -478,6 +479,7 @@ #define PSR_D 0x00000200 #define PSR_IL 0x00100000 #define PSR_SS 0x00200000 +#define PSR_PAN 0x00400000 #define PSR_V 0x10000000 #define PSR_C 0x20000000 #define PSR_Z 0x40000000