From owner-svn-src-all@FreeBSD.ORG Fri Feb 1 03:49:10 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id E782B179; Fri, 1 Feb 2013 03:49:10 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id D51E37C7; Fri, 1 Feb 2013 03:49:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r113nA7U049266; Fri, 1 Feb 2013 03:49:10 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r113nAFE049263; Fri, 1 Feb 2013 03:49:10 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201302010349.r113nAFE049263@svn.freebsd.org> From: Neel Natu Date: Fri, 1 Feb 2013 03:49:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r246191 - in head: sys/amd64/vmm/io usr.sbin/bhyve X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Feb 2013 03:49:11 -0000 Author: neel Date: Fri Feb 1 03:49:09 2013 New Revision: 246191 URL: http://svnweb.freebsd.org/changeset/base/246191 Log: Fix a broken assumption in the passthru implementation that the MSI-X table can only be located at the beginning or the end of the BAR. If the MSI-table is located in the middle of a BAR then we will split the BAR into two and create two mappings - one before the table and one after the table - leaving a hole in place of the table so accesses to it can be trapped and emulated. Obtained from: NetApp Modified: head/sys/amd64/vmm/io/ppt.c head/usr.sbin/bhyve/pci_passthru.c Modified: head/sys/amd64/vmm/io/ppt.c ============================================================================== --- head/sys/amd64/vmm/io/ppt.c Fri Feb 1 02:41:47 2013 (r246190) +++ head/sys/amd64/vmm/io/ppt.c Fri Feb 1 03:49:09 2013 (r246191) @@ -56,9 +56,18 @@ __FBSDID("$FreeBSD$"); /* XXX locking */ #define MAX_PPTDEVS (sizeof(pptdevs) / sizeof(pptdevs[0])) -#define MAX_MMIOSEGS (PCIR_MAX_BAR_0 + 1) #define MAX_MSIMSGS 32 +/* + * If the MSI-X table is located in the middle of a BAR then that MMIO + * region gets split into two segments - one segment above the MSI-X table + * and the other segment below the MSI-X table - with a hole in place of + * the MSI-X table so accesses to it can be trapped and emulated. + * + * So, allocate a MMIO segment for each BAR register + 1 additional segment. + */ +#define MAX_MMIOSEGS ((PCIR_MAX_BAR_0 + 1) + 1) + MALLOC_DEFINE(M_PPTMSIX, "pptmsix", "Passthru MSI-X resources"); struct pptintr_arg { /* pptintr(pptintr_arg) */ Modified: head/usr.sbin/bhyve/pci_passthru.c ============================================================================== --- head/usr.sbin/bhyve/pci_passthru.c Fri Feb 1 02:41:47 2013 (r246190) +++ head/usr.sbin/bhyve/pci_passthru.c Fri Feb 1 03:49:09 2013 (r246191) @@ -355,14 +355,18 @@ msix_table_write(struct vmctx *ctx, int static int init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base) { - int idx; - size_t table_size; + int b, s, f; + int error, idx; + size_t len, remaining, table_size; vm_paddr_t start; - size_t len; struct pci_devinst *pi = sc->psc_pi; assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0); + b = sc->psc_sel.pc_bus; + s = sc->psc_sel.pc_dev; + f = sc->psc_sel.pc_func; + /* * If the MSI-X table BAR maps memory intended for * other uses, it is at least assured that the table @@ -372,34 +376,44 @@ init_msix_table(struct vmctx *ctx, struc if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar && ((pi->pi_msix.pba_offset - pi->pi_msix.table_offset) < 4096)) { /* Need to also emulate the PBA, not supported yet */ - printf("Unsupported MSI-X configuration: %d/%d/%d\n", - sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, - sc->psc_sel.pc_func); + printf("Unsupported MSI-X configuration: %d/%d/%d\n", b, s, f); return (-1); } - /* - * May need to split the BAR into 3 regions: - * Before the MSI-X table, the MSI-X table, and after it - * XXX for now, assume that the table is not in the middle - */ + /* Compute the MSI-X table size */ table_size = pi->pi_msix.table_count * MSIX_TABLE_ENTRY_SIZE; + table_size = roundup2(table_size, 4096); + idx = pi->pi_msix.table_bar; + start = pi->pi_bar[idx].addr; + remaining = pi->pi_bar[idx].size; - /* Round up to page size */ - table_size = roundup2(table_size, 4096); - if (pi->pi_msix.table_offset == 0) { - /* Map everything after the MSI-X table */ - start = pi->pi_bar[idx].addr + table_size; - len = pi->pi_bar[idx].size - table_size; - } else { - /* Map everything before the MSI-X table */ - start = pi->pi_bar[idx].addr; + /* Map everything before the MSI-X table */ + if (pi->pi_msix.table_offset > 0) { len = pi->pi_msix.table_offset; + error = vm_map_pptdev_mmio(ctx, b, s, f, start, len, base); + if (error) + return (error); + + base += len; + start += len; + remaining -= len; + } + + /* Skip the MSI-X table */ + base += table_size; + start += table_size; + remaining -= table_size; + + /* Map everything beyond the end of the MSI-X table */ + if (remaining > 0) { + len = remaining; + error = vm_map_pptdev_mmio(ctx, b, s, f, start, len, base); + if (error) + return (error); } - return (vm_map_pptdev_mmio(ctx, sc->psc_sel.pc_bus, - sc->psc_sel.pc_dev, sc->psc_sel.pc_func, - start, len, base + table_size)); + + return (0); } static int