Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
330f434
KVM: riscv: selftests: Add senvcfg register to get-reg-list test
avpatel Sep 15, 2023
faa2ece
KVM: riscv: selftests: Add smstateen registers to get-reg-list test
avpatel Sep 15, 2023
08573b1
KVM: riscv: selftests: Add condops extensions to get-reg-list test
avpatel Sep 15, 2023
3da0a2c
KVM: riscv: selftests: Fix get-reg-list print_reg defaults
Dec 7, 2023
7f4989d
KVM: riscv: selftests: Drop SBI multi registers
Dec 13, 2023
3eae978
KVM: riscv: selftests: Use register subtypes
Dec 13, 2023
2cadb7f
RISC-V: KVM: selftests: Treat SBI ext regs like ISA ext regs
Dec 13, 2023
ae70009
KVM: riscv: selftests: Add Zbc extension to get-reg-list test
avpatel Nov 27, 2023
136c8cc
KVM: riscv: selftests: Add scaler crypto extensions to get-reg-list test
avpatel Nov 27, 2023
4ed8335
KVM: riscv: selftests: Add vector crypto extensions to get-reg-list test
avpatel Nov 27, 2023
c4846ce
KVM: riscv: selftests: Add Zfh[min] extensions to get-reg-list test
avpatel Nov 27, 2023
9b1fac7
KVM: riscv: selftests: Add Zihintntl extension to get-reg-list test
avpatel Nov 27, 2023
0bff81c
KVM: riscv: selftests: Add Zvfh[min] extensions to get-reg-list test
avpatel Nov 27, 2023
3441565
KVM: riscv: selftests: Add Zfa extension to get-reg-list test
avpatel Nov 27, 2023
aea0109
KVM: selftests: riscv: Remove redundant newlines
Dec 6, 2023
27067da
KVM: riscv: selftests: complete backport for change vcpu_has_ext
uestc-gr Jan 22, 2024
170cc0f
KVM: riscv: selftests: Add Ztso extension to get-reg-list test
avpatel Feb 13, 2024
e724c93
KVM: riscv: selftests: Add Zacas extension to get-reg-list test
avpatel Feb 13, 2024
103b4c8
KVM: riscv: selftests: Add Zimop extension to get-reg-list test
clementleger Jun 19, 2024
7d89380
KVM: riscv: selftests: Add some Zc* extensions to get-reg-list test
clementleger Jun 19, 2024
60d37bc
KVM: riscv: selftests: Add Zawrs extension to get-reg-list test
Apr 26, 2024
ba0a39e
KVM: riscv: selftests: Fix compile error
yong-xuan Jul 26, 2024
cece69c
KVM: riscv: selftests: Add Svade and Svadu Extension to get-reg-list …
yong-xuan Jul 26, 2024
a640794
KVM: riscv: selftests: Add Svvptc/Zabha/Ziccrse exts to get-reg-list …
zcxGGmu Dec 2, 2024
5c97d56
KVM: riscv: selftests: Add Zaamo/Zalrsc extensions to get-reg-list test
clementleger Jun 19, 2024
3f893d5
KVM: riscv: selftests: Add bfloat16 extension to get-reg-list test
zcxGGmu Aug 8, 2025
9542401
KVM: riscv: selftests: Add Zcmop extension to get-reg-list test
clementleger Jun 19, 2024
ea3b0ed
RISC-V: KVM: selftests: Add Zalasr extensions to get-reg-list test
luxukernel Oct 20, 2025
81b24d2
RISC-V: KVM: Fix inclusion of Smnpm in the guest ISA bitmap
SiFiveHolland Jan 11, 2025
4ff4b2f
RISC-V: KVM: Add support for SBI_FWFT_POINTER_MASKING_PMLEN
SiFiveHolland Jan 11, 2025
80bb4db
RISC-V: KVM: Set initial value of hedeleg in kvm_arch_vcpu_create()
avpatel Aug 23, 2025
28d7655
RISC-V: KVM: Introduce feature specific reset for SBI FWFT
avpatel Aug 23, 2025
f20cbda
RISC-V: KVM: Introduce optional ONE_REG callbacks for SBI extensions
avpatel Aug 23, 2025
889ac66
RISC-V: KVM: Move copy_sbi_ext_reg_indices() to SBI implementation
avpatel Aug 23, 2025
c4f95e9
RISC-V: KVM: Implement ONE_REG interface for SBI FWFT state
avpatel Aug 23, 2025
96178e9
KVM: riscv: selftests: Add SBI FWFT to get-reg-list test
avpatel Aug 23, 2025
2f31c8a
KVM: RISC-V: SBI FWFT: Mark vCPU CSRs dirty after setting feature value
yong-xuan Jun 1, 2026
5bafc11
KVM: RISC-V: SBI FWFT: Add optional init() callback for hardware probing
yong-xuan Jun 1, 2026
4413259
KVM: RISC-V: SBI FWFT: Fix stale feature exposure after runtime exten…
yong-xuan Jun 1, 2026
f93a147
KVM: selftests: Return a value from vcpu_get_reg() instead of using a…
sean-jc Nov 28, 2024
a1e21d9
KVM: riscv: selftests: Align the trap information wiht pt_regs
atishp04 Apr 30, 2025
0803d49
KVM: riscv: selftests: Decode stval to identify exact exception type
atishp04 Apr 30, 2025
4ffd2fa
KVM: riscv: selftests: Add vector extension tests
atishp04 Apr 30, 2025
c8d5b18
KVM: riscv: selftests: Refactor ISA and SBI extension sublist macros
yong-xuan Jun 1, 2026
da85bc0
KVM: riscv: selftests: Split SBI FWFT into separate feature-specific …
yong-xuan Jun 1, 2026
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
22 changes: 12 additions & 10 deletions arch/riscv/include/asm/kvm_vcpu_sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,34 +59,36 @@ struct kvm_vcpu_sbi_extension {
void (*deinit)(struct kvm_vcpu *vcpu);

void (*reset)(struct kvm_vcpu *vcpu);

unsigned long state_reg_subtype;
unsigned long (*get_state_reg_count)(struct kvm_vcpu *vcpu);
int (*get_state_reg_id)(struct kvm_vcpu *vcpu, int index, u64 *reg_id);
int (*get_state_reg)(struct kvm_vcpu *vcpu, unsigned long reg_num,
unsigned long reg_size, void *reg_val);
int (*set_state_reg)(struct kvm_vcpu *vcpu, unsigned long reg_num,
unsigned long reg_size, const void *reg_val);
};

void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run);
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
struct kvm_run *run,
u32 type, u64 flags);
int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run);
int kvm_riscv_vcpu_reg_indices_sbi_ext(struct kvm_vcpu *vcpu, u64 __user *uindices);
int kvm_riscv_vcpu_set_reg_sbi_ext(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg);
int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg);
int kvm_riscv_vcpu_set_reg_sbi(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg);
int kvm_riscv_vcpu_get_reg_sbi(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg);
int kvm_riscv_vcpu_reg_indices_sbi(struct kvm_vcpu *vcpu, u64 __user *uindices);
int kvm_riscv_vcpu_set_reg_sbi(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
int kvm_riscv_vcpu_get_reg_sbi(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(
struct kvm_vcpu *vcpu, unsigned long extid);
bool riscv_vcpu_supports_sbi_ext(struct kvm_vcpu *vcpu, int idx);
int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run);
void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_sbi_deinit(struct kvm_vcpu *vcpu);
void kvm_riscv_vcpu_sbi_reset(struct kvm_vcpu *vcpu);

int kvm_riscv_vcpu_get_reg_sbi_sta(struct kvm_vcpu *vcpu, unsigned long reg_num,
unsigned long *reg_val);
int kvm_riscv_vcpu_set_reg_sbi_sta(struct kvm_vcpu *vcpu, unsigned long reg_num,
unsigned long reg_val);

#ifdef CONFIG_RISCV_SBI_V01
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01;
#endif
Expand Down
5 changes: 5 additions & 0 deletions arch/riscv/include/asm/kvm_vcpu_sbi_fwft.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ struct kvm_sbi_fwft_feature;
struct kvm_sbi_fwft_config {
const struct kvm_sbi_fwft_feature *feature;
bool supported;
bool enabled;
unsigned long flags;
};

/* FWFT data structure per vcpu */
struct kvm_sbi_fwft {
struct kvm_sbi_fwft_config *configs;
#ifndef CONFIG_32BIT
bool have_vs_pmlen_7;
bool have_vs_pmlen_16;
#endif
};

#define vcpu_to_fwft(vcpu) (&(vcpu)->arch.fwft_context)
Expand Down
15 changes: 15 additions & 0 deletions arch/riscv/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ struct kvm_riscv_sbi_sta {
unsigned long shmem_hi;
};

struct kvm_riscv_sbi_fwft_feature {
unsigned long enable;
unsigned long flags;
unsigned long value;
};

/* SBI FWFT extension registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
struct kvm_riscv_sbi_fwft {
struct kvm_riscv_sbi_fwft_feature misaligned_deleg;
struct kvm_riscv_sbi_fwft_feature pointer_masking;
};

/* Possible states for kvm_riscv_timer */
#define KVM_RISCV_TIMER_STATE_OFF 0
#define KVM_RISCV_TIMER_STATE_ON 1
Expand Down Expand Up @@ -309,6 +321,9 @@ struct kvm_riscv_sbi_sta {
#define KVM_REG_RISCV_SBI_STA (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
#define KVM_REG_RISCV_SBI_STA_REG(name) \
(offsetof(struct kvm_riscv_sbi_sta, name) / sizeof(unsigned long))
#define KVM_REG_RISCV_SBI_FWFT (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
#define KVM_REG_RISCV_SBI_FWFT_REG(name) \
(offsetof(struct kvm_riscv_sbi_fwft, name) / sizeof(unsigned long))

/* Device Control API: RISC-V AIA */
#define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
Expand Down
3 changes: 2 additions & 1 deletion arch/riscv/kvm/vcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)

/* Mark this VCPU never ran */
vcpu->arch.ran_atleast_once = false;

vcpu->arch.cfg.hedeleg = KVM_HEDELEG_DEFAULT;
vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
bitmap_zero(vcpu->arch.isa, RISCV_ISA_EXT_MAX);

Expand Down Expand Up @@ -606,7 +608,6 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu)
cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0;
}

cfg->hedeleg = KVM_HEDELEG_DEFAULT;
if (vcpu->guest_debug)
cfg->hedeleg &= ~BIT(EXC_BREAKPOINT);
}
Expand Down
144 changes: 57 additions & 87 deletions arch/riscv/kvm/vcpu_onereg.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define KVM_ISA_EXT_ARR(ext) \
[KVM_RISCV_ISA_EXT_##ext] = RISCV_ISA_EXT_##ext

/* Mapping between KVM ISA Extension ID & Host ISA extension ID */
/* Mapping between KVM ISA Extension ID & guest ISA extension ID */
static const unsigned long kvm_isa_ext_arr[] = {
/* Single letter extensions (alphabetically sorted) */
[KVM_RISCV_ISA_EXT_A] = RISCV_ISA_EXT_a,
Expand All @@ -35,7 +35,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_RISCV_ISA_EXT_SMNPM] = RISCV_ISA_EXT_SSNPM,
KVM_ISA_EXT_ARR(SMNPM),
KVM_ISA_EXT_ARR(SMSTATEEN),
KVM_ISA_EXT_ARR(SSAIA),
KVM_ISA_EXT_ARR(SSNPM),
Expand Down Expand Up @@ -119,6 +119,36 @@ static unsigned long kvm_riscv_vcpu_base2isa_ext(unsigned long base_ext)
return KVM_RISCV_ISA_EXT_MAX;
}

static int kvm_riscv_vcpu_isa_check_host(unsigned long kvm_ext, unsigned long *guest_ext)
{
unsigned long host_ext;

if (kvm_ext >= KVM_RISCV_ISA_EXT_MAX ||
kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr))
return -ENOENT;

*guest_ext = kvm_isa_ext_arr[kvm_ext];
switch (*guest_ext) {
case RISCV_ISA_EXT_SMNPM:
/*
* Pointer masking effective in (H)S-mode is provided by the
* Smnpm extension, so that extension is reported to the guest,
* even though the CSR bits for configuring VS-mode pointer
* masking on the host side are part of the Ssnpm extension.
*/
host_ext = RISCV_ISA_EXT_SSNPM;
break;
default:
host_ext = *guest_ext;
break;
}

if (!__riscv_isa_extension_available(NULL, host_ext))
return -ENOENT;

return 0;
}

static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
{
switch (ext) {
Expand Down Expand Up @@ -150,7 +180,6 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_C:
case KVM_RISCV_ISA_EXT_I:
case KVM_RISCV_ISA_EXT_M:
case KVM_RISCV_ISA_EXT_SMNPM:
case KVM_RISCV_ISA_EXT_SSNPM:
/* There is not architectural config bit to disable sscofpmf completely */
case KVM_RISCV_ISA_EXT_SSCOFPMF:
Expand Down Expand Up @@ -231,13 +260,13 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)

void kvm_riscv_vcpu_setup_isa(struct kvm_vcpu *vcpu)
{
unsigned long host_isa, i;
unsigned long guest_ext, i;

for (i = 0; i < ARRAY_SIZE(kvm_isa_ext_arr); i++) {
host_isa = kvm_isa_ext_arr[i];
if (__riscv_isa_extension_available(NULL, host_isa) &&
kvm_riscv_vcpu_isa_enable_allowed(i))
set_bit(host_isa, vcpu->arch.isa);
if (kvm_riscv_vcpu_isa_check_host(i, &guest_ext))
continue;
if (kvm_riscv_vcpu_isa_enable_allowed(i))
set_bit(guest_ext, vcpu->arch.isa);
}
}

Expand Down Expand Up @@ -636,18 +665,15 @@ static int riscv_vcpu_get_isa_ext_single(struct kvm_vcpu *vcpu,
unsigned long reg_num,
unsigned long *reg_val)
{
unsigned long host_isa_ext;

if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
return -ENOENT;
unsigned long guest_ext;
int ret;

host_isa_ext = kvm_isa_ext_arr[reg_num];
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
return -ENOENT;
ret = kvm_riscv_vcpu_isa_check_host(reg_num, &guest_ext);
if (ret)
return ret;

*reg_val = 0;
if (__riscv_isa_extension_available(vcpu->arch.isa, host_isa_ext))
if (__riscv_isa_extension_available(vcpu->arch.isa, guest_ext))
*reg_val = 1; /* Mark the given extension as available */

return 0;
Expand All @@ -657,17 +683,14 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
unsigned long reg_num,
unsigned long reg_val)
{
unsigned long host_isa_ext;

if (reg_num >= KVM_RISCV_ISA_EXT_MAX ||
reg_num >= ARRAY_SIZE(kvm_isa_ext_arr))
return -ENOENT;
unsigned long guest_ext;
int ret;

host_isa_ext = kvm_isa_ext_arr[reg_num];
if (!__riscv_isa_extension_available(NULL, host_isa_ext))
return -ENOENT;
ret = kvm_riscv_vcpu_isa_check_host(reg_num, &guest_ext);
if (ret)
return ret;

if (reg_val == test_bit(host_isa_ext, vcpu->arch.isa))
if (reg_val == test_bit(guest_ext, vcpu->arch.isa))
return 0;

if (!vcpu->arch.ran_atleast_once) {
Expand All @@ -677,10 +700,10 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
*/
if (reg_val == 1 &&
kvm_riscv_vcpu_isa_enable_allowed(reg_num))
set_bit(host_isa_ext, vcpu->arch.isa);
set_bit(guest_ext, vcpu->arch.isa);
else if (!reg_val &&
kvm_riscv_vcpu_isa_disable_allowed(reg_num))
clear_bit(host_isa_ext, vcpu->arch.isa);
clear_bit(guest_ext, vcpu->arch.isa);
else
return -EINVAL;
kvm_riscv_vcpu_fp_reset(vcpu);
Expand Down Expand Up @@ -1041,16 +1064,15 @@ static int copy_fp_d_reg_indices(const struct kvm_vcpu *vcpu,
static int copy_isa_ext_reg_indices(const struct kvm_vcpu *vcpu,
u64 __user *uindices)
{
unsigned long guest_ext;
unsigned int n = 0;
unsigned long isa_ext;

for (int i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) {
u64 size = IS_ENABLED(CONFIG_32BIT) ?
KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64;
u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_ISA_EXT | i;

isa_ext = kvm_isa_ext_arr[i];
if (!__riscv_isa_extension_available(NULL, isa_ext))
if (kvm_riscv_vcpu_isa_check_host(i, &guest_ext))
continue;

if (uindices) {
Expand All @@ -1070,66 +1092,14 @@ static inline unsigned long num_isa_ext_regs(const struct kvm_vcpu *vcpu)
return copy_isa_ext_reg_indices(vcpu, NULL);;
}

static int copy_sbi_ext_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
unsigned int n = 0;

for (int i = 0; i < KVM_RISCV_SBI_EXT_MAX; i++) {
u64 size = IS_ENABLED(CONFIG_32BIT) ?
KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64;
u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_SBI_EXT |
KVM_REG_RISCV_SBI_SINGLE | i;

if (!riscv_vcpu_supports_sbi_ext(vcpu, i))
continue;

if (uindices) {
if (put_user(reg, uindices))
return -EFAULT;
uindices++;
}

n++;
}

return n;
}

static unsigned long num_sbi_ext_regs(struct kvm_vcpu *vcpu)
{
return copy_sbi_ext_reg_indices(vcpu, NULL);
}

static int copy_sbi_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
int total = 0;

if (scontext->ext_status[KVM_RISCV_SBI_EXT_STA] == KVM_RISCV_SBI_EXT_STATUS_ENABLED) {
u64 size = IS_ENABLED(CONFIG_32BIT) ? KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64;
int n = sizeof(struct kvm_riscv_sbi_sta) / sizeof(unsigned long);

for (int i = 0; i < n; i++) {
u64 reg = KVM_REG_RISCV | size |
KVM_REG_RISCV_SBI_STATE |
KVM_REG_RISCV_SBI_STA | i;

if (uindices) {
if (put_user(reg, uindices))
return -EFAULT;
uindices++;
}
}

total += n;
}

return total;
return kvm_riscv_vcpu_reg_indices_sbi_ext(vcpu, NULL);
}

static inline unsigned long num_sbi_regs(struct kvm_vcpu *vcpu)
{
return copy_sbi_reg_indices(vcpu, NULL);
return kvm_riscv_vcpu_reg_indices_sbi(vcpu, NULL);
}

static inline unsigned long num_vector_regs(const struct kvm_vcpu *vcpu)
Expand Down Expand Up @@ -1252,12 +1222,12 @@ int kvm_riscv_vcpu_copy_reg_indices(struct kvm_vcpu *vcpu,
return ret;
uindices += ret;

ret = copy_sbi_ext_reg_indices(vcpu, uindices);
ret = kvm_riscv_vcpu_reg_indices_sbi_ext(vcpu, uindices);
if (ret < 0)
return ret;
uindices += ret;

ret = copy_sbi_reg_indices(vcpu, uindices);
ret = kvm_riscv_vcpu_reg_indices_sbi(vcpu, uindices);
if (ret < 0)
return ret;
uindices += ret;
Expand Down
Loading
Loading