git: 6e68cd8666e1 - main - vmm: Initialize AMD IOMMU command buffers

From: Chuck Tuffli <chuck_at_FreeBSD.org>
Date: Wed, 12 Nov 2025 15:43:12 UTC
The branch main has been updated by chuck:

URL: https://cgit.FreeBSD.org/src/commit/?id=6e68cd8666e14db265f00e9ee59b670ca2964e0d

commit 6e68cd8666e14db265f00e9ee59b670ca2964e0d
Author:     Chuck Tuffli <chuck@FreeBSD.org>
AuthorDate: 2025-11-12 15:39:29 +0000
Commit:     Chuck Tuffli <chuck@FreeBSD.org>
CommitDate: 2025-11-12 15:39:29 +0000

    vmm: Initialize AMD IOMMU command buffers
    
    The driver communicates with the AMD IOMMU by writing to the tail of a
    fixed length command ring buffer. After issuing cmd_max commands, the
    tail pointer wraps back to the beginning of the ring buffer. Now, each
    command buffer entry will contain content from previous commands which
    may set bits in fields marked as Reserved for the current command. In
    some cases, the hardware will return an ILLEGAL_COMMAND_ERROR event when
    this occurs.
    
    Fix is to memset the command buffer prior to use.
    
    PR:             270966
    Reviewed by:    corvink, kib, markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D53692
---
 sys/amd64/vmm/amd/amdvi_hw.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/sys/amd64/vmm/amd/amdvi_hw.c b/sys/amd64/vmm/amd/amdvi_hw.c
index 831c31277570..4dd0339654a9 100644
--- a/sys/amd64/vmm/amd/amdvi_hw.c
+++ b/sys/amd64/vmm/amd/amdvi_hw.c
@@ -274,6 +274,7 @@ amdvi_get_cmd_tail(struct amdvi_softc *softc)
 
 	tail = (struct amdvi_cmd *)((uint8_t *)softc->cmd +
 	    ctrl->cmd_tail);
+	memset(tail, 0, sizeof(*tail));
 
 	return (tail);
 }
@@ -316,7 +317,6 @@ amdvi_cmd_cmp(struct amdvi_softc *softc, const uint64_t data)
 	uint64_t pa;
 
 	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 
 	pa = vtophys(&softc->cmp_data);
 	cmd->opcode = AMDVI_CMP_WAIT_OPCODE;
@@ -334,7 +334,6 @@ amdvi_cmd_inv_dte(struct amdvi_softc *softc, uint16_t devid)
 	struct amdvi_cmd *cmd;
 
 	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 	cmd->opcode = AMDVI_INVD_DTE_OPCODE;
 	cmd->word0 = devid;
 	amdvi_update_cmd_tail(softc);
@@ -352,7 +351,6 @@ amdvi_cmd_inv_iommu_pages(struct amdvi_softc *softc, uint16_t domain_id,
 	struct amdvi_cmd *cmd;
 
 	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 
 	cmd->opcode = AMDVI_INVD_PAGE_OPCODE;
 	cmd->word1 = domain_id;
@@ -383,7 +381,6 @@ amdvi_cmd_inv_iotlb(struct amdvi_softc *softc, uint16_t devid)
 		      qlen, RID2PCI_STR(devid));
 	}
 	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 
 #ifdef AMDVI_DEBUG_CMD
 	device_printf(softc->dev, "Invalidate IOTLB devID 0x%x"
@@ -406,7 +403,6 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc,
 	struct amdvi_cmd *cmd;
 
 	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 	cmd->opcode = AMDVI_INVD_INTR_OPCODE;
 	cmd->word0 = devid;
 	amdvi_update_cmd_tail(softc);
@@ -420,10 +416,6 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc,
 static void
 amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id)
 {
-	struct amdvi_cmd *cmd __diagused;
-
-	cmd = amdvi_get_cmd_tail(softc);
-	KASSERT(cmd != NULL, ("Cmd is NULL"));
 
 	/*
 	 * See section 3.3.3 of IOMMU spec rev 2.0, software note