Author: jhb
Date: Tue Nov 24 23:56:33 2020
New Revision: 368004
URL: https://svnweb.freebsd.org/changeset/base/368004

Log:
  Pull the check for VM ownership into ppt_find().
  
  This reduces some code duplication.  One behavior change is that
  ppt_assign_device() will now only succeed if the device is unowned.
  Previously, a device could be assigned to the same VM multiple times,
  but each time it was assigned, the device's state was reset.
  
  Reviewed by:  markj, grehan
  MFC after:    2 weeks
  Sponsored by: Chelsio Communications
  Differential Revision:        https://reviews.freebsd.org/D27301

Modified:
  head/sys/amd64/vmm/io/ppt.c

Modified: head/sys/amd64/vmm/io/ppt.c
==============================================================================
--- head/sys/amd64/vmm/io/ppt.c Tue Nov 24 23:18:52 2020        (r368003)
+++ head/sys/amd64/vmm/io/ppt.c Tue Nov 24 23:56:33 2020        (r368004)
@@ -199,8 +199,8 @@ static devclass_t ppt_devclass;
 DEFINE_CLASS_0(ppt, ppt_driver, ppt_methods, sizeof(struct pptdev));
 DRIVER_MODULE(ppt, pci, ppt_driver, ppt_devclass, NULL, NULL);
 
-static struct pptdev *
-ppt_find(int bus, int slot, int func)
+static int
+ppt_find(struct vm *vm, int bus, int slot, int func, struct pptdev **pptp)
 {
        device_t dev;
        struct pptdev *ppt;
@@ -212,9 +212,15 @@ ppt_find(int bus, int slot, int func)
                s = pci_get_slot(dev);
                f = pci_get_function(dev);
                if (bus == b && slot == s && func == f)
-                       return (ppt);
+                       break;
        }
-       return (NULL);
+
+       if (ppt == NULL)
+               return (ENOENT);
+       if (ppt->vm != vm)              /* Make sure we own this device */
+               return (EBUSY);
+       *pptp = ppt;
+       return (0);
 }
 
 static void
@@ -378,50 +384,40 @@ int
 ppt_assign_device(struct vm *vm, int bus, int slot, int func)
 {
        struct pptdev *ppt;
+       int error;
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt != NULL) {
-               /*
-                * If this device is owned by a different VM then we
-                * cannot change its owner.
-                */
-               if (ppt->vm != NULL && ppt->vm != vm)
-                       return (EBUSY);
+       /* Passing NULL requires the device to be unowned. */
+       error = ppt_find(NULL, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
-               pci_save_state(ppt->dev);
-               ppt_pci_reset(ppt->dev);
-               pci_restore_state(ppt->dev);
-               ppt->vm = vm;
-               iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
-               return (0);
-       }
-       return (ENOENT);
+       pci_save_state(ppt->dev);
+       ppt_pci_reset(ppt->dev);
+       pci_restore_state(ppt->dev);
+       ppt->vm = vm;
+       iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
+       return (0);
 }
 
 int
 ppt_unassign_device(struct vm *vm, int bus, int slot, int func)
 {
        struct pptdev *ppt;
+       int error;
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt != NULL) {
-               /*
-                * If this device is not owned by this 'vm' then bail out.
-                */
-               if (ppt->vm != vm)
-                       return (EBUSY);
+       error = ppt_find(vm, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
-               pci_save_state(ppt->dev);
-               ppt_pci_reset(ppt->dev);
-               pci_restore_state(ppt->dev);
-               ppt_unmap_mmio(vm, ppt);
-               ppt_teardown_msi(ppt);
-               ppt_teardown_msix(ppt);
-               iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
-               ppt->vm = NULL;
-               return (0);
-       }
-       return (ENOENT);
+       pci_save_state(ppt->dev);
+       ppt_pci_reset(ppt->dev);
+       pci_restore_state(ppt->dev);
+       ppt_unmap_mmio(vm, ppt);
+       ppt_teardown_msi(ppt);
+       ppt_teardown_msix(ppt);
+       iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
+       ppt->vm = NULL;
+       return (0);
 }
 
 int
@@ -452,25 +448,22 @@ ppt_map_mmio(struct vm *vm, int bus, int slot, int fun
        struct pptseg *seg;
        struct pptdev *ppt;
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt != NULL) {
-               if (ppt->vm != vm)
-                       return (EBUSY);
+       error = ppt_find(vm, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
-               for (i = 0; i < MAX_MMIOSEGS; i++) {
-                       seg = &ppt->mmio[i];
-                       if (seg->len == 0) {
-                               error = vm_map_mmio(vm, gpa, len, hpa);
-                               if (error == 0) {
-                                       seg->gpa = gpa;
-                                       seg->len = len;
-                               }
-                               return (error);
+       for (i = 0; i < MAX_MMIOSEGS; i++) {
+               seg = &ppt->mmio[i];
+               if (seg->len == 0) {
+                       error = vm_map_mmio(vm, gpa, len, hpa);
+                       if (error == 0) {
+                               seg->gpa = gpa;
+                               seg->len = len;
                        }
+                       return (error);
                }
-               return (ENOSPC);
        }
-       return (ENOENT);
+       return (ENOSPC);
 }
 
 static int
@@ -512,11 +505,9 @@ ppt_setup_msi(struct vm *vm, int vcpu, int bus, int sl
        if (numvec < 0 || numvec > MAX_MSIMSGS)
                return (EINVAL);
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt == NULL)
-               return (ENOENT);
-       if (ppt->vm != vm)              /* Make sure we own this device */
-               return (EBUSY);
+       error = ppt_find(vm, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
        /* Reject attempts to enable MSI while MSI-X is active. */
        if (ppt->msix.num_msgs != 0 && numvec != 0)
@@ -605,11 +596,9 @@ ppt_setup_msix(struct vm *vm, int vcpu, int bus, int s
        int numvec, alloced, rid, error;
        size_t res_size, cookie_size, arg_size;
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt == NULL)
-               return (ENOENT);
-       if (ppt->vm != vm)              /* Make sure we own this device */
-               return (EBUSY);
+       error = ppt_find(vm, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
        /* Reject attempts to enable MSI-X while MSI is active. */
        if (ppt->msi.num_msgs != 0)
@@ -713,12 +702,11 @@ int
 ppt_disable_msix(struct vm *vm, int bus, int slot, int func)
 {
        struct pptdev *ppt;
+       int error;
 
-       ppt = ppt_find(bus, slot, func);
-       if (ppt == NULL)
-               return (ENOENT);
-       if (ppt->vm != vm)              /* Make sure we own this device */
-               return (EBUSY);
+       error = ppt_find(vm, bus, slot, func, &ppt);
+       if (error)
+               return (error);
 
        ppt_teardown_msix(ppt);
        return (0);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to