Skip to content

Commit 43f640f

Browse files
committed
Merge tag 'kvm-riscv-6.14-1' of https://github.com/kvm-riscv/linux into HEAD
KVM/riscv changes for 6.14 - Svvptc, Zabha, and Ziccrse extension support for Guest/VM - Virtualize SBI system suspend extension for Guest/VM - Trap related exit statstics as SBI PMU firmware counters for Guest/VM
2 parents 4f7ff70 + af79caa commit 43f640f

File tree

10 files changed

+150
-6
lines changed

10 files changed

+150
-6
lines changed

arch/riscv/include/asm/kvm_host.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ struct kvm_vcpu_stat {
8787
u64 csr_exit_kernel;
8888
u64 signal_exits;
8989
u64 exits;
90+
u64 instr_illegal_exits;
91+
u64 load_misaligned_exits;
92+
u64 store_misaligned_exits;
93+
u64 load_access_exits;
94+
u64 store_access_exits;
9095
};
9196

9297
struct kvm_arch_memory_slot {

arch/riscv/include/asm/kvm_vcpu_sbi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence;
8585
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst;
8686
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm;
8787
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn;
88+
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_susp;
8889
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_sta;
8990
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
9091
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;

arch/riscv/include/uapi/asm/kvm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ enum KVM_RISCV_ISA_EXT_ID {
179179
KVM_RISCV_ISA_EXT_SSNPM,
180180
KVM_RISCV_ISA_EXT_SVADE,
181181
KVM_RISCV_ISA_EXT_SVADU,
182+
KVM_RISCV_ISA_EXT_SVVPTC,
183+
KVM_RISCV_ISA_EXT_ZABHA,
184+
KVM_RISCV_ISA_EXT_ZICCRSE,
182185
KVM_RISCV_ISA_EXT_MAX,
183186
};
184187

@@ -198,6 +201,7 @@ enum KVM_RISCV_SBI_EXT_ID {
198201
KVM_RISCV_SBI_EXT_VENDOR,
199202
KVM_RISCV_SBI_EXT_DBCN,
200203
KVM_RISCV_SBI_EXT_STA,
204+
KVM_RISCV_SBI_EXT_SUSP,
201205
KVM_RISCV_SBI_EXT_MAX,
202206
};
203207

arch/riscv/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ kvm-y += vcpu_sbi_hsm.o
3030
kvm-$(CONFIG_RISCV_PMU_SBI) += vcpu_sbi_pmu.o
3131
kvm-y += vcpu_sbi_replace.o
3232
kvm-y += vcpu_sbi_sta.o
33+
kvm-y += vcpu_sbi_system.o
3334
kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o
3435
kvm-y += vcpu_switch.o
3536
kvm-y += vcpu_timer.o

arch/riscv/kvm/vcpu.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
3434
STATS_DESC_COUNTER(VCPU, csr_exit_user),
3535
STATS_DESC_COUNTER(VCPU, csr_exit_kernel),
3636
STATS_DESC_COUNTER(VCPU, signal_exits),
37-
STATS_DESC_COUNTER(VCPU, exits)
37+
STATS_DESC_COUNTER(VCPU, exits),
38+
STATS_DESC_COUNTER(VCPU, instr_illegal_exits),
39+
STATS_DESC_COUNTER(VCPU, load_misaligned_exits),
40+
STATS_DESC_COUNTER(VCPU, store_misaligned_exits),
41+
STATS_DESC_COUNTER(VCPU, load_access_exits),
42+
STATS_DESC_COUNTER(VCPU, store_access_exits),
3843
};
3944

4045
const struct kvm_stats_header kvm_vcpu_stats_header = {

arch/riscv/kvm/vcpu_exit.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu,
165165
vcpu->arch.guest_context.sstatus |= SR_SPP;
166166
}
167167

168+
static inline int vcpu_redirect(struct kvm_vcpu *vcpu, struct kvm_cpu_trap *trap)
169+
{
170+
int ret = -EFAULT;
171+
172+
if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) {
173+
kvm_riscv_vcpu_trap_redirect(vcpu, trap);
174+
ret = 1;
175+
}
176+
return ret;
177+
}
178+
168179
/*
169180
* Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
170181
* proper exit to userspace.
@@ -183,14 +194,32 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
183194
run->exit_reason = KVM_EXIT_UNKNOWN;
184195
switch (trap->scause) {
185196
case EXC_INST_ILLEGAL:
197+
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ILLEGAL_INSN);
198+
vcpu->stat.instr_illegal_exits++;
199+
ret = vcpu_redirect(vcpu, trap);
200+
break;
186201
case EXC_LOAD_MISALIGNED:
202+
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_MISALIGNED_LOAD);
203+
vcpu->stat.load_misaligned_exits++;
204+
ret = vcpu_redirect(vcpu, trap);
205+
break;
187206
case EXC_STORE_MISALIGNED:
207+
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_MISALIGNED_STORE);
208+
vcpu->stat.store_misaligned_exits++;
209+
ret = vcpu_redirect(vcpu, trap);
210+
break;
188211
case EXC_LOAD_ACCESS:
212+
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ACCESS_LOAD);
213+
vcpu->stat.load_access_exits++;
214+
ret = vcpu_redirect(vcpu, trap);
215+
break;
189216
case EXC_STORE_ACCESS:
190-
if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) {
191-
kvm_riscv_vcpu_trap_redirect(vcpu, trap);
192-
ret = 1;
193-
}
217+
kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_ACCESS_STORE);
218+
vcpu->stat.store_access_exits++;
219+
ret = vcpu_redirect(vcpu, trap);
220+
break;
221+
case EXC_INST_ACCESS:
222+
ret = vcpu_redirect(vcpu, trap);
194223
break;
195224
case EXC_VIRTUAL_INST_FAULT:
196225
if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV)

arch/riscv/kvm/vcpu_onereg.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static const unsigned long kvm_isa_ext_arr[] = {
4646
KVM_ISA_EXT_ARR(SVINVAL),
4747
KVM_ISA_EXT_ARR(SVNAPOT),
4848
KVM_ISA_EXT_ARR(SVPBMT),
49+
KVM_ISA_EXT_ARR(SVVPTC),
50+
KVM_ISA_EXT_ARR(ZABHA),
4951
KVM_ISA_EXT_ARR(ZACAS),
5052
KVM_ISA_EXT_ARR(ZAWRS),
5153
KVM_ISA_EXT_ARR(ZBA),
@@ -65,6 +67,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
6567
KVM_ISA_EXT_ARR(ZFHMIN),
6668
KVM_ISA_EXT_ARR(ZICBOM),
6769
KVM_ISA_EXT_ARR(ZICBOZ),
70+
KVM_ISA_EXT_ARR(ZICCRSE),
6871
KVM_ISA_EXT_ARR(ZICNTR),
6972
KVM_ISA_EXT_ARR(ZICOND),
7073
KVM_ISA_EXT_ARR(ZICSR),
@@ -145,6 +148,8 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
145148
case KVM_RISCV_ISA_EXT_SSTC:
146149
case KVM_RISCV_ISA_EXT_SVINVAL:
147150
case KVM_RISCV_ISA_EXT_SVNAPOT:
151+
case KVM_RISCV_ISA_EXT_SVVPTC:
152+
case KVM_RISCV_ISA_EXT_ZABHA:
148153
case KVM_RISCV_ISA_EXT_ZACAS:
149154
case KVM_RISCV_ISA_EXT_ZAWRS:
150155
case KVM_RISCV_ISA_EXT_ZBA:
@@ -162,6 +167,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
162167
case KVM_RISCV_ISA_EXT_ZFA:
163168
case KVM_RISCV_ISA_EXT_ZFH:
164169
case KVM_RISCV_ISA_EXT_ZFHMIN:
170+
case KVM_RISCV_ISA_EXT_ZICCRSE:
165171
case KVM_RISCV_ISA_EXT_ZICNTR:
166172
case KVM_RISCV_ISA_EXT_ZICOND:
167173
case KVM_RISCV_ISA_EXT_ZICSR:

arch/riscv/kvm/vcpu_sbi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = {
7070
.ext_idx = KVM_RISCV_SBI_EXT_DBCN,
7171
.ext_ptr = &vcpu_sbi_ext_dbcn,
7272
},
73+
{
74+
.ext_idx = KVM_RISCV_SBI_EXT_SUSP,
75+
.ext_ptr = &vcpu_sbi_ext_susp,
76+
},
7377
{
7478
.ext_idx = KVM_RISCV_SBI_EXT_STA,
7579
.ext_ptr = &vcpu_sbi_ext_sta,

arch/riscv/kvm/vcpu_sbi_system.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2024 Ventana Micro Systems Inc.
4+
*/
5+
6+
#include <linux/kvm_host.h>
7+
8+
#include <asm/kvm_vcpu_sbi.h>
9+
#include <asm/sbi.h>
10+
11+
static int kvm_sbi_ext_susp_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
12+
struct kvm_vcpu_sbi_return *retdata)
13+
{
14+
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
15+
struct kvm_cpu_context *reset_cntx;
16+
unsigned long funcid = cp->a6;
17+
unsigned long hva, i;
18+
struct kvm_vcpu *tmp;
19+
20+
switch (funcid) {
21+
case SBI_EXT_SUSP_SYSTEM_SUSPEND:
22+
if (cp->a0 != SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM) {
23+
retdata->err_val = SBI_ERR_INVALID_PARAM;
24+
return 0;
25+
}
26+
27+
if (!(cp->sstatus & SR_SPP)) {
28+
retdata->err_val = SBI_ERR_FAILURE;
29+
return 0;
30+
}
31+
32+
hva = kvm_vcpu_gfn_to_hva_prot(vcpu, cp->a1 >> PAGE_SHIFT, NULL);
33+
if (kvm_is_error_hva(hva)) {
34+
retdata->err_val = SBI_ERR_INVALID_ADDRESS;
35+
return 0;
36+
}
37+
38+
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
39+
if (tmp == vcpu)
40+
continue;
41+
if (!kvm_riscv_vcpu_stopped(tmp)) {
42+
retdata->err_val = SBI_ERR_DENIED;
43+
return 0;
44+
}
45+
}
46+
47+
spin_lock(&vcpu->arch.reset_cntx_lock);
48+
reset_cntx = &vcpu->arch.guest_reset_context;
49+
reset_cntx->sepc = cp->a1;
50+
reset_cntx->a0 = vcpu->vcpu_id;
51+
reset_cntx->a1 = cp->a2;
52+
spin_unlock(&vcpu->arch.reset_cntx_lock);
53+
54+
kvm_make_request(KVM_REQ_VCPU_RESET, vcpu);
55+
56+
/* userspace provides the suspend implementation */
57+
kvm_riscv_vcpu_sbi_forward(vcpu, run);
58+
retdata->uexit = true;
59+
break;
60+
default:
61+
retdata->err_val = SBI_ERR_NOT_SUPPORTED;
62+
break;
63+
}
64+
65+
return 0;
66+
}
67+
68+
const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_susp = {
69+
.extid_start = SBI_EXT_SUSP,
70+
.extid_end = SBI_EXT_SUSP,
71+
.default_disabled = true,
72+
.handler = kvm_sbi_ext_susp_handler,
73+
};

tools/testing/selftests/kvm/riscv/get-reg-list.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ bool filter_reg(__u64 reg)
5252
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVINVAL:
5353
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVNAPOT:
5454
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVPBMT:
55+
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_SVVPTC:
56+
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZABHA:
5557
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZACAS:
5658
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZAWRS:
5759
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZBA:
@@ -71,6 +73,7 @@ bool filter_reg(__u64 reg)
7173
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZFHMIN:
7274
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOM:
7375
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICBOZ:
76+
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICCRSE:
7477
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICNTR:
7578
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICOND:
7679
case KVM_REG_RISCV_ISA_EXT | KVM_REG_RISCV_ISA_SINGLE | KVM_RISCV_ISA_EXT_ZICSR:
@@ -112,6 +115,7 @@ bool filter_reg(__u64 reg)
112115
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_HSM:
113116
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU:
114117
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN:
118+
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_SUSP:
115119
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_STA:
116120
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL:
117121
case KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR:
@@ -429,6 +433,8 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
429433
KVM_ISA_EXT_ARR(SVINVAL),
430434
KVM_ISA_EXT_ARR(SVNAPOT),
431435
KVM_ISA_EXT_ARR(SVPBMT),
436+
KVM_ISA_EXT_ARR(SVVPTC),
437+
KVM_ISA_EXT_ARR(ZABHA),
432438
KVM_ISA_EXT_ARR(ZACAS),
433439
KVM_ISA_EXT_ARR(ZAWRS),
434440
KVM_ISA_EXT_ARR(ZBA),
@@ -448,6 +454,7 @@ static const char *isa_ext_single_id_to_str(__u64 reg_off)
448454
KVM_ISA_EXT_ARR(ZFHMIN),
449455
KVM_ISA_EXT_ARR(ZICBOM),
450456
KVM_ISA_EXT_ARR(ZICBOZ),
457+
KVM_ISA_EXT_ARR(ZICCRSE),
451458
KVM_ISA_EXT_ARR(ZICNTR),
452459
KVM_ISA_EXT_ARR(ZICOND),
453460
KVM_ISA_EXT_ARR(ZICSR),
@@ -535,10 +542,11 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off)
535542
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_SRST),
536543
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_HSM),
537544
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU),
545+
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN),
546+
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_SUSP),
538547
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_STA),
539548
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL),
540549
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR),
541-
KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN),
542550
};
543551

544552
if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name))
@@ -949,6 +957,7 @@ KVM_SBI_EXT_SUBLIST_CONFIG(base, BASE);
949957
KVM_SBI_EXT_SUBLIST_CONFIG(sta, STA);
950958
KVM_SBI_EXT_SIMPLE_CONFIG(pmu, PMU);
951959
KVM_SBI_EXT_SIMPLE_CONFIG(dbcn, DBCN);
960+
KVM_SBI_EXT_SIMPLE_CONFIG(susp, SUSP);
952961

953962
KVM_ISA_EXT_SUBLIST_CONFIG(aia, AIA);
954963
KVM_ISA_EXT_SUBLIST_CONFIG(fp_f, FP_F);
@@ -964,6 +973,8 @@ KVM_ISA_EXT_SIMPLE_CONFIG(svadu, SVADU);
964973
KVM_ISA_EXT_SIMPLE_CONFIG(svinval, SVINVAL);
965974
KVM_ISA_EXT_SIMPLE_CONFIG(svnapot, SVNAPOT);
966975
KVM_ISA_EXT_SIMPLE_CONFIG(svpbmt, SVPBMT);
976+
KVM_ISA_EXT_SIMPLE_CONFIG(svvptc, SVVPTC);
977+
KVM_ISA_EXT_SIMPLE_CONFIG(zabha, ZABHA);
967978
KVM_ISA_EXT_SIMPLE_CONFIG(zacas, ZACAS);
968979
KVM_ISA_EXT_SIMPLE_CONFIG(zawrs, ZAWRS);
969980
KVM_ISA_EXT_SIMPLE_CONFIG(zba, ZBA);
@@ -983,6 +994,7 @@ KVM_ISA_EXT_SIMPLE_CONFIG(zfh, ZFH);
983994
KVM_ISA_EXT_SIMPLE_CONFIG(zfhmin, ZFHMIN);
984995
KVM_ISA_EXT_SUBLIST_CONFIG(zicbom, ZICBOM);
985996
KVM_ISA_EXT_SUBLIST_CONFIG(zicboz, ZICBOZ);
997+
KVM_ISA_EXT_SIMPLE_CONFIG(ziccrse, ZICCRSE);
986998
KVM_ISA_EXT_SIMPLE_CONFIG(zicntr, ZICNTR);
987999
KVM_ISA_EXT_SIMPLE_CONFIG(zicond, ZICOND);
9881000
KVM_ISA_EXT_SIMPLE_CONFIG(zicsr, ZICSR);
@@ -1017,6 +1029,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
10171029
&config_sbi_sta,
10181030
&config_sbi_pmu,
10191031
&config_sbi_dbcn,
1032+
&config_sbi_susp,
10201033
&config_aia,
10211034
&config_fp_f,
10221035
&config_fp_d,
@@ -1031,6 +1044,8 @@ struct vcpu_reg_list *vcpu_configs[] = {
10311044
&config_svinval,
10321045
&config_svnapot,
10331046
&config_svpbmt,
1047+
&config_svvptc,
1048+
&config_zabha,
10341049
&config_zacas,
10351050
&config_zawrs,
10361051
&config_zba,
@@ -1050,6 +1065,7 @@ struct vcpu_reg_list *vcpu_configs[] = {
10501065
&config_zfhmin,
10511066
&config_zicbom,
10521067
&config_zicboz,
1068+
&config_ziccrse,
10531069
&config_zicntr,
10541070
&config_zicond,
10551071
&config_zicsr,

0 commit comments

Comments
 (0)