From: Mark Rutland <mark.rutland@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: linux-arch@vger.kernel.org, arnd@arndb.de, jiong.wang@arm.com, marc.zyngier@arm.com, catalin.marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, kvmarm@lists.cs.columbia.edu Subject: [RFC 8/9] arm64/kvm: context-switch PAC registers Date: Mon, 3 Apr 2017 16:19:24 +0100 [thread overview] Message-ID: <1491232765-32501-9-git-send-email-mark.rutland@arm.com> (raw) In-Reply-To: <1491232765-32501-1-git-send-email-mark.rutland@arm.com> If we have pointer authentication support, a guest may wish to use it. This patch adds the infrastructure to allow it to do so. This is sufficient for basic testing, but not for real-world usage. A guest will still see pointer authentication support advertised in the ID registers, and we will need to trap accesses to these to provide santized values. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Christoffer Dall <christoffer.dall@linaro.org> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: kvmarm@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_emulate.h | 15 +++++++++++++ arch/arm64/include/asm/kvm_host.h | 12 ++++++++++ arch/arm64/kvm/hyp/sysreg-sr.c | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index f5ea0ba..0c3cb43 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -28,6 +28,8 @@ #include <asm/kvm_arm.h> #include <asm/kvm_mmio.h> #include <asm/ptrace.h> +#include <asm/cpucaps.h> +#include <asm/cpufeature.h> #include <asm/cputype.h> #include <asm/virt.h> @@ -49,6 +51,19 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 |= HCR_E2H; if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) vcpu->arch.hcr_el2 &= ~HCR_RW; + + /* + * Address auth and generic auth share the same enable bits, so we have + * to ensure both are uniform before we can enable support in a guest. + * Until we have the infrastructure to detect uniform absence of a + * feature, only permit the case when both are supported. + * + * Note that a guest will still see the feature in ID_AA64_ISAR1 until + * we introduce code to emulate the ID registers. + */ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH) && + cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) + vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); } static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e7705e7..b25f710 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -133,6 +133,18 @@ enum vcpu_sysreg { PMSWINC_EL0, /* Software Increment Register */ PMUSERENR_EL0, /* User Enable Register */ + /* Pointer Authentication Registers */ + APIAKEYLO_EL1, + APIAKEYHI_EL1, + APIBKEYLO_EL1, + APIBKEYHI_EL1, + APDAKEYLO_EL1, + APDAKEYHI_EL1, + APDBKEYLO_EL1, + APDBKEYHI_EL1, + APGAKEYLO_EL1, + APGAKEYHI_EL1, + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 9341376..3440b42 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -18,6 +18,8 @@ #include <linux/compiler.h> #include <linux/kvm_host.h> +#include <asm/cpucaps.h> +#include <asm/cpufeature.h> #include <asm/kvm_asm.h> #include <asm/kvm_hyp.h> @@ -31,6 +33,24 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } * pstate, and guest must save everything. */ +#define __save_ap_key(regs, key) \ + regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \ + regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_save_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __save_ap_key(ctxt->sys_regs, APIA); + __save_ap_key(ctxt->sys_regs, APIB); + __save_ap_key(ctxt->sys_regs, APDA); + __save_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __save_ap_key(ctxt->sys_regs, APGA); + } +} + static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); @@ -41,6 +61,8 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); + + __sysreg_save_ap_keys(ctxt); } static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) @@ -84,6 +106,25 @@ void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt) __sysreg_save_common_state(ctxt); } +#define __restore_ap_key(regs, key) \ + write_sysreg_s(regs[key ## KEYLO_EL1], SYS_ ## key ## KEYLO_EL1); \ + write_sysreg_s(regs[key ## KEYHI_EL1], SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_restore_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __restore_ap_key(ctxt->sys_regs, APIA); + __restore_ap_key(ctxt->sys_regs, APIB); + __restore_ap_key(ctxt->sys_regs, APDA); + __restore_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __restore_ap_key(ctxt->sys_regs, APGA); + } +} + + static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) { write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1); @@ -94,6 +135,8 @@ static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctx write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); write_sysreg_el2(ctxt->gp_regs.regs.pc, elr); write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr); + + __sysreg_restore_ap_keys(ctxt); } static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland@arm.com> To: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org, arnd@arndb.de, catalin.marinas@arm.com, christoffer.dall@linaro.org, jiong.wang@arm.com, kvmarm@lists.cs.columbia.edu, linux-arch@vger.kernel.org, marc.zyngier@arm.com, mark.rutland@arm.com, suzuki.poulose@arm.com, will.deacon@arm.com Subject: [RFC 8/9] arm64/kvm: context-switch PAC registers Date: Mon, 3 Apr 2017 16:19:24 +0100 [thread overview] Message-ID: <1491232765-32501-9-git-send-email-mark.rutland@arm.com> (raw) Message-ID: <20170403151924.zPdXQyN5nKDxVvj0jXmHBb_xG8F9MC2TNxklBiCmksE@z> (raw) In-Reply-To: <1491232765-32501-1-git-send-email-mark.rutland@arm.com> If we have pointer authentication support, a guest may wish to use it. This patch adds the infrastructure to allow it to do so. This is sufficient for basic testing, but not for real-world usage. A guest will still see pointer authentication support advertised in the ID registers, and we will need to trap accesses to these to provide santized values. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Christoffer Dall <christoffer.dall@linaro.org> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: kvmarm@lists.cs.columbia.edu --- arch/arm64/include/asm/kvm_emulate.h | 15 +++++++++++++ arch/arm64/include/asm/kvm_host.h | 12 ++++++++++ arch/arm64/kvm/hyp/sysreg-sr.c | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index f5ea0ba..0c3cb43 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -28,6 +28,8 @@ #include <asm/kvm_arm.h> #include <asm/kvm_mmio.h> #include <asm/ptrace.h> +#include <asm/cpucaps.h> +#include <asm/cpufeature.h> #include <asm/cputype.h> #include <asm/virt.h> @@ -49,6 +51,19 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 |= HCR_E2H; if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) vcpu->arch.hcr_el2 &= ~HCR_RW; + + /* + * Address auth and generic auth share the same enable bits, so we have + * to ensure both are uniform before we can enable support in a guest. + * Until we have the infrastructure to detect uniform absence of a + * feature, only permit the case when both are supported. + * + * Note that a guest will still see the feature in ID_AA64_ISAR1 until + * we introduce code to emulate the ID registers. + */ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH) && + cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) + vcpu->arch.hcr_el2 |= (HCR_API | HCR_APK); } static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e7705e7..b25f710 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -133,6 +133,18 @@ enum vcpu_sysreg { PMSWINC_EL0, /* Software Increment Register */ PMUSERENR_EL0, /* User Enable Register */ + /* Pointer Authentication Registers */ + APIAKEYLO_EL1, + APIAKEYHI_EL1, + APIBKEYLO_EL1, + APIBKEYHI_EL1, + APDAKEYLO_EL1, + APDAKEYHI_EL1, + APDBKEYLO_EL1, + APDBKEYHI_EL1, + APGAKEYLO_EL1, + APGAKEYHI_EL1, + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c index 9341376..3440b42 100644 --- a/arch/arm64/kvm/hyp/sysreg-sr.c +++ b/arch/arm64/kvm/hyp/sysreg-sr.c @@ -18,6 +18,8 @@ #include <linux/compiler.h> #include <linux/kvm_host.h> +#include <asm/cpucaps.h> +#include <asm/cpufeature.h> #include <asm/kvm_asm.h> #include <asm/kvm_hyp.h> @@ -31,6 +33,24 @@ static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { } * pstate, and guest must save everything. */ +#define __save_ap_key(regs, key) \ + regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \ + regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_save_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __save_ap_key(ctxt->sys_regs, APIA); + __save_ap_key(ctxt->sys_regs, APIB); + __save_ap_key(ctxt->sys_regs, APDA); + __save_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __save_ap_key(ctxt->sys_regs, APGA); + } +} + static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { ctxt->sys_regs[ACTLR_EL1] = read_sysreg(actlr_el1); @@ -41,6 +61,8 @@ static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt) ctxt->gp_regs.regs.sp = read_sysreg(sp_el0); ctxt->gp_regs.regs.pc = read_sysreg_el2(elr); ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr); + + __sysreg_save_ap_keys(ctxt); } static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt) @@ -84,6 +106,25 @@ void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt) __sysreg_save_common_state(ctxt); } +#define __restore_ap_key(regs, key) \ + write_sysreg_s(regs[key ## KEYLO_EL1], SYS_ ## key ## KEYLO_EL1); \ + write_sysreg_s(regs[key ## KEYHI_EL1], SYS_ ## key ## KEYHI_EL1) + +static void __hyp_text __sysreg_restore_ap_keys(struct kvm_cpu_context *ctxt) +{ + if (cpus_have_const_cap(ARM64_HAS_ADDRESS_AUTH)) { + __restore_ap_key(ctxt->sys_regs, APIA); + __restore_ap_key(ctxt->sys_regs, APIB); + __restore_ap_key(ctxt->sys_regs, APDA); + __restore_ap_key(ctxt->sys_regs, APDB); + } + + if (cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH)) { + __restore_ap_key(ctxt->sys_regs, APGA); + } +} + + static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) { write_sysreg(ctxt->sys_regs[ACTLR_EL1], actlr_el1); @@ -94,6 +135,8 @@ static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctx write_sysreg(ctxt->gp_regs.regs.sp, sp_el0); write_sysreg_el2(ctxt->gp_regs.regs.pc, elr); write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr); + + __sysreg_restore_ap_keys(ctxt); } static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt) -- 1.9.1
next prev parent reply other threads:[~2017-04-03 15:19 UTC|newest] Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-04-03 15:19 [RFC 0/9] ARMv8.3 pointer authentication userspace support Mark Rutland 2017-04-03 15:19 ` [RFC 1/9] asm-generic: mm_hooks: allow hooks to be overridden individually Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 2/9] arm64: add pointer authentication register bits Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 3/9] arm64/cpufeature: add ARMv8.3 id_aa64isar1 bits Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 4/9] arm64/cpufeature: detect pointer authentication Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 5/9] arm64: Don't trap host pointer auth use to EL2 Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 6/9] arm64: add basic pointer authentication support Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-04-03 15:19 ` [RFC 7/9] arm64: expose PAC bit positions via ptrace Mark Rutland 2017-04-03 15:19 ` Mark Rutland 2017-07-25 12:11 ` Dave Martin 2017-07-25 14:59 ` Mark Rutland 2017-07-25 15:06 ` Dave Martin 2017-04-03 15:19 ` Mark Rutland [this message] 2017-04-03 15:19 ` [RFC 8/9] arm64/kvm: context-switch PAC registers Mark Rutland 2017-04-07 15:41 ` Marc Zyngier 2017-04-03 15:19 ` [RFC 9/9] arm64: docs: document pointer authentication Mark Rutland 2017-04-07 15:09 ` [RFC 0/9] ARMv8.3 pointer authentication userspace support Adam Wallis
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1491232765-32501-9-git-send-email-mark.rutland@arm.com \ --to=mark.rutland@arm.com \ --cc=arnd@arndb.de \ --cc=catalin.marinas@arm.com \ --cc=jiong.wang@arm.com \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arch@vger.kernel.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=marc.zyngier@arm.com \ --cc=will.deacon@arm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).