svn commit: r355138 - in head/sys/x86: include iommu x86
Konstantin Belousov
kib at FreeBSD.org
Wed Nov 27 19:57:19 UTC 2019
Author: kib
Date: Wed Nov 27 19:57:17 2019
New Revision: 355138
URL: https://svnweb.freebsd.org/changeset/base/355138
Log:
bus_dma_dmar_load_ident(9): load identity mapping into the map.
Requested, reviewed and tested by: mav
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D22559
Modified:
head/sys/x86/include/bus_dma.h
head/sys/x86/iommu/busdma_dmar.c
head/sys/x86/iommu/intel_ctx.c
head/sys/x86/iommu/intel_dmar.h
head/sys/x86/iommu/intel_gas.c
head/sys/x86/x86/busdma_machdep.c
Modified: head/sys/x86/include/bus_dma.h
==============================================================================
--- head/sys/x86/include/bus_dma.h Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/include/bus_dma.h Wed Nov 27 19:57:17 2019 (r355138)
@@ -193,6 +193,8 @@ _bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t
#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_ */
Modified: head/sys/x86/iommu/busdma_dmar.c
==============================================================================
--- head/sys/x86/iommu/busdma_dmar.c Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/iommu/busdma_dmar.c Wed Nov 27 19:57:17 2019 (r355138)
@@ -973,3 +973,66 @@ dmar_fini_busdma(struct dmar_unit *unit)
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);
+}
Modified: head/sys/x86/iommu/intel_ctx.c
==============================================================================
--- head/sys/x86/iommu/intel_ctx.c Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/iommu/intel_ctx.c Wed Nov 27 19:57:17 2019 (r355138)
@@ -279,7 +279,7 @@ domain_init_rmrr(struct dmar_domain *domain, device_t
}
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
Modified: head/sys/x86/iommu/intel_dmar.h
==============================================================================
--- head/sys/x86/iommu/intel_dmar.h Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/iommu/intel_dmar.h Wed Nov 27 19:57:17 2019 (r355138)
@@ -391,6 +391,7 @@ bool dmar_is_buswide_ctx(struct dmar_unit *unit, u_int
#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
Modified: head/sys/x86/iommu/intel_gas.c
==============================================================================
--- head/sys/x86/iommu/intel_gas.c Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/iommu/intel_gas.c Wed Nov 27 19:57:17 2019 (r355138)
@@ -543,13 +543,15 @@ dmar_gas_alloc_region(struct dmar_domain *domain, stru
*/
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 @@ dmar_gas_alloc_region(struct dmar_domain *domain, stru
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 @@ dmar_gas_map_region(struct dmar_domain *domain, struct
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;
Modified: head/sys/x86/x86/busdma_machdep.c
==============================================================================
--- head/sys/x86/x86/busdma_machdep.c Wed Nov 27 19:49:55 2019 (r355137)
+++ head/sys/x86/x86/busdma_machdep.c Wed Nov 27 19:57:17 2019 (r355138)
@@ -253,4 +253,11 @@ bus_dma_dmar_set_buswide(device_t dev)
{
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
More information about the svn-src-all
mailing list