[PATCH 5/5] arm64: kernel: Add support for Privileged Access Never
Catalin Marinas
catalin.marinas at arm.com
Fri Jul 17 05:57:03 PDT 2015
On Thu, Jul 16, 2015 at 05:01:59PM +0100, James Morse wrote:
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 7e419fabe75a..68aa1e399575 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -20,9 +20,18 @@
> #ifndef __ASM_SYSREG_H
> #define __ASM_SYSREG_H
>
> +#include <asm/opcodes.h>
> +
> #define sys_reg(op0, op1, crn, crm, op2) \
> ((((op0)-2)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
>
> +#define REG_PSTATE_PAN_IMM sys_reg(2, 0, 4, 0, 4)
> +#define PSTATE_PAN (1 << 22)
I missed this before, can we have a PSR_PAN_BIT in uapi/asm/ptrace.h for
consistency with the other PSTATE bits? It's not user accessible but we
did the same with the I and F bits already.
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index f260affb825c..0464eaef6667 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -21,6 +21,7 @@
> #include <linux/types.h>
> #include <asm/cpu.h>
> #include <asm/cpufeature.h>
> +#include <asm/processor.h>
>
> static bool
> has_id_aa64pfr0_feature(const struct arm64_cpu_capabilities *entry)
> @@ -32,6 +33,16 @@ has_id_aa64pfr0_feature(const struct arm64_cpu_capabilities *entry)
> (val & entry->register_mask) <= entry->max_register_value);
> }
>
> +static bool __maybe_unused
> +has_id_aa64mmfr1_feature(const struct arm64_cpu_capabilities *entry)
> +{
> + u64 val;
> +
> + val = read_cpuid(id_aa64mmfr1_el1);
> + return ((val & entry->register_mask) >= entry->min_register_value &&
> + (val & entry->register_mask) <= entry->max_register_value);
> +}
That's fine until we clarify what we actually want here in the other
patch.
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 223b093c9440..cea69aae4997 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -277,6 +277,9 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
> } else {
> memset(childregs, 0, sizeof(struct pt_regs));
> childregs->pstate = PSR_MODE_EL1h;
> + if (IS_ENABLED(CONFIG_ARM64_PAN) &&
> + cpus_have_cap(ARM64_HAS_PAN))
> + childregs->pstate |= PSTATE_PAN;
> p->thread.cpu_context.x19 = stack_start;
> p->thread.cpu_context.x20 = stk_sz;
I wonder if this is actually needed. When we run in kernel mode, PAN is
always set (automatically on exception entry) and only explicitly
cleared for get_user/put_user etc. Switching to a kernel thread is done
via switch_to which preserves PAN, so the regs->pstate here is not
relevant (IOW, we only ever ERET to a kernel thread after an
exception/interrupt but in that case pstate.pan is already set by the
handler).
--
Catalin
More information about the linux-arm-kernel
mailing list