Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jun 2020 00:31:34 +0000 (UTC)
From:      Chuck Tuffli <chuck@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r362751 - head/usr.sbin/bhyve
Message-ID:  <202006290031.05T0VYG5047200@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: chuck
Date: Mon Jun 29 00:31:34 2020
New Revision: 362751
URL: https://svnweb.freebsd.org/changeset/base/362751

Log:
  bhyve: fix NVMe Get Log Page command
  
  Fix the logic in nvme_opc_get_log_page to calculate the number of DWORDS
  (uint32_t) instead of WORDS (uint16_t) for the byte length. And only
  return the allowed number of Log Page bytes as determined by the user
  request and actual size of the requested log page.
  
  Fixes UNH Test 1.3
  
  Tested by:	Jason Tubnor
  MFC after:	2 weeks
  Differential Revision: https://reviews.freebsd.org/D24885

Modified:
  head/usr.sbin/bhyve/pci_nvme.c

Modified: head/usr.sbin/bhyve/pci_nvme.c
==============================================================================
--- head/usr.sbin/bhyve/pci_nvme.c	Mon Jun 29 00:31:30 2020	(r362750)
+++ head/usr.sbin/bhyve/pci_nvme.c	Mon Jun 29 00:31:34 2020	(r362751)
@@ -830,32 +830,42 @@ static int
 nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
 	struct nvme_completion* compl)
 {
-	uint32_t logsize = (1 + ((command->cdw10 >> 16) & 0xFFF)) * 2;
+	uint32_t logsize;
 	uint8_t logpage = command->cdw10 & 0xFF;
 
 	DPRINTF("%s log page %u len %u", __func__, logpage, logsize);
 
 	pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
 
+	/*
+	 * Command specifies the number of dwords to return in fields NUMDU
+	 * and NUMDL. This is a zero-based value.
+	 */
+	logsize = ((command->cdw11 << 16) | (command->cdw10 >> 16)) + 1;
+	logsize *= sizeof(uint32_t);
+
 	switch (logpage) {
 	case NVME_LOG_ERROR:
 		nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
-		    command->prp2, (uint8_t *)&sc->err_log, logsize,
+		    command->prp2, (uint8_t *)&sc->err_log,
+		    MIN(logsize, sizeof(sc->err_log)),
 		    NVME_COPY_TO_PRP);
 		break;
 	case NVME_LOG_HEALTH_INFORMATION:
 		/* TODO: present some smart info */
 		nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
-		    command->prp2, (uint8_t *)&sc->health_log, logsize,
+		    command->prp2, (uint8_t *)&sc->health_log,
+		    MIN(logsize, sizeof(sc->health_log)),
 		    NVME_COPY_TO_PRP);
 		break;
 	case NVME_LOG_FIRMWARE_SLOT:
 		nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
-		    command->prp2, (uint8_t *)&sc->fw_log, logsize,
+		    command->prp2, (uint8_t *)&sc->fw_log,
+		    MIN(logsize, sizeof(sc->fw_log)),
 		    NVME_COPY_TO_PRP);
 		break;
 	default:
-		WPRINTF("%s get log page %x command not supported",
+		DPRINTF("%s get log page %x command not supported",
 		        __func__, logpage);
 
 		pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,



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