summaryrefslogtreecommitdiffstats
path: root/sys/x86/iommu/intel_fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/x86/iommu/intel_fault.c')
-rw-r--r--sys/x86/iommu/intel_fault.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/x86/iommu/intel_fault.c b/sys/x86/iommu/intel_fault.c
index 18f8fef..af18010 100644
--- a/sys/x86/iommu/intel_fault.c
+++ b/sys/x86/iommu/intel_fault.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
@@ -203,19 +205,28 @@ dmar_fault_task(void *arg, int pending __unused)
DMAR_FAULT_UNLOCK(unit);
sid = DMAR_FRCD2_SID(fault_rec[1]);
- bus = (sid >> 8) & 0xf;
- slot = (sid >> 3) & 0x1f;
- func = sid & 0x7;
printf("DMAR%d: ", unit->unit);
DMAR_LOCK(unit);
- ctx = dmar_find_ctx_locked(unit, bus, slot, func);
+ ctx = dmar_find_ctx_locked(unit, sid);
if (ctx == NULL) {
printf("<unknown dev>:");
+
+ /*
+ * Note that the slot and function will not be correct
+ * if ARI is in use, but without a ctx entry we have
+ * no way of knowing whether ARI is in use or not.
+ */
+ bus = PCI_RID2BUS(sid);
+ slot = PCI_RID2SLOT(sid);
+ func = PCI_RID2FUNC(sid);
} else {
ctx->flags |= DMAR_CTX_FAULTED;
ctx->last_fault_rec[0] = fault_rec[0];
ctx->last_fault_rec[1] = fault_rec[1];
device_print_prettyname(ctx->ctx_tag.owner);
+ bus = pci_get_bus(ctx->ctx_tag.owner);
+ slot = pci_get_slot(ctx->ctx_tag.owner);
+ func = pci_get_function(ctx->ctx_tag.owner);
}
DMAR_UNLOCK(unit);
printf(
OpenPOWER on IntegriCloud