Page MenuHomeFreeBSD

D19753.id55738.diff
No OneTemporary

D19753.id55738.diff

Index: sys/x86/iommu/busdma_dmar.c
===================================================================
--- sys/x86/iommu/busdma_dmar.c
+++ sys/x86/iommu/busdma_dmar.c
@@ -665,9 +665,9 @@
{
struct bus_dma_tag_dmar *tag;
struct bus_dmamap_dmar *map;
- vm_page_t *ma;
- vm_paddr_t pstart, pend;
- int error, i, ma_cnt, offset;
+ vm_page_t *ma, fma;
+ vm_paddr_t pstart, pend, paddr;
+ int error, i, ma_cnt, mflags, offset;
tag = (struct bus_dma_tag_dmar *)dmat;
map = (struct bus_dmamap_dmar *)map1;
@@ -675,14 +675,36 @@
pend = round_page(buf + buflen);
offset = buf & PAGE_MASK;
ma_cnt = OFF_TO_IDX(pend - pstart);
- ma = malloc(sizeof(vm_page_t) * ma_cnt, M_DEVBUF, map->cansleep ?
- M_WAITOK : M_NOWAIT);
+ mflags = map->cansleep ? M_WAITOK : M_NOWAIT;
+ ma = malloc(sizeof(vm_page_t) * ma_cnt, M_DEVBUF, mflags);
if (ma == NULL)
return (ENOMEM);
- for (i = 0; i < ma_cnt; i++)
- ma[i] = PHYS_TO_VM_PAGE(pstart + i * PAGE_SIZE);
+ fma = NULL;
+ for (i = 0; i < ma_cnt; i++) {
+ paddr = pstart + i * PAGE_SIZE;
+ ma[i] = PHYS_TO_VM_PAGE(paddr);
+ if (ma[i] == NULL || VM_PAGE_TO_PHYS(ma[i]) != paddr) {
+ /*
+ * If PHYS_TO_VM_PAGE() returned NULL or the
+ * vm_page was not initialized we'll use a
+ * fake page.
+ */
+ if (fma == NULL) {
+ fma = malloc(sizeof(struct vm_page) * ma_cnt,
+ M_DEVBUF, mflags);
+ if (fma == NULL) {
+ free(ma, M_DEVBUF);
+ return (ENOMEM);
+ }
+ }
+ vm_page_initfake(&fma[i], pstart + i * PAGE_SIZE,
+ VM_MEMATTR_DEFAULT);
+ ma[i] = &fma[i];
+ }
+ }
error = dmar_bus_dmamap_load_something(tag, map, ma, offset, buflen,
flags, segs, segp);
+ free(fma, M_DEVBUF);
free(ma, M_DEVBUF);
return (error);
}
@@ -696,7 +718,7 @@
struct bus_dmamap_dmar *map;
vm_page_t *ma, fma;
vm_paddr_t pstart, pend, paddr;
- int error, i, ma_cnt, offset;
+ int error, i, ma_cnt, mflags, offset;
tag = (struct bus_dma_tag_dmar *)dmat;
map = (struct bus_dmamap_dmar *)map1;
@@ -704,42 +726,34 @@
pend = round_page((vm_offset_t)buf + buflen);
offset = (vm_offset_t)buf & PAGE_MASK;
ma_cnt = OFF_TO_IDX(pend - pstart);
- ma = malloc(sizeof(vm_page_t) * ma_cnt, M_DEVBUF, map->cansleep ?
- M_WAITOK : M_NOWAIT);
+ mflags = map->cansleep ? M_WAITOK : M_NOWAIT;
+ ma = malloc(sizeof(vm_page_t) * ma_cnt, M_DEVBUF, mflags);
if (ma == NULL)
return (ENOMEM);
- if (dumping) {
- /*
- * If dumping, do not attempt to call
- * PHYS_TO_VM_PAGE() at all. It may return non-NULL
- * but the vm_page returned might be not initialized,
- * e.g. for the kernel itself.
- */
- KASSERT(pmap == kernel_pmap, ("non-kernel address write"));
- fma = malloc(sizeof(struct vm_page) * ma_cnt, M_DEVBUF,
- M_ZERO | (map->cansleep ? M_WAITOK : M_NOWAIT));
- if (fma == NULL) {
- free(ma, M_DEVBUF);
- return (ENOMEM);
- }
- for (i = 0; i < ma_cnt; i++, pstart += PAGE_SIZE) {
+ fma = NULL;
+ for (i = 0; i < ma_cnt; i++, pstart += PAGE_SIZE) {
+ if (pmap == kernel_pmap)
paddr = pmap_kextract(pstart);
+ else
+ paddr = pmap_extract(pmap, pstart);
+ ma[i] = PHYS_TO_VM_PAGE(paddr);
+ if (ma[i] == NULL || VM_PAGE_TO_PHYS(ma[i]) != paddr) {
+ /*
+ * If PHYS_TO_VM_PAGE() returned NULL or the
+ * vm_page was not initialized we'll use a
+ * fake page.
+ */
+ if (fma == NULL) {
+ fma = malloc(sizeof(struct vm_page) * ma_cnt,
+ M_DEVBUF, mflags);
+ if (fma == NULL) {
+ free(ma, M_DEVBUF);
+ return (ENOMEM);
+ }
+ }
vm_page_initfake(&fma[i], paddr, VM_MEMATTR_DEFAULT);
ma[i] = &fma[i];
}
- } else {
- fma = NULL;
- for (i = 0; i < ma_cnt; i++, pstart += PAGE_SIZE) {
- if (pmap == kernel_pmap)
- paddr = pmap_kextract(pstart);
- else
- paddr = pmap_extract(pmap, pstart);
- ma[i] = PHYS_TO_VM_PAGE(paddr);
- KASSERT(VM_PAGE_TO_PHYS(ma[i]) == paddr,
- ("PHYS_TO_VM_PAGE failed %jx %jx m %p",
- (uintmax_t)paddr, (uintmax_t)VM_PAGE_TO_PHYS(ma[i]),
- ma[i]));
- }
}
error = dmar_bus_dmamap_load_something(tag, map, ma, offset, buflen,
flags, segs, segp);

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 10, 11:25 PM (18 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29518123
Default Alt Text
D19753.id55738.diff (3 KB)

Event Timeline