Skip to content

Commit c62a768

Browse files
atishp04avpatel
authored andcommitted
RISC-V: KVM: Add SBI v0.2 base extension
SBI v0.2 base extension defined to allow backward compatibility and probing of future extensions. This is also the only mandatory SBI extension that must be implemented by SBI implementors. Signed-off-by: Atish Patra <[email protected]> Signed-off-by: Atish Patra <[email protected]> Signed-off-by: Anup Patel <[email protected]>
1 parent a046c2d commit c62a768

File tree

5 files changed

+85
-1
lines changed

5 files changed

+85
-1
lines changed

arch/riscv/include/asm/kvm_vcpu_sbi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#ifndef __RISCV_KVM_VCPU_SBI_H__
1010
#define __RISCV_KVM_VCPU_SBI_H__
1111

12+
#define KVM_SBI_IMPID 3
13+
1214
#define KVM_SBI_VERSION_MAJOR 0
1315
#define KVM_SBI_VERSION_MINOR 2
1416

arch/riscv/include/asm/sbi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ enum sbi_ext_id {
2727
SBI_EXT_IPI = 0x735049,
2828
SBI_EXT_RFENCE = 0x52464E43,
2929
SBI_EXT_HSM = 0x48534D,
30+
31+
/* Experimentals extensions must lie within this range */
32+
SBI_EXT_EXPERIMENTAL_START = 0x08000000,
33+
SBI_EXT_EXPERIMENTAL_END = 0x08FFFFFF,
34+
35+
/* Vendor extensions must lie within this range */
36+
SBI_EXT_VENDOR_START = 0x09000000,
37+
SBI_EXT_VENDOR_END = 0x09FFFFFF,
3038
};
3139

3240
enum sbi_ext_base_fid {

arch/riscv/kvm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ kvm-y += vcpu_fp.o
2020
kvm-y += vcpu_switch.o
2121
kvm-y += vcpu_sbi.o
2222
kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o
23+
kvm-y += vcpu_sbi_base.o
2324
kvm-y += vcpu_timer.o

arch/riscv/kvm/vcpu_sbi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = {
3939
.handler = NULL,
4040
};
4141
#endif
42-
42+
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
4343
static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
4444
&vcpu_sbi_ext_v01,
45+
&vcpu_sbi_ext_base,
4546
};
4647

4748
void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)

arch/riscv/kvm/vcpu_sbi_base.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2021 Western Digital Corporation or its affiliates.
4+
*
5+
* Authors:
6+
* Atish Patra <[email protected]>
7+
*/
8+
9+
#include <linux/errno.h>
10+
#include <linux/err.h>
11+
#include <linux/kvm_host.h>
12+
#include <asm/csr.h>
13+
#include <asm/sbi.h>
14+
#include <asm/kvm_vcpu_timer.h>
15+
#include <asm/kvm_vcpu_sbi.h>
16+
17+
static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
18+
unsigned long *out_val,
19+
struct kvm_cpu_trap *trap, bool *exit)
20+
{
21+
int ret = 0;
22+
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
23+
struct sbiret ecall_ret;
24+
25+
switch (cp->a6) {
26+
case SBI_EXT_BASE_GET_SPEC_VERSION:
27+
*out_val = (KVM_SBI_VERSION_MAJOR <<
28+
SBI_SPEC_VERSION_MAJOR_SHIFT) |
29+
KVM_SBI_VERSION_MINOR;
30+
break;
31+
case SBI_EXT_BASE_GET_IMP_ID:
32+
*out_val = KVM_SBI_IMPID;
33+
break;
34+
case SBI_EXT_BASE_GET_IMP_VERSION:
35+
*out_val = 0;
36+
break;
37+
case SBI_EXT_BASE_PROBE_EXT:
38+
if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START &&
39+
cp->a0 <= SBI_EXT_EXPERIMENTAL_END) ||
40+
(cp->a0 >= SBI_EXT_VENDOR_START &&
41+
cp->a0 <= SBI_EXT_VENDOR_END)) {
42+
/*
43+
* For experimental/vendor extensions
44+
* forward it to the userspace
45+
*/
46+
kvm_riscv_vcpu_sbi_forward(vcpu, run);
47+
*exit = true;
48+
} else
49+
*out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0;
50+
break;
51+
case SBI_EXT_BASE_GET_MVENDORID:
52+
case SBI_EXT_BASE_GET_MARCHID:
53+
case SBI_EXT_BASE_GET_MIMPID:
54+
ecall_ret = sbi_ecall(SBI_EXT_BASE, cp->a6, 0, 0, 0, 0, 0, 0);
55+
if (!ecall_ret.error)
56+
*out_val = ecall_ret.value;
57+
/*TODO: We are unnecessarily converting the error twice */
58+
ret = sbi_err_map_linux_errno(ecall_ret.error);
59+
break;
60+
default:
61+
ret = -EOPNOTSUPP;
62+
break;
63+
}
64+
65+
return ret;
66+
}
67+
68+
const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = {
69+
.extid_start = SBI_EXT_BASE,
70+
.extid_end = SBI_EXT_BASE,
71+
.handler = kvm_sbi_ext_base_handler,
72+
};

0 commit comments

Comments
 (0)