Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Nov 2020 23:56:33 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r368004 - head/sys/amd64/vmm/io
Message-ID:  <202011242356.0AONuXXJ052529@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011242356.0AONuXXJ052529>