[kvmtool PATCH v2 05/10] riscv: Add SBI system suspend support
Anup Patel
apatel at ventanamicro.com
Thu Apr 24 08:31:54 PDT 2025
From: Andrew Jones <ajones at ventanamicro.com>
Provide a handler for SBI system suspend requests forwarded to the
VMM by KVM and enable system suspend by default. This is just for
testing purposes, so the handler only sleeps 5 seconds before
resuming the guest. Resuming a system suspend only requires running
the system suspend invoking hart again, everything else is handled by
KVM.
Note, resuming after a suspend doesn't work with 9p used for the
guest's rootfs. Testing with a disk works though, e.g.
lkvm-static run --nodefaults -m 256 -c 2 -d rootfs.ext2 -k Image \
-p 'console=ttyS0 rootwait root=/dev/vda ro no_console_suspend'
Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
riscv/include/kvm/kvm-config-arch.h | 3 +++
riscv/include/kvm/sbi.h | 9 ++++++++
riscv/kvm-cpu.c | 36 +++++++++++++++++++++++++++++
3 files changed, 48 insertions(+)
diff --git a/riscv/include/kvm/kvm-config-arch.h b/riscv/include/kvm/kvm-config-arch.h
index 5badb74..0553004 100644
--- a/riscv/include/kvm/kvm-config-arch.h
+++ b/riscv/include/kvm/kvm-config-arch.h
@@ -238,6 +238,9 @@ struct kvm_config_arch {
OPT_BOOLEAN('\0', "disable-sbi-dbcn", \
&(cfg)->sbi_ext_disabled[KVM_RISCV_SBI_EXT_DBCN], \
"Disable SBI DBCN Extension"), \
+ OPT_BOOLEAN('\0', "disable-sbi-susp", \
+ &(cfg)->sbi_ext_disabled[KVM_RISCV_SBI_EXT_SUSP], \
+ "Disable SBI SUSP Extension"), \
OPT_BOOLEAN('\0', "disable-sbi-sta", \
&(cfg)->sbi_ext_disabled[KVM_RISCV_SBI_EXT_STA], \
"Disable SBI STA Extension"),
diff --git a/riscv/include/kvm/sbi.h b/riscv/include/kvm/sbi.h
index a0f2c70..10bbe1b 100644
--- a/riscv/include/kvm/sbi.h
+++ b/riscv/include/kvm/sbi.h
@@ -21,6 +21,7 @@ enum sbi_ext_id {
SBI_EXT_0_1_SHUTDOWN = 0x8,
SBI_EXT_BASE = 0x10,
SBI_EXT_DBCN = 0x4442434E,
+ SBI_EXT_SUSP = 0x53555350,
};
enum sbi_ext_base_fid {
@@ -39,6 +40,14 @@ enum sbi_ext_dbcn_fid {
SBI_EXT_DBCN_CONSOLE_WRITE_BYTE = 2,
};
+enum sbi_ext_susp_fid {
+ SBI_EXT_SUSP_SYSTEM_SUSPEND = 0,
+};
+
+enum sbi_ext_susp_sleep_type {
+ SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM = 0,
+};
+
#define SBI_SPEC_VERSION_DEFAULT 0x1
#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
diff --git a/riscv/kvm-cpu.c b/riscv/kvm-cpu.c
index 0c171da..ad68b58 100644
--- a/riscv/kvm-cpu.c
+++ b/riscv/kvm-cpu.c
@@ -1,3 +1,5 @@
+#include <unistd.h>
+
#include "kvm/csr.h"
#include "kvm/kvm-cpu.h"
#include "kvm/kvm.h"
@@ -117,6 +119,17 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
KVM_RISCV_SBI_EXT_DBCN);
}
+ /* Force enable SBI system suspend if not disabled from command line */
+ if (!kvm->cfg.arch.sbi_ext_disabled[KVM_RISCV_SBI_EXT_SUSP]) {
+ id = 1;
+ reg.id = RISCV_SBI_EXT_REG(KVM_REG_RISCV_SBI_SINGLE,
+ KVM_RISCV_SBI_EXT_SUSP);
+ reg.addr = (unsigned long)&id;
+ if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
+ pr_warning("KVM_SET_ONE_REG failed (sbi_ext %d)",
+ KVM_RISCV_SBI_EXT_SUSP);
+ }
+
/* Populate the vcpu structure. */
vcpu->kvm = kvm;
vcpu->cpu_id = cpu_id;
@@ -203,6 +216,29 @@ static bool kvm_cpu_riscv_sbi(struct kvm_cpu *vcpu)
break;
}
break;
+ case SBI_EXT_SUSP:
+ {
+ unsigned long susp_type, ret = SBI_SUCCESS;
+
+ switch (vcpu->kvm_run->riscv_sbi.function_id) {
+ case SBI_EXT_SUSP_SYSTEM_SUSPEND:
+ susp_type = vcpu->kvm_run->riscv_sbi.args[0];
+ if (susp_type != SBI_SUSP_SLEEP_TYPE_SUSPEND_TO_RAM) {
+ ret = SBI_ERR_INVALID_PARAM;
+ break;
+ }
+
+ sleep(5);
+
+ break;
+ default:
+ ret = SBI_ERR_NOT_SUPPORTED;
+ break;
+ }
+
+ vcpu->kvm_run->riscv_sbi.ret[0] = ret;
+ break;
+ }
default:
dprintf(dfd, "Unhandled SBI call\n");
dprintf(dfd, "extension_id=0x%lx function_id=0x%lx\n",
--
2.43.0
More information about the kvm-riscv
mailing list