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
> 

Reply via email to