KVM: arm64: Support FEAT_LS64_ACCDATA in guests
Subsystems (5)
Fuad Tabba
reviewerv2 cover KVM: arm64: Support FEAT_LS64_ACCDATA in guests
Hi folks,
Changes since v1 [1]:
- Support FEAT_LS64_ACCDATA in guests instead of capping ID_AA64ISAR1_EL1.LS64 at LS64_V. A saved VM keeps its level, so restore no longer has to accept older kernels' levels, and v1's set_id_regs patch goes. (Marc)
- Add an arm64.nols64 option. (Marc)
- Retitled the series to match.
On a host with FEAT_LS64_ACCDATA, KVM advertises ST64BV0 and ACCDATA_EL1 to guests but doesn't support either. A guest's ST64BV0 hits the WARN in handle_other(), and every guest on a CPU shares ACCDATA_EL1.
Patches 2 and 3 are Marc's from 2024 [2], rebased. I changed patch 3 to switch ACCDATA_EL1 for guests only, and only when the new ARM64_HAS_LS64_ACCDATA capability is set, for the reasons in its note. Patch 4 sets HCRX_EL2.EnAS0. Patch 1 adds arm64.nols64 to disable LS64 on a host whose firmware leaves SCR_EL3.ADEn clear. It comes first so that the option exists in every commit that switches ACCDATA_EL1. All five carry Cc: stable. The get-reg-list patch carries it because the test fails on a host with the feature once patch 2 is in.
Tested on the FVP with arm_v8_7_accelerator_support_level at 3 (LS64_ACCDATA) in VHE, nVHE and protected mode, and at 4 (LS64WB) in VHE, with cpuidle.off=1 so that idle doesn't reset ACCDATA_EL1 between VMs. In my reproducer, one VM writes ACCDATA_EL1 and the next VM on the same CPU reads it. Unpatched, it reads the first VM's value and ST64BV0 hits the WARN. Patched, the second VM reads 0 and ST64BV0 doesn't trap.
Based on Linux 7.3-rc3 (fd73f4a665989).
Cheers,
/fuad
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
Fuad Tabba (3):
arm64: Add override for ID_AA64ISAR1_EL1.LS64
KVM: arm64: Enable ST64BV0 for guests with FEAT_LS64_ACCDATA
KVM: arm64: selftests: Add ACCDATA_EL1 to get-reg-list
Marc Zyngier (2):
KVM: arm64: Add ACCDATA_EL1 to the sysreg array
KVM: arm64: Add context-switch of ACCDATA_EL1
.../admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/include/asm/kvm_emulate.h | 3 +++ arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kernel/cpufeature.c | 7 ++++++ arch/arm64/kernel/pi/idreg-override.c | 2 ++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 23 +++++++++++++++++++ arch/arm64/kvm/sys_regs.c | 12 +++++++++- arch/arm64/tools/cpucaps | 1 + .../selftests/kvm/arm64/get-reg-list.c | 2 ++ 9 files changed, 55 insertions(+), 1 deletion(-)
base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
Signature · 1 line
2.47.3
Fuad Tabba
reviewerPATCH v2 1/5 arm64: Add override for ID_AA64ISAR1_EL1.LS64
Accesses to ACCDATA_EL1, which FEAT_LS64_ACCDATA adds, trap to EL3 unless firmware sets SCR_EL3.ADEn. Once KVM context-switches the register for its guests, a host whose firmware leaves the bit clear can't run them.
Add an override for ID_AA64ISAR1_EL1.LS64, with an arm64.nols64 alias, so that the feature can be disabled on such a host and for its guests. id_aa64isar1.ls64=2 disables only FEAT_LS64_ACCDATA and above.
--- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/kernel/pi/idreg-override.c | 2 ++ 2 files changed, 5 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -571,6 +571,9 @@ Kernel parameters arm64.nohaft [ARM64] Unconditionally disable Hardware managed Access Flag for Table descriptors support + arm64.nols64 [ARM64] Unconditionally disable 64-byte Load/Store + instructions support + arm64.nomops [ARM64] Unconditionally disable Memory Copy and Memory Set instructions support
arch/arm64/kernel/pi/idreg-override.c +2 -0
@@ -174,6 +174,7 @@ static const struct ftr_set_desc isar1 __prel64_initconst = { .name = "id_aa64isar1", .override = &id_aa64isar1_override, .fields = { +FIELD ("ls64" ,ID_AA64ISAR1_EL1_LS64_SHIFT ,NULL ),FIELD ("gpi" ,ID_AA64ISAR1_EL1_GPI_SHIFT ,NULL ),FIELD ("gpa" ,ID_AA64ISAR1_EL1_GPA_SHIFT ,NULL ), FIELD("api", ID_AA64ISAR1_EL1_API_SHIFT, NULL),
@@ -253,6 +254,7 @@ static const struct {"id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 " "id_aa64isar1.api=0 id_aa64isar1.apa=0 " "id_aa64isar2.gpa3=0 id_aa64isar2.apa3=0" }, + { "arm64.nols64", "id_aa64isar1.ls64=0" }, { "arm64.nomops", "id_aa64isar2.mops=0" }, { "arm64.nomte", "id_aa64pfr1.mte=0" }, { "nokaslr", "arm64_sw.nokaslr=1" },
Signature · 1 line
2.47.3
Re: [PATCH v2 1/5] arm64: Add override for ID_AA64ISAR1_EL1.LS64
Quoted 11 lines · Fuad Tabba
Accesses to
ACCDATA_EL1, whichFEAT_LS64_ACCDATAadds, trap to EL3 unless firmware sets SCR_EL3.ADEn. Once KVM context-switches the register for its guests, a host whose firmware leaves the bit clear can't run them.Add an override for ID_AA64ISAR1_EL1.LS64, with an arm64.nols64 alias, so that the feature can be disabled on such a host and for its guests. id_aa64isar1.ls64=2 disables only
FEAT_LS64_ACCDATAand above.Signed-off-by Fuad Tabba <[email protected]>
However, does this need a plain cc stable? I assume you want it to go in with patch 3 but that one only goes as far as 7.0. Same cc stable in patch 2 which you may want to limit (or add both as dependencies to the cc stable in patch 3 when committing).
Signature · 1 line
Catalin
Fuad Tabba
reviewerRe: [PATCH v2 1/5] arm64: Add override for ID_AA64ISAR1_EL1.LS64
Hi Catalin,
On Thu, 29 Oct 2026 21:14:18 +0000, Catalin Marinas <[email protected]> wrote:
[...]
Quoted 4 lines
However, does this need a plain cc stable? I assume you want it to go in with patch 3 but that one only goes as far as 7.0. Same cc stable in patch 2 which you may want to limit (or add both as dependencies to the cc stable in patch 3 when committing).
No, it doesn't. Patches 1, 2 and 5 are only there for patches 3 and 4, so none of them need to go further back than 7.0.
Marc, Oliver, could the tag on all five patches become "Cc:
[email protected] # 7.0.x" when you apply them? I'll respin if that's easier.
Thanks!
/fuad
Fuad Tabba
reviewerPATCH v2 2/5 KVM: arm64: Add ACCDATA_EL1 to the sysreg array
In reply to Fuad TabbaFrom: Marc Zyngier <[email protected]>
Make ACCDATA_EL1 a first-class citizen, and add it to the sysreg array. Visibility is conditioned on the feature being enabled.
--- arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kvm/sys_regs.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-)
arch/arm64/include/asm/kvm_host.h +3 -0
@@ -498,6 +498,9 @@ enum vcpu_sysreg {GCR_EL1 ,/* Tag Control Register */ TFSRE0_EL1 ,/* Tag Fault Status Register (EL0) */ +/* Random stuff */ +ACCDATA_EL1 ,/* Accelerator Data */ + POR_EL0, /* Permission Overlay Register 0 (EL0) *//* FP/SIMD/SVE */
arch/arm64/kvm/sys_regs.c +11 -1
@@ -2914,6 +2914,15 @@ static unsigned int sve_el2_visibility(const struct kvm_vcpu *vcpu,return __el2_visibility (vcpu, rd, sve_visibility); } +static unsigned int accdata_visibility (const struct kvm_vcpu *vcpu, +const struct sys_reg_desc *rd) +{ +if (kvm_has_feat (vcpu->kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA )) +return 0 ; + +return REG_HIDDEN ; +} +static unsigned int vncr_el2_visibility (const struct kvm_vcpu *vcpu,const struct sys_reg_desc *rd) {
@@ -3601,7 +3610,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 }, { SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 }, - { SYS_DESC(SYS_ACCDATA_EL1), undef_access }, + { SYS_DESC(SYS_ACCDATA_EL1), undef_access, reset_val, ACCDATA_EL1, 0, + .visibility = accdata_visibility}, { SYS_DESC(SYS_SCXTNUM_EL1), undef_access },
Signature · 1 line
2.47.3
Re: [PATCH v2 2/5] KVM: arm64: Add ACCDATA_EL1 to the sysreg array
Quoted 5 lines · Fuad Tabba
From: Marc Zyngier <[email protected]>
Make
ACCDATA_EL1a first-class citizen, and add it to the sysreg array. Visibility is conditioned on the feature being enabled.
Hi Tabba,
LGTM.
Quoted 57 lines
Signed-off-by Marc Zyngier <[email protected]>[Fuad: rebased]Signed-off-by Fuad Tabba <[email protected]>--- arch/arm64/include/asm/kvm_host.h | 3 +++ arch/arm64/kvm/sys_regs.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-)arch/arm64/include/asm/kvm_host.h +3
-0@@ -498,6 +498,9 @@ enum vcpu_sysreg {GCR_EL1 ,/* Tag Control Register */ TFSRE0_EL1 ,/* Tag Fault Status Register (EL0) */ +/* Random stuff */ +ACCDATA_EL1 ,/* Accelerator Data */ + POR_EL0, /* Permission Overlay Register 0 (EL0) *//* FP/SIMD/SVE */ arch/arm64/kvm/sys_regs.c +11
-2@@ -2914,6 +2914,15 @@ static unsigned int sve_el2_visibility(const struct kvm_vcpu *vcpu,return __el2_visibility (vcpu, rd, sve_visibility); } +static unsigned int accdata_visibility (const struct kvm_vcpu *vcpu, +const struct sys_reg_desc *rd) +{ +if (kvm_has_feat (vcpu->kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA )) +return 0 ; + +return REG_HIDDEN ; +} +static unsigned int vncr_el2_visibility (const struct kvm_vcpu *vcpu,const struct sys_reg_desc *rd) {@@ -3601,7 +3610,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 }, { SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 }, - { SYS_DESC(SYS_ACCDATA_EL1), undef_access }, + { SYS_DESC(SYS_ACCDATA_EL1), undef_access, reset_val, ACCDATA_EL1, 0, + .visibility = accdata_visibility}, { SYS_DESC(SYS_SCXTNUM_EL1), undef_access }, --2.47.3
Fuad Tabba
reviewerPATCH v2 3/5 KVM: arm64: Add context-switch of ACCDATA_EL1
In reply to Fuad TabbaFrom: Marc Zyngier <[email protected]>
Add ACCDATA_EL1 save/restore as part of the EL0 context. This is conditioned on the guest's view of ID_AA64ISAR1_EL1.LS64 reporting that this register is supported.
[Fuad: rebased; switch ACCDATA_EL1 for guests only, as the host never
uses it; gate it on a new ARM64_HAS_LS64_ACCDATA capability, since in pKVM the host controls a non-protected guest's ID registers, and an EL2 access to ACCDATA_EL1 on a CPU without the feature is UNDEFINED]
--- arch/arm64/kernel/cpufeature.c | 7 +++++++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 23 ++++++++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 3 files changed, 31 insertions(+)
arch/arm64/kernel/cpufeature.c +7 -0
@@ -3225,6 +3225,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_ls64_v,ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_V ) }, + { + .desc ="LS64_ACCDATA" , + .capability = ARM64_HAS_LS64_ACCDATA, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, +ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ) + }, #ifdef CONFIG_ARM64_LSUI { .desc = "Unprivileged Load Store Instructions (LSUI)",
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +23 -0
@@ -17,6 +17,7 @@#include <asm/kvm_mmu.h> static inline bool ctxt_has_s1poe (struct kvm_cpu_context *ctxt); +static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt);static inline struct kvm_vcpu *ctxt_to_vcpu (struct kvm_cpu_context *ctxt) {
@@ -67,6 +68,13 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,TPIDR_EL0 ) =read_sysreg (tpidr_el0);ctxt_sys_reg (ctxt,TPIDRRO_EL0 ) =read_sysreg (tpidrro_el0); + +/* +* Despite the appearances, ACCDATA_EL1 is part of the EL0 +* context, as it can only be used using ST64BV0. +*/ +if (ctxt_has_accdata (ctxt)) +ctxt_sys_reg (ctxt,ACCDATA_EL1 ) =read_sysreg_s (SYS_ACCDATA_EL1 ); }static inline bool ctxt_has_mte (struct kvm_cpu_context *ctxt)
@@ -131,6 +139,18 @@ static inline bool ctxt_has_sctlr2(struct kvm_cpu_context *ctxt)return kvm_has_sctlr2 (kern_hyp_va (vcpu->kvm)); } +static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt) +{ +struct kvm_vcpu *vcpu; + +/* The host never uses ACCDATA_EL1 */ +if (!cpus_have_final_cap (ARM64_HAS_LS64_ACCDATA ) || !ctxt_is_guest (ctxt)) +return false; + + vcpu =ctxt_to_vcpu (ctxt); +return kvm_has_feat (kern_hyp_va (vcpu->kvm),ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ); +} +static inline void __sysreg_save_el1_state (struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,SCTLR_EL1 ) =read_sysreg_el1 (SYS_SCTLR );
@@ -210,6 +230,9 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) {write_sysreg (ctxt_sys_reg (ctxt,TPIDR_EL0 ), tpidr_el0);write_sysreg (ctxt_sys_reg (ctxt,TPIDRRO_EL0 ), tpidrro_el0); + +if (ctxt_has_accdata (ctxt)) +write_sysreg_s (ctxt_sys_reg (ctxt,ACCDATA_EL1 ),SYS_ACCDATA_EL1 ); } static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
arch/arm64/tools/cpucaps +1 -0
@@ -49,6 +49,7 @@ HAS_LPA2 HAS_LSE_ATOMICS HAS_LS64 HAS_LS64_V +HAS_LS64_ACCDATA HAS_LSUI HAS_MOPS HAS_NESTED_VIRT
Signature · 1 line
2.47.3
Suzuki K Poulose
reviewerRe: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
Hi Fuad
Quoted 69 lines · Fuad Tabba
From: Marc Zyngier <[email protected]>
Add
ACCDATA_EL1save/restore as part of the EL0 context. This is conditioned on the guest's view of ID_AA64ISAR1_EL1.LS64 reporting that this register is supported.Signed-off-by Marc Zyngier <[email protected]>Fixes 58ce78667a641 ("arm64: Add support for FEAT_{LS64, LS64_V}")[Fuad: rebased; switch
ACCDATA_EL1for guests only, as the host never
uses it; gate it on a newARM64_HAS_LS64_ACCDATAcapability, since in pKVM the host controls a non-protected guest's ID registers, and an EL2 access toACCDATA_EL1on a CPU without the feature is UNDEFINED]Signed-off-by Fuad Tabba <[email protected]>--- arch/arm64/kernel/cpufeature.c | 7 +++++++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 23 ++++++++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 3 files changed, 31 insertions(+)arch/arm64/kernel/cpufeature.c +7
-0@@ -3225,6 +3225,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_ls64_v,ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_V ) }, + { + .desc ="LS64_ACCDATA" , + .capability = ARM64_HAS_LS64_ACCDATA, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, +ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ) + }, #ifdef CONFIG_ARM64_LSUI { .desc = "Unprivileged Load Store Instructions (LSUI)",arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +8
-0@@ -17,6 +17,7 @@#include <asm/kvm_mmu.h> static inline bool ctxt_has_s1poe (struct kvm_cpu_context *ctxt); +static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt);static inline struct kvm_vcpu *ctxt_to_vcpu (struct kvm_cpu_context *ctxt) {@@ -67,6 +68,13 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,TPIDR_EL0 ) =read_sysreg (tpidr_el0);ctxt_sys_reg (ctxt,TPIDRRO_EL0 ) =read_sysreg (tpidrro_el0); + +/* +* Despite the appearances, ACCDATA_EL1 is part of the EL0 +* context, as it can only be used using ST64BV0. +*/ +if (ctxt_has_accdata (ctxt)) +ctxt_sys_reg (ctxt,ACCDATA_EL1 ) =read_sysreg_s (SYS_ACCDATA_EL1 ); }static inline bool ctxt_has_mte (struct kvm_cpu_context *ctxt)@@ -131,6 +139,18 @@ static inline bool ctxt_has_sctlr2(struct kvm_cpu_context *ctxt)return kvm_has_sctlr2 (kern_hyp_va (vcpu->kvm)); }
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h static inline bool ctxt_has_sctlr2(struct kvm_cpu_context *ctxt) · line 151
Quoted 10 lines
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +10
-0+static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt) +{ +struct kvm_vcpu *vcpu; + +/* The host never uses ACCDATA_EL1 */ +if (!cpus_have_final_cap (ARM64_HAS_LS64_ACCDATA ) || !ctxt_is_guest (ctxt)) +return false; + + vcpu =ctxt_to_vcpu (ctxt); +return kvm_has_feat (kern_hyp_va (vcpu->kvm),ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA );
minor nit: Aligning with the other kvm_has_feat() usecsaes, should we wrap this under kvm_has_accdata() (with moving the cpus_have_final_cap() to the wrapper ?)
Otherwise looks good to me.
Suzuki
Quoted 27 lines
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +5
-0+} +static inline void __sysreg_save_el1_state (struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,SCTLR_EL1 ) =read_sysreg_el1 (SYS_SCTLR );@@ -210,6 +230,9 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) {write_sysreg (ctxt_sys_reg (ctxt,TPIDR_EL0 ), tpidr_el0);write_sysreg (ctxt_sys_reg (ctxt,TPIDRRO_EL0 ), tpidrro_el0); + +if (ctxt_has_accdata (ctxt)) +write_sysreg_s (ctxt_sys_reg (ctxt,ACCDATA_EL1 ),SYS_ACCDATA_EL1 ); } static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,arch/arm64/tools/cpucaps +1
-0@@ -49,6 +49,7 @@ HAS_LPA2 HAS_LSE_ATOMICS HAS_LS64 HAS_LS64_V +HAS_LS64_ACCDATA HAS_LSUI HAS_MOPS HAS_NESTED_VIRT
Fuad Tabba
reviewerRe: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
On Mon, 26 Oct 2026 at 15:41, Suzuki K Poulose <[email protected]> wrote:
[...]
Quoted 6 lines
Quoted 6 lines
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +6
-0+static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt) +{ +struct kvm_vcpu *vcpu; + +/* The host never uses ACCDATA_EL1 */ +if (!cpus_have_final_cap (ARM64_HAS_LS64_ACCDATA ) || !ctxt_is_guest (ctxt))
Quoted 8 lines
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h static inline bool ctxt_has_sctlr2(struct kvm_cpu_context *ctxt) · line 151
Quoted 4 lines
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +4
-0+return false; + + vcpu =ctxt_to_vcpu (ctxt); +return kvm_has_feat (kern_hyp_va (vcpu->kvm),ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA );minor nit: Aligning with the other
kvm_has_feat()usecsaes, should we wrap this underkvm_has_accdata()(with moving thecpus_have_final_cap()to the wrapper ?)
Thanks Suzuki. I'll do this change if I respin.
Cheers,
/fuad
Re: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
In reply to Fuad TabbaReview
Quoted 11 lines · Fuad Tabba
(quoted diff) +6
-0return kvm_has_sctlr2(kern_hyp_va(vcpu->kvm)); } +static inline bool ctxt_has_accdata(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu; + + /* The host never uses ACCDATA_EL1 */ + if (!cpus_have_final_cap(ARM64_HAS_LS64_ACCDATA) ||!ctxt_is_guest(ctxt))
(quoted diff) +1
-0+ return false;
Maybe add a wrapper for this as we have for other features?
In my patch I've converted the check to use this one now:
arch/arm64/include/asm/cpufeature.h +5 -0
@@ -909,6 +909,11 @@ static inline bool system_supports_bbml3(void)return alternative_has_cap_unlikely (ARM64_HAS_BBML3 ); } +static inline bool system_supports_ls64_accdata (void ) +{ +return cpus_have_final_cap (ARM64_HAS_LS64_ACCDATA ); +} +int do_emulate_mrs (struct pt_regs *regs,u32 sys_reg,u32 rt);bool try_emulate_mrs (struct pt_regs *regs,u32 isn);
which makes sense to add in your patch first.
I think we'll also want a HWCAP3_LS64_ACCDATA exported to userspace, but we can keep that separate.
Arnd
Fuad Tabba
reviewerRe: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
Quoted 5 lines · Arnd Bergmann
Quoted 3 lines · Fuad Tabba
return kvm_has_sctlr2(kern_hyp_va(vcpu->kvm));}
Quoted 10 lines
Quoted 8 lines
(quoted diff) +6
-0+static inline bool ctxt_has_accdata(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu; + + /* The host never uses ACCDATA_EL1 */ + if (!cpus_have_final_cap(ARM64_HAS_LS64_ACCDATA) ||!ctxt_is_guest(ctxt))
+ return false;Maybe add a wrapper for this as we have for other features?
Thanks Arnd. Makes sense, I'll do this if I respin.
Cheers,
/fuad
Re: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
In reply to Fuad TabbaQuoted 10 lines · Fuad Tabba
From: Marc Zyngier <[email protected]>
Add
ACCDATA_EL1save/restore as part of the EL0 context. This is conditioned on the guest's view of ID_AA64ISAR1_EL1.LS64 reporting that this register is supported.Signed-off-by Marc Zyngier <[email protected]>Fixes 58ce78667a641 ("arm64: Add support for FEAT_{LS64, LS64_V}")
Quoted 5 lines
[Fuad: rebased; switch
ACCDATA_EL1for guests only, as the host never
uses it; gate it on a newARM64_HAS_LS64_ACCDATAcapability, since in pKVM the host controls a non-protected guest's ID registers, and an EL2 access toACCDATA_EL1on a CPU without the feature is UNDEFINED]Signed-off-by Fuad Tabba <[email protected]>
Re: [PATCH v2 3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
In reply to Fuad TabbaQuoted 10 lines · Fuad Tabba
From: Marc Zyngier <[email protected]>
Add
ACCDATA_EL1save/restore as part of the EL0 context. This is conditioned on the guest's view of ID_AA64ISAR1_EL1.LS64 reporting that this register is supported.Signed-off-by Marc Zyngier <[email protected]>Fixes 58ce78667a641 ("arm64: Add support for FEAT_{LS64, LS64_V}")
Quoted 5 lines
[Fuad: rebased; switch
ACCDATA_EL1for guests only, as the host never
uses it; gate it on a newARM64_HAS_LS64_ACCDATAcapability, since in pKVM the host controls a non-protected guest's ID registers, and an EL2 access toACCDATA_EL1on a CPU without the feature is UNDEFINED]Signed-off-by Fuad Tabba <[email protected]>
Quoted 94 lines
--- arch/arm64/kernel/cpufeature.c | 7 +++++++ arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 23 ++++++++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 3 files changed, 31 insertions(+)arch/arm64/kernel/cpufeature.c +7
-0@@ -3225,6 +3225,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .cpu_enable = cpu_enable_ls64_v,ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_V ) }, + { + .desc ="LS64_ACCDATA" , + .capability = ARM64_HAS_LS64_ACCDATA, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .matches = has_cpuid_feature, +ARM64_CPUID_FIELDS (ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ) + }, #ifdef CONFIG_ARM64_LSUI { .desc = "Unprivileged Load Store Instructions (LSUI)",arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +23
-0@@ -17,6 +17,7 @@#include <asm/kvm_mmu.h> static inline bool ctxt_has_s1poe (struct kvm_cpu_context *ctxt); +static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt);static inline struct kvm_vcpu *ctxt_to_vcpu (struct kvm_cpu_context *ctxt) {@@ -67,6 +68,13 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,TPIDR_EL0 ) =read_sysreg (tpidr_el0);ctxt_sys_reg (ctxt,TPIDRRO_EL0 ) =read_sysreg (tpidrro_el0); + +/* +* Despite the appearances, ACCDATA_EL1 is part of the EL0 +* context, as it can only be used using ST64BV0. +*/ +if (ctxt_has_accdata (ctxt)) +ctxt_sys_reg (ctxt,ACCDATA_EL1 ) =read_sysreg_s (SYS_ACCDATA_EL1 ); }static inline bool ctxt_has_mte (struct kvm_cpu_context *ctxt)@@ -131,6 +139,18 @@ static inline bool ctxt_has_sctlr2(struct kvm_cpu_context *ctxt)return kvm_has_sctlr2 (kern_hyp_va (vcpu->kvm)); } +static inline bool ctxt_has_accdata (struct kvm_cpu_context *ctxt) +{ +struct kvm_vcpu *vcpu; + +/* The host never uses ACCDATA_EL1 */ +if (!cpus_have_final_cap (ARM64_HAS_LS64_ACCDATA ) || !ctxt_is_guest (ctxt)) +return false; + + vcpu =ctxt_to_vcpu (ctxt); +return kvm_has_feat (kern_hyp_va (vcpu->kvm),ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ); +} +static inline void __sysreg_save_el1_state (struct kvm_cpu_context *ctxt) {ctxt_sys_reg (ctxt,SCTLR_EL1 ) =read_sysreg_el1 (SYS_SCTLR );@@ -210,6 +230,9 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) {write_sysreg (ctxt_sys_reg (ctxt,TPIDR_EL0 ), tpidr_el0);write_sysreg (ctxt_sys_reg (ctxt,TPIDRRO_EL0 ), tpidrro_el0); + +if (ctxt_has_accdata (ctxt)) +write_sysreg_s (ctxt_sys_reg (ctxt,ACCDATA_EL1 ),SYS_ACCDATA_EL1 ); } static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,arch/arm64/tools/cpucaps +1
-1@@ -49,6 +49,7 @@ HAS_LPA2 HAS_LSE_ATOMICS HAS_LS64 HAS_LS64_V +HAS_LS64_ACCDATA HAS_LSUI HAS_MOPS HAS_NESTED_VIRT --2.47.3
Fuad Tabba
reviewerPATCH v2 4/5 KVM: arm64: Enable ST64BV0 for guests with FEAT_LS64_ACCDATA
In reply to Fuad TabbaSince commit 58ce78667a641 ("arm64: Add support for FEAT_{LS64, LS64_V}"), a guest sees the host's ID_AA64ISAR1_EL1.LS64, but KVM only enables the FEAT_LS64 and FEAT_LS64_V instructions in HCRX_EL2. On a host with FEAT_LS64_ACCDATA, a guest's ST64BV0 therefore traps and hits the WARN_ON_ONCE() in handle_other().
Set HCRX_EL2.EnAS0 when the guest has FEAT_LS64_ACCDATA, now that ACCDATA_EL1 is context-switched.
--- arch/arm64/include/asm/kvm_emulate.h | 3 +++ 1 file changed, 3 insertions(+)
arch/arm64/include/asm/kvm_emulate.h +3 -0
@@ -712,6 +712,9 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)if (kvm_has_feat (kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_V )) vcpu->arch.hcrx_el2 |= HCRX_EL2_EnASR; +if (kvm_has_feat (kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA )) + vcpu->arch.hcrx_el2 |= HCRX_EL2_EnAS0; +/* * NV3 is a host-specific extension, and we always use * it when present and that the guest uses NV. It may
Signature · 1 line
2.47.3
Re: [PATCH v2 4/5] KVM: arm64: Enable ST64BV0 for guests with FEAT_LS64_ACCDATA
Quoted 6 lines · Fuad Tabba
Since commit
58ce78667a641("arm64: Add support for FEAT_{LS64,LS64_V}"), a guest sees the host's ID_AA64ISAR1_EL1.LS64, but KVM only enables theFEAT_LS64andFEAT_LS64_Vinstructions inHCRX_EL2. On a host withFEAT_LS64_ACCDATA, a guest's ST64BV0 therefore traps and hits theWARN_ON_ONCE()inhandle_other().
Quoted 6 lines
Set HCRX_EL2.EnAS0 when the guest has
FEAT_LS64_ACCDATA, now thatACCDATA_EL1is context-switched.Fixes 58ce78667a641 ("arm64: Add support for FEAT_{LS64, LS64_V}")Signed-off-by Fuad Tabba <[email protected]>
lgtm.
Quoted 21 lines
--- arch/arm64/include/asm/kvm_emulate.h | 3 +++ 1 file changed, 3 insertions(+)arch/arm64/include/asm/kvm_emulate.h +3
-1@@ -712,6 +712,9 @@ static inline void vcpu_set_hcrx(struct kvm_vcpu *vcpu)if (kvm_has_feat (kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_V )) vcpu->arch.hcrx_el2 |= HCRX_EL2_EnASR; +if (kvm_has_feat (kvm,ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA )) + vcpu->arch.hcrx_el2 |= HCRX_EL2_EnAS0; +/* * NV3 is a host-specific extension, and we always use * it when present and that the guest uses NV. It may -- 2.47.3
Fuad Tabba
reviewerPATCH v2 5/5 KVM: arm64: selftests: Add ACCDATA_EL1 to get-reg-list
In reply to Fuad TabbaKVM exposes ACCDATA_EL1 to userspace when the guest has FEAT_LS64_ACCDATA. Add it to get-reg-list, conditioned on ID_AA64ISAR1_EL1.LS64, so that the test still passes on hosts that implement the feature.
--- tools/testing/selftests/kvm/arm64/get-reg-list.c | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/selftests/kvm/arm64/get-reg-list.c +2 -0
@@ -49,6 +49,7 @@ static struct feature_id_reg feat_id_regs[] = {REG_FEAT (POR_EL1 ,ID_AA64MMFR3_EL1 ,S1POE ,IMP ),REG_FEAT (POR_EL0 ,ID_AA64MMFR3_EL1 ,S1POE ,IMP ),REG_FEAT (POR_EL2 ,ID_AA64MMFR3_EL1 ,S1POE ,IMP ), +REG_FEAT (ACCDATA_EL1 ,ID_AA64ISAR1_EL1 ,LS64 ,LS64_ACCDATA ),REG_FEAT (HCRX_EL2 ,ID_AA64MMFR1_EL1 ,HCX ,IMP ),REG_FEAT (HFGRTR_EL2 ,ID_AA64MMFR0_EL1 ,FGT ,IMP ), REG_FEAT(HFGWTR_EL2, ID_AA64MMFR0_EL1, FGT, IMP),
@@ -517,6 +518,7 @@ static __u64 base_regs[] = {ARM64_SYS_REG (3 ,0 ,12 ,1 ,1 ),/* DISR_EL1 */ ARM64_SYS_REG (3 ,0 ,13 ,0 ,1 ),/* CONTEXTIDR_EL1 */ ARM64_SYS_REG (3 ,0 ,13 ,0 ,4 ),/* TPIDR_EL1 */ +ARM64_SYS_REG (3 ,0 ,13 ,0 ,5 ),/* ACCDATA_EL1 */ ARM64_SYS_REG (3 ,0 ,14 ,1 ,0 ),/* CNTKCTL_EL1 */ ARM64_SYS_REG (3 ,2 ,0 ,0 ,0 ),/* CSSELR_EL1 */ ARM64_SYS_REG(3, 3, 10, 2, 4), /* POR_EL0 */
Signature · 1 line
2.47.3
Quoted 9 lines · Fuad Tabba
Changes since v1 [1]:
- SupportFEAT_LS64_ACCDATAin guests instead of capping ID_AA64ISAR1_EL1.LS64 atLS64_V. A saved VM keeps its level, so restore no longer has to accept older kernels' levels, and v1'sset_id_regspatch goes. (Marc)
- Add an arm64.nols64 option. (Marc)
- Retitled the series to match.[...]
Applied to fixes, thanks!
[1/5] arm64: Add override for ID_AA64ISAR1_EL1.LS64
commit: 699edee85fb9f4403b5bc939f3f84374f841b33b
[2/5] KVM: arm64: Add ACCDATA_EL1 to the sysreg array
commit: 8b5bcf2e799c24906b813f4a63081e68721a026b
[3/5] KVM: arm64: Add context-switch of ACCDATA_EL1
commit: c122ea1564b41326d8c09c64005d38ec2fa6dd8f
[4/5] KVM: arm64: Enable ST64BV0 for guests with FEAT_LS64_ACCDATA
commit: e2412d6a90a4b39e3fc464eeab8637a7f4eccc10
[5/5] KVM: arm64: selftests: Add ACCDATA_EL1 to get-reg-list
commit: b7bb9e9425dd7772cba9ac4392e982f541cccfacCheers,
M.
Signature · 1 line
Without deviation from the norm, progress is not possible.