On Thu, Aug 13, 2020 at 09:17:41PM +0200, Mark Kettenis wrote: > 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? >
So if I read this right, the SPAN bit makes that an exception to kernel/hypervisor mode sets the PAN bit in the PSTATE. Exception also means "interrupt", or is this only syscall? I think intrs are also exceptions... Essentially, everytime we switch to EL1/EL2 PAN will be enabled? Sounds good to me, ok patrick@ > > 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 >