KVM: document lock nesting rule
[firefly-linux-kernel-4.4.55.git] / virt / kvm / kvm_main.c
index f1e2e8c373c64b88d3bf71f4c7f91a7ff37c40a7..fc1b58a72757b43d75f04534ffc37d222033c91a 100644 (file)
@@ -68,7 +68,7 @@ MODULE_LICENSE("GPL");
 /*
  * Ordering of locks:
  *
- *             kvm->lock --> kvm->irq_lock
+ *             kvm->slots_lock --> kvm->lock --> kvm->irq_lock
  */
 
 DEFINE_SPINLOCK(kvm_lock);
@@ -2398,7 +2398,7 @@ static long kvm_dev_ioctl(struct file *filp,
        case KVM_TRACE_ENABLE:
        case KVM_TRACE_PAUSE:
        case KVM_TRACE_DISABLE:
-               r = kvm_trace_ioctl(ioctl, arg);
+               r = -EOPNOTSUPP;
                break;
        default:
                return kvm_arch_dev_ioctl(filp, ioctl, arg);
@@ -2512,22 +2512,38 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
        }
 }
 
-struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
-                                         gpa_t addr, int len, int is_write)
+/* kvm_io_bus_write - called under kvm->slots_lock */
+int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
+                    int len, const void *val)
 {
        int i;
+       for (i = 0; i < bus->dev_count; i++)
+               if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
+                       return 0;
+       return -EOPNOTSUPP;
+}
 
-       for (i = 0; i < bus->dev_count; i++) {
-               struct kvm_io_device *pos = bus->devs[i];
-
-               if (kvm_iodevice_in_range(pos, addr, len, is_write))
-                       return pos;
-       }
+/* kvm_io_bus_read - called under kvm->slots_lock */
+int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, void *val)
+{
+       int i;
+       for (i = 0; i < bus->dev_count; i++)
+               if (!kvm_iodevice_read(bus->devs[i], addr, len, val))
+                       return 0;
+       return -EOPNOTSUPP;
+}
 
-       return NULL;
+void kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
+                            struct kvm_io_device *dev)
+{
+       down_write(&kvm->slots_lock);
+       __kvm_io_bus_register_dev(bus, dev);
+       up_write(&kvm->slots_lock);
 }
 
-void kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_io_device *dev)
+/* An unlocked version. Caller must have write lock on slots_lock. */
+void __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
+                            struct kvm_io_device *dev)
 {
        BUG_ON(bus->dev_count > (NR_IOBUS_DEVS-1));
 
@@ -2748,7 +2764,6 @@ EXPORT_SYMBOL_GPL(kvm_init);
 
 void kvm_exit(void)
 {
-       kvm_trace_cleanup();
        tracepoint_synchronize_unregister();
        misc_deregister(&kvm_dev);
        kmem_cache_destroy(kvm_vcpu_cache);