@samitouri / QOSamiQemu / commits / 6b580d87fc

hw/arm/tegra241-cmdqv: Do not sync GERRORN on VCMDQ allocation

When a guest hits a command error, the hardware sets GERROR and the guest acknowledges it by writing GERRORN to match. These registers use toggle semantics, and since GERROR is read-only, both GERROR and GERRORN may remain set after an error has been handled. As long as they stay equal there is no pending error, so a subsequent VM is unaffected. When a new VM starts, QEMU allocates the hardware VCMDQ and flushes its cached GERRORN of zero, while the hardware may still have both GERROR and GERRORN set from an error the previous guest acknowledged. This makes them differ again, so the hardware sees a pending error and stall the VCMDQ, leading to CMD_SYNC timeouts. Do not sync GERRORN when allocating a hardware VCMDQ. Fixes: 1d0f77535417 ("hw/arm/tegra241-cmdqv: Route allocated VCMDQ Page0 accesses to the mmap'd host VINTF page0") Suggested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Message-id: 20260707112450.111178-1-skolothumtho@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Shameer Kolothum committed Jul 13, 2026 at 12:34 UTC 6b580d87fcd154d39895062b626709112f9f3d39
1 file changed +3 -4
hw/arm/tegra241-cmdqv.c
+3 -4
@@ -212,7 +212,9 @@ static inline uint32_t *tegra241_cmdqv_vintf_lvcmdq_ptr(Tegra241CMDQV *cmdqv,
212 /*
213 * Flush cached register writes into the mmap'd host VINTF page0 after a
214 * successful HW_QUEUE_ALLOC, so the guest's earlier writes survive
215 - * the cache-to-hardware transition.
215 + * the cache-to-hardware transition. GERRORN is intentionally not synced,
216 + * as overwriting it with the cached value could recreate a GERROR != GERRORN
217 + * mismatch and stall the VCMDQ.
218 */
219 static void tegra241_cmdqv_sync_vcmdq(Tegra241CMDQV *cmdqv, int index)
220 {
@@ -229,9 +231,6 @@ static void tegra241_cmdqv_sync_vcmdq(Tegra241CMDQV *cmdqv, int index)
231
232 ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_CONFIG);
233 *ptr = cmdqv->vcmdq_config[index];
232 -
233 - ptr = tegra241_cmdqv_vintf_lvcmdq_ptr(cmdqv, index, A_VCMDQ0_GERRORN);
234 - *ptr = cmdqv->vcmdq_gerrorn[index];
234 }
235
236 /*