Page MenuHomeFreeBSD

D28984.id84840.diff
No OneTemporary

D28984.id84840.diff

Index: sys/amd64/vmm/amd/amdiommu.c
===================================================================
--- /dev/null
+++ sys/amd64/vmm/amd/amdiommu.c
@@ -0,0 +1,77 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021, Ka Ho Ng <khng300@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include "amdvi_priv.h"
+
+static devclass_t amdiommu_devclass;
+
+static int amdiommu_probe(device_t);
+static int amdiommu_attach(device_t);
+static int amdiommu_detach(device_t);
+
+static device_method_t amdiommu_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, amdiommu_probe),
+ DEVMETHOD(device_attach, amdiommu_attach),
+ DEVMETHOD(device_detach, amdiommu_detach),
+ DEVMETHOD_END
+};
+driver_t amdiommu_driver = {
+ "amdiommu",
+ amdiommu_methods,
+ 0
+};
+
+static int
+amdiommu_probe(device_t dev)
+{
+ return (ENXIO);
+}
+
+static int
+amdiommu_attach(device_t dev)
+{
+ device_set_desc(dev, "AMD-Vi/IOMMU PCI function");
+ return (0);
+}
+
+static int
+amdiommu_detach(device_t dev)
+{
+ return (0);
+}
+
+DRIVER_MODULE(amdiommu, pci, amdiommu_driver, amdiommu_devclass, 0, 0);
+MODULE_DEPEND(amdiommu, pci, 1, 1, 1);
Index: sys/amd64/vmm/amd/amdvi_hw.c
===================================================================
--- sys/amd64/vmm/amd/amdvi_hw.c
+++ sys/amd64/vmm/amd/amdvi_hw.c
@@ -772,62 +772,55 @@
{
struct amdvi_softc *softc;
+ device_t mmio_dev;
softc = device_get_softc(dev);
+ mmio_dev = softc->pci_dev;
+
if (softc->event_tag != NULL) {
- bus_teardown_intr(dev, softc->event_res, softc->event_tag);
+ bus_teardown_intr(mmio_dev, softc->event_res, softc->event_tag);
}
if (softc->event_res != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, softc->event_rid,
+ bus_release_resource(mmio_dev, SYS_RES_IRQ, softc->event_rid,
softc->event_res);
}
- bus_delete_resource(dev, SYS_RES_IRQ, softc->event_rid);
- PCIB_RELEASE_MSI(device_get_parent(device_get_parent(dev)),
- dev, 1, &softc->event_irq);
+ pci_release_msi(mmio_dev);
}
static bool
amdvi_alloc_intr_resources(struct amdvi_softc *softc)
{
struct amdvi_ctrl *ctrl;
- device_t dev, pcib;
- device_t mmio_dev;
- uint64_t msi_addr;
- uint32_t msi_data;
- int err;
+ device_t dev, mmio_dev;
+ int err, count;
dev = softc->dev;
- pcib = device_get_parent(device_get_parent(dev));
- mmio_dev = pci_find_bsf(PCI_RID2BUS(softc->pci_rid),
- PCI_RID2SLOT(softc->pci_rid), PCI_RID2FUNC(softc->pci_rid));
- if (device_is_attached(mmio_dev)) {
- device_printf(dev,
- "warning: IOMMU device is claimed by another driver %s\n",
- device_get_driver(mmio_dev)->name);
+ mmio_dev = softc->pci_dev;
+ if (!device_is_attached(mmio_dev)) {
+ if (device_set_devclass(mmio_dev, "amdiommu"))
+ return (ENXIO);
+ if (device_set_driver(mmio_dev, &amdiommu_driver))
+ return (ENXIO);
+ device_quiet(mmio_dev);
+ if (device_attach(mmio_dev))
+ return (ENXIO);
}
- softc->event_irq = -1;
- softc->event_rid = 0;
+ softc->event_rid = 1;
/*
* Section 3.7.1 of IOMMU rev 2.0. With MSI, there is only one
* interrupt. XXX: Enable MSI/X support.
*/
- err = PCIB_ALLOC_MSI(pcib, dev, 1, 1, &softc->event_irq);
+ count = 1;
+ err = pci_alloc_msi(mmio_dev, &count);
if (err) {
- device_printf(dev,
+ device_printf(mmio_dev,
"Couldn't find event MSI IRQ resource.\n");
return (ENOENT);
}
- err = bus_set_resource(dev, SYS_RES_IRQ, softc->event_rid,
- softc->event_irq, 1);
- if (err) {
- device_printf(dev, "Couldn't set event MSI resource.\n");
- return (ENXIO);
- }
-
- softc->event_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ softc->event_res = bus_alloc_resource_any(mmio_dev, SYS_RES_IRQ,
&softc->event_rid, RF_ACTIVE);
if (!softc->event_res) {
device_printf(dev,
@@ -835,35 +828,23 @@
return (ENOMEM);
}
- if (bus_setup_intr(dev, softc->event_res,
+ /* Clear interrupt status bits. */
+ ctrl = softc->ctrl;
+ ctrl->status &= AMDVI_STATUS_EV_OF | AMDVI_STATUS_EV_INTR;
+
+ /* Now enable MSI interrupt. */
+ if (bus_setup_intr(mmio_dev, softc->event_res,
INTR_TYPE_MISC | INTR_MPSAFE, NULL, amdvi_event_intr,
softc, &softc->event_tag)) {
device_printf(dev, "Fail to setup event intr\n");
- bus_release_resource(softc->dev, SYS_RES_IRQ,
+ bus_release_resource(mmio_dev, SYS_RES_IRQ,
softc->event_rid, softc->event_res);
softc->event_res = NULL;
return (ENXIO);
}
- bus_describe_intr(dev, softc->event_res, softc->event_tag,
+ bus_describe_intr(mmio_dev, softc->event_res, softc->event_tag,
"fault");
-
- err = PCIB_MAP_MSI(pcib, dev, softc->event_irq, &msi_addr,
- &msi_data);
- if (err) {
- device_printf(dev,
- "Event interrupt config failed, err=%d.\n",
- err);
- amdvi_free_evt_intr_res(softc->dev);
- return (err);
- }
-
- /* Clear interrupt status bits. */
- ctrl = softc->ctrl;
- ctrl->status &= AMDVI_STATUS_EV_OF | AMDVI_STATUS_EV_INTR;
-
- /* Now enable MSI interrupt. */
- pci_enable_msi(mmio_dev, msi_addr, msi_data);
return (0);
}
Index: sys/amd64/vmm/amd/amdvi_priv.h
===================================================================
--- sys/amd64/vmm/amd/amdvi_priv.h
+++ sys/amd64/vmm/amd/amdvi_priv.h
@@ -375,6 +375,7 @@
struct amdvi_softc {
struct amdvi_ctrl *ctrl; /* Control area. */
device_t dev; /* IOMMU device. */
+ device_t pci_dev; /* IOMMU PCI function device. */
enum IvrsType ivhd_type; /* IOMMU IVHD type. */
bool iotlb; /* IOTLB supported by IOMMU */
struct amdvi_cmd *cmd; /* Command descriptor area. */
@@ -384,7 +385,6 @@
struct resource *event_res; /* Event interrupt resource. */
void *event_tag; /* Event interrupt tag. */
int event_max; /* Max number of events. */
- int event_irq;
int event_rid;
/* ACPI various flags. */
uint32_t ivhd_flag; /* ACPI IVHD flag. */
@@ -408,6 +408,8 @@
uint64_t total_cmd; /* Total number of commands. */
};
+extern driver_t amdiommu_driver;
+
int amdvi_setup_hw(struct amdvi_softc *softc);
int amdvi_teardown_hw(struct amdvi_softc *softc);
#endif /* _AMDVI_PRIV_H_ */
Index: sys/amd64/vmm/amd/ivrs_drv.c
===================================================================
--- sys/amd64/vmm/amd/ivrs_drv.c
+++ sys/amd64/vmm/amd/ivrs_drv.c
@@ -44,6 +44,8 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
#include "io/iommu.h"
#include "amdvi_priv.h"
@@ -627,6 +629,9 @@
softc->dev = dev;
ivhd = ivhd_hdrs[unit];
KASSERT(ivhd, ("ivhd is NULL"));
+ softc->pci_dev = pci_find_bsf(PCI_RID2BUS(ivhd->Header.DeviceId),
+ PCI_RID2SLOT(ivhd->Header.DeviceId),
+ PCI_RID2FUNC(ivhd->Header.DeviceId));
softc->ivhd_type = ivhd->Header.Type;
softc->pci_seg = ivhd->PciSegmentGroup;
Index: sys/modules/vmm/Makefile
===================================================================
--- sys/modules/vmm/Makefile
+++ sys/modules/vmm/Makefile
@@ -51,6 +51,7 @@
# amd-specific files
.PATH: ${SRCTOP}/sys/amd64/vmm/amd
SRCS+= vmcb.c \
+ amdiommu.c \
svm.c \
svm_support.S \
npt.c \

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 10, 5:03 AM (20 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23519506
Default Alt Text
D28984.id84840.diff (8 KB)

Event Timeline