Author: kib
Date: Wed Dec  4 09:18:32 2019
New Revision: 355384
URL: https://svnweb.freebsd.org/changeset/base/355384

Log:
  MFC r355138:
  bus_dma_dmar_load_ident(9): load identity mapping into the map.

Modified:
  stable/12/sys/x86/include/bus_dma.h
  stable/12/sys/x86/iommu/busdma_dmar.c
  stable/12/sys/x86/iommu/intel_ctx.c
  stable/12/sys/x86/iommu/intel_dmar.h
  stable/12/sys/x86/iommu/intel_gas.c
  stable/12/sys/x86/x86/busdma_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/x86/include/bus_dma.h
==============================================================================
--- stable/12/sys/x86/include/bus_dma.h Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/include/bus_dma.h Wed Dec  4 09:18:32 2019        
(r355384)
@@ -181,6 +181,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: stable/12/sys/x86/iommu/busdma_dmar.c
==============================================================================
--- stable/12/sys/x86/iommu/busdma_dmar.c       Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/iommu/busdma_dmar.c       Wed Dec  4 09:18:32 2019        
(r355384)
@@ -950,3 +950,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: stable/12/sys/x86/iommu/intel_ctx.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_ctx.c Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/iommu/intel_ctx.c Wed Dec  4 09:18:32 2019        
(r355384)
@@ -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: stable/12/sys/x86/iommu/intel_dmar.h
==============================================================================
--- stable/12/sys/x86/iommu/intel_dmar.h        Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/iommu/intel_dmar.h        Wed Dec  4 09:18:32 2019        
(r355384)
@@ -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: stable/12/sys/x86/iommu/intel_gas.c
==============================================================================
--- stable/12/sys/x86/iommu/intel_gas.c Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/iommu/intel_gas.c Wed Dec  4 09:18:32 2019        
(r355384)
@@ -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 != NULL && 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: stable/12/sys/x86/x86/busdma_machdep.c
==============================================================================
--- stable/12/sys/x86/x86/busdma_machdep.c      Wed Dec  4 08:21:54 2019        
(r355383)
+++ stable/12/sys/x86/x86/busdma_machdep.c      Wed Dec  4 09:18:32 2019        
(r355384)
@@ -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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to