Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp180103imm; Fri, 5 Oct 2018 01:50:58 -0700 (PDT) X-Google-Smtp-Source: ACcGV630DSlrF4uSb0LHFK5OA12r4+cwTWxTdQbPLS0UoSws1HMdf06AghOgfOqBTvPQAge1bJmR X-Received: by 2002:a17:902:bd06:: with SMTP id p6-v6mr10298578pls.226.1538729458747; Fri, 05 Oct 2018 01:50:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538729458; cv=none; d=google.com; s=arc-20160816; b=Q17hAvpWmgUysa6qLFDGg4PBWt6BJ655GPJ2Mcfr4yydkJnJyaE1o+0ybmLphgmsJ3 SF5BP1/aEFEN8N2JLdopaK/WfrsOWACdoB10tFhpGjGV39hwL0tF0QPK2PD1uMgKhdoS v8mgs78RYPd6jGilMzUuTVmDZSdDhMBr0ikN4rfmogcq1rhLAnVhGQYuyMBqWAHIGdAs jO8VcxByOsmHIqoSp0wd1XUOXVWcWWIbiV9A0xu0nbNbK6+pHaALsk7njLiO00X+CVZy 0VWyOMBePPmVcIePuEl7MaGMJ7lTgTWQHs6/KExtEYJDc5gDX19kRqy0jNntpJnurJJa cbdg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=X9VNFR2Mca9Xb7fZD7ZMjS6wGUV4haBQwV7Xj4Eg+EY=; b=BsGPDTLgn24ID/UxyL8Q5yZERxm+MQVDFZZS02ID2Pzh3aZZ69VXop6gJczydeYFvL O2DdeQ7OybaZwnjxcIgJnkNwvkxT+8GfWTUSBAK0DtwpP3bBDLOPyDEMZiRW6BgQjdrV 1DDtHpETV8gbcTA+ggpUGQQ5qxF0Ld26KOxoandeHJefTihirCGEmyH+Fa5CpM9QFbhG MpnIvPjB6M68EH9B638wBhwNn9O9QaKc6/dza0sno4ENZklZbx4e0tCf/VMV5srxtghq kGsDCDxRkhesAN23+q+/XAAgdG92j31dwj8looZOW484g9Qkvoxog9MIvI0o1JMMgMZE qc0w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f3-v6si7718833pld.416.2018.10.05.01.50.42; Fri, 05 Oct 2018 01:50:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728820AbeJEPr4 (ORCPT + 99 others); Fri, 5 Oct 2018 11:47:56 -0400 Received: from foss.arm.com ([217.140.101.70]:47876 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728587AbeJEPr4 (ORCPT ); Fri, 5 Oct 2018 11:47:56 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C844B80D; Fri, 5 Oct 2018 01:50:11 -0700 (PDT) Received: from moonbear.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 933E03F5B3; Fri, 5 Oct 2018 01:50:08 -0700 (PDT) From: Kristina Martsenko To: linux-arm-kernel@lists.infradead.org Cc: Adam Wallis , Amit Kachhap , Andrew Jones , Ard Biesheuvel , Arnd Bergmann , Catalin Marinas , Christoffer Dall , Dave P Martin , Jacob Bramley , Kees Cook , Marc Zyngier , Mark Rutland , Ramana Radhakrishnan , "Suzuki K . Poulose" , Will Deacon , kvmarm@lists.cs.columbia.edu, linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 07/17] arm64: add basic pointer authentication support Date: Fri, 5 Oct 2018 09:47:44 +0100 Message-Id: <20181005084754.20950-8-kristina.martsenko@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181005084754.20950-1-kristina.martsenko@arm.com> References: <20181005084754.20950-1-kristina.martsenko@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mark Rutland This patch adds basic support for pointer authentication, allowing userspace to make use of APIAKey. The kernel maintains an APIAKey value for each process (shared by all threads within), which is initialised to a random value at exec() time. To describe that address authentication instructions are available, the ID_AA64ISAR0.{APA,API} fields are exposed to userspace. A new hwcap, APIA, is added to describe that the kernel manages APIAKey. Instructions using other keys (APIBKey, APDAKey, APDBKey) are disabled, and will behave as NOPs. These may be made use of in future patches. No support is added for the generic key (APGAKey), though this cannot be trapped or made to behave as a NOP. Its presence is not advertised with a hwcap. Signed-off-by: Mark Rutland [kristina: init keys in arch_bprm_mm_init; add AA64ISAR1.API HWCAP_CAP; use sysreg_clear_set] Signed-off-by: Kristina Martsenko Tested-by: Adam Wallis Cc: Catalin Marinas Cc: Ramana Radhakrishnan Cc: Suzuki K Poulose Cc: Will Deacon --- arch/arm64/include/asm/mmu.h | 5 +++ arch/arm64/include/asm/mmu_context.h | 16 ++++++++- arch/arm64/include/asm/pointer_auth.h | 63 +++++++++++++++++++++++++++++++++++ arch/arm64/include/uapi/asm/hwcap.h | 1 + arch/arm64/kernel/cpufeature.c | 10 ++++++ arch/arm64/kernel/cpuinfo.c | 1 + 6 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/pointer_auth.h diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index dd320df0d026..f6480ea7b0d5 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -25,10 +25,15 @@ #ifndef __ASSEMBLY__ +#include + typedef struct { atomic64_t id; void *vdso; unsigned long flags; +#ifdef CONFIG_ARM64_PTR_AUTH + struct ptrauth_keys ptrauth_keys; +#endif } mm_context_t; /* diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index 39ec0b8a689e..983f80925566 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -216,6 +215,8 @@ static inline void __switch_mm(struct mm_struct *next) return; } + mm_ctx_ptrauth_switch(&next->context); + check_and_switch_context(next, cpu); } @@ -241,6 +242,19 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, void verify_cpu_asid_bits(void); void post_ttbr_update_workaround(void); +static inline void arch_bprm_mm_init(struct mm_struct *mm, + struct vm_area_struct *vma) +{ + mm_ctx_ptrauth_init(&mm->context); +} +#define arch_bprm_mm_init arch_bprm_mm_init + +/* + * We need to override arch_bprm_mm_init before including the generic hooks, + * which are otherwise sufficient for us. + */ +#include + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_MMU_CONTEXT_H */ diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h new file mode 100644 index 000000000000..2aefedc31d9e --- /dev/null +++ b/arch/arm64/include/asm/pointer_auth.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __ASM_POINTER_AUTH_H +#define __ASM_POINTER_AUTH_H + +#include + +#include +#include + +#ifdef CONFIG_ARM64_PTR_AUTH +/* + * Each key is a 128-bit quantity which is split across a pair of 64-bit + * registers (Lo and Hi). + */ +struct ptrauth_key { + unsigned long lo, hi; +}; + +/* + * We give each process its own instruction A key (APIAKey), which is shared by + * all threads. This is inherited upon fork(), and reinitialised upon exec*(). + * All other keys are currently unused, with APIBKey, APDAKey, and APBAKey + * instructions behaving as NOPs. + */ +struct ptrauth_keys { + struct ptrauth_key apia; +}; + +static inline void ptrauth_keys_init(struct ptrauth_keys *keys) +{ + if (!cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) + return; + + get_random_bytes(keys, sizeof(*keys)); +} + +#define __ptrauth_key_install(k, v) \ +do { \ + struct ptrauth_key __pki_v = (v); \ + write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \ + write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \ +} while (0) + +static inline void ptrauth_keys_switch(struct ptrauth_keys *keys) +{ + if (!cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) + return; + + __ptrauth_key_install(APIA, keys->apia); +} + +#define mm_ctx_ptrauth_init(ctx) \ + ptrauth_keys_init(&(ctx)->ptrauth_keys) + +#define mm_ctx_ptrauth_switch(ctx) \ + ptrauth_keys_switch(&(ctx)->ptrauth_keys) + +#else /* CONFIG_ARM64_PTR_AUTH */ +#define mm_ctx_ptrauth_init(ctx) +#define mm_ctx_ptrauth_switch(ctx) +#endif /* CONFIG_ARM64_PTR_AUTH */ + +#endif /* __ASM_POINTER_AUTH_H */ diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 17c65c8f33cb..01f02ac500ae 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -48,5 +48,6 @@ #define HWCAP_USCAT (1 << 25) #define HWCAP_ILRCPC (1 << 26) #define HWCAP_FLAGM (1 << 27) +#define HWCAP_APIA (1 << 28) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 0dd171c7d71e..3157685aa56a 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1040,6 +1040,11 @@ static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused) } #ifdef CONFIG_ARM64_PTR_AUTH +static void cpu_enable_address_auth(struct arm64_cpu_capabilities const *cap) +{ + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ENIA); +} + static bool has_address_auth(const struct arm64_cpu_capabilities *entry, int __unused) { @@ -1267,6 +1272,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .capability = ARM64_HAS_ADDRESS_AUTH, .type = ARM64_CPUCAP_SYSTEM_FEATURE, .matches = has_address_auth, + .cpu_enable = cpu_enable_address_auth, }, #endif /* CONFIG_ARM64_PTR_AUTH */ {}, @@ -1314,6 +1320,10 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { #ifdef CONFIG_ARM64_SVE HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, HWCAP_SVE), #endif +#ifdef CONFIG_ARM64_PTR_AUTH + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_APIA), + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_APIA), +#endif {}, }; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index e9ab7b3ed317..608411e3aaff 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -81,6 +81,7 @@ static const char *const hwcap_str[] = { "uscat", "ilrcpc", "flagm", + "apia", NULL }; -- 2.11.0