From 2cedd8f0ecbd2b29bf0aac72bb8b7413b0326938 Mon Sep 17 00:00:00 2001 From: Hans Rosenfeld Date: Thu, 11 May 2017 17:06:26 +0200 Subject: [PATCH] 8622 panic in PTE_set_all() 8623 IMMU_CONTIG_PADDR is broken for cookies with more than one page 8625 nvme causes bad free panic in IOMMU Reviewed by: Robert Mustacchi Reviewed by: Jerry Jelinek Approved by: Garrett D'Amore --- usr/src/uts/i86pc/io/immu_dvma.c | 14 +++++++++----- usr/src/uts/i86pc/io/rootnex.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/usr/src/uts/i86pc/io/immu_dvma.c b/usr/src/uts/i86pc/io/immu_dvma.c index efc30c3d64..f1db9ee317 100644 --- a/usr/src/uts/i86pc/io/immu_dvma.c +++ b/usr/src/uts/i86pc/io/immu_dvma.c @@ -28,6 +28,7 @@ */ /* * Copyright 2012 Garrett D'Amore . All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* @@ -58,7 +59,8 @@ #define IMMU_PCI_CLASS2SUB(c) (((c) >> 8) & 0xff); /* classcode */ #define IMMU_CONTIG_PADDR(d, p) \ - ((d).dck_paddr && ((d).dck_paddr + IMMU_PAGESIZE) == (p)) + ((d).dck_paddr && ((d).dck_paddr + (d).dck_npages * IMMU_PAGESIZE) \ + == (p)) typedef struct dvma_arg { immu_t *dva_immu; @@ -2125,6 +2127,7 @@ PTE_set_all(immu_t *immu, domain_t *domain, xlate_t *xlate, nvpages -= dcookies[j].dck_npages; } + VERIFY(j >= 0); nppages = nvpages; paddr = dcookies[j].dck_paddr + (dcookies[j].dck_npages - nppages) * IMMU_PAGESIZE; @@ -2666,10 +2669,8 @@ immu_map_dvmaseg(dev_info_t *rdip, ddi_dma_handle_t handle, vaddr += psize; } - npages++; - if (ihp->ihp_npremapped > 0) { - *ihp->ihp_preptes[npages - 1] = + *ihp->ihp_preptes[npages] = PDTE_PADDR(paddr) | rwmask; } else if (IMMU_CONTIG_PADDR(dcookies[dmax], paddr)) { dcookies[dmax].dck_npages++; @@ -2691,12 +2692,15 @@ immu_map_dvmaseg(dev_info_t *rdip, ddi_dma_handle_t handle, dvma += (npages << IMMU_PAGESHIFT); npages = 0; dmax = 0; - } else + } else { dmax++; + } dcookies[dmax].dck_paddr = paddr; dcookies[dmax].dck_npages = 1; } size -= psize; + if (npages != 0) + npages++; } /* diff --git a/usr/src/uts/i86pc/io/rootnex.c b/usr/src/uts/i86pc/io/rootnex.c index 3bd23a87bd..81b87c4520 100644 --- a/usr/src/uts/i86pc/io/rootnex.c +++ b/usr/src/uts/i86pc/io/rootnex.c @@ -2337,7 +2337,7 @@ rootnex_coredma_unbindhdl(dev_info_t *dip, dev_info_t *rdip, rootnex_teardown_windows(dma); #if defined(__amd64) && !defined(__xpv) - if (IOMMU_USED(rdip)) + if (IOMMU_USED(rdip) && dma->dp_dvma_used) (void) iommulib_nexdma_unmapobject(dip, rdip, handle, &dma->dp_dvma); #endif -- 2.11.4.GIT