Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106160364
D22559.id64970.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D22559.id64970.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
@@ -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
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 27, 9:27 AM (11 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15607972
Default Alt Text
D22559.id64970.diff (5 KB)
Attached To
Mode
D22559: bus_dma_dmar_load_ident((): load identity mapping into the map
Attached
Detach File
Event Timeline
Log In to Comment