@@ -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);
@@ -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)
@@ -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;
+}