RISC-V: KVM: Implement SBI v0.3 SRST extension
authorAnup Patel <apatel@ventanamicro.com>
Mon, 31 Jan 2022 05:23:13 +0000 (10:53 +0530)
committerAnup Patel <anup@brainfault.org>
Fri, 11 Mar 2022 13:32:31 +0000 (19:02 +0530)
The SBI v0.3 specification defines SRST (System Reset) extension which
provides a standard poweroff and reboot interface. This patch implements
SRST extension for the KVM Guest.

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
arch/riscv/kvm/vcpu_sbi.c
arch/riscv/kvm/vcpu_sbi_replace.c

index 11ae4f6..a09ecb9 100644 (file)
@@ -45,6 +45,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base;
 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time;
 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_experimental;
 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
@@ -55,6 +56,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = {
        &vcpu_sbi_ext_time,
        &vcpu_sbi_ext_ipi,
        &vcpu_sbi_ext_rfence,
+       &vcpu_sbi_ext_srst,
        &vcpu_sbi_ext_hsm,
        &vcpu_sbi_ext_experimental,
        &vcpu_sbi_ext_vendor,
index 1bc0608..0f21736 100644 (file)
@@ -130,3 +130,47 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = {
        .extid_end = SBI_EXT_RFENCE,
        .handler = kvm_sbi_ext_rfence_handler,
 };
+
+static int kvm_sbi_ext_srst_handler(struct kvm_vcpu *vcpu,
+                                   struct kvm_run *run,
+                                   unsigned long *out_val,
+                                   struct kvm_cpu_trap *utrap, bool *exit)
+{
+       struct kvm_cpu_context *cp = &vcpu->arch.guest_context;
+       unsigned long funcid = cp->a6;
+       u32 reason = cp->a1;
+       u32 type = cp->a0;
+       int ret = 0;
+
+       switch (funcid) {
+       case SBI_EXT_SRST_RESET:
+               switch (type) {
+               case SBI_SRST_RESET_TYPE_SHUTDOWN:
+                       kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+                                               KVM_SYSTEM_EVENT_SHUTDOWN,
+                                               reason);
+                       *exit = true;
+                       break;
+               case SBI_SRST_RESET_TYPE_COLD_REBOOT:
+               case SBI_SRST_RESET_TYPE_WARM_REBOOT:
+                       kvm_riscv_vcpu_sbi_system_reset(vcpu, run,
+                                               KVM_SYSTEM_EVENT_RESET,
+                                               reason);
+                       *exit = true;
+                       break;
+               default:
+                       ret = -EOPNOTSUPP;
+               }
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+       }
+
+       return ret;
+}
+
+const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = {
+       .extid_start = SBI_EXT_SRST,
+       .extid_end = SBI_EXT_SRST,
+       .handler = kvm_sbi_ext_srst_handler,
+};