[PATCH 16/18] KVM: riscv: add hstatus to allow endian control
Ben Dooks
ben.dooks at codethink.co.uk
Fri Aug 22 09:52:46 PDT 2025
---
arch/riscv/include/uapi/asm/kvm.h | 1 +
arch/riscv/kvm/vcpu_onereg.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index ef27d4289da1..4cec75665f55 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -81,6 +81,7 @@ struct kvm_riscv_csr {
unsigned long satp;
unsigned long scounteren;
unsigned long senvcfg;
+ unsigned long hstatus;
};
/* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index cce6a38ea54f..25c1e43f80bc 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -484,6 +484,7 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,
unsigned long reg_num,
unsigned long *out_val)
{
+ struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
@@ -493,6 +494,8 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,
kvm_riscv_vcpu_flush_interrupts(vcpu);
*out_val = (csr->hvip >> VSIP_TO_HVIP_SHIFT) & VSIP_VALID_MASK;
*out_val |= csr->hvip & ~IRQ_LOCAL_MASK;
+ } else if (reg_num == KVM_REG_RISCV_CSR_REG(hstatus)) {
+ *out_val = cntx->hstatus;
} else
*out_val = ((unsigned long *)csr)[reg_num];
@@ -503,6 +506,7 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
unsigned long reg_num,
unsigned long reg_val)
{
+ struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
@@ -511,6 +515,11 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
reg_val &= VSIP_VALID_MASK;
reg_val <<= VSIP_TO_HVIP_SHIFT;
+ } else if (reg_num == KVM_REG_RISCV_CSR_REG(hstatus)) {
+ /* for now only allow the S level endianness */
+ cntx->hstatus &= ~HSTATUS_VSBE;
+ cntx->hstatus |= reg_val & HSTATUS_VSBE;
+ return 0;
}
((unsigned long *)csr)[reg_num] = reg_val;
--
2.37.2.352.g3c44437643
More information about the linux-riscv
mailing list