@@ -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"),
@@ -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
@@ -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",