diff mbox

[RFC,05/19] kvm: Add uuid member in struct kvm + support for KVM_CAP_VM_UUID

Message ID 20170616134348.17725-6-alazar@bitdefender.com (mailing list archive)
State New, archived
Headers show

Commit Message

Adalbert Lazăr June 16, 2017, 1:43 p.m. UTC
From: Mihai Dontu <mdontu@bitdefender.com>

The introspection subsystem uses UUIDs to identify VMs.

This patch adds support for QEMU to query for KVM_CAP_VM_UUID
and set the uuid with KVM_SET_VM_UUID.

The kvm_from_uuid() helper is used to search and 'get' a kvm struct by
UUID, in order to link the VM and the guest introspection tool with a
control socket connection.

Signed-off-by: Mihai Dontu <mdontu@bitdefender.com>
---
 include/linux/kvm_host.h |  4 ++++
 include/uapi/linux/kvm.h |  2 ++
 virt/kvm/kvm_main.c      | 26 ++++++++++++++++++++++++++
 3 files changed, 32 insertions(+)
diff mbox

Patch

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 88d4e4cbaba5..545964ed6a63 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -27,6 +27,7 @@ 
 #include <linux/irqbypass.h>
 #include <linux/swait.h>
 #include <linux/refcount.h>
+#include <linux/uuid.h>
 #include <asm/signal.h>
 
 #include <linux/kvm.h>
@@ -438,6 +439,8 @@  struct kvm {
 	struct kvm_stat_data **debugfs_stat_data;
 	struct srcu_struct srcu;
 	struct srcu_struct irq_srcu;
+
+	uuid_le uuid;
 };
 
 #define kvm_err(fmt, ...) \
@@ -551,6 +554,7 @@  int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
 void kvm_exit(void);
 void kvm_enum(int (*enum_cb) (const struct kvm *kvm, void *param),
 	      void *param);
+struct kvm *kvm_from_uuid(const uuid_le *uuid);
 
 void kvm_get_kvm(struct kvm *kvm);
 void kvm_put_kvm(struct kvm *kvm);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 577429a95ad8..9b5813597d71 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -895,6 +895,7 @@  struct kvm_ppc_resize_hpt {
 #define KVM_CAP_SPAPR_TCE_VFIO 142
 #define KVM_CAP_X86_GUEST_MWAIT 143
 #define KVM_CAP_ARM_USER_IRQ 144
+#define KVM_CAP_VM_UUID 145
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1318,6 +1319,7 @@  struct kvm_s390_ucas_mapping {
 #define KVM_S390_GET_IRQ_STATE	  _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
 /* Available with KVM_CAP_X86_SMM */
 #define KVM_SMI                   _IO(KVMIO,   0xb7)
+#define KVM_SET_VM_UUID           _IOW(KVMIO, 0xb8, uuid_le)
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
 #define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cfd2d1bf8ac4..31bcdc92f1ea 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2924,6 +2924,7 @@  static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
 #endif
 	case KVM_CAP_IOEVENTFD_ANY_LENGTH:
 	case KVM_CAP_CHECK_EXTENSION_VM:
+	case KVM_CAP_VM_UUID:
 		return 1;
 #ifdef CONFIG_KVM_MMIO
 	case KVM_CAP_COALESCED_MMIO:
@@ -3106,6 +3107,13 @@  static long kvm_vm_ioctl(struct file *filp,
 	case KVM_CHECK_EXTENSION:
 		r = kvm_vm_ioctl_check_extension_generic(kvm, arg);
 		break;
+	case KVM_SET_VM_UUID:
+		r = -EFAULT;
+		if (copy_from_user(&kvm->uuid, argp, sizeof(kvm->uuid)))
+			goto out;
+
+		r = 0;
+		break;
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}
@@ -4058,3 +4066,21 @@  void kvm_enum(int (*enum_cb) (const struct kvm *kvm, void *param), void *param)
 	}
 	spin_unlock(&kvm_lock);
 }
+
+/* Make sure to call kvm_put_kvm() when done */
+struct kvm *kvm_from_uuid(const uuid_le *uuid)
+{
+	struct kvm *kvm;
+	struct kvm *found = NULL;
+
+	spin_lock(&kvm_lock);
+	list_for_each_entry(kvm, &vm_list, vm_list) {
+		if (!memcmp(&kvm->uuid, uuid, sizeof(kvm->uuid))) {
+			kvm_get_kvm(kvm);
+			found = kvm;
+			break;
+		}
+	}
+	spin_unlock(&kvm_lock);
+	return found;
+}