Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/riscv/include/asm/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
#define EXC_INST_PAGE_FAULT 12
#define EXC_LOAD_PAGE_FAULT 13
#define EXC_STORE_PAGE_FAULT 15
#define EXC_SOFTWARE_CHECK 18
#define EXC_INST_GUEST_PAGE_FAULT 20
#define EXC_LOAD_GUEST_PAGE_FAULT 21
#define EXC_VIRTUAL_INST_FAULT 22
Expand Down
5 changes: 5 additions & 0 deletions arch/riscv/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ enum KVM_RISCV_ISA_EXT_ID {
KVM_RISCV_ISA_EXT_ZCLSD,
KVM_RISCV_ISA_EXT_ZILSD,
KVM_RISCV_ISA_EXT_ZALASR,
KVM_RISCV_ISA_EXT_ZICFILP,
KVM_RISCV_ISA_EXT_ZICFISS,
KVM_RISCV_ISA_EXT_MAX,
};

Expand Down Expand Up @@ -240,6 +242,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: */
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/kvm/isa.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(ZICBOP),
KVM_ISA_EXT_ARR(ZICBOZ),
KVM_ISA_EXT_ARR(ZICCRSE),
KVM_ISA_EXT_ARR(ZICFILP),
KVM_ISA_EXT_ARR(ZICFISS),
KVM_ISA_EXT_ARR(ZICNTR),
KVM_ISA_EXT_ARR(ZICOND),
KVM_ISA_EXT_ARR(ZICSR),
Expand Down
8 changes: 4 additions & 4 deletions arch/riscv/kvm/vcpu_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ void kvm_riscv_vcpu_config_ran_once(struct kvm_vcpu *vcpu)
if (riscv_isa_extension_available(isa, ZICBOZ))
cfg->henvcfg |= ENVCFG_CBZE;

if (riscv_isa_extension_available(isa, SVADU) &&
!riscv_isa_extension_available(isa, SVADE))
cfg->henvcfg |= ENVCFG_ADUE;

if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) {
cfg->hstateen0 |= SMSTATEEN0_HSENVCFG;
if (riscv_isa_extension_available(isa, SSAIA))
Expand All @@ -69,6 +65,10 @@ void kvm_riscv_vcpu_config_ran_once(struct kvm_vcpu *vcpu)

if (vcpu->guest_debug)
cfg->hedeleg &= ~BIT(EXC_BREAKPOINT);

if (riscv_isa_extension_available(isa, ZICFILP) ||
riscv_isa_extension_available(isa, ZICFISS))
cfg->hedeleg |= BIT(EXC_SOFTWARE_CHECK);
}

void kvm_riscv_vcpu_config_load(struct kvm_vcpu *vcpu)
Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/kvm/vcpu_exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
run->exit_reason = KVM_EXIT_DEBUG;
ret = 0;
break;
case EXC_SOFTWARE_CHECK:
ret = vcpu_redirect(vcpu, trap);
break;
default:
break;
}
Expand Down
142 changes: 142 additions & 0 deletions arch/riscv/kvm/vcpu_sbi_fwft.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -127,6 +163,85 @@ static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu *vcpu,
return SBI_SUCCESS;
}

static bool kvm_sbi_fwft_landing_pad_supported(struct kvm_vcpu *vcpu)
{
return riscv_isa_extension_available(vcpu->arch.isa, ZICFILP);
}

static void kvm_sbi_fwft_reset_landing_pad(struct kvm_vcpu *vcpu)
{
kvm_sbi_fwft_env_flag_reset_helper(vcpu, ENVCFG_LPE);
}

static long kvm_sbi_fwft_set_landing_pad(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_LPE);
}

static long kvm_sbi_fwft_get_landing_pad(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_LPE);
}

static bool kvm_sbi_fwft_shadow_stack_supported(struct kvm_vcpu *vcpu)
{
return riscv_isa_extension_available(vcpu->arch.isa, ZICFISS);
}

static void kvm_sbi_fwft_reset_shadow_stack(struct kvm_vcpu *vcpu)
{
kvm_sbi_fwft_env_flag_reset_helper(vcpu, ENVCFG_SSE);
}

static long kvm_sbi_fwft_set_shadow_stack(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_SSE);
}

static long kvm_sbi_fwft_get_shadow_stack(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_SSE);
}

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)
Expand Down Expand Up @@ -225,6 +340,33 @@ 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_LANDING_PAD,
.first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, landing_pad.enable) /
sizeof(unsigned long),
.supported = kvm_sbi_fwft_landing_pad_supported,
.reset = kvm_sbi_fwft_reset_landing_pad,
.set = kvm_sbi_fwft_set_landing_pad,
.get = kvm_sbi_fwft_get_landing_pad,
},
{
.id = SBI_FWFT_SHADOW_STACK,
.first_reg_num = offsetof(struct kvm_riscv_sbi_fwft, shadow_stack.enable) /
sizeof(unsigned long),
.supported = kvm_sbi_fwft_shadow_stack_supported,
.reset = kvm_sbi_fwft_reset_shadow_stack,
.set = kvm_sbi_fwft_set_shadow_stack,
.get = kvm_sbi_fwft_get_shadow_stack,
},
{
.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,
Expand Down
22 changes: 22 additions & 0 deletions tools/testing/selftests/kvm/riscv/get-reg-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ bool filter_reg(__u64 reg)
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOP:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOZ:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICCRSE:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICFILP:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICFISS:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICNTR:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICOND:
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICSR:
Expand Down Expand Up @@ -552,6 +554,8 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
KVM_ISA_EXT_ARR(ZICBOP),
KVM_ISA_EXT_ARR(ZICBOZ),
KVM_ISA_EXT_ARR(ZICCRSE),
KVM_ISA_EXT_ARR(ZICFILP),
KVM_ISA_EXT_ARR(ZICFISS),
KVM_ISA_EXT_ARR(ZICNTR),
KVM_ISA_EXT_ARR(ZICOND),
KVM_ISA_EXT_ARR(ZICSR),
Expand Down Expand Up @@ -712,6 +716,15 @@ static const char *sbi_fwft_id_to_str(__u64 reg_off)
case 3: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable)";
case 4: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags)";
case 5: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value)";
case 6: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.enable)";
case 7: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.flags)";
case 8: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.value)";
case 9: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.enable)";
case 10: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.flags)";
case 11: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.value)";
case 12: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.enable)";
case 13: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.flags)";
case 14: return "KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.value)";
}
return strdup_printf("KVM_REG_RISCV_SBI_FWFT | %lld /* UNKNOWN */", reg_off);
}
Expand Down Expand Up @@ -905,6 +918,15 @@ static __u64 sbi_fwft_regs[] = {
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.enable),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.flags),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pointer_masking.value),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.enable),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.flags),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(pte_ad_hw_updating.value),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.enable),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.flags),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(landing_pad.value),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.enable),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.flags),
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_STATE | KVM_REG_RISCV_SBI_FWFT | KVM_REG_RISCV_SBI_FWFT_REG(shadow_stack.value),
};

static __u64 zicbom_regs[] = {
Expand Down
Loading