[PATCH v2 1/7] RISC-V: KVM: Add support for Svadu FWFT features
Inochi Amaoto
inochiama at gmail.com
Mon Jun 1 01:43:29 PDT 2026
Hardware updating of PTE A/D bits is controlled through ADUE bit in
henvcfg Expose the feature only if the Svadu is supported for VS-mode.
Allow the VMM to block access to the feature by disabling the ISA
extension in the guest.
Assisted-by: YuanSheng:claude-4.7-opus
Co-developed-by: Quan Zhou <zhouquan at iscas.ac.cn>
Signed-off-by: Quan Zhou <zhouquan at iscas.ac.cn>
Signed-off-by: Inochi Amaoto <inochiama at gmail.com>
---
arch/riscv/include/uapi/asm/kvm.h | 3 ++
arch/riscv/kvm/vcpu_sbi_fwft.c | 72 +++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 504e73305343..501e4fc60dd2 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -240,6 +240,9 @@ struct kvm_riscv_sbi_fwft_feature {
struct kvm_riscv_sbi_fwft {
struct kvm_riscv_sbi_fwft_feature misaligned_deleg;
struct kvm_riscv_sbi_fwft_feature pointer_masking;
+ struct kvm_riscv_sbi_fwft_feature pte_ad_hw_updating;
+ struct kvm_riscv_sbi_fwft_feature landing_pad;
+ struct kvm_riscv_sbi_fwft_feature shadow_stack;
};
/* If you need to interpret the index values, here is the key: */
diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c
index 2eab15339694..375269e43c13 100644
--- a/arch/riscv/kvm/vcpu_sbi_fwft.c
+++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
@@ -84,6 +84,42 @@ static bool kvm_fwft_is_defined_feature(enum sbi_fwft_feature_t feature)
return false;
}
+static void kvm_sbi_fwft_env_flag_reset_helper(struct kvm_vcpu *vcpu,
+ unsigned long flag)
+{
+ vcpu->arch.cfg.henvcfg &= ~flag;
+}
+
+static long kvm_sbi_fwft_env_flag_set_helper(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ bool one_reg_access,
+ unsigned long value, unsigned long flag)
+{
+ struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
+
+ if (value == 0)
+ cfg->henvcfg &= ~flag;
+ else if (value == 1)
+ cfg->henvcfg |= flag;
+ else
+ return SBI_ERR_INVALID_PARAM;
+
+ if (!one_reg_access)
+ csr_write(CSR_HENVCFG, vcpu->arch.cfg.henvcfg);
+
+ return SBI_SUCCESS;
+}
+
+static long kvm_sbi_fwft_env_flag_get_helper(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ bool one_reg_access,
+ unsigned long *value, unsigned long flag)
+{
+ *value = (vcpu->arch.cfg.henvcfg & flag) == flag;
+
+ return SBI_SUCCESS;
+}
+
static bool kvm_sbi_fwft_misaligned_delegation_supported(struct kvm_vcpu *vcpu)
{
return misaligned_traps_can_delegate();
@@ -127,6 +163,33 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
return SBI_SUCCESS;
}
+static bool kvm_sbi_fwft_pte_ad_hw_updating_supported(struct kvm_vcpu *vcpu)
+{
+ return riscv_isa_extension_available(vcpu->arch.isa, SVADU) &&
+ !riscv_isa_extension_available(vcpu->arch.isa, SVADE);
+}
+
+static void kvm_sbi_fwft_reset_pte_ad_hw_updating(struct kvm_vcpu *vcpu)
+{
+ kvm_sbi_fwft_env_flag_reset_helper(vcpu, ENVCFG_ADUE);
+}
+
+static long kvm_sbi_fwft_set_pte_ad_hw_updating(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ bool one_reg_access, unsigned long value)
+{
+ return kvm_sbi_fwft_env_flag_set_helper(vcpu, conf, one_reg_access,
+ value, ENVCFG_ADUE);
+}
+
+static long kvm_sbi_fwft_get_pte_ad_hw_updating(struct kvm_vcpu *vcpu,
+ struct kvm_sbi_fwft_config *conf,
+ bool one_reg_access, unsigned long *value)
+{
+ return kvm_sbi_fwft_env_flag_get_helper(vcpu, conf, one_reg_access,
+ value, ENVCFG_ADUE);
+}
+
#ifndef CONFIG_32BIT
static bool try_to_set_pmm(unsigned long value)
@@ -225,6 +288,15 @@ static const struct kvm_sbi_fwft_feature features[] = {
.set = kvm_sbi_fwft_set_misaligned_delegation,
.get = kvm_sbi_fwft_get_misaligned_delegation,
},
+ {
+ .id = SBI_FWFT_PTE_AD_HW_UPDATING,
+ .first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, pte_ad_hw_updating.enable) /
+ sizeof(unsigned long),
+ .supported = kvm_sbi_fwft_pte_ad_hw_updating_supported,
+ .reset = kvm_sbi_fwft_reset_pte_ad_hw_updating,
+ .set = kvm_sbi_fwft_set_pte_ad_hw_updating,
+ .get = kvm_sbi_fwft_get_pte_ad_hw_updating,
+ },
#ifndef CONFIG_32BIT
{
.id = SBI_FWFT_POINTER_MASKING_PMLEN,
--
2.54.0
More information about the kvm-riscv
mailing list