Print this page
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 <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

*** 26,35 **** --- 26,36 ---- * Copyright (c) 2009, Intel Corporation. * All rights reserved. */ /* * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* * DVMA code * This file contains Intel IOMMU code that deals with DVMA
*** 56,66 **** #define IMMU_PCI_REV2CLASS(r) ((r) >> 8) /* classcode from revid */ #define IMMU_PCI_CLASS2BASE(c) ((c) >> 16) /* baseclass from classcode */ #define IMMU_PCI_CLASS2SUB(c) (((c) >> 8) & 0xff); /* classcode */ #define IMMU_CONTIG_PADDR(d, p) \ ! ((d).dck_paddr && ((d).dck_paddr + IMMU_PAGESIZE) == (p)) typedef struct dvma_arg { immu_t *dva_immu; dev_info_t *dva_rdip; dev_info_t *dva_ddip; --- 57,68 ---- #define IMMU_PCI_REV2CLASS(r) ((r) >> 8) /* classcode from revid */ #define IMMU_PCI_CLASS2BASE(c) ((c) >> 16) /* baseclass from classcode */ #define IMMU_PCI_CLASS2SUB(c) (((c) >> 8) & 0xff); /* classcode */ #define IMMU_CONTIG_PADDR(d, p) \ ! ((d).dck_paddr && ((d).dck_paddr + (d).dck_npages * IMMU_PAGESIZE) \ ! == (p)) typedef struct dvma_arg { immu_t *dva_immu; dev_info_t *dva_rdip; dev_info_t *dva_ddip;
*** 2123,2132 **** --- 2125,2135 ---- if (nvpages <= dcookies[j].dck_npages) break; nvpages -= dcookies[j].dck_npages; } + VERIFY(j >= 0); nppages = nvpages; paddr = dcookies[j].dck_paddr + (dcookies[j].dck_npages - nppages) * IMMU_PAGESIZE; nvpages = *nvpages_ptr;
*** 2664,2677 **** /* call into the VM to get the paddr */ paddr = pfn_to_pa(hat_getpfnum(vas->a_hat, vaddr)); vaddr += psize; } - npages++; - if (ihp->ihp_npremapped > 0) { ! *ihp->ihp_preptes[npages - 1] = PDTE_PADDR(paddr) | rwmask; } else if (IMMU_CONTIG_PADDR(dcookies[dmax], paddr)) { dcookies[dmax].dck_npages++; } else { /* No, we need a new dcookie */ --- 2667,2678 ---- /* call into the VM to get the paddr */ paddr = pfn_to_pa(hat_getpfnum(vas->a_hat, vaddr)); vaddr += psize; } if (ihp->ihp_npremapped > 0) { ! *ihp->ihp_preptes[npages] = PDTE_PADDR(paddr) | rwmask; } else if (IMMU_CONTIG_PADDR(dcookies[dmax], paddr)) { dcookies[dmax].dck_npages++; } else { /* No, we need a new dcookie */
*** 2689,2704 **** uint_t, npages, uint_t, dmax+1); dvma += (npages << IMMU_PAGESHIFT); npages = 0; dmax = 0; ! } else dmax++; dcookies[dmax].dck_paddr = paddr; dcookies[dmax].dck_npages = 1; } size -= psize; } /* * Finish up, mapping all, or all of the remaining, * physical memory ranges. --- 2690,2708 ---- uint_t, npages, uint_t, dmax+1); dvma += (npages << IMMU_PAGESHIFT); npages = 0; dmax = 0; ! } else { dmax++; + } dcookies[dmax].dck_paddr = paddr; dcookies[dmax].dck_npages = 1; } size -= psize; + if (npages != 0) + npages++; } /* * Finish up, mapping all, or all of the remaining, * physical memory ranges.