RE: [PATCH v1 1/5] iommu/arm-smmu-v3-iommufd: Reject unsupported bits in invalidation commands
From: "Tian, Kevin" <kevin.tian@intel.com>
Date: 2026-07-03 06:23:05
Also in:
linux-iommu, lkml
From: Nicolin Chen <redacted>
Sent: Tuesday, June 30, 2026 5:16 AM
The arm_vsmmu_cache_invalidate() op hands a guest's invalidation
commands
to the trusted main command queue after enforcing only the VMID or the
SID,
and passes the rest of the command through to the queue unchanged.
That lets a guest set bits the host never meant to forward, in two ways. A
bit can take the command out of the guest's own scope: the ATC_INV Global
bit, for one, makes the SMMU ignore the SID and invalidate the ATC of every
device, not just the guest's. A reserved or undefined bit instead makes the
command malformed; per the Arm SMMUv3 specification, in its section 4.1.3
"Command errors", a CERROR_ILL is raised, among other cases, when:
A valid command opcode is used and a Reserved or undefined field is
optionally detected as non-zero, which results in the command being
treated as malformed.
Restrict each opcode to the fields that the driver supports and reject the
command with -EIO if it sets any other bit, before the command reaches the
queue. This keeps a guest scoped to its own devices and stops the host from
forwarding any bit whose meaning it does not control.
Some fields and whole opcodes are legal only on an SMMU that implements
the
matching feature, so accept them conditionally. The NUM, SCALE and TG
range
fields need FEAT_RANGE_INV. The ATC_INV opcode needs FEAT_ATS. Per the
same
specification's section 4.5 "ATS and PRI", CMD_ATC_INV is ILLEGAL when:
SMMU_IDR0.ATS == 0 and this command is issued on a Non-secure or
Secure
Command queue.
The SSV and SSID substream fields require a non-zero ssid_bits, so without
substream support setting them is not illegal but CONSTRAINED
UNPREDICTABLE,
which a guest should not be able to provoke.
Fixes: d68beb276ba2 ("iommu/arm-smmu-v3: Support
IOMMU_HWPT_INVALIDATE using a VIOMMU object")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <redacted>Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+ case CMDQ_OP_ATC_INV: + /* + * Exclude the Global bit: it makes the SMMU ignore the SID and + * invalidate the ATC of every device, not just the guest's. + */
I suppose the Global bit in vcmdq is guaranteed by HW to be contained within the vcmdq, then the SMMU will convert it into multiple INV cmds sent to devices associated with the vcmdq?
+ allowed[0] |= CMDQ_ATC_0_SID; + allowed[1] |= CMDQ_ATC_1_SIZE | CMDQ_ATC_1_ADDR_MASK; + /* SSV/SSID require substream support */ + if (vsmmu->smmu->ssid_bits) + allowed[0] |= CMDQ_0_SSV | CMDQ_ATC_0_SSID; + break;
the latter check of ARM_SMMU_FEAT_ATS could be moved here before setting any allowed bits for ATC_INV.