Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148331863
D22434.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D22434.diff
View Options
Index: head/sys/x86/include/bus_dma.h
===================================================================
--- head/sys/x86/include/bus_dma.h
+++ head/sys/x86/include/bus_dma.h
@@ -191,5 +191,7 @@
return (tc->impl->map_complete(dmat, map, segs, nsegs, error));
}
+bool bus_dma_dmar_set_buswide(device_t dev);
+
#endif /* !_X86_BUS_DMA_H_ */
Index: head/sys/x86/iommu/busdma_dmar.c
===================================================================
--- head/sys/x86/iommu/busdma_dmar.c
+++ head/sys/x86/iommu/busdma_dmar.c
@@ -289,6 +289,34 @@
return (res);
}
+bool
+bus_dma_dmar_set_buswide(device_t dev)
+{
+ struct dmar_unit *dmar;
+ device_t parent;
+ u_int busno, slot, func;
+
+ parent = device_get_parent(dev);
+ if (device_get_devclass(parent) != devclass_find("pci"))
+ return (false);
+ dmar = dmar_find(dev, bootverbose);
+ if (dmar == NULL)
+ return (false);
+ busno = pci_get_bus(dev);
+ slot = pci_get_slot(dev);
+ func = pci_get_function(dev);
+ if (slot != 0 || func != 0) {
+ if (bootverbose) {
+ device_printf(dev,
+ "dmar%d pci%d:%d:%d requested buswide busdma\n",
+ dmar->unit, busno, slot, func);
+ }
+ return (false);
+ }
+ dmar_set_buswide_ctx(dmar, busno);
+ return (true);
+}
+
static MALLOC_DEFINE(M_DMAR_DMAMAP, "dmar_dmamap", "Intel DMAR DMA Map");
static void dmar_bus_schedule_dmamap(struct dmar_unit *unit,
Index: head/sys/x86/iommu/intel_ctx.c
===================================================================
--- head/sys/x86/iommu/intel_ctx.c
+++ head/sys/x86/iommu/intel_ctx.c
@@ -67,8 +67,8 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
-#include <x86/iommu/intel_dmar.h>
#include <dev/pci/pcireg.h>
+#include <x86/iommu/intel_dmar.h>
#include <dev/pci/pcivar.h>
static MALLOC_DEFINE(M_DMAR_CTX, "dmar_ctx", "Intel DMAR Context");
@@ -141,20 +141,9 @@
}
static void
-ctx_id_entry_init(struct dmar_ctx *ctx, dmar_ctx_entry_t *ctxp, bool move)
+ctx_id_entry_init_one(dmar_ctx_entry_t *ctxp, struct dmar_domain *domain,
+ vm_page_t ctx_root)
{
- struct dmar_unit *unit;
- struct dmar_domain *domain;
- vm_page_t ctx_root;
-
- domain = ctx->domain;
- unit = domain->dmar;
- KASSERT(move || (ctxp->ctx1 == 0 && ctxp->ctx2 == 0),
- ("dmar%d: initialized ctx entry %d:%d:%d 0x%jx 0x%jx",
- unit->unit, pci_get_bus(ctx->ctx_tag.owner),
- pci_get_slot(ctx->ctx_tag.owner),
- pci_get_function(ctx->ctx_tag.owner),
- ctxp->ctx1, ctxp->ctx2));
/*
* For update due to move, the store is not atomic. It is
* possible that DMAR read upper doubleword, while low
@@ -166,17 +155,49 @@
*/
dmar_pte_store1(&ctxp->ctx2, DMAR_CTX2_DID(domain->domain) |
domain->awlvl);
+ if (ctx_root == NULL) {
+ dmar_pte_store1(&ctxp->ctx1, DMAR_CTX1_T_PASS | DMAR_CTX1_P);
+ } else {
+ dmar_pte_store1(&ctxp->ctx1, DMAR_CTX1_T_UNTR |
+ (DMAR_CTX1_ASR_MASK & VM_PAGE_TO_PHYS(ctx_root)) |
+ DMAR_CTX1_P);
+ }
+}
+
+static void
+ctx_id_entry_init(struct dmar_ctx *ctx, dmar_ctx_entry_t *ctxp, bool move,
+ int busno)
+{
+ struct dmar_unit *unit;
+ struct dmar_domain *domain;
+ vm_page_t ctx_root;
+ int i;
+
+ domain = ctx->domain;
+ unit = domain->dmar;
+ KASSERT(move || (ctxp->ctx1 == 0 && ctxp->ctx2 == 0),
+ ("dmar%d: initialized ctx entry %d:%d:%d 0x%jx 0x%jx",
+ unit->unit, busno, pci_get_slot(ctx->ctx_tag.owner),
+ pci_get_function(ctx->ctx_tag.owner),
+ ctxp->ctx1, ctxp->ctx2));
+
if ((domain->flags & DMAR_DOMAIN_IDMAP) != 0 &&
(unit->hw_ecap & DMAR_ECAP_PT) != 0) {
KASSERT(domain->pgtbl_obj == NULL,
("ctx %p non-null pgtbl_obj", ctx));
- dmar_pte_store1(&ctxp->ctx1, DMAR_CTX1_T_PASS | DMAR_CTX1_P);
+ ctx_root = NULL;
} else {
ctx_root = dmar_pgalloc(domain->pgtbl_obj, 0, DMAR_PGF_NOALLOC);
- dmar_pte_store1(&ctxp->ctx1, DMAR_CTX1_T_UNTR |
- (DMAR_CTX1_ASR_MASK & VM_PAGE_TO_PHYS(ctx_root)) |
- DMAR_CTX1_P);
}
+
+ if (dmar_is_buswide_ctx(unit, busno)) {
+ MPASS(!move);
+ for (i = 0; i <= PCI_BUSMAX; i++) {
+ ctx_id_entry_init_one(&ctxp[i], domain, ctx_root);
+ }
+ } else {
+ ctx_id_entry_init_one(ctxp, domain, ctx_root);
+ }
dmar_flush_ctx_to_ram(unit, ctxp);
}
@@ -444,6 +465,9 @@
enable = false;
TD_PREP_PINNED_ASSERT;
DMAR_LOCK(dmar);
+ KASSERT(!dmar_is_buswide_ctx(dmar, bus) || (slot == 0 && func == 0),
+ ("dmar%d pci%d:%d:%d get_ctx for buswide", dmar->unit, bus,
+ slot, func));
ctx = dmar_find_ctx_locked(dmar, rid);
error = 0;
if (ctx == NULL) {
@@ -492,7 +516,7 @@
if (LIST_EMPTY(&dmar->domains))
enable = true;
LIST_INSERT_HEAD(&dmar->domains, domain, link);
- ctx_id_entry_init(ctx, ctxp, false);
+ ctx_id_entry_init(ctx, ctxp, false, bus);
if (dev != NULL) {
device_printf(dev,
"dmar%d pci%d:%d:%d:%d rid %x domain %d mgaw %d "
@@ -597,7 +621,7 @@
dmar_ctx_unlink(ctx);
ctx->domain = domain;
dmar_ctx_link(ctx);
- ctx_id_entry_init(ctx, ctxp, true);
+ ctx_id_entry_init(ctx, ctxp, true, PCI_BUSMAX + 100);
dmar_unmap_pgtbl(sf);
error = dmar_flush_for_ctx_entry(dmar, true);
/* If flush failed, rolling back would not work as well. */
Index: head/sys/x86/iommu/intel_dmar.h
===================================================================
--- head/sys/x86/iommu/intel_dmar.h
+++ head/sys/x86/iommu/intel_dmar.h
@@ -239,6 +239,15 @@
struct taskqueue *delayed_taskqueue;
int dma_enabled;
+
+ /*
+ * Bitmap of buses for which context must ignore slot:func,
+ * duplicating the page table pointer into all context table
+ * entries. This is a client-controlled quirk to support some
+ * NTBs.
+ */
+ uint32_t buswide_ctxs[(PCI_BUSMAX + 1) / NBBY / sizeof(uint32_t)];
+
};
#define DMAR_LOCK(dmar) mtx_lock(&(dmar)->lock)
@@ -376,6 +385,9 @@
int dmar_init_irt(struct dmar_unit *unit);
void dmar_fini_irt(struct dmar_unit *unit);
+
+void dmar_set_buswide_ctx(struct dmar_unit *unit, u_int busno);
+bool dmar_is_buswide_ctx(struct dmar_unit *unit, u_int busno);
#define DMAR_GM_CANWAIT 0x0001
#define DMAR_GM_CANSPLIT 0x0002
Index: head/sys/x86/iommu/intel_drv.c
===================================================================
--- head/sys/x86/iommu/intel_drv.c
+++ head/sys/x86/iommu/intel_drv.c
@@ -69,9 +69,9 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
-#include <x86/iommu/intel_dmar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <x86/iommu/intel_dmar.h>
#ifdef DEV_APIC
#include "pcib_if.h"
@@ -594,6 +594,26 @@
DRIVER_MODULE(dmar, acpi, dmar_driver, dmar_devclass, 0, 0);
MODULE_DEPEND(dmar, acpi, 1, 1, 1);
+
+void
+dmar_set_buswide_ctx(struct dmar_unit *unit, u_int busno)
+{
+
+ MPASS(busno <= PCI_BUSMAX);
+ DMAR_LOCK(unit);
+ unit->buswide_ctxs[busno / NBBY / sizeof(uint32_t)] |=
+ 1 << (busno % (NBBY * sizeof(uint32_t)));
+ DMAR_UNLOCK(unit);
+}
+
+bool
+dmar_is_buswide_ctx(struct dmar_unit *unit, u_int busno)
+{
+
+ MPASS(busno <= PCI_BUSMAX);
+ return ((unit->buswide_ctxs[busno / NBBY / sizeof(uint32_t)] &
+ (1U << (busno % (NBBY * sizeof(uint32_t))))) != 0);
+}
static void
dmar_print_path(int busno, int depth, const ACPI_DMAR_PCI_PATH *path)
Index: head/sys/x86/iommu/intel_gas.c
===================================================================
--- head/sys/x86/iommu/intel_gas.c
+++ head/sys/x86/iommu/intel_gas.c
@@ -67,6 +67,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
/*
Index: head/sys/x86/iommu/intel_idpgtbl.c
===================================================================
--- head/sys/x86/iommu/intel_idpgtbl.c
+++ head/sys/x86/iommu/intel_idpgtbl.c
@@ -66,6 +66,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
static int domain_unmap_buf_locked(struct dmar_domain *domain,
Index: head/sys/x86/iommu/intel_intrmap.c
===================================================================
--- head/sys/x86/iommu/intel_intrmap.c
+++ head/sys/x86/iommu/intel_intrmap.c
@@ -55,6 +55,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
#include <dev/pci/pcivar.h>
#include <x86/iommu/iommu_intrmap.h>
Index: head/sys/x86/iommu/intel_qi.c
===================================================================
--- head/sys/x86/iommu/intel_qi.c
+++ head/sys/x86/iommu/intel_qi.c
@@ -58,6 +58,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
static bool
Index: head/sys/x86/iommu/intel_quirks.c
===================================================================
--- head/sys/x86/iommu/intel_quirks.c
+++ head/sys/x86/iommu/intel_quirks.c
@@ -60,6 +60,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
#include <dev/pci/pcivar.h>
Index: head/sys/x86/iommu/intel_utils.c
===================================================================
--- head/sys/x86/iommu/intel_utils.c
+++ head/sys/x86/iommu/intel_utils.c
@@ -66,6 +66,7 @@
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
+#include <dev/pci/pcireg.h>
#include <x86/iommu/intel_dmar.h>
u_int
Index: head/sys/x86/x86/busdma_machdep.c
===================================================================
--- head/sys/x86/x86/busdma_machdep.c
+++ head/sys/x86/x86/busdma_machdep.c
@@ -33,6 +33,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_acpi.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@@ -245,3 +247,10 @@
return (tc->impl->tag_destroy(dmat));
}
+#ifndef ACPI_DMAR
+bool
+bus_dma_dmar_set_buswide(device_t dev)
+{
+ return (false);
+}
+#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 18, 5:21 AM (8 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29883229
Default Alt Text
D22434.diff (9 KB)
Attached To
Mode
D22434: bus_dma_dmar_set_buswide(9): KPI to indicate that whole dmar context should share page tables.
Attached
Detach File
Event Timeline
Log In to Comment