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
This commit is contained in:
parent
f8fa74679c
commit
f6f02911b6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362751
@ -830,32 +830,42 @@ static int
|
|||||||
nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
|
nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command,
|
||||||
struct nvme_completion* compl)
|
struct nvme_completion* compl)
|
||||||
{
|
{
|
||||||
uint32_t logsize = (1 + ((command->cdw10 >> 16) & 0xFFF)) * 2;
|
uint32_t logsize;
|
||||||
uint8_t logpage = command->cdw10 & 0xFF;
|
uint8_t logpage = command->cdw10 & 0xFF;
|
||||||
|
|
||||||
DPRINTF("%s log page %u len %u", __func__, logpage, logsize);
|
DPRINTF("%s log page %u len %u", __func__, logpage, logsize);
|
||||||
|
|
||||||
pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS);
|
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) {
|
switch (logpage) {
|
||||||
case NVME_LOG_ERROR:
|
case NVME_LOG_ERROR:
|
||||||
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
|
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);
|
NVME_COPY_TO_PRP);
|
||||||
break;
|
break;
|
||||||
case NVME_LOG_HEALTH_INFORMATION:
|
case NVME_LOG_HEALTH_INFORMATION:
|
||||||
/* TODO: present some smart info */
|
/* TODO: present some smart info */
|
||||||
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
|
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);
|
NVME_COPY_TO_PRP);
|
||||||
break;
|
break;
|
||||||
case NVME_LOG_FIRMWARE_SLOT:
|
case NVME_LOG_FIRMWARE_SLOT:
|
||||||
nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1,
|
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);
|
NVME_COPY_TO_PRP);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WPRINTF("%s get log page %x command not supported",
|
DPRINTF("%s get log page %x command not supported",
|
||||||
__func__, logpage);
|
__func__, logpage);
|
||||||
|
|
||||||
pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
|
pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC,
|
||||||
|
Loading…
Reference in New Issue
Block a user