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.