Page MenuHomeFreeBSD

D22559.diff
No OneTemporary

D22559.diff

Index: head/sys/x86/include/bus_dma.h
===================================================================
--- head/sys/x86/include/bus_dma.h
+++ head/sys/x86/include/bus_dma.h
@@ -193,6 +193,8 @@
#ifdef _KERNEL
bool bus_dma_dmar_set_buswide(device_t dev);
+int bus_dma_dmar_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_paddr_t start, vm_size_t length, int flags);
#endif
#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
@@ -973,3 +973,66 @@
taskqueue_free(unit->delayed_taskqueue);
unit->delayed_taskqueue = NULL;
}
+
+int
+bus_dma_dmar_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map1,
+ vm_paddr_t start, vm_size_t length, int flags)
+{
+ struct bus_dma_tag_common *tc;
+ struct bus_dma_tag_dmar *tag;
+ struct bus_dmamap_dmar *map;
+ struct dmar_ctx *ctx;
+ struct dmar_domain *domain;
+ struct dmar_map_entry *entry;
+ vm_page_t *ma;
+ vm_size_t i;
+ int error;
+ bool waitok;
+
+ MPASS((start & PAGE_MASK) == 0);
+ MPASS((length & PAGE_MASK) == 0);
+ MPASS(length > 0);
+ MPASS(start + length >= start);
+ MPASS((flags & ~(BUS_DMA_NOWAIT | BUS_DMA_NOWRITE)) == 0);
+
+ tc = (struct bus_dma_tag_common *)dmat;
+ if (tc->impl != &bus_dma_dmar_impl)
+ return (0);
+
+ tag = (struct bus_dma_tag_dmar *)dmat;
+ ctx = tag->ctx;
+ domain = ctx->domain;
+ map = (struct bus_dmamap_dmar *)map1;
+ waitok = (flags & BUS_DMA_NOWAIT) != 0;
+
+ entry = dmar_gas_alloc_entry(domain, waitok ? 0 : DMAR_PGF_WAITOK);
+ if (entry == NULL)
+ return (ENOMEM);
+ entry->start = start;
+ entry->end = start + length;
+ ma = malloc(sizeof(vm_page_t) * atop(length), M_TEMP, waitok ?
+ M_WAITOK : M_NOWAIT);
+ if (ma == NULL) {
+ dmar_gas_free_entry(domain, entry);
+ return (ENOMEM);
+ }
+ for (i = 0; i < atop(length); i++) {
+ ma[i] = vm_page_getfake(entry->start + PAGE_SIZE * i,
+ VM_MEMATTR_DEFAULT);
+ }
+ error = dmar_gas_map_region(domain, entry, DMAR_MAP_ENTRY_READ |
+ ((flags & BUS_DMA_NOWRITE) ? 0 : DMAR_MAP_ENTRY_WRITE),
+ waitok ? DMAR_GM_CANWAIT : 0, ma);
+ if (error == 0) {
+ DMAR_DOMAIN_LOCK(domain);
+ TAILQ_INSERT_TAIL(&map->map_entries, entry, dmamap_link);
+ entry->flags |= DMAR_MAP_ENTRY_MAP;
+ DMAR_DOMAIN_UNLOCK(domain);
+ } else {
+ dmar_domain_unload_entry(entry, true);
+ }
+ for (i = 0; i < atop(length); i++)
+ vm_page_putfake(ma[i]);
+ free(ma, M_TEMP);
+ return (error);
+}
Index: head/sys/x86/iommu/intel_ctx.c
===================================================================
--- head/sys/x86/iommu/intel_ctx.c
+++ head/sys/x86/iommu/intel_ctx.c
@@ -279,7 +279,7 @@
}
error1 = dmar_gas_map_region(domain, entry,
DMAR_MAP_ENTRY_READ | DMAR_MAP_ENTRY_WRITE,
- DMAR_GM_CANWAIT, ma);
+ DMAR_GM_CANWAIT | DMAR_GM_RMRR, ma);
/*
* Non-failed RMRR entries are owned by context rb
* tree. Get rid of the failed entry, but do not stop
Index: head/sys/x86/iommu/intel_dmar.h
===================================================================
--- head/sys/x86/iommu/intel_dmar.h
+++ head/sys/x86/iommu/intel_dmar.h
@@ -391,6 +391,7 @@
#define DMAR_GM_CANWAIT 0x0001
#define DMAR_GM_CANSPLIT 0x0002
+#define DMAR_GM_RMRR 0x0004
#define DMAR_PGF_WAITOK 0x0001
#define DMAR_PGF_ZERO 0x0002
Index: head/sys/x86/iommu/intel_gas.c
===================================================================
--- head/sys/x86/iommu/intel_gas.c
+++ head/sys/x86/iommu/intel_gas.c
@@ -543,13 +543,15 @@
*/
if (prev != NULL && prev->end > entry->start &&
(prev->flags & DMAR_MAP_ENTRY_PLACE) == 0) {
- if ((prev->flags & DMAR_MAP_ENTRY_RMRR) == 0)
+ if ((flags & DMAR_GM_RMRR) == 0 ||
+ (prev->flags & DMAR_MAP_ENTRY_RMRR) == 0)
return (EBUSY);
entry->start = prev->end;
}
if (next->start < entry->end &&
(next->flags & DMAR_MAP_ENTRY_PLACE) == 0) {
- if ((next->flags & DMAR_MAP_ENTRY_RMRR) == 0)
+ if ((flags & DMAR_GM_RMRR) == 0 ||
+ (next->flags & DMAR_MAP_ENTRY_RMRR) == 0)
return (EBUSY);
entry->end = next->start;
}
@@ -569,7 +571,8 @@
found = dmar_gas_rb_insert(domain, entry);
KASSERT(found, ("found RMRR dup %p start %jx end %jx",
domain, (uintmax_t)entry->start, (uintmax_t)entry->end));
- entry->flags = DMAR_MAP_ENTRY_RMRR;
+ if ((flags & DMAR_GM_RMRR) != 0)
+ entry->flags = DMAR_MAP_ENTRY_RMRR;
#ifdef INVARIANTS
struct dmar_map_entry *ip, *in;
@@ -689,7 +692,7 @@
KASSERT(entry->flags == 0, ("used RMRR entry %p %p %x", domain,
entry, entry->flags));
- KASSERT((flags & ~(DMAR_GM_CANWAIT)) == 0,
+ KASSERT((flags & ~(DMAR_GM_CANWAIT | DMAR_GM_RMRR)) == 0,
("invalid flags 0x%x", flags));
start = entry->start;
Index: head/sys/x86/x86/busdma_machdep.c
===================================================================
--- head/sys/x86/x86/busdma_machdep.c
+++ head/sys/x86/x86/busdma_machdep.c
@@ -253,4 +253,11 @@
{
return (false);
}
+
+int
+bus_dma_dmar_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map,
+ vm_paddr_t start, vm_size_t length, int flags)
+{
+ return (0);
+}
#endif

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 26, 9:23 PM (12 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15607972
Default Alt Text
D22559.diff (5 KB)

Event Timeline