mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
KVM/riscv changes for 6.7
- Smstateen and Zicond support for Guest/VM - Virtualized senvcfg CSR for Guest/VM - Added Smstateen registers to the get-reg-list selftests - Added Zicond to the get-reg-list selftests - Virtualized SBI debug console (DBCN) for Guest/VM - Added SBI debug console (DBCN) to the get-reg-list selftests -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEZdn75s5e6LHDQ+f/rUjsVaLHLAcFAmU3dKgACgkQrUjsVaLH LAeh6g//RVlm3rLLwnWes3PwnBZDtkXYVVLy8oCEPjjjZGMJ+piwV8kcq4QpNear e1nrOJTnndkjPG9TdJIxFW0qGnPLe4D9Ag6NoFpJXwxZRy/Glr8iWbt3pOcrv6vu gk/9RP5gQpJpcP7D2scR+go6ryEzncCNY5GLtXoyFM9drQk+IROSrMWrWI5CXBJi c0qwQWsSWb3KTBTZ7Gsm0Y7E9WIi5u6bBxcLJvblUKszS+PpXO9IA+8qOGZS4Cts ocy5qqu+NNPECZjSa+kZti8ZSbdjNw9ORyB4OHlBUt55Uidp72pPFdTjGvSvs/jq 6wF70i1qjZOtjVUNdlkF93EN1xu4f3Hus/6/Q1pcyq+k9vo7eeJQQRWR4bJZ9SJR ZkhYfOgqMUzMnrf2M20en9DygRDFstL2XW5mGDPmk9XLSNv1KwpKf96Xl2E20uPb 21EVQSiybmpl80WkWs0txwk62qQYzYUx+Io8XKXl8MrqNN2HCnzUUy/fjy/kd7iM Oe1a8kNcV/eawpURBNVCcpld9qM1OPCmseqrr9tpvdR4SmAo1mAi/d7/I61umwpE a36fqmwIZ0ppMs86BOcMRcTaee6EjPeldXnRCTjCLqo6YvsdHRrwpNBHRMbUOKpy 0688Xf+vjmu81IXhfaRTcs5dvKe1NI4puRtG5DUt7n1csSUyNWI= =TFKQ -----END PGP SIGNATURE----- Merge tag 'kvm-riscv-6.7-1' of https://github.com/kvm-riscv/linux into HEAD KVM/riscv changes for 6.7 - Smstateen and Zicond support for Guest/VM - Virtualized senvcfg CSR for Guest/VM - Added Smstateen registers to the get-reg-list selftests - Added Zicond to the get-reg-list selftests - Virtualized SBI debug console (DBCN) for Guest/VM - Added SBI debug console (DBCN) to the get-reg-list selftests
This commit is contained in:
commit
957eedc703
@ -128,6 +128,12 @@ properties:
|
||||
changes to interrupts as frozen at commit ccbddab ("Merge pull
|
||||
request #42 from riscv/jhauser-2023-RC4") of riscv-aia.
|
||||
|
||||
- const: smstateen
|
||||
description: |
|
||||
The standard Smstateen extension for controlling access to CSRs
|
||||
added by other RISC-V extensions in H/S/VS/U/VU modes and as
|
||||
ratified at commit a28bfae (Ratified (#7)) of riscv-state-enable.
|
||||
|
||||
- const: ssaia
|
||||
description: |
|
||||
The standard Ssaia supervisor-level extension for the advanced
|
||||
@ -212,6 +218,12 @@ properties:
|
||||
ratified in the 20191213 version of the unprivileged ISA
|
||||
specification.
|
||||
|
||||
- const: zicond
|
||||
description:
|
||||
The standard Zicond extension for conditional arithmetic and
|
||||
conditional-select/move operations as ratified in commit 95cf1f9
|
||||
("Add changes requested by Ved during signoff") of riscv-zicond.
|
||||
|
||||
- const: zicsr
|
||||
description: |
|
||||
The standard Zicsr extension for control and status register
|
||||
|
@ -11570,6 +11570,7 @@ F: arch/riscv/include/asm/kvm*
|
||||
F: arch/riscv/include/uapi/asm/kvm*
|
||||
F: arch/riscv/kvm/
|
||||
F: tools/testing/selftests/kvm/*/riscv/
|
||||
F: tools/testing/selftests/kvm/riscv/
|
||||
|
||||
KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
|
||||
M: Christian Borntraeger <borntraeger@linux.ibm.com>
|
||||
|
@ -203,6 +203,18 @@
|
||||
#define ENVCFG_CBIE_INV _AC(0x3, UL)
|
||||
#define ENVCFG_FIOM _AC(0x1, UL)
|
||||
|
||||
/* Smstateen bits */
|
||||
#define SMSTATEEN0_AIA_IMSIC_SHIFT 58
|
||||
#define SMSTATEEN0_AIA_IMSIC (_ULL(1) << SMSTATEEN0_AIA_IMSIC_SHIFT)
|
||||
#define SMSTATEEN0_AIA_SHIFT 59
|
||||
#define SMSTATEEN0_AIA (_ULL(1) << SMSTATEEN0_AIA_SHIFT)
|
||||
#define SMSTATEEN0_AIA_ISEL_SHIFT 60
|
||||
#define SMSTATEEN0_AIA_ISEL (_ULL(1) << SMSTATEEN0_AIA_ISEL_SHIFT)
|
||||
#define SMSTATEEN0_HSENVCFG_SHIFT 62
|
||||
#define SMSTATEEN0_HSENVCFG (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
|
||||
#define SMSTATEEN0_SSTATEEN0_SHIFT 63
|
||||
#define SMSTATEEN0_SSTATEEN0 (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT)
|
||||
|
||||
/* symbolic CSR names: */
|
||||
#define CSR_CYCLE 0xc00
|
||||
#define CSR_TIME 0xc01
|
||||
@ -275,6 +287,8 @@
|
||||
#define CSR_SIE 0x104
|
||||
#define CSR_STVEC 0x105
|
||||
#define CSR_SCOUNTEREN 0x106
|
||||
#define CSR_SENVCFG 0x10a
|
||||
#define CSR_SSTATEEN0 0x10c
|
||||
#define CSR_SSCRATCH 0x140
|
||||
#define CSR_SEPC 0x141
|
||||
#define CSR_SCAUSE 0x142
|
||||
@ -349,6 +363,10 @@
|
||||
#define CSR_VSIEH 0x214
|
||||
#define CSR_VSIPH 0x254
|
||||
|
||||
/* Hypervisor stateen CSRs */
|
||||
#define CSR_HSTATEEN0 0x60c
|
||||
#define CSR_HSTATEEN0H 0x61c
|
||||
|
||||
#define CSR_MSTATUS 0x300
|
||||
#define CSR_MISA 0x301
|
||||
#define CSR_MIDELEG 0x303
|
||||
|
@ -58,6 +58,8 @@
|
||||
#define RISCV_ISA_EXT_ZICSR 40
|
||||
#define RISCV_ISA_EXT_ZIFENCEI 41
|
||||
#define RISCV_ISA_EXT_ZIHPM 42
|
||||
#define RISCV_ISA_EXT_SMSTATEEN 43
|
||||
#define RISCV_ISA_EXT_ZICOND 44
|
||||
|
||||
#define RISCV_ISA_EXT_MAX 64
|
||||
|
||||
|
@ -162,6 +162,16 @@ struct kvm_vcpu_csr {
|
||||
unsigned long hvip;
|
||||
unsigned long vsatp;
|
||||
unsigned long scounteren;
|
||||
unsigned long senvcfg;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_config {
|
||||
u64 henvcfg;
|
||||
u64 hstateen0;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_smstateen_csr {
|
||||
unsigned long sstateen0;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_arch {
|
||||
@ -183,6 +193,8 @@ struct kvm_vcpu_arch {
|
||||
unsigned long host_sscratch;
|
||||
unsigned long host_stvec;
|
||||
unsigned long host_scounteren;
|
||||
unsigned long host_senvcfg;
|
||||
unsigned long host_sstateen0;
|
||||
|
||||
/* CPU context of Host */
|
||||
struct kvm_cpu_context host_context;
|
||||
@ -193,6 +205,9 @@ struct kvm_vcpu_arch {
|
||||
/* CPU CSR context of Guest VCPU */
|
||||
struct kvm_vcpu_csr guest_csr;
|
||||
|
||||
/* CPU Smstateen CSR context of Guest VCPU */
|
||||
struct kvm_vcpu_smstateen_csr smstateen_csr;
|
||||
|
||||
/* CPU context upon Guest VCPU reset */
|
||||
struct kvm_cpu_context guest_reset_context;
|
||||
|
||||
@ -244,6 +259,9 @@ struct kvm_vcpu_arch {
|
||||
|
||||
/* Performance monitoring context */
|
||||
struct kvm_pmu pmu_context;
|
||||
|
||||
/* 'static' configurations which are set only once */
|
||||
struct kvm_vcpu_config cfg;
|
||||
};
|
||||
|
||||
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#define KVM_SBI_IMPID 3
|
||||
|
||||
#define KVM_SBI_VERSION_MAJOR 1
|
||||
#define KVM_SBI_VERSION_MAJOR 2
|
||||
#define KVM_SBI_VERSION_MINOR 0
|
||||
|
||||
enum kvm_riscv_sbi_ext_status {
|
||||
@ -35,6 +35,9 @@ struct kvm_vcpu_sbi_return {
|
||||
struct kvm_vcpu_sbi_extension {
|
||||
unsigned long extid_start;
|
||||
unsigned long extid_end;
|
||||
|
||||
bool default_unavail;
|
||||
|
||||
/**
|
||||
* SBI extension handler. It can be defined for a given extension or group of
|
||||
* extension. But it should always return linux error codes rather than SBI
|
||||
@ -59,6 +62,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(
|
||||
struct kvm_vcpu *vcpu, unsigned long extid);
|
||||
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu);
|
||||
|
||||
#ifdef CONFIG_RISCV_SBI_V01
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
|
||||
@ -69,6 +73,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
|
||||
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
|
||||
|
||||
|
@ -30,6 +30,7 @@ enum sbi_ext_id {
|
||||
SBI_EXT_HSM = 0x48534D,
|
||||
SBI_EXT_SRST = 0x53525354,
|
||||
SBI_EXT_PMU = 0x504D55,
|
||||
SBI_EXT_DBCN = 0x4442434E,
|
||||
|
||||
/* Experimentals extensions must lie within this range */
|
||||
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
|
||||
@ -236,6 +237,12 @@ enum sbi_pmu_ctr_type {
|
||||
/* Flags defined for counter stop function */
|
||||
#define SBI_PMU_STOP_FLAG_RESET (1 << 0)
|
||||
|
||||
enum sbi_ext_dbcn_fid {
|
||||
SBI_EXT_DBCN_CONSOLE_WRITE = 0,
|
||||
SBI_EXT_DBCN_CONSOLE_READ = 1,
|
||||
SBI_EXT_DBCN_CONSOLE_WRITE_BYTE = 2,
|
||||
};
|
||||
|
||||
#define SBI_SPEC_VERSION_DEFAULT 0x1
|
||||
#define SBI_SPEC_VERSION_MAJOR_SHIFT 24
|
||||
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
|
||||
|
@ -80,6 +80,7 @@ struct kvm_riscv_csr {
|
||||
unsigned long sip;
|
||||
unsigned long satp;
|
||||
unsigned long scounteren;
|
||||
unsigned long senvcfg;
|
||||
};
|
||||
|
||||
/* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
|
||||
@ -93,6 +94,11 @@ struct kvm_riscv_aia_csr {
|
||||
unsigned long iprio2h;
|
||||
};
|
||||
|
||||
/* Smstateen CSR for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
|
||||
struct kvm_riscv_smstateen_csr {
|
||||
unsigned long sstateen0;
|
||||
};
|
||||
|
||||
/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
|
||||
struct kvm_riscv_timer {
|
||||
__u64 frequency;
|
||||
@ -131,6 +137,8 @@ enum KVM_RISCV_ISA_EXT_ID {
|
||||
KVM_RISCV_ISA_EXT_ZICSR,
|
||||
KVM_RISCV_ISA_EXT_ZIFENCEI,
|
||||
KVM_RISCV_ISA_EXT_ZIHPM,
|
||||
KVM_RISCV_ISA_EXT_SMSTATEEN,
|
||||
KVM_RISCV_ISA_EXT_ZICOND,
|
||||
KVM_RISCV_ISA_EXT_MAX,
|
||||
};
|
||||
|
||||
@ -148,6 +156,7 @@ enum KVM_RISCV_SBI_EXT_ID {
|
||||
KVM_RISCV_SBI_EXT_PMU,
|
||||
KVM_RISCV_SBI_EXT_EXPERIMENTAL,
|
||||
KVM_RISCV_SBI_EXT_VENDOR,
|
||||
KVM_RISCV_SBI_EXT_DBCN,
|
||||
KVM_RISCV_SBI_EXT_MAX,
|
||||
};
|
||||
|
||||
@ -178,10 +187,13 @@ enum KVM_RISCV_SBI_EXT_ID {
|
||||
#define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
|
||||
#define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
|
||||
#define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
|
||||
#define KVM_REG_RISCV_CSR_SMSTATEEN (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT)
|
||||
#define KVM_REG_RISCV_CSR_REG(name) \
|
||||
(offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
|
||||
#define KVM_REG_RISCV_CSR_AIA_REG(name) \
|
||||
(offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long))
|
||||
#define KVM_REG_RISCV_CSR_SMSTATEEN_REG(name) \
|
||||
(offsetof(struct kvm_riscv_smstateen_csr, name) / sizeof(unsigned long))
|
||||
|
||||
/* Timer registers are mapped as type 4 */
|
||||
#define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
|
||||
|
@ -167,6 +167,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
|
||||
__RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ),
|
||||
__RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR),
|
||||
__RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND),
|
||||
__RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR),
|
||||
__RISCV_ISA_EXT_DATA(zifencei, RISCV_ISA_EXT_ZIFENCEI),
|
||||
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
|
||||
@ -175,6 +176,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
|
||||
__RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB),
|
||||
__RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS),
|
||||
__RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA),
|
||||
__RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN),
|
||||
__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
|
||||
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
|
||||
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
|
||||
|
@ -141,6 +141,12 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Setup SBI extensions
|
||||
* NOTE: This must be the last thing to be initialized.
|
||||
*/
|
||||
kvm_riscv_vcpu_sbi_init(vcpu);
|
||||
|
||||
/* Reset VCPU */
|
||||
kvm_riscv_reset_vcpu(vcpu);
|
||||
|
||||
@ -471,31 +477,38 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void kvm_riscv_vcpu_update_config(const unsigned long *isa)
|
||||
static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 henvcfg = 0;
|
||||
const unsigned long *isa = vcpu->arch.isa;
|
||||
struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
|
||||
|
||||
if (riscv_isa_extension_available(isa, SVPBMT))
|
||||
henvcfg |= ENVCFG_PBMTE;
|
||||
cfg->henvcfg |= ENVCFG_PBMTE;
|
||||
|
||||
if (riscv_isa_extension_available(isa, SSTC))
|
||||
henvcfg |= ENVCFG_STCE;
|
||||
cfg->henvcfg |= ENVCFG_STCE;
|
||||
|
||||
if (riscv_isa_extension_available(isa, ZICBOM))
|
||||
henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE);
|
||||
cfg->henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE);
|
||||
|
||||
if (riscv_isa_extension_available(isa, ZICBOZ))
|
||||
henvcfg |= ENVCFG_CBZE;
|
||||
cfg->henvcfg |= ENVCFG_CBZE;
|
||||
|
||||
csr_write(CSR_HENVCFG, henvcfg);
|
||||
#ifdef CONFIG_32BIT
|
||||
csr_write(CSR_HENVCFGH, henvcfg >> 32);
|
||||
#endif
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) {
|
||||
cfg->hstateen0 |= SMSTATEEN0_HSENVCFG;
|
||||
if (riscv_isa_extension_available(isa, SSAIA))
|
||||
cfg->hstateen0 |= SMSTATEEN0_AIA_IMSIC |
|
||||
SMSTATEEN0_AIA |
|
||||
SMSTATEEN0_AIA_ISEL;
|
||||
if (riscv_isa_extension_available(isa, SMSTATEEN))
|
||||
cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0;
|
||||
}
|
||||
}
|
||||
|
||||
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
{
|
||||
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
|
||||
struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
|
||||
|
||||
csr_write(CSR_VSSTATUS, csr->vsstatus);
|
||||
csr_write(CSR_VSIE, csr->vsie);
|
||||
@ -506,8 +519,14 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
csr_write(CSR_VSTVAL, csr->vstval);
|
||||
csr_write(CSR_HVIP, csr->hvip);
|
||||
csr_write(CSR_VSATP, csr->vsatp);
|
||||
|
||||
kvm_riscv_vcpu_update_config(vcpu->arch.isa);
|
||||
csr_write(CSR_HENVCFG, cfg->henvcfg);
|
||||
if (IS_ENABLED(CONFIG_32BIT))
|
||||
csr_write(CSR_HENVCFGH, cfg->henvcfg >> 32);
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) {
|
||||
csr_write(CSR_HSTATEEN0, cfg->hstateen0);
|
||||
if (IS_ENABLED(CONFIG_32BIT))
|
||||
csr_write(CSR_HSTATEEN0H, cfg->hstateen0 >> 32);
|
||||
}
|
||||
|
||||
kvm_riscv_gstage_update_hgatp(vcpu);
|
||||
|
||||
@ -606,6 +625,32 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)
|
||||
kvm_riscv_vcpu_aia_update_hvip(vcpu);
|
||||
}
|
||||
|
||||
static __always_inline void kvm_riscv_vcpu_swap_in_guest_state(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr;
|
||||
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
|
||||
struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
|
||||
|
||||
vcpu->arch.host_senvcfg = csr_swap(CSR_SENVCFG, csr->senvcfg);
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) &&
|
||||
(cfg->hstateen0 & SMSTATEEN0_SSTATEEN0))
|
||||
vcpu->arch.host_sstateen0 = csr_swap(CSR_SSTATEEN0,
|
||||
smcsr->sstateen0);
|
||||
}
|
||||
|
||||
static __always_inline void kvm_riscv_vcpu_swap_in_host_state(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr;
|
||||
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
|
||||
struct kvm_vcpu_config *cfg = &vcpu->arch.cfg;
|
||||
|
||||
csr->senvcfg = csr_swap(CSR_SENVCFG, vcpu->arch.host_senvcfg);
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) &&
|
||||
(cfg->hstateen0 & SMSTATEEN0_SSTATEEN0))
|
||||
smcsr->sstateen0 = csr_swap(CSR_SSTATEEN0,
|
||||
vcpu->arch.host_sstateen0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
|
||||
* the vCPU is running.
|
||||
@ -615,10 +660,12 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)
|
||||
*/
|
||||
static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
kvm_riscv_vcpu_swap_in_guest_state(vcpu);
|
||||
guest_state_enter_irqoff();
|
||||
__kvm_riscv_switch_to(&vcpu->arch);
|
||||
vcpu->arch.last_exit_cpu = vcpu->cpu;
|
||||
guest_state_exit_irqoff();
|
||||
kvm_riscv_vcpu_swap_in_host_state(vcpu);
|
||||
}
|
||||
|
||||
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
|
||||
@ -627,6 +674,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
|
||||
struct kvm_cpu_trap trap;
|
||||
struct kvm_run *run = vcpu->run;
|
||||
|
||||
if (!vcpu->arch.ran_atleast_once)
|
||||
kvm_riscv_vcpu_setup_config(vcpu);
|
||||
|
||||
/* Mark this VCPU ran at least once */
|
||||
vcpu->arch.ran_atleast_once = true;
|
||||
|
||||
|
@ -34,6 +34,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
|
||||
[KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m,
|
||||
[KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_v,
|
||||
/* Multi letter extensions (alphabetically sorted) */
|
||||
KVM_ISA_EXT_ARR(SMSTATEEN),
|
||||
KVM_ISA_EXT_ARR(SSAIA),
|
||||
KVM_ISA_EXT_ARR(SSTC),
|
||||
KVM_ISA_EXT_ARR(SVINVAL),
|
||||
@ -45,6 +46,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
|
||||
KVM_ISA_EXT_ARR(ZICBOM),
|
||||
KVM_ISA_EXT_ARR(ZICBOZ),
|
||||
KVM_ISA_EXT_ARR(ZICNTR),
|
||||
KVM_ISA_EXT_ARR(ZICOND),
|
||||
KVM_ISA_EXT_ARR(ZICSR),
|
||||
KVM_ISA_EXT_ARR(ZIFENCEI),
|
||||
KVM_ISA_EXT_ARR(ZIHINTPAUSE),
|
||||
@ -80,11 +82,11 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
|
||||
static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
|
||||
{
|
||||
switch (ext) {
|
||||
/* Extensions which don't have any mechanism to disable */
|
||||
case KVM_RISCV_ISA_EXT_A:
|
||||
case KVM_RISCV_ISA_EXT_C:
|
||||
case KVM_RISCV_ISA_EXT_I:
|
||||
case KVM_RISCV_ISA_EXT_M:
|
||||
case KVM_RISCV_ISA_EXT_SSAIA:
|
||||
case KVM_RISCV_ISA_EXT_SSTC:
|
||||
case KVM_RISCV_ISA_EXT_SVINVAL:
|
||||
case KVM_RISCV_ISA_EXT_SVNAPOT:
|
||||
@ -92,11 +94,15 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
|
||||
case KVM_RISCV_ISA_EXT_ZBB:
|
||||
case KVM_RISCV_ISA_EXT_ZBS:
|
||||
case KVM_RISCV_ISA_EXT_ZICNTR:
|
||||
case KVM_RISCV_ISA_EXT_ZICOND:
|
||||
case KVM_RISCV_ISA_EXT_ZICSR:
|
||||
case KVM_RISCV_ISA_EXT_ZIFENCEI:
|
||||
case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
|
||||
case KVM_RISCV_ISA_EXT_ZIHPM:
|
||||
return false;
|
||||
/* Extensions which can be disabled using Smstateen */
|
||||
case KVM_RISCV_ISA_EXT_SSAIA:
|
||||
return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -378,6 +384,34 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kvm_riscv_vcpu_smstateen_set_csr(struct kvm_vcpu *vcpu,
|
||||
unsigned long reg_num,
|
||||
unsigned long reg_val)
|
||||
{
|
||||
struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr;
|
||||
|
||||
if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) /
|
||||
sizeof(unsigned long))
|
||||
return -EINVAL;
|
||||
|
||||
((unsigned long *)csr)[reg_num] = reg_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_riscv_vcpu_smstateen_get_csr(struct kvm_vcpu *vcpu,
|
||||
unsigned long reg_num,
|
||||
unsigned long *out_val)
|
||||
{
|
||||
struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr;
|
||||
|
||||
if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) /
|
||||
sizeof(unsigned long))
|
||||
return -EINVAL;
|
||||
|
||||
*out_val = ((unsigned long *)csr)[reg_num];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
@ -401,6 +435,12 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
|
||||
case KVM_REG_RISCV_CSR_AIA:
|
||||
rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val);
|
||||
break;
|
||||
case KVM_REG_RISCV_CSR_SMSTATEEN:
|
||||
rc = -EINVAL;
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN))
|
||||
rc = kvm_riscv_vcpu_smstateen_get_csr(vcpu, reg_num,
|
||||
®_val);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOENT;
|
||||
break;
|
||||
@ -440,6 +480,12 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu,
|
||||
case KVM_REG_RISCV_CSR_AIA:
|
||||
rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val);
|
||||
break;
|
||||
case KVM_REG_RISCV_CSR_SMSTATEEN:
|
||||
rc = -EINVAL;
|
||||
if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN))
|
||||
rc = kvm_riscv_vcpu_smstateen_set_csr(vcpu, reg_num,
|
||||
reg_val);
|
||||
break;
|
||||
default:
|
||||
rc = -ENOENT;
|
||||
break;
|
||||
@ -696,6 +742,8 @@ static inline unsigned long num_csr_regs(const struct kvm_vcpu *vcpu)
|
||||
|
||||
if (riscv_isa_extension_available(vcpu->arch.isa, SSAIA))
|
||||
n += sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long);
|
||||
if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN))
|
||||
n += sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long);
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -704,7 +752,7 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu,
|
||||
u64 __user *uindices)
|
||||
{
|
||||
int n1 = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long);
|
||||
int n2 = 0;
|
||||
int n2 = 0, n3 = 0;
|
||||
|
||||
/* copy general csr regs */
|
||||
for (int i = 0; i < n1; i++) {
|
||||
@ -738,7 +786,25 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu,
|
||||
}
|
||||
}
|
||||
|
||||
return n1 + n2;
|
||||
/* copy Smstateen csr regs */
|
||||
if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) {
|
||||
n3 = sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long);
|
||||
|
||||
for (int i = 0; i < n3; i++) {
|
||||
u64 size = IS_ENABLED(CONFIG_32BIT) ?
|
||||
KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64;
|
||||
u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_CSR |
|
||||
KVM_REG_RISCV_CSR_SMSTATEEN | i;
|
||||
|
||||
if (uindices) {
|
||||
if (put_user(reg, uindices))
|
||||
return -EFAULT;
|
||||
uindices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n1 + n2 + n3;
|
||||
}
|
||||
|
||||
static inline unsigned long num_timer_regs(void)
|
||||
|
@ -66,6 +66,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = {
|
||||
.ext_idx = KVM_RISCV_SBI_EXT_PMU,
|
||||
.ext_ptr = &vcpu_sbi_ext_pmu,
|
||||
},
|
||||
{
|
||||
.ext_idx = KVM_RISCV_SBI_EXT_DBCN,
|
||||
.ext_ptr = &vcpu_sbi_ext_dbcn,
|
||||
},
|
||||
{
|
||||
.ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL,
|
||||
.ext_ptr = &vcpu_sbi_ext_experimental,
|
||||
@ -155,14 +159,8 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu,
|
||||
if (!sext)
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* We can't set the extension status to available here, since it may
|
||||
* have a probe() function which needs to confirm availability first,
|
||||
* but it may be too early to call that here. We can set the status to
|
||||
* unavailable, though.
|
||||
*/
|
||||
if (!reg_val)
|
||||
scontext->ext_status[sext->ext_idx] =
|
||||
scontext->ext_status[sext->ext_idx] = (reg_val) ?
|
||||
KVM_RISCV_SBI_EXT_AVAILABLE :
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE;
|
||||
|
||||
return 0;
|
||||
@ -188,16 +186,8 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu,
|
||||
if (!sext)
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* If the extension status is still uninitialized, then we should probe
|
||||
* to determine if it's available, but it may be too early to do that
|
||||
* here. The best we can do is report that the extension has not been
|
||||
* disabled, i.e. we return 1 when the extension is available and also
|
||||
* when it only may be available.
|
||||
*/
|
||||
*reg_val = scontext->ext_status[sext->ext_idx] !=
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE;
|
||||
|
||||
*reg_val = scontext->ext_status[sext->ext_idx] ==
|
||||
KVM_RISCV_SBI_EXT_AVAILABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -337,18 +327,8 @@ const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(
|
||||
scontext->ext_status[entry->ext_idx] ==
|
||||
KVM_RISCV_SBI_EXT_AVAILABLE)
|
||||
return ext;
|
||||
if (scontext->ext_status[entry->ext_idx] ==
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE)
|
||||
return NULL;
|
||||
if (ext->probe && !ext->probe(vcpu)) {
|
||||
scontext->ext_status[entry->ext_idx] =
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scontext->ext_status[entry->ext_idx] =
|
||||
KVM_RISCV_SBI_EXT_AVAILABLE;
|
||||
return ext;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,3 +399,26 @@ ecall_done:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
|
||||
const struct kvm_riscv_sbi_extension_entry *entry;
|
||||
const struct kvm_vcpu_sbi_extension *ext;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
|
||||
entry = &sbi_ext[i];
|
||||
ext = entry->ext_ptr;
|
||||
|
||||
if (ext->probe && !ext->probe(vcpu)) {
|
||||
scontext->ext_status[entry->ext_idx] =
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE;
|
||||
continue;
|
||||
}
|
||||
|
||||
scontext->ext_status[entry->ext_idx] = ext->default_unavail ?
|
||||
KVM_RISCV_SBI_EXT_UNAVAILABLE :
|
||||
KVM_RISCV_SBI_EXT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
@ -175,3 +175,35 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
|
||||
.extid_end = SBI_EXT_SRST,
|
||||
.handler = kvm_sbi_ext_srst_handler,
|
||||
};
|
||||
|
||||
static int kvm_sbi_ext_dbcn_handler(struct kvm_vcpu *vcpu,
|
||||
struct kvm_run *run,
|
||||
struct kvm_vcpu_sbi_return *retdata)
|
||||
{
|
||||
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
|
||||
unsigned long funcid = cp->a6;
|
||||
|
||||
switch (funcid) {
|
||||
case SBI_EXT_DBCN_CONSOLE_WRITE:
|
||||
case SBI_EXT_DBCN_CONSOLE_READ:
|
||||
case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
|
||||
/*
|
||||
* The SBI debug console functions are unconditionally
|
||||
* forwarded to the userspace.
|
||||
*/
|
||||
kvm_riscv_vcpu_sbi_forward(vcpu, run);
|
||||
retdata->uexit = true;
|
||||
break;
|
||||
default:
|
||||
retdata->err_val = SBI_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = {
|
||||
.extid_start = SBI_EXT_DBCN,
|
||||
.extid_end = SBI_EXT_DBCN,
|
||||
.default_unavail = true,
|
||||
.handler = kvm_sbi_ext_dbcn_handler,
|
||||
};
|
||||
|
@ -25,6 +25,8 @@ bool filter_reg(__u64 reg)
|
||||
* the visibility of the ISA_EXT register itself.
|
||||
*
|
||||
* Based on above, we should filter-out all ISA_EXT registers.
|
||||
*
|
||||
* Note: The below list is alphabetically sorted.
|
||||
*/
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_A:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_C:
|
||||
@ -33,21 +35,23 @@ bool filter_reg(__u64 reg)
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_H:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_I:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_M:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVPBMT:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SMSTATEEN:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSTC:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVINVAL:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVNAPOT:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVPBMT:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBA:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBS:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOM:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOZ:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVNAPOT:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBA:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBS:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICOND:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICSR:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIFENCEI:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
|
||||
case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHPM:
|
||||
return true;
|
||||
/* AIA registers are always available when Ssaia can't be disabled */
|
||||
@ -112,11 +116,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *config_id_to_str(__u64 id)
|
||||
static const char *config_id_to_str(const char *prefix, __u64 id)
|
||||
{
|
||||
/* reg_off is the offset into struct kvm_riscv_config */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CONFIG);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG);
|
||||
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_CONFIG_REG(isa):
|
||||
return "KVM_REG_RISCV_CONFIG_REG(isa)";
|
||||
@ -134,11 +140,7 @@ static const char *config_id_to_str(__u64 id)
|
||||
return "KVM_REG_RISCV_CONFIG_REG(satp_mode)";
|
||||
}
|
||||
|
||||
/*
|
||||
* Config regs would grow regularly with new pseudo reg added, so
|
||||
* just show raw id to indicate a new pseudo config reg.
|
||||
*/
|
||||
return strdup_printf("KVM_REG_RISCV_CONFIG_REG(%lld) /* UNKNOWN */", reg_off);
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *core_id_to_str(const char *prefix, __u64 id)
|
||||
@ -146,6 +148,8 @@ static const char *core_id_to_str(const char *prefix, __u64 id)
|
||||
/* reg_off is the offset into struct kvm_riscv_core */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CORE);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE);
|
||||
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_CORE_REG(regs.pc):
|
||||
return "KVM_REG_RISCV_CORE_REG(regs.pc)";
|
||||
@ -176,14 +180,15 @@ static const char *core_id_to_str(const char *prefix, __u64 id)
|
||||
return "KVM_REG_RISCV_CORE_REG(mode)";
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown core reg id: 0x%llx", prefix, id);
|
||||
return NULL;
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
#define RISCV_CSR_GENERAL(csr) \
|
||||
"KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(" #csr ")"
|
||||
#define RISCV_CSR_AIA(csr) \
|
||||
"KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_REG(" #csr ")"
|
||||
#define RISCV_CSR_SMSTATEEN(csr) \
|
||||
"KVM_REG_RISCV_CSR_SMSTATEEN | KVM_REG_RISCV_CSR_REG(" #csr ")"
|
||||
|
||||
static const char *general_csr_id_to_str(__u64 reg_off)
|
||||
{
|
||||
@ -209,10 +214,11 @@ static const char *general_csr_id_to_str(__u64 reg_off)
|
||||
return RISCV_CSR_GENERAL(satp);
|
||||
case KVM_REG_RISCV_CSR_REG(scounteren):
|
||||
return RISCV_CSR_GENERAL(scounteren);
|
||||
case KVM_REG_RISCV_CSR_REG(senvcfg):
|
||||
return RISCV_CSR_GENERAL(senvcfg);
|
||||
}
|
||||
|
||||
TEST_FAIL("Unknown general csr reg: 0x%llx", reg_off);
|
||||
return NULL;
|
||||
return strdup_printf("KVM_REG_RISCV_CSR_GENERAL | %lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *aia_csr_id_to_str(__u64 reg_off)
|
||||
@ -235,7 +241,18 @@ static const char *aia_csr_id_to_str(__u64 reg_off)
|
||||
return RISCV_CSR_AIA(iprio2h);
|
||||
}
|
||||
|
||||
TEST_FAIL("Unknown aia csr reg: 0x%llx", reg_off);
|
||||
return strdup_printf("KVM_REG_RISCV_CSR_AIA | %lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *smstateen_csr_id_to_str(__u64 reg_off)
|
||||
{
|
||||
/* reg_off is the offset into struct kvm_riscv_smstateen_csr */
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_CSR_SMSTATEEN_REG(sstateen0):
|
||||
return RISCV_CSR_SMSTATEEN(sstateen0);
|
||||
}
|
||||
|
||||
TEST_FAIL("Unknown smstateen csr reg: 0x%llx", reg_off);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -244,6 +261,8 @@ static const char *csr_id_to_str(const char *prefix, __u64 id)
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CSR);
|
||||
__u64 reg_subtype = reg_off & KVM_REG_RISCV_SUBTYPE_MASK;
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR);
|
||||
|
||||
reg_off &= ~KVM_REG_RISCV_SUBTYPE_MASK;
|
||||
|
||||
switch (reg_subtype) {
|
||||
@ -251,10 +270,11 @@ static const char *csr_id_to_str(const char *prefix, __u64 id)
|
||||
return general_csr_id_to_str(reg_off);
|
||||
case KVM_REG_RISCV_CSR_AIA:
|
||||
return aia_csr_id_to_str(reg_off);
|
||||
case KVM_REG_RISCV_CSR_SMSTATEEN:
|
||||
return smstateen_csr_id_to_str(reg_off);
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown csr subtype: 0x%llx", prefix, reg_subtype);
|
||||
return NULL;
|
||||
return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off);
|
||||
}
|
||||
|
||||
static const char *timer_id_to_str(const char *prefix, __u64 id)
|
||||
@ -262,6 +282,8 @@ static const char *timer_id_to_str(const char *prefix, __u64 id)
|
||||
/* reg_off is the offset into struct kvm_riscv_timer */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_TIMER);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER);
|
||||
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_TIMER_REG(frequency):
|
||||
return "KVM_REG_RISCV_TIMER_REG(frequency)";
|
||||
@ -273,8 +295,7 @@ static const char *timer_id_to_str(const char *prefix, __u64 id)
|
||||
return "KVM_REG_RISCV_TIMER_REG(state)";
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown timer reg id: 0x%llx", prefix, id);
|
||||
return NULL;
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *fp_f_id_to_str(const char *prefix, __u64 id)
|
||||
@ -282,6 +303,8 @@ static const char *fp_f_id_to_str(const char *prefix, __u64 id)
|
||||
/* reg_off is the offset into struct __riscv_f_ext_state */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_FP_F);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F);
|
||||
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_FP_F_REG(f[0]) ...
|
||||
KVM_REG_RISCV_FP_F_REG(f[31]):
|
||||
@ -290,8 +313,7 @@ static const char *fp_f_id_to_str(const char *prefix, __u64 id)
|
||||
return "KVM_REG_RISCV_FP_F_REG(fcsr)";
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown fp_f reg id: 0x%llx", prefix, id);
|
||||
return NULL;
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *fp_d_id_to_str(const char *prefix, __u64 id)
|
||||
@ -299,6 +321,8 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
|
||||
/* reg_off is the offset into struct __riscv_d_ext_state */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_FP_D);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D);
|
||||
|
||||
switch (reg_off) {
|
||||
case KVM_REG_RISCV_FP_D_REG(f[0]) ...
|
||||
KVM_REG_RISCV_FP_D_REG(f[31]):
|
||||
@ -307,96 +331,93 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id)
|
||||
return "KVM_REG_RISCV_FP_D_REG(fcsr)";
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown fp_d reg id: 0x%llx", prefix, id);
|
||||
return NULL;
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
static const char *isa_ext_id_to_str(__u64 id)
|
||||
#define KVM_ISA_EXT_ARR(ext) \
|
||||
[KVM_RISCV_ISA_EXT_##ext] = "KVM_RISCV_ISA_EXT_" #ext
|
||||
|
||||
static const char *isa_ext_id_to_str(const char *prefix, __u64 id)
|
||||
{
|
||||
/* reg_off is the offset into unsigned long kvm_isa_ext_arr[] */
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_ISA_EXT);
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT);
|
||||
|
||||
static const char * const kvm_isa_ext_reg_name[] = {
|
||||
"KVM_RISCV_ISA_EXT_A",
|
||||
"KVM_RISCV_ISA_EXT_C",
|
||||
"KVM_RISCV_ISA_EXT_D",
|
||||
"KVM_RISCV_ISA_EXT_F",
|
||||
"KVM_RISCV_ISA_EXT_H",
|
||||
"KVM_RISCV_ISA_EXT_I",
|
||||
"KVM_RISCV_ISA_EXT_M",
|
||||
"KVM_RISCV_ISA_EXT_SVPBMT",
|
||||
"KVM_RISCV_ISA_EXT_SSTC",
|
||||
"KVM_RISCV_ISA_EXT_SVINVAL",
|
||||
"KVM_RISCV_ISA_EXT_ZIHINTPAUSE",
|
||||
"KVM_RISCV_ISA_EXT_ZICBOM",
|
||||
"KVM_RISCV_ISA_EXT_ZICBOZ",
|
||||
"KVM_RISCV_ISA_EXT_ZBB",
|
||||
"KVM_RISCV_ISA_EXT_SSAIA",
|
||||
"KVM_RISCV_ISA_EXT_V",
|
||||
"KVM_RISCV_ISA_EXT_SVNAPOT",
|
||||
"KVM_RISCV_ISA_EXT_ZBA",
|
||||
"KVM_RISCV_ISA_EXT_ZBS",
|
||||
"KVM_RISCV_ISA_EXT_ZICNTR",
|
||||
"KVM_RISCV_ISA_EXT_ZICSR",
|
||||
"KVM_RISCV_ISA_EXT_ZIFENCEI",
|
||||
"KVM_RISCV_ISA_EXT_ZIHPM",
|
||||
KVM_ISA_EXT_ARR(A),
|
||||
KVM_ISA_EXT_ARR(C),
|
||||
KVM_ISA_EXT_ARR(D),
|
||||
KVM_ISA_EXT_ARR(F),
|
||||
KVM_ISA_EXT_ARR(H),
|
||||
KVM_ISA_EXT_ARR(I),
|
||||
KVM_ISA_EXT_ARR(M),
|
||||
KVM_ISA_EXT_ARR(V),
|
||||
KVM_ISA_EXT_ARR(SMSTATEEN),
|
||||
KVM_ISA_EXT_ARR(SSAIA),
|
||||
KVM_ISA_EXT_ARR(SSTC),
|
||||
KVM_ISA_EXT_ARR(SVINVAL),
|
||||
KVM_ISA_EXT_ARR(SVNAPOT),
|
||||
KVM_ISA_EXT_ARR(SVPBMT),
|
||||
KVM_ISA_EXT_ARR(ZBA),
|
||||
KVM_ISA_EXT_ARR(ZBB),
|
||||
KVM_ISA_EXT_ARR(ZBS),
|
||||
KVM_ISA_EXT_ARR(ZICBOM),
|
||||
KVM_ISA_EXT_ARR(ZICBOZ),
|
||||
KVM_ISA_EXT_ARR(ZICNTR),
|
||||
KVM_ISA_EXT_ARR(ZICOND),
|
||||
KVM_ISA_EXT_ARR(ZICSR),
|
||||
KVM_ISA_EXT_ARR(ZIFENCEI),
|
||||
KVM_ISA_EXT_ARR(ZIHINTPAUSE),
|
||||
KVM_ISA_EXT_ARR(ZIHPM),
|
||||
};
|
||||
|
||||
if (reg_off >= ARRAY_SIZE(kvm_isa_ext_reg_name)) {
|
||||
/*
|
||||
* isa_ext regs would grow regularly with new isa extension added, so
|
||||
* just show "reg" to indicate a new extension.
|
||||
*/
|
||||
if (reg_off >= ARRAY_SIZE(kvm_isa_ext_reg_name))
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
return kvm_isa_ext_reg_name[reg_off];
|
||||
}
|
||||
|
||||
#define KVM_SBI_EXT_ARR(ext) \
|
||||
[ext] = "KVM_REG_RISCV_SBI_SINGLE | " #ext
|
||||
|
||||
static const char *sbi_ext_single_id_to_str(__u64 reg_off)
|
||||
{
|
||||
/* reg_off is KVM_RISCV_SBI_EXT_ID */
|
||||
static const char * const kvm_sbi_ext_reg_name[] = {
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_V01",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_TIME",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_IPI",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_RFENCE",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_SRST",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_HSM",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL",
|
||||
"KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR",
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_V01),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_TIME),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_IPI),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_RFENCE),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_SRST),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_HSM),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR),
|
||||
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN),
|
||||
};
|
||||
|
||||
if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) {
|
||||
/*
|
||||
* sbi_ext regs would grow regularly with new sbi extension added, so
|
||||
* just show "reg" to indicate a new extension.
|
||||
*/
|
||||
if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name))
|
||||
return strdup_printf("KVM_REG_RISCV_SBI_SINGLE | %lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
|
||||
return kvm_sbi_ext_reg_name[reg_off];
|
||||
}
|
||||
|
||||
static const char *sbi_ext_multi_id_to_str(__u64 reg_subtype, __u64 reg_off)
|
||||
{
|
||||
if (reg_off > KVM_REG_RISCV_SBI_MULTI_REG_LAST) {
|
||||
/*
|
||||
* sbi_ext regs would grow regularly with new sbi extension added, so
|
||||
* just show "reg" to indicate a new extension.
|
||||
*/
|
||||
return strdup_printf("%lld /* UNKNOWN */", reg_off);
|
||||
}
|
||||
const char *unknown = "";
|
||||
|
||||
if (reg_off > KVM_REG_RISCV_SBI_MULTI_REG_LAST)
|
||||
unknown = " /* UNKNOWN */";
|
||||
|
||||
switch (reg_subtype) {
|
||||
case KVM_REG_RISCV_SBI_MULTI_EN:
|
||||
return strdup_printf("KVM_REG_RISCV_SBI_MULTI_EN | %lld", reg_off);
|
||||
return strdup_printf("KVM_REG_RISCV_SBI_MULTI_EN | %lld%s", reg_off, unknown);
|
||||
case KVM_REG_RISCV_SBI_MULTI_DIS:
|
||||
return strdup_printf("KVM_REG_RISCV_SBI_MULTI_DIS | %lld", reg_off);
|
||||
return strdup_printf("KVM_REG_RISCV_SBI_MULTI_DIS | %lld%s", reg_off, unknown);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off);
|
||||
}
|
||||
|
||||
static const char *sbi_ext_id_to_str(const char *prefix, __u64 id)
|
||||
@ -404,6 +425,8 @@ static const char *sbi_ext_id_to_str(const char *prefix, __u64 id)
|
||||
__u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_SBI_EXT);
|
||||
__u64 reg_subtype = reg_off & KVM_REG_RISCV_SUBTYPE_MASK;
|
||||
|
||||
assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_EXT);
|
||||
|
||||
reg_off &= ~KVM_REG_RISCV_SUBTYPE_MASK;
|
||||
|
||||
switch (reg_subtype) {
|
||||
@ -414,8 +437,7 @@ static const char *sbi_ext_id_to_str(const char *prefix, __u64 id)
|
||||
return sbi_ext_multi_id_to_str(reg_subtype, reg_off);
|
||||
}
|
||||
|
||||
TEST_FAIL("%s: Unknown sbi ext subtype: 0x%llx", prefix, reg_subtype);
|
||||
return NULL;
|
||||
return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off);
|
||||
}
|
||||
|
||||
void print_reg(const char *prefix, __u64 id)
|
||||
@ -436,14 +458,14 @@ void print_reg(const char *prefix, __u64 id)
|
||||
reg_size = "KVM_REG_SIZE_U128";
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL("%s: Unexpected reg size: 0x%llx in reg id: 0x%llx",
|
||||
prefix, (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id);
|
||||
printf("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,",
|
||||
(id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id & REG_MASK);
|
||||
}
|
||||
|
||||
switch (id & KVM_REG_RISCV_TYPE_MASK) {
|
||||
case KVM_REG_RISCV_CONFIG:
|
||||
printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_CONFIG | %s,\n",
|
||||
reg_size, config_id_to_str(id));
|
||||
reg_size, config_id_to_str(prefix, id));
|
||||
break;
|
||||
case KVM_REG_RISCV_CORE:
|
||||
printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_CORE | %s,\n",
|
||||
@ -467,15 +489,15 @@ void print_reg(const char *prefix, __u64 id)
|
||||
break;
|
||||
case KVM_REG_RISCV_ISA_EXT:
|
||||
printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n",
|
||||
reg_size, isa_ext_id_to_str(id));
|
||||
reg_size, isa_ext_id_to_str(prefix, id));
|
||||
break;
|
||||
case KVM_REG_RISCV_SBI_EXT:
|
||||
printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_SBI_EXT | %s,\n",
|
||||
reg_size, sbi_ext_id_to_str(prefix, id));
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL("%s: Unexpected reg type: 0x%llx in reg id: 0x%llx", prefix,
|
||||
(id & KVM_REG_RISCV_TYPE_MASK) >> KVM_REG_RISCV_TYPE_SHIFT, id);
|
||||
printf("\tKVM_REG_RISCV | %s | 0x%llx /* UNKNOWN */,",
|
||||
reg_size, id & REG_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,6 +554,7 @@ static __u64 base_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(sip),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(satp),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(scounteren),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(senvcfg),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(frequency),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(time),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(compare),
|
||||
@ -545,6 +568,7 @@ static __u64 base_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU,
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL,
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR,
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN,
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_EN | 0,
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_DIS | 0,
|
||||
};
|
||||
@ -603,6 +627,10 @@ static __u64 zicntr_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR,
|
||||
};
|
||||
|
||||
static __u64 zicond_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICOND,
|
||||
};
|
||||
|
||||
static __u64 zicsr_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICSR,
|
||||
};
|
||||
@ -626,6 +654,11 @@ static __u64 aia_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA,
|
||||
};
|
||||
|
||||
static __u64 smstateen_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_SMSTATEEN | KVM_REG_RISCV_CSR_SMSTATEEN_REG(sstateen0),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SMSTATEEN,
|
||||
};
|
||||
|
||||
static __u64 fp_f_regs[] = {
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_U32 | KVM_REG_RISCV_FP_F | KVM_REG_RISCV_FP_F_REG(f[0]),
|
||||
KVM_REG_RISCV | KVM_REG_SIZE_U32 | KVM_REG_RISCV_FP_F | KVM_REG_RISCV_FP_F_REG(f[1]),
|
||||
@ -725,6 +758,8 @@ static __u64 fp_d_regs[] = {
|
||||
{"zbs", .feature = KVM_RISCV_ISA_EXT_ZBS, .regs = zbs_regs, .regs_n = ARRAY_SIZE(zbs_regs),}
|
||||
#define ZICNTR_REGS_SUBLIST \
|
||||
{"zicntr", .feature = KVM_RISCV_ISA_EXT_ZICNTR, .regs = zicntr_regs, .regs_n = ARRAY_SIZE(zicntr_regs),}
|
||||
#define ZICOND_REGS_SUBLIST \
|
||||
{"zicond", .feature = KVM_RISCV_ISA_EXT_ZICOND, .regs = zicond_regs, .regs_n = ARRAY_SIZE(zicond_regs),}
|
||||
#define ZICSR_REGS_SUBLIST \
|
||||
{"zicsr", .feature = KVM_RISCV_ISA_EXT_ZICSR, .regs = zicsr_regs, .regs_n = ARRAY_SIZE(zicsr_regs),}
|
||||
#define ZIFENCEI_REGS_SUBLIST \
|
||||
@ -733,6 +768,8 @@ static __u64 fp_d_regs[] = {
|
||||
{"zihpm", .feature = KVM_RISCV_ISA_EXT_ZIHPM, .regs = zihpm_regs, .regs_n = ARRAY_SIZE(zihpm_regs),}
|
||||
#define AIA_REGS_SUBLIST \
|
||||
{"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),}
|
||||
#define SMSTATEEN_REGS_SUBLIST \
|
||||
{"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),}
|
||||
#define FP_F_REGS_SUBLIST \
|
||||
{"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \
|
||||
.regs_n = ARRAY_SIZE(fp_f_regs),}
|
||||
@ -828,6 +865,14 @@ static struct vcpu_reg_list zicntr_config = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct vcpu_reg_list zicond_config = {
|
||||
.sublists = {
|
||||
BASE_SUBLIST,
|
||||
ZICOND_REGS_SUBLIST,
|
||||
{0},
|
||||
},
|
||||
};
|
||||
|
||||
static struct vcpu_reg_list zicsr_config = {
|
||||
.sublists = {
|
||||
BASE_SUBLIST,
|
||||
@ -860,6 +905,14 @@ static struct vcpu_reg_list aia_config = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct vcpu_reg_list smstateen_config = {
|
||||
.sublists = {
|
||||
BASE_SUBLIST,
|
||||
SMSTATEEN_REGS_SUBLIST,
|
||||
{0},
|
||||
},
|
||||
};
|
||||
|
||||
static struct vcpu_reg_list fp_f_config = {
|
||||
.sublists = {
|
||||
BASE_SUBLIST,
|
||||
@ -888,10 +941,12 @@ struct vcpu_reg_list *vcpu_configs[] = {
|
||||
&zbb_config,
|
||||
&zbs_config,
|
||||
&zicntr_config,
|
||||
&zicond_config,
|
||||
&zicsr_config,
|
||||
&zifencei_config,
|
||||
&zihpm_config,
|
||||
&aia_config,
|
||||
&smstateen_config,
|
||||
&fp_f_config,
|
||||
&fp_d_config,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user