Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Jun 2021 22:23:06 GMT
From:      Chuck Tuffli <chuck@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 91064841d72b - main - bhyve: Fix NVMe iovec construction for large IOs
Message-ID:  <202106272223.15RMN69Q030539@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by chuck:

URL: https://cgit.FreeBSD.org/src/commit/?id=91064841d72b285a146a3f1c32cb447251e062ea

commit 91064841d72b285a146a3f1c32cb447251e062ea
Author:     Chuck Tuffli <chuck@FreeBSD.org>
AuthorDate: 2021-06-27 22:14:52 +0000
Commit:     Chuck Tuffli <chuck@FreeBSD.org>
CommitDate: 2021-06-27 22:14:52 +0000

    bhyve: Fix NVMe iovec construction for large IOs
    
    The UEFI driver included with Rocky Linux 8.4 uncovered an existing bug
    in the NVMe emulation's construction of iovec's.
    
    By default, NVMe data transfer operations use a scatter-gather list in
    which all entries point to a fixed size memory region. For example, if
    the Memory Page Size is 4KiB, a 2MiB IO requires 512 entries. Lists
    themselves are also fixed size (default is 512 entries).
    
    Because the list size is fixed, the last entry is special. If the IO
    requires more than 512 entries, the last entry in the list contains the
    address of the next list of entries. But if the IO requires exactly 512
    entries, the last entry points to data.
    
    The NVMe emulation missed this logic and unconditionally treated the
    last entry as a pointer to the next list. Fix is to check if the
    remaining data is greater than the page size before using the last entry
    as a pointer to the next list.
    
    PR:             256422
    Reported by:    dave@syix.com
    Tested by:      jason@tubnor.net
    MFC after:      5 days
    Relnotes:       yes
    Reviewed by:    imp, grehan
    Differential Revision:  https://reviews.freebsd.org/D30897
---
 usr.sbin/bhyve/pci_nvme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c
index 414edabc2b7c..fa316fa285db 100644
--- a/usr.sbin/bhyve/pci_nvme.c
+++ b/usr.sbin/bhyve/pci_nvme.c
@@ -1976,7 +1976,7 @@ nvme_write_read_blockif(struct pci_nvme_softc *sc,
 		/* PRP2 is pointer to a physical region page list */
 		while (bytes) {
 			/* Last entry in list points to the next list */
-			if (prp_list == last) {
+			if ((prp_list == last) && (bytes > PAGE_SIZE)) {
 				uint64_t prp = *prp_list;
 
 				prp_list = paddr_guest2host(vmctx, prp,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106272223.15RMN69Q030539>