Page MenuHomeFreeBSD

D25665.diff
No OneTemporary

D25665.diff

Index: head/sys/sys/iommu.h
===================================================================
--- head/sys/sys/iommu.h
+++ head/sys/sys/iommu.h
@@ -35,6 +35,7 @@
#define _SYS_IOMMU_H_
#include <sys/queue.h>
+#include <sys/taskqueue.h>
#include <sys/tree.h>
#include <sys/types.h>
@@ -43,6 +44,7 @@
/* Guest or bus address, before translation. */
typedef uint64_t iommu_gaddr_t;
+struct bus_dma_tag_common;
struct iommu_map_entry;
TAILQ_HEAD(iommu_map_entries_tailq, iommu_map_entry);
@@ -102,6 +104,7 @@
struct iommu_unit *iommu; /* (c) */
struct mtx lock; /* (c) */
struct task unload_task; /* (c) */
+ u_int entries_cnt; /* (d) */
struct iommu_map_entries_tailq unload_entries; /* (d) Entries to
unload */
};
@@ -128,6 +131,16 @@
#define IOMMU_DOMAIN_LOCK(dom) mtx_lock(&(dom)->lock)
#define IOMMU_DOMAIN_UNLOCK(dom) mtx_unlock(&(dom)->lock)
#define IOMMU_DOMAIN_ASSERT_LOCKED(dom) mtx_assert(&(dom)->lock, MA_OWNED)
+
+static inline bool
+iommu_test_boundary(iommu_gaddr_t start, iommu_gaddr_t size,
+ iommu_gaddr_t boundary)
+{
+
+ if (boundary == 0)
+ return (true);
+ return (start + size <= ((start + boundary) & ~(boundary - 1)));
+}
void iommu_free_ctx(struct iommu_ctx *ctx);
void iommu_free_ctx_locked(struct iommu_unit *iommu, struct iommu_ctx *ctx);
Index: head/sys/x86/iommu/busdma_dmar.c
===================================================================
--- head/sys/x86/iommu/busdma_dmar.c
+++ head/sys/x86/iommu/busdma_dmar.c
@@ -39,6 +39,7 @@
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/interrupt.h>
+#include <sys/iommu.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/lock.h>
@@ -62,11 +63,13 @@
#include <machine/atomic.h>
#include <machine/bus.h>
#include <machine/md_var.h>
+#if defined(__amd64__) || defined(__i386__)
#include <machine/specialreg.h>
#include <x86/include/busdma_impl.h>
#include <x86/iommu/intel_reg.h>
#include <x86/iommu/busdma_dmar.h>
#include <x86/iommu/intel_dmar.h>
+#endif
/*
* busdma_dmar.c, the implementation of the busdma(9) interface using
@@ -112,11 +115,11 @@
/*
* Given original device, find the requester ID that will be seen by
- * the DMAR unit and used for page table lookup. PCI bridges may take
+ * the IOMMU unit and used for page table lookup. PCI bridges may take
* ownership of transactions from downstream devices, so it may not be
* the same as the BSF of the target device. In those cases, all
* devices downstream of the bridge must share a single mapping
- * domain, and must collectively be assigned to use either DMAR or
+ * domain, and must collectively be assigned to use either IOMMU or
* bounce mapping.
*/
device_t
@@ -135,7 +138,7 @@
/*
* Walk the bridge hierarchy from the target device to the
- * host port to find the translating bridge nearest the DMAR
+ * host port to find the translating bridge nearest the IOMMU
* unit.
*/
for (;;) {
@@ -173,7 +176,7 @@
} else {
/*
* Device is not PCIe, it cannot be seen as a
- * requester by DMAR unit. Check whether the
+ * requester by IOMMU unit. Check whether the
* bridge is PCIe.
*/
bridge_is_pcie = pci_find_cap(pcib, PCIY_EXPRESS,
@@ -243,8 +246,8 @@
/*
* If the user requested the IOMMU disabled for the device, we
- * cannot disable the DMAR, due to possibility of other
- * devices on the same DMAR still requiring translation.
+ * cannot disable the IOMMU unit, due to possibility of other
+ * devices on the same IOMMU unit still requiring translation.
* Instead provide the identity mapping for the device
* context.
*/
@@ -279,13 +282,16 @@
bus_dma_tag_t res;
unit = iommu_find(child, bootverbose);
- /* Not in scope of any DMAR ? */
+ /* Not in scope of any IOMMU ? */
if (unit == NULL)
return (NULL);
if (!unit->dma_enabled)
return (NULL);
+
+#if defined(__amd64__) || defined(__i386__)
dmar_quirks_pre_use(unit);
dmar_instantiate_rmrr_ctxs(unit);
+#endif
ctx = iommu_instantiate_ctx(unit, child, false);
res = ctx == NULL ? NULL : (bus_dma_tag_t)ctx->tag;
@@ -536,7 +542,7 @@
bus_size_t buflen1;
int error, idx, gas_flags, seg;
- KASSERT(offset < DMAR_PAGE_SIZE, ("offset %d", offset));
+ KASSERT(offset < IOMMU_PAGE_SIZE, ("offset %d", offset));
if (segs == NULL)
segs = tag->segments;
ctx = tag->ctx;
@@ -621,7 +627,7 @@
idx += OFF_TO_IDX(trunc_page(offset + buflen1));
offset += buflen1;
- offset &= DMAR_PAGE_MASK;
+ offset &= IOMMU_PAGE_MASK;
buflen -= buflen1;
}
if (error == 0)
@@ -841,7 +847,7 @@
}
/*
- * The limitations of busdma KPI forces the dmar to perform the actual
+ * The limitations of busdma KPI forces the iommu to perform the actual
* unload, consisting of the unmapping of the map entries page tables,
* from the delayed context on i386, since page table page mapping
* might require a sleep to be successfull. The unfortunate
Index: head/sys/x86/iommu/intel_dmar.h
===================================================================
--- head/sys/x86/iommu/intel_dmar.h
+++ head/sys/x86/iommu/intel_dmar.h
@@ -77,7 +77,6 @@
LIST_HEAD(, dmar_ctx) contexts; /* (u) */
vm_object_t pgtbl_obj; /* (c) Page table pages */
u_int flags; /* (u) */
- u_int entries_cnt; /* (d) */
struct dmar_gas_entries_tree rb_root; /* (d) */
struct iommu_map_entry *first_place, *last_place; /* (d) */
u_int batch_no;
@@ -458,16 +457,6 @@
#else
*dst = 0;
#endif
-}
-
-static inline bool
-iommu_test_boundary(iommu_gaddr_t start, iommu_gaddr_t size,
- iommu_gaddr_t boundary)
-{
-
- if (boundary == 0)
- return (true);
- return (start + size <= ((start + boundary) & ~(boundary - 1)));
}
extern struct timespec dmar_hw_timeout;
Index: head/sys/x86/iommu/intel_drv.c
===================================================================
--- head/sys/x86/iommu/intel_drv.c
+++ head/sys/x86/iommu/intel_drv.c
@@ -1160,7 +1160,7 @@
" ctx_cnt %d flags %x pgobj %p map_ents %u\n",
domain, domain->domain, domain->mgaw, domain->agaw, domain->pglvl,
(uintmax_t)domain->end, domain->refs, domain->ctx_cnt,
- domain->flags, domain->pgtbl_obj, domain->entries_cnt);
+ domain->flags, domain->pgtbl_obj, domain->iodom.entries_cnt);
if (!LIST_EMPTY(&domain->contexts)) {
db_printf(" Contexts:\n");
LIST_FOREACH(ctx, &domain->contexts, link)
Index: head/sys/x86/iommu/intel_gas.c
===================================================================
--- head/sys/x86/iommu/intel_gas.c
+++ head/sys/x86/iommu/intel_gas.c
@@ -98,7 +98,7 @@
0 ? M_WAITOK : M_NOWAIT) | M_ZERO);
if (res != NULL) {
res->domain = (struct iommu_domain *)domain;
- atomic_add_int(&domain->entries_cnt, 1);
+ atomic_add_int(&domain->iodom.entries_cnt, 1);
}
return (res);
}
@@ -110,7 +110,7 @@
KASSERT(domain == (struct dmar_domain *)entry->domain,
("mismatched free domain %p entry %p entry->domain %p", domain,
entry, entry->domain));
- atomic_subtract_int(&domain->entries_cnt, 1);
+ atomic_subtract_int(&domain->iodom.entries_cnt, 1);
uma_zfree(iommu_map_entry_zone, entry);
}
@@ -214,7 +214,7 @@
end = dmar_gas_alloc_entry(domain, DMAR_PGF_WAITOK);
DMAR_DOMAIN_LOCK(domain);
- KASSERT(domain->entries_cnt == 2, ("dirty domain %p", domain));
+ KASSERT(domain->iodom.entries_cnt == 2, ("dirty domain %p", domain));
KASSERT(RB_EMPTY(&domain->rb_root), ("non-empty entries %p", domain));
begin->start = 0;
@@ -239,7 +239,8 @@
struct iommu_map_entry *entry, *entry1;
DMAR_DOMAIN_ASSERT_LOCKED(domain);
- KASSERT(domain->entries_cnt == 2, ("domain still in use %p", domain));
+ KASSERT(domain->iodom.entries_cnt == 2,
+ ("domain still in use %p", domain));
entry = RB_MIN(dmar_gas_entries_tree, &domain->rb_root);
KASSERT(entry->start == 0, ("start entry start %p", domain));
Index: head/sys/x86/iommu/intel_reg.h
===================================================================
--- head/sys/x86/iommu/intel_reg.h
+++ head/sys/x86/iommu/intel_reg.h
@@ -41,6 +41,9 @@
#define DMAR_NPTEPGSHIFT 9
#define DMAR_PTEMASK (DMAR_NPTEPG - 1)
+#define IOMMU_PAGE_SIZE DMAR_PAGE_SIZE
+#define IOMMU_PAGE_MASK DMAR_PAGE_MASK
+
typedef struct dmar_root_entry {
uint64_t r1;
uint64_t r2;

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 23, 1:53 AM (6 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16785289
Default Alt Text
D25665.diff (8 KB)

Event Timeline