[PATCH v6 1/8] RISC-V: KVM: Add support for Svadu FWFT features
Anup Patel
anup at brainfault.org
Wed Jul 29 05:43:52 PDT 2026
On Mon, Jul 13, 2026 at 6:33 AM Inochi Amaoto <inochiama at gmail.com> wrote:
>
> Hardware updating of PTE A/D bits is controlled through ADUE bit in
> henvcfg Expose the feature only if both Svadu and Svade are supported
> for VS-mode.
>
> Allow the VMM to enable/disable this feature by change the ISA
> extension state 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 | 1 +
> arch/riscv/kvm/vcpu_sbi_fwft.c | 76 +++++++++++++++++++++++++++++++
> 2 files changed, 77 insertions(+)
>
> diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
> index 504e73305343..7bbea8812d92 100644
> --- a/arch/riscv/include/uapi/asm/kvm.h
> +++ b/arch/riscv/include/uapi/asm/kvm.h
> @@ -240,6 +240,7 @@ 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;
> };
>
> /* 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 ab39ac464ffd..4d474a439b29 100644
> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c
> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c
> @@ -94,6 +94,45 @@ 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,
> + u64 flag)
Try to use upto 80-90 characters per-line.
s/kvm_sbi_fwft_env_flag_reset_helper/kvm_sbi_fwft_envcfg_flag_reset/
> +{
> + 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, u64 flag)
s/kvm_sbi_fwft_env_flag_set_helper/kvm_sbi_fwft_envcfg_flag_set/
> +{
> + 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);
> + if (IS_ENABLED(CONFIG_32BIT))
> + csr_write(CSR_HENVCFGH, vcpu->arch.cfg.henvcfg >> 32);
> + }
> +
> + 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, u64 flag)
s/kvm_sbi_fwft_env_flag_get_helper/kvm_sbi_fwft_envcfg_flag_get/
> +{
> + *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();
> @@ -137,6 +176,34 @@ 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)
> +{
> + if (kvm_sbi_fwft_pte_ad_hw_updating_supported(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)
> @@ -246,6 +313,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.55.0
>
Otherwise, this looks good to me.
Reviewed-by: Anup Patel <anup at brainfault.org>
Regards,
Anup
More information about the linux-riscv
mailing list