On 09/05/2025 20:09, Atish Patra wrote: > On 4/24/25 10:32 AM, Clément Léger wrote: >> SBI_FWFT_MISALIGNED_DELEG needs hedeleg to be modified to delegate >> misaligned load/store exceptions. Save and restore it during CPU >> load/put. >> >> Signed-off-by: Clément Léger <cleger@xxxxxxxxxxxx> >> Reviewed-by: Deepak Gupta <debug@xxxxxxxxxxxx> >> Reviewed-by: Andrew Jones <ajones@xxxxxxxxxxxxxxxx> >> --- >> arch/riscv/kvm/vcpu.c | 3 +++ >> arch/riscv/kvm/vcpu_sbi_fwft.c | 36 ++++++++++++++++++++++++++++++++++ >> 2 files changed, 39 insertions(+) >> >> diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c >> index 542747e2c7f5..d98e379945c3 100644 >> --- a/arch/riscv/kvm/vcpu.c >> +++ b/arch/riscv/kvm/vcpu.c >> @@ -646,6 +646,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) >> { >> void *nsh; >> struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; >> + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; >> vcpu->cpu = -1; >> @@ -671,6 +672,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) >> csr->vstval = nacl_csr_read(nsh, CSR_VSTVAL); >> csr->hvip = nacl_csr_read(nsh, CSR_HVIP); >> csr->vsatp = nacl_csr_read(nsh, CSR_VSATP); >> + cfg->hedeleg = nacl_csr_read(nsh, CSR_HEDELEG); >> } else { >> csr->vsstatus = csr_read(CSR_VSSTATUS); >> csr->vsie = csr_read(CSR_VSIE); >> @@ -681,6 +683,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) >> csr->vstval = csr_read(CSR_VSTVAL); >> csr->hvip = csr_read(CSR_HVIP); >> csr->vsatp = csr_read(CSR_VSATP); >> + cfg->hedeleg = csr_read(CSR_HEDELEG); > > Can we avoid saving hedeleg in vcpu_put path by updating the cfg- >>hedeleg in kvm_sbi_fwft_set_misaligned_delegation. > > We already update the hedeleg in vcpu_load path from cfg->hedeleg. > If the next vcpu did not enable delegation it will get the correct > config written to hedeleg. Yeah that make sense, I'll modify that. Thanks, Clément > > This will save us a csr read cost in each VM exit path for something > that is probably configured once in guest life time.> >> } >> } >> diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/ >> vcpu_sbi_fwft.c >> index b0f66c7bf010..d16ee477042f 100644 >> --- a/arch/riscv/kvm/vcpu_sbi_fwft.c >> +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c >> @@ -14,6 +14,8 @@ >> #include <asm/kvm_vcpu_sbi.h> >> #include <asm/kvm_vcpu_sbi_fwft.h> >> +#define MIS_DELEG (BIT_ULL(EXC_LOAD_MISALIGNED) | >> BIT_ULL(EXC_STORE_MISALIGNED)) >> + >> struct kvm_sbi_fwft_feature { >> /** >> * @id: Feature ID >> @@ -68,7 +70,41 @@ static bool kvm_fwft_is_defined_feature(enum >> sbi_fwft_feature_t feature) >> return false; >> } >> +static bool kvm_sbi_fwft_misaligned_delegation_supported(struct >> kvm_vcpu *vcpu) >> +{ >> + return misaligned_traps_can_delegate(); >> +} >> + >> +static long kvm_sbi_fwft_set_misaligned_delegation(struct kvm_vcpu >> *vcpu, >> + struct kvm_sbi_fwft_config *conf, >> + unsigned long value) >> +{ >> + if (value == 1) >> + csr_set(CSR_HEDELEG, MIS_DELEG); >> + else if (value == 0) >> + csr_clear(CSR_HEDELEG, MIS_DELEG); >> + else >> + return SBI_ERR_INVALID_PARAM; >> + >> + return SBI_SUCCESS; >> +} >> + >> +static long kvm_sbi_fwft_get_misaligned_delegation(struct kvm_vcpu >> *vcpu, >> + struct kvm_sbi_fwft_config *conf, >> + unsigned long *value) >> +{ >> + *value = (csr_read(CSR_HEDELEG) & MIS_DELEG) == MIS_DELEG; >> + >> + return SBI_SUCCESS; >> +} >> + >> static const struct kvm_sbi_fwft_feature features[] = { >> + { >> + .id = SBI_FWFT_MISALIGNED_EXC_DELEG, >> + .supported = kvm_sbi_fwft_misaligned_delegation_supported, >> + .set = kvm_sbi_fwft_set_misaligned_delegation, >> + .get = kvm_sbi_fwft_get_misaligned_delegation, >> + }, >> }; >> static struct kvm_sbi_fwft_config * >