* [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co
@ 2024-08-15 12:59 Marc Zyngier
2024-08-15 12:59 ` [PATCH 01/11] arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers Marc Zyngier
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
The ARM architecture has introduced a while back some 64 byte
Load/Store operations that are targeting NormalNC or Device memory.
People have been threatening of using this in actual code, so we might
as well support it. It also fits my plans to cover the features
enabled by HCRX_EL2.
From a KVM perspective, it is only a load/store. Nothing to call home
about. However, there are two situations where this is interesting:
- a NV guest wants to trap these instructions: we need to correctly
route them.
- the access falls outside of a memslot, and userspace needs to handle
this.
This last point is of special interest. Instead of going through the
pain of doing all the decoding in the kernel and presenting the VMM
with a fully decoded access (like it is the case for normal MMIO), we
brutally return the ESR+IPA and let userspace deal with the outcome,
hijacking the data structures for KVM_EXIT_ARM_NISV for that purpose.
It has all the information at its disposal through the vcpu ioctl
interface, and can definitely do what's asked. Just not very quickly
I don't think this is a problem, and that approximately 100% of the
VMMs will simply inject an external abort as an indication that they
are not handling this.
This is otherwise pretty uninteresting code.
Marc Zyngier (11):
arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers
arm64: Add syndrome information for trapped LD64B/ST64B{,V,V0}
KVM: arm64: Add ACCDATA_EL1 to the sysreg array
KVM: arm64: Add context-switch of ACCDATA_EL1
KVM: arm64: Handle trapping of FEAT_LS64* instructions
KVM: arm64: Add exit to userspace on {LD,ST}64B* outside of memslots
KVM: arm64: Restrict ACCDATA_EL1 undef to FEAT_ST64_ACCDATA being
disabled
KVM: arm64: Conditionnaly enable FEAT_LS64* instructions
KVM: arm64: nv: Expose FEAT_LS64* to a nested guest
arm64: Expose ID_AA64ISAR1_EL1.LS64 to sanitised feature consumers
KVM: arm64: Add documentation for KVM_EXIT_ARM_LDST64B
Documentation/virt/kvm/api.rst | 43 ++++++++++++---
arch/arm64/include/asm/esr.h | 8 ++-
arch/arm64/include/asm/kvm_host.h | 3 +
arch/arm64/kernel/cpufeature.c | 2 +
arch/arm64/kvm/handle_exit.c | 64 ++++++++++++++++++++++
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 29 ++++++++--
arch/arm64/kvm/mmio.c | 27 ++++++++-
arch/arm64/kvm/nested.c | 5 +-
arch/arm64/kvm/sys_regs.c | 25 ++++++++-
include/uapi/linux/kvm.h | 3 +-
10 files changed, 188 insertions(+), 21 deletions(-)
--
2.39.2
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 01/11] arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 02/11] arm64: Add syndrome information for trapped LD64B/ST64B{,V,V0} Marc Zyngier
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Despite KVM now being able to deal with XS-tagged TLBIs, we still don't
expose these feature bits to KVM.
Plumb in the feature in ID_AA64ISAR1_EL1.
Fixes: 0feec7769a63 ("KVM: arm64: nv: Add handling of NXS-flavoured TLBI operations")
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/cpufeature.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 646ecd3069fd..4901daace5a3 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -228,6 +228,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_XS_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_BF16_SHIFT, 4, 0),
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 02/11] arm64: Add syndrome information for trapped LD64B/ST64B{,V,V0}
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
2024-08-15 12:59 ` [PATCH 01/11] arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 03/11] KVM: arm64: Add ACCDATA_EL1 to the sysreg array Marc Zyngier
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Provide the architected EC and ISS values for all the FEAT_LS64*
instructions.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/esr.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 56c148890daf..4a76883616ab 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -20,7 +20,8 @@
#define ESR_ELx_EC_FP_ASIMD (0x07)
#define ESR_ELx_EC_CP10_ID (0x08) /* EL2 only */
#define ESR_ELx_EC_PAC (0x09) /* EL2 and above */
-/* Unallocated EC: 0x0A - 0x0B */
+#define ESR_ELx_EC_LS64B (0x0A)
+/* Unallocated EC: 0x0B */
#define ESR_ELx_EC_CP14_64 (0x0C)
#define ESR_ELx_EC_BTI (0x0D)
#define ESR_ELx_EC_ILL (0x0E)
@@ -172,6 +173,11 @@
#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
#define ESR_ELx_xVC_IMM_MASK ((UL(1) << 16) - 1)
+/* ISS definitions for LD64B/ST64B instructions */
+#define ESR_ELx_ISS_ST64BV (0)
+#define ESR_ELx_ISS_ST64BV0 (1)
+#define ESR_ELx_ISS_LDST64B (2)
+
#define DISR_EL1_IDS (UL(1) << 24)
/*
* DISR_EL1 and ESR_ELx share the bottom 13 bits, but the RES0 bits may mean
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 03/11] KVM: arm64: Add ACCDATA_EL1 to the sysreg array
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
2024-08-15 12:59 ` [PATCH 01/11] arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers Marc Zyngier
2024-08-15 12:59 ` [PATCH 02/11] arm64: Add syndrome information for trapped LD64B/ST64B{,V,V0} Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 04/11] KVM: arm64: Add context-switch of ACCDATA_EL1 Marc Zyngier
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Make ACCDATA_EL1 a first-class citizen, and add it to the sysreg
array. Visibility is conditioned on the feature being enabled.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/kvm/sys_regs.c | 12 +++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a33f5996ca9f..25ee4e5f55f1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -446,6 +446,9 @@ enum vcpu_sysreg {
GCR_EL1, /* Tag Control Register */
TFSRE0_EL1, /* Tag Fault Status Register (EL0) */
+ /* Random stuff */
+ ACCDATA_EL1, /* Accelerator Data */
+
/* 32bit specific registers. */
DACR32_EL2, /* Domain Access Control Register */
IFSR32_EL2, /* Instruction Fault Status Register */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c90324060436..7b540811aa38 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2233,6 +2233,15 @@ static unsigned int sve_el2_visibility(const struct kvm_vcpu *vcpu,
return sve_visibility(vcpu, rd);
}
+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 bool access_zcr_el2(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
@@ -2519,7 +2528,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.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 04/11] KVM: arm64: Add context-switch of ACCDATA_EL1
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (2 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 03/11] KVM: arm64: Add ACCDATA_EL1 to the sysreg array Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 05/11] KVM: arm64: Handle trapping of FEAT_LS64* instructions Marc Zyngier
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 29 +++++++++++++++++-----
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 4c0fdabaf8ae..d23d7113261b 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -21,12 +21,6 @@ static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
ctxt_sys_reg(ctxt, MDSCR_EL1) = read_sysreg(mdscr_el1);
}
-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);
-}
-
static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt)
{
struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu;
@@ -66,6 +60,26 @@ static inline bool ctxt_has_tcrx(struct kvm_cpu_context *ctxt)
return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, TCRX, IMP);
}
+static inline bool ctxt_has_accdata(struct kvm_cpu_context *ctxt)
+{
+ struct kvm_vcpu *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_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 void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
{
ctxt_sys_reg(ctxt, SCTLR_EL1) = read_sysreg_el1(SYS_SCTLR);
@@ -126,6 +140,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)
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 05/11] KVM: arm64: Handle trapping of FEAT_LS64* instructions
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (3 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 04/11] KVM: arm64: Add context-switch of ACCDATA_EL1 Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 06/11] KVM: arm64: Add exit to userspace on {LD,ST}64B* outside of memslots Marc Zyngier
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
We generally don't expect FEAT_LS64* instructions to trap, unless
they are trapped by a guest hypervisor.
Otherwise, this is just the guest playing tricks on us by using
an instruction that isn't advertised, which we handle with a well
deserved UNDEF.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/handle_exit.c | 64 ++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index d7c2990e7c9e..8cb0091f8e1e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -291,6 +291,69 @@ static int handle_svc(struct kvm_vcpu *vcpu)
return 1;
}
+static int handle_ls64b(struct kvm_vcpu *vcpu)
+{
+ struct kvm *kvm = vcpu->kvm;
+ u64 esr = kvm_vcpu_get_esr(vcpu);
+ u64 iss = ESR_ELx_ISS(esr);
+ bool allowed;
+
+ switch (iss) {
+ case ESR_ELx_ISS_ST64BV:
+ allowed = kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V);
+ break;
+ case ESR_ELx_ISS_ST64BV0:
+ allowed = kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA);
+ break;
+ case ESR_ELx_ISS_LDST64B:
+ allowed = kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64);
+ break;
+ default:
+ /* Clearly, we're missing something. */
+ goto unknown_trap;
+ }
+
+ if (!allowed)
+ goto undef;
+
+ if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
+ u64 hcrx = __vcpu_sys_reg(vcpu, HCRX_EL2);
+ bool fwd;
+
+ switch (iss) {
+ case ESR_ELx_ISS_ST64BV:
+ fwd = !(hcrx & HCRX_EL2_EnASR);
+ break;
+ case ESR_ELx_ISS_ST64BV0:
+ fwd = !(hcrx & HCRX_EL2_EnAS0);
+ break;
+ case ESR_ELx_ISS_LDST64B:
+ fwd = !(hcrx & HCRX_EL2_EnALS);
+ break;
+ default:
+ /* We don't expect to be here */
+ fwd = false;
+ }
+
+ if (fwd) {
+ kvm_inject_nested_sync(vcpu, esr);
+ return 1;
+ }
+ }
+
+unknown_trap:
+ /*
+ * If we land here, something must be very wrong, because we
+ * have no idea why we trapped at all. Warn and undef as a
+ * fallback.
+ */
+ WARN_ON(1);
+
+undef:
+ kvm_inject_undefined(vcpu);
+ return 1;
+}
+
static exit_handle_fn arm_exit_handlers[] = {
[0 ... ESR_ELx_EC_MAX] = kvm_handle_unknown_ec,
[ESR_ELx_EC_WFx] = kvm_handle_wfx,
@@ -300,6 +363,7 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_CP14_LS] = kvm_handle_cp14_load_store,
[ESR_ELx_EC_CP10_ID] = kvm_handle_cp10_id,
[ESR_ELx_EC_CP14_64] = kvm_handle_cp14_64,
+ [ESR_ELx_EC_LS64B] = handle_ls64b,
[ESR_ELx_EC_HVC32] = handle_hvc,
[ESR_ELx_EC_SMC32] = handle_smc,
[ESR_ELx_EC_HVC64] = handle_hvc,
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 06/11] KVM: arm64: Add exit to userspace on {LD,ST}64B* outside of memslots
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (4 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 05/11] KVM: arm64: Handle trapping of FEAT_LS64* instructions Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 07/11] KVM: arm64: Restrict ACCDATA_EL1 undef to FEAT_ST64_ACCDATA being disabled Marc Zyngier
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
The main use of {LD,ST}64B* is to talk to a device, which is hopefully
directly assigned to the guest and requires no additional handling.
However, this does not preclude a VMM from exposing a virtual device
to the guest, and to allow 64 byte accesses as part of the programming
interface. A direct consequence of this is that we need to be able
to forward such access to userspace.
Given that such a contraption is very unlikely to ever exist, we choose
to offer a limited service: userspace gets (as part of a new exit reason)
the ESR, the IPA, and that's it. It is fully expected to handle the full
semantics of the instructions, deal with ACCDATA, the return values and
increment PC. Much fun.
A canonical implementation can also simply inject an abort and be done
with it. Frankly, don't try to do anything else unless you have time
to waste.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/mmio.c | 27 ++++++++++++++++++++++++++-
include/uapi/linux/kvm.h | 3 ++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c
index cd6b7b83e2c3..849ea6a02d7b 100644
--- a/arch/arm64/kvm/mmio.c
+++ b/arch/arm64/kvm/mmio.c
@@ -129,6 +129,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
bool is_write;
int len;
u8 data_buf[8];
+ u64 esr;
+
+ esr = kvm_vcpu_get_esr(vcpu);
/*
* No valid syndrome? Ask userspace for help if it has
@@ -138,7 +141,7 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
* though, so directly deliver an exception to the guest.
*/
if (!kvm_vcpu_dabt_isvalid(vcpu)) {
- trace_kvm_mmio_nisv(*vcpu_pc(vcpu), kvm_vcpu_get_esr(vcpu),
+ trace_kvm_mmio_nisv(*vcpu_pc(vcpu), esr,
kvm_vcpu_get_hfar(vcpu), fault_ipa);
if (vcpu_is_protected(vcpu)) {
@@ -157,6 +160,28 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
return -ENOSYS;
}
+ /*
+ * When (DFSC == 0b00xxxx || DFSC == 0b10101x) && DFSC != 0b0000xx
+ * ESR_EL2[12:11] describe the Load/Store Type. This allows us to
+ * punt the LD64B/ST64B/ST64BV/ST64BV0 instructions to luserspace,
+ * which will have to provide a full emulation of these 4
+ * instructions. No, we don't expect this do be fast.
+ *
+ * We rely on traps being set if the corresponding features are not
+ * enabled, so if we get here, userspace has promised us to handle
+ * it already.
+ */
+ switch (kvm_vcpu_trap_get_fault(vcpu)) {
+ case 0b000100 ... 0b001111:
+ case 0b101010 ... 0b101011:
+ if (FIELD_GET(GENMASK(12, 11), esr)) {
+ run->exit_reason = KVM_EXIT_ARM_LDST64B;
+ run->arm_nisv.esr_iss = esr & ~(u64)ESR_ELx_FSC;
+ run->arm_nisv.fault_ipa = fault_ipa;
+ return 0;
+ }
+ }
+
/*
* Prepare MMIO operation. First decode the syndrome data we get
* from the CPU. Then try if some in-kernel emulation feels
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 637efc055145..24fcbc8d7dc3 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -178,6 +178,7 @@ struct kvm_xen_exit {
#define KVM_EXIT_NOTIFY 37
#define KVM_EXIT_LOONGARCH_IOCSR 38
#define KVM_EXIT_MEMORY_FAULT 39
+#define KVM_EXIT_ARM_LDST64B 40
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -399,7 +400,7 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
- /* KVM_EXIT_ARM_NISV */
+ /* KVM_EXIT_ARM_NISV / KVM_EXIT_ARM_LDST64B */
struct {
__u64 esr_iss;
__u64 fault_ipa;
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 07/11] KVM: arm64: Restrict ACCDATA_EL1 undef to FEAT_ST64_ACCDATA being disabled
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (5 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 06/11] KVM: arm64: Add exit to userspace on {LD,ST}64B* outside of memslots Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 08/11] KVM: arm64: Conditionnaly enable FEAT_LS64* instructions Marc Zyngier
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
We currently unconditionally make ACCDATA_EL1 accesses UNDEF.
As we are about to support it, restrict the UNDEF behaviour to cases
where FEAT_ST64_ACCDATA is not exposed to the guest.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/sys_regs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7b540811aa38..39c2ee15dc0a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -4580,10 +4580,12 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
HFGxTR_EL2_nS2POR_EL1 |
HFGxTR_EL2_nPOR_EL1 |
HFGxTR_EL2_nPOR_EL0 |
- HFGxTR_EL2_nACCDATA_EL1 |
HFGxTR_EL2_nSMPRI_EL1_MASK |
HFGxTR_EL2_nTPIDR2_EL0_MASK);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+ kvm->arch.fgu[HFGxTR_GROUP] |= HFGxTR_EL2_nACCDATA_EL1;
+
if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
HFGITR_EL2_TLBIRVALE1OS |
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 08/11] KVM: arm64: Conditionnaly enable FEAT_LS64* instructions
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (6 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 07/11] KVM: arm64: Restrict ACCDATA_EL1 undef to FEAT_ST64_ACCDATA being disabled Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 09/11] KVM: arm64: nv: Expose FEAT_LS64* to a nested guest Marc Zyngier
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Enable the FEAT_LS64* features by setting the corresponding HCRX_EL2
bits in the vcpu context when these features are exposed to the guest.
The effective value programmed into the HW will change depending on
what a NV guest will program in its own HCRX_EL2 view.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/sys_regs.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 39c2ee15dc0a..cfd1a1bb9675 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -4570,6 +4570,15 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
if (kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
vcpu->arch.hcrx_el2 |= HCRX_EL2_TCR2En;
+
+ 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))
+ vcpu->arch.hcrx_el2 |= HCRX_EL2_EnALS;
+
+ if (kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+ vcpu->arch.hcrx_el2 |= HCRX_EL2_EnAS0;
}
if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 09/11] KVM: arm64: nv: Expose FEAT_LS64* to a nested guest
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (7 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 08/11] KVM: arm64: Conditionnaly enable FEAT_LS64* instructions Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 10/11] arm64: Expose ID_AA64ISAR1_EL1.LS64 to sanitised feature consumers Marc Zyngier
2024-08-15 12:59 ` [PATCH 11/11] KVM: arm64: Add documentation for KVM_EXIT_ARM_LDST64B Marc Zyngier
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Now that we correctly support FEAT_LS64*, don't hide it from nested
guests anymore.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kvm/nested.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index de789e0f1ae9..97b16127755e 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -808,10 +808,9 @@ static void limit_nv_id_regs(struct kvm *kvm)
val &= ~NV_FTR(ISAR0, TME);
kvm_set_vm_id_reg(kvm, SYS_ID_AA64ISAR0_EL1, val);
- /* Support everything but Spec Invalidation and LS64 */
+ /* Support everything but Spec Invalidation */
val = kvm_read_vm_id_reg(kvm, SYS_ID_AA64ISAR1_EL1);
- val &= ~(NV_FTR(ISAR1, LS64) |
- NV_FTR(ISAR1, SPECRES));
+ val &= ~NV_FTR(ISAR1, SPECRES);
kvm_set_vm_id_reg(kvm, SYS_ID_AA64ISAR1_EL1, val);
/* No AMU, MPAM, S-EL2, or RAS */
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 10/11] arm64: Expose ID_AA64ISAR1_EL1.LS64 to sanitised feature consumers
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (8 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 09/11] KVM: arm64: nv: Expose FEAT_LS64* to a nested guest Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
2024-08-15 12:59 ` [PATCH 11/11] KVM: arm64: Add documentation for KVM_EXIT_ARM_LDST64B Marc Zyngier
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Despite KVM now being able to deal with FEAT_LS64, we still don't
expose these feature bits to KVM.
Plumb in the feature in ID_AA64ISAR1_EL1.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/cpufeature.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4901daace5a3..1489179f1b25 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -228,6 +228,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_LS64_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_XS_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, 0),
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 11/11] KVM: arm64: Add documentation for KVM_EXIT_ARM_LDST64B
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
` (9 preceding siblings ...)
2024-08-15 12:59 ` [PATCH 10/11] arm64: Expose ID_AA64ISAR1_EL1.LS64 to sanitised feature consumers Marc Zyngier
@ 2024-08-15 12:59 ` Marc Zyngier
10 siblings, 0 replies; 12+ messages in thread
From: Marc Zyngier @ 2024-08-15 12:59 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, kvm
Cc: James Morse, Suzuki K Poulose, Oliver Upton, Zenghui Yu
Add a bit of documentation for KVM_EXIT_ARM_LDST64B so that userspace
knows what to expect.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
Documentation/virt/kvm/api.rst | 43 ++++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 7 deletions(-)
diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index fe722c5dada9..323f9fdf225d 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -1283,12 +1283,13 @@ userspace, for example because of missing instruction syndrome decode
information or because there is no device mapped at the accessed IPA, then
userspace can ask the kernel to inject an external abort using the address
from the exiting fault on the VCPU. It is a programming error to set
-ext_dabt_pending after an exit which was not either KVM_EXIT_MMIO or
-KVM_EXIT_ARM_NISV. This feature is only available if the system supports
-KVM_CAP_ARM_INJECT_EXT_DABT. This is a helper which provides commonality in
-how userspace reports accesses for the above cases to guests, across different
-userspace implementations. Nevertheless, userspace can still emulate all Arm
-exceptions by manipulating individual registers using the KVM_SET_ONE_REG API.
+ext_dabt_pending after an exit which was not either KVM_EXIT_MMIO,
+KVM_EXIT_ARM_NISV, or KVM_EXIT_ARM_LDST64B. This feature is only available if
+the system supports KVM_CAP_ARM_INJECT_EXT_DABT. This is a helper which
+provides commonality in how userspace reports accesses for the above cases to
+guests, across different userspace implementations. Nevertheless, userspace
+can still emulate all Arm exceptions by manipulating individual registers
+using the KVM_SET_ONE_REG API.
See KVM_GET_VCPU_EVENTS for the data structure.
@@ -6935,12 +6936,14 @@ in send_page or recv a buffer to recv_page).
::
- /* KVM_EXIT_ARM_NISV */
+ /* KVM_EXIT_ARM_NISV / KVM_EXIT_ARM_LDST64B */
struct {
__u64 esr_iss;
__u64 fault_ipa;
} arm_nisv;
+- KVM_EXIT_ARM_NISV:
+
Used on arm64 systems. If a guest accesses memory not in a memslot,
KVM will typically return to userspace and ask it to do MMIO emulation on its
behalf. However, for certain classes of instructions, no instruction decode
@@ -6974,6 +6977,32 @@ Note that although KVM_CAP_ARM_NISV_TO_USER will be reported if
queried outside of a protected VM context, the feature will not be
exposed if queried on a protected VM file descriptor.
+- KVM_EXIT_ARM_LDST64B:
+
+Used on arm64 systems. When a guest using a LD64B, ST64B, ST64BV, ST64BV0,
+outside of a memslot, KVM will return to userspace with KVM_EXIT_ARM_LDST64B,
+exposing the relevant ESR_EL2 information and faulting IPA, similarly to
+KVM_EXIT_ARM_NISV.
+
+Userspace is supposed to fully emulate the instructions, which includes:
+
+ - fetch of the operands for a store, including ACCDATA_EL1 in the case
+ of a ST64BV0 instruction
+ - deal with the endianness if the guest is big-endian
+ - emulate the access, including the delivery of an exception if the
+ access didn't succeed
+ - provide a return value in the case of ST64BV/ST64BV0
+ - return the data in the case of a load
+ - increment PC if the instruction was successfully executed
+
+Note that there is no expectation of performance for this emulation, as it
+involves a large number of interaction with the guest state. It is, however,
+expected that the instruction's semantics are preserved, specially the
+single-copy atomicity property of the 64 byte access.
+
+This exit reason must be handled if userspace sets ID_AA64ISAR1_EL1.LS64 to a
+non-zero value, indicating that FEAT_LS64* is enabled.
+
::
/* KVM_EXIT_X86_RDMSR / KVM_EXIT_X86_WRMSR */
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2024-08-15 13:00 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-15 12:59 [PATCH 00/11] KVM: arm64: Add support for FEAT_LS64 and co Marc Zyngier
2024-08-15 12:59 ` [PATCH 01/11] arm64: Expose ID_AA64ISAR1_EL1.XS to sanitised feature consumers Marc Zyngier
2024-08-15 12:59 ` [PATCH 02/11] arm64: Add syndrome information for trapped LD64B/ST64B{,V,V0} Marc Zyngier
2024-08-15 12:59 ` [PATCH 03/11] KVM: arm64: Add ACCDATA_EL1 to the sysreg array Marc Zyngier
2024-08-15 12:59 ` [PATCH 04/11] KVM: arm64: Add context-switch of ACCDATA_EL1 Marc Zyngier
2024-08-15 12:59 ` [PATCH 05/11] KVM: arm64: Handle trapping of FEAT_LS64* instructions Marc Zyngier
2024-08-15 12:59 ` [PATCH 06/11] KVM: arm64: Add exit to userspace on {LD,ST}64B* outside of memslots Marc Zyngier
2024-08-15 12:59 ` [PATCH 07/11] KVM: arm64: Restrict ACCDATA_EL1 undef to FEAT_ST64_ACCDATA being disabled Marc Zyngier
2024-08-15 12:59 ` [PATCH 08/11] KVM: arm64: Conditionnaly enable FEAT_LS64* instructions Marc Zyngier
2024-08-15 12:59 ` [PATCH 09/11] KVM: arm64: nv: Expose FEAT_LS64* to a nested guest Marc Zyngier
2024-08-15 12:59 ` [PATCH 10/11] arm64: Expose ID_AA64ISAR1_EL1.LS64 to sanitised feature consumers Marc Zyngier
2024-08-15 12:59 ` [PATCH 11/11] KVM: arm64: Add documentation for KVM_EXIT_ARM_LDST64B Marc Zyngier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox