svn commit: r325039 - head/sys/amd64/vmm/io
John Baldwin
jhb at FreeBSD.org
Fri Oct 27 14:57:16 UTC 2017
Author: jhb
Date: Fri Oct 27 14:57:14 2017
New Revision: 325039
URL: https://svnweb.freebsd.org/changeset/base/325039
Log:
Rework pass through changes in r305485 to be safer.
Specifically, devices that do not support PCI-e FLR and were not
gracefully shutdown by the guest OS could continue to issue DMA
requests after the VM was terminated. The changes in r305485 meant
that those DMA requests were completed against the host's memory which
could result in random memory corruption. Instead, leave ppt devices
that are not attached to a VM disabled in the IOMMU and only restore
the devices to the host domain if the ppt(4) driver is detached from a
device.
As an added safety belt, disable busmastering for a pass-through device
when before adding it to the host domain during ppt(4) detach.
PR: 222937
Tested by: Harry Schmalzbauer <freebsd at omnilan.de>
Reviewed by: grehan
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D12661
Modified:
head/sys/amd64/vmm/io/iommu.c
head/sys/amd64/vmm/io/ppt.c
Modified: head/sys/amd64/vmm/io/iommu.c
==============================================================================
--- head/sys/amd64/vmm/io/iommu.c Fri Oct 27 14:24:35 2017 (r325038)
+++ head/sys/amd64/vmm/io/iommu.c Fri Oct 27 14:57:14 2017 (r325039)
@@ -174,6 +174,7 @@ iommu_init(void)
{
int error, bus, slot, func;
vm_paddr_t maxaddr;
+ devclass_t dc;
device_t dev;
if (!iommu_enable)
@@ -214,6 +215,7 @@ iommu_init(void)
add_tag = EVENTHANDLER_REGISTER(pci_add_device, iommu_pci_add, NULL, 0);
delete_tag = EVENTHANDLER_REGISTER(pci_delete_device, iommu_pci_delete,
NULL, 0);
+ dc = devclass_find("ppt");
for (bus = 0; bus <= PCI_BUSMAX; bus++) {
for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
for (func = 0; func <= PCI_FUNCMAX; func++) {
@@ -221,7 +223,15 @@ iommu_init(void)
if (dev == NULL)
continue;
- /* Everything belongs to the host domain. */
+ /* Skip passthrough devices. */
+ if (dc != NULL &&
+ device_get_devclass(dev) == dc)
+ continue;
+
+ /*
+ * Everything else belongs to the host
+ * domain.
+ */
iommu_add_device(host_domain,
pci_get_rid(dev));
}
Modified: head/sys/amd64/vmm/io/ppt.c
==============================================================================
--- head/sys/amd64/vmm/io/ppt.c Fri Oct 27 14:24:35 2017 (r325038)
+++ head/sys/amd64/vmm/io/ppt.c Fri Oct 27 14:57:14 2017 (r325039)
@@ -154,6 +154,7 @@ ppt_attach(device_t dev)
ppt = device_get_softc(dev);
+ iommu_remove_device(iommu_host_domain(), pci_get_rid(dev));
num_pptdevs++;
TAILQ_INSERT_TAIL(&pptdev_list, ppt, next);
ppt->dev = dev;
@@ -175,6 +176,8 @@ ppt_detach(device_t dev)
return (EBUSY);
num_pptdevs--;
TAILQ_REMOVE(&pptdev_list, ppt, next);
+ pci_disable_busmaster(dev);
+ iommu_add_device(iommu_host_domain(), pci_get_rid(dev));
return (0);
}
@@ -368,7 +371,6 @@ ppt_assign_device(struct vm *vm, int bus, int slot, in
true);
pci_restore_state(ppt->dev);
ppt->vm = vm;
- iommu_remove_device(iommu_host_domain(), pci_get_rid(ppt->dev));
iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
return (0);
}
@@ -397,7 +399,6 @@ ppt_unassign_device(struct vm *vm, int bus, int slot,
ppt_teardown_msi(ppt);
ppt_teardown_msix(ppt);
iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
- iommu_add_device(iommu_host_domain(), pci_get_rid(ppt->dev));
ppt->vm = NULL;
return (0);
}
More information about the svn-src-all
mailing list