Skip to content

Commit

Permalink
RISC-V: Add SBI v0.2 base extension
Browse files Browse the repository at this point in the history
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 <atish.patra@wdc.com>
  • Loading branch information
atishp04 committed Oct 7, 2021
1 parent 13b3d3f commit 373ce9e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 1 deletion.
2 changes: 2 additions & 0 deletions arch/riscv/include/asm/kvm_vcpu_sbi.h
Expand Up @@ -9,6 +9,8 @@
#ifndef __RISCV_KVM_VCPU_SBI_H__
#define __RISCV_KVM_VCPU_SBI_H__

#define KVM_SBI_IMPID 3

#define KVM_SBI_VERSION_MAJOR 0
#define KVM_SBI_VERSION_MINOR 2

Expand Down
8 changes: 8 additions & 0 deletions arch/riscv/include/asm/sbi.h
Expand Up @@ -28,6 +28,14 @@ enum sbi_ext_id {
SBI_EXT_RFENCE = 0x52464E43,
SBI_EXT_HSM = 0x48534D,
SBI_EXT_SRST = 0x53525354,

/* Experimentals extensions must lie within this range */
SBI_EXT_EXPERIMENTAL_START = 0x0800000,
SBI_EXT_EXPERIMENTAL_END = 0x08FFFFFF,

/* Vendor extensions must lie within this range */
SBI_EXT_VENDOR_START = 0x09000000,
SBI_EXT_VENDOR_END = 0x09FFFFFF,
};

enum sbi_ext_base_fid {
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/kvm/Makefile
Expand Up @@ -23,4 +23,5 @@ kvm-y += vcpu_exit.o
kvm-y += vcpu_switch.o
kvm-y += vcpu_sbi.o
kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_legacy.o
kvm-y += vcpu_sbi_base.o
kvm-y += vcpu_timer.o
3 changes: 2 additions & 1 deletion arch/riscv/kvm/vcpu_sbi.c
Expand Up @@ -39,9 +39,10 @@ static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy = {
.handler = NULL,
};
#endif

extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
&vcpu_sbi_ext_legacy,
&vcpu_sbi_ext_base,
};

void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
Expand Down
73 changes: 73 additions & 0 deletions arch/riscv/kvm/vcpu_sbi_base.c
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPL-2.0
/**
* Copyright (c) 2020 Western Digital Corporation or its affiliates.
*
* Authors:
* Atish Patra <atish.patra@wdc.com>
*/

#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
#include <asm/csr.h>
#include <asm/sbi.h>
#include <asm/kvm_vcpu_timer.h>
#include <asm/kvm_vcpu_sbi.h>

static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
unsigned long *out_val,
struct kvm_cpu_trap *trap, bool *exit)
{
int ret = 0;
struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
struct sbiret ecall_ret;

if (!cp)
return -EINVAL;

switch (cp->a6) {
case SBI_EXT_BASE_GET_SPEC_VERSION:
*out_val = (KVM_SBI_VERSION_MAJOR <<
SBI_SPEC_VERSION_MAJOR_SHIFT) |
KVM_SBI_VERSION_MINOR;
break;
case SBI_EXT_BASE_GET_IMP_ID:
*out_val = KVM_SBI_IMPID;
break;
case SBI_EXT_BASE_GET_IMP_VERSION:
*out_val = 0;
break;
case SBI_EXT_BASE_PROBE_EXT:
*out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0;
if ((!*out_val) &&
((cp->a0 >= SBI_EXT_EXPERIMENTAL_START &&
cp->a0 <= SBI_EXT_EXPERIMENTAL_END) ||
((cp->a0 >= SBI_EXT_VENDOR_START &&
cp->a0 <= SBI_EXT_VENDOR_END)))) {
/* For experimental/vendor extensions forward to the userspace*/
kvm_riscv_vcpu_sbi_forward(vcpu, run);
*exit = true;
}
break;
case SBI_EXT_BASE_GET_MVENDORID:
case SBI_EXT_BASE_GET_MARCHID:
case SBI_EXT_BASE_GET_MIMPID:
ecall_ret = sbi_ecall(SBI_EXT_BASE, cp->a6, 0, 0, 0, 0, 0, 0);
if (!ecall_ret.error)
*out_val = ecall_ret.value;
/*TODO: We are unnecessarily converting the error twice */
ret = sbi_err_map_linux_errno(ecall_ret.error);
break;
default:
ret = -EOPNOTSUPP;
break;
}

return ret;
}

const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = {
.extid_start = SBI_EXT_BASE,
.extid_end = SBI_EXT_BASE,
.handler = kvm_sbi_ext_base_handler,
};

0 comments on commit 373ce9e

Please sign in to comment.