diff mbox series

[RFC,kvmtool,2/2] arm64: Add support for KVM_CAP_ARM_SYSTEM_SUSPEND

Message ID 20210827215827.3774670-3-oupton@google.com (mailing list archive)
State New, archived
Headers show
Series PSCI SYSTEM_SUSPEND support | expand

Commit Message

Oliver Upton Aug. 27, 2021, 9:58 p.m. UTC
KVM now allows a guest to issue the SYSTEM_SUSPEND PSCI call with buy-in
from the VMM. Opt in to the new capability and handle the
KVM_SYSTEM_EVENT_SUSPEND exit subtype by ignoring the guest request and
entering KVM again. Since KVM has already configured the guest to
resume, this will result in the guest immediately coming out of reset.

Signed-off-by: Oliver Upton <oupton@google.com>
---
 arm/kvm.c         | 12 ++++++++++++
 include/kvm/kvm.h |  1 +
 kvm-cpu.c         |  5 +++++
 kvm.c             |  7 +++++++
 4 files changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/arm/kvm.c b/arm/kvm.c
index 5aea18f..0a53c46 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -59,6 +59,18 @@  void kvm__arch_set_cmdline(char *cmdline, bool video)
 
 void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 {
+	if (kvm__supports_vm_extension(kvm, KVM_CAP_ARM_SYSTEM_SUSPEND)) {
+		struct kvm_enable_cap cap = {
+			.cap = KVM_CAP_ARM_SYSTEM_SUSPEND
+		};
+		int err;
+
+		err = kvm__enable_vm_extension(kvm, &cap);
+		if (err)
+			die("Failed to enable KVM_CAP_ARM_SYSTEM_SUSPEND "
+			    "[err %d]", err);
+	}
+
 	/*
 	 * Allocate guest memory. We must align our buffer to 64K to
 	 * correlate with the maximum guest page size for virtio-mmio.
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 56e9c8e..c797516 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -236,6 +236,7 @@  static inline bool host_ptr_in_ram(struct kvm *kvm, void *p)
 
 bool kvm__supports_extension(struct kvm *kvm, unsigned int extension);
 bool kvm__supports_vm_extension(struct kvm *kvm, unsigned int extension);
+int kvm__enable_vm_extension(struct kvm *kvm, struct kvm_enable_cap *cap);
 
 static inline void kvm__set_thread_name(const char *name)
 {
diff --git a/kvm-cpu.c b/kvm-cpu.c
index 7dec088..1fedacf 100644
--- a/kvm-cpu.c
+++ b/kvm-cpu.c
@@ -236,6 +236,11 @@  int kvm_cpu__start(struct kvm_cpu *cpu)
 				 */
 				kvm__reboot(cpu->kvm);
 				goto exit_kvm;
+			case KVM_SYSTEM_EVENT_SUSPEND:
+				/*
+				 * Ignore the guest; kvm will resume it normally
+				 */
+				break;
 			};
 			break;
 		default: {
diff --git a/kvm.c b/kvm.c
index e327541..66815b4 100644
--- a/kvm.c
+++ b/kvm.c
@@ -123,6 +123,13 @@  bool kvm__supports_vm_extension(struct kvm *kvm, unsigned int extension)
 	return ret;
 }
 
+int kvm__enable_vm_extension(struct kvm *kvm, struct kvm_enable_cap *cap)
+{
+	int ret = ioctl(kvm->vm_fd, KVM_ENABLE_CAP, cap);
+
+	return ret ? errno : 0;
+}
+
 bool kvm__supports_extension(struct kvm *kvm, unsigned int extension)
 {
 	int ret;