Implement function to initialize VCPU's CSR registers to delegate handling of some traps to VS-mode ( guest ), enable vstimecmp for VS-mode, and allow some AIA-related register (thier vs* copies ) for VS-mode.
Add detection of Smstateen extension to properly initialize hstateen0 to allow guest to access AIA-added state. Add call of vcpu_csr_init() in arch_vcpu_create(). Signed-off-by: Oleksii Kurochko <[email protected]> --- xen/arch/riscv/cpufeature.c | 1 + xen/arch/riscv/domain.c | 63 +++++++++++++++++++++ xen/arch/riscv/include/asm/cpufeature.h | 1 + xen/arch/riscv/include/asm/riscv_encoding.h | 2 + 4 files changed, 67 insertions(+) diff --git a/xen/arch/riscv/cpufeature.c b/xen/arch/riscv/cpufeature.c index 02b68aeaa49f..03e27b037be0 100644 --- a/xen/arch/riscv/cpufeature.c +++ b/xen/arch/riscv/cpufeature.c @@ -137,6 +137,7 @@ const struct riscv_isa_ext_data __initconst riscv_isa_ext[] = { RISCV_ISA_EXT_DATA(zbb), RISCV_ISA_EXT_DATA(zbs), RISCV_ISA_EXT_DATA(smaia), + RISCV_ISA_EXT_DATA(smstateen), RISCV_ISA_EXT_DATA(ssaia), RISCV_ISA_EXT_DATA(svade), RISCV_ISA_EXT_DATA(svpbmt), diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c index e5fda1af4ee9..44387d056546 100644 --- a/xen/arch/riscv/domain.c +++ b/xen/arch/riscv/domain.c @@ -3,6 +3,67 @@ #include <xen/mm.h> #include <xen/sched.h> +#include <asm/cpufeature.h> +#include <asm/csr.h> +#include <asm/riscv_encoding.h> + +static void vcpu_csr_init(struct vcpu *v) +{ + unsigned long hedeleg, hideleg, hstatus; + + hedeleg = 0; + hedeleg |= (1U << CAUSE_MISALIGNED_FETCH); + hedeleg |= (1U << CAUSE_FETCH_ACCESS); + hedeleg |= (1U << CAUSE_ILLEGAL_INSTRUCTION); + hedeleg |= (1U << CAUSE_MISALIGNED_LOAD); + hedeleg |= (1U << CAUSE_LOAD_ACCESS); + hedeleg |= (1U << CAUSE_MISALIGNED_STORE); + hedeleg |= (1U << CAUSE_STORE_ACCESS); + hedeleg |= (1U << CAUSE_BREAKPOINT); + hedeleg |= (1U << CAUSE_USER_ECALL); + hedeleg |= (1U << CAUSE_FETCH_PAGE_FAULT); + hedeleg |= (1U << CAUSE_LOAD_PAGE_FAULT); + hedeleg |= (1U << CAUSE_STORE_PAGE_FAULT); + v->arch.hedeleg = hedeleg; + + hstatus = HSTATUS_SPV | HSTATUS_SPVP; + v->arch.hstatus = hstatus; + + hideleg = MIP_VSTIP | MIP_VSEIP | MIP_VSSIP; + v->arch.hideleg = hideleg; + + /* + * VS should access only the time counter directly. + * Everything else should trap. + */ + v->arch.hcounteren |= HCOUNTEREN_TM; + + if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svpbmt) ) + v->arch.henvcfg |= ENVCFG_PBMTE; + + if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_smstateen) ) + { + /* + * If the hypervisor extension is implemented, the same three bitsare + * defined also in hypervisor CSR hstateen0 but concern only the state + * potentially accessible to a virtual machine executing in privilege + * modes VS and VU: + * bit 60 CSRs siselect and sireg (really vsiselect and vsireg) + * bit 59 CSRs siph and sieh (RV32 only) and stopi (really vsiph, + * vsieh, and vstopi) + * bit 58 all state of IMSIC guest interrupt files, including CSR + * stopei (really vstopei) + * If one of these bits is zero in hstateen0, and the same bit is one + * in mstateen0, then an attempt to access the corresponding state from + * VS or VU-mode raises a virtual instruction exception. + */ + v->arch.hstateen0 = SMSTATEEN0_AIA | SMSTATEEN0_IMSIC | SMSTATEEN0_SVSLCT; + + /* Allow guest to access CSR_ENVCFG */ + v->arch.hstateen0 |= SMSTATEEN0_HSENVCFG; + } +} + static void continue_new_vcpu(struct vcpu *prev) { BUG_ON("unimplemented\n"); @@ -30,6 +91,8 @@ int arch_vcpu_create(struct vcpu *v) v->arch.xen_saved_context.sp, v->arch.xen_saved_context.ra, (unsigned long)v->arch.cpu_info); + vcpu_csr_init(v); + /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; diff --git a/xen/arch/riscv/include/asm/cpufeature.h b/xen/arch/riscv/include/asm/cpufeature.h index b69616038888..ef02a3e26d2c 100644 --- a/xen/arch/riscv/include/asm/cpufeature.h +++ b/xen/arch/riscv/include/asm/cpufeature.h @@ -36,6 +36,7 @@ enum riscv_isa_ext_id { RISCV_ISA_EXT_zbb, RISCV_ISA_EXT_zbs, RISCV_ISA_EXT_smaia, + RISCV_ISA_EXT_smstateen, RISCV_ISA_EXT_ssaia, RISCV_ISA_EXT_svade, RISCV_ISA_EXT_svpbmt, diff --git a/xen/arch/riscv/include/asm/riscv_encoding.h b/xen/arch/riscv/include/asm/riscv_encoding.h index 1f7e612366f8..dd15731a86fa 100644 --- a/xen/arch/riscv/include/asm/riscv_encoding.h +++ b/xen/arch/riscv/include/asm/riscv_encoding.h @@ -228,6 +228,8 @@ #define ENVCFG_CBIE_INV _UL(0x3) #define ENVCFG_FIOM _UL(0x1) +#define HCOUNTEREN_TM BIT(1, U) + /* ===== User-level CSRs ===== */ /* User Trap Setup (N-extension) */ -- 2.52.0
