[PATCH 08/17] dmaengine: idxd: compare the device disable status code whole
From: Daniel Byrne
Date: Mon Oct 19 2026 - 12:36:03 EST
idxd_device_disable() accepts the command's status when it is success
or when `status & IDXD_CMDSTS_ERR_DIS_DEV_EN` is non-zero. The error
code is a value, not a bit mask, so that test accepts every code that
has bit 0 or bits 4-5 set, and IDXD_CMDSTS_HW_ERR (0x3), the code a
refused or timed-out command reports, is one of them. A disable that
the device refused then read as a device already disabled, after which
the device-level remove cleared the software state and freed memory
that the still-enabled device writes.
Compare the error code whole against the already-disabled code.
Fixes: bfe1d56091c1 ("dmaengine: idxd: Init and probe for Intel data accelerators")
Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Daniel Byrne <daniel1.byrne@xxxxxxxxx>
---
drivers/dma/idxd/device.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 5ebc2c1a3859..41223d2e20af 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -704,9 +704,16 @@ int idxd_device_disable(struct idxd_device *idxd)
idxd_cmd_exec(idxd, IDXD_CMD_DISABLE_DEVICE, 0, &status);
- /* If the command is successful or if the device was disabled */
+ /*
+ * The command succeeded, or the device was already disabled. The
+ * error code is a value, not a bit mask, so compare it whole. A
+ * refused command reports IDXD_CMDSTS_HW_ERR, which shares a bit
+ * with the already-disabled code but leaves the device enabled,
+ * and clearing the software state of an enabled device lets a
+ * later teardown free memory the device still writes.
+ */
if (status != IDXD_CMDSTS_SUCCESS &&
- !(status & IDXD_CMDSTS_ERR_DIS_DEV_EN)) {
+ (status & IDXD_CMDSTS_ERR_MASK) != IDXD_CMDSTS_ERR_DIS_DEV_EN) {
dev_dbg(dev, "%s: err_code: %#x\n", __func__, status);
return -ENXIO;
}
--
2.43.0