On 5/21/26 19:46, Duan, Zhenzhong wrote:
@@ -64,6 +65,13 @@ bool vtd_check_hiod_accel(IntelIOMMUState *s,
VTDHostIOMMUDevice *vtd_hiod,
return false;
}
+ /* Only do the check when host device support PASIDs */
+ if (caps->max_pasid_log2 && s->pasid > hpasid) {
the second comparison looks strange. hpasid is derived from ecap_reg,
while ecap_reg is from s->pasid... is there any place that changes
the pss filed of ecap_reg afterward? I think this check should be
against caps->max_pasid_log2 as this is the value from hardware. right?
ecap_reg is from ioctl(IOMMU_GET_HW_INFO), it's not ecap register in
vIOMMU.
I see. I misunderstood that the hpasid is got from the vIOMMU ecap
register.
My understanding is that guest kernel will pick the min(caps->max_pasid_log2, s-
pasid), so checking the two doesn't make sense?
I think the caps->max_pasid_log2 should be the same with hpasid since
both are from host. Also, I didn't see the logic to pick the
min(caps->max_pasid_log2, s->pasid). This is not expected just like the
aw bits.
We fail if aw-bits > host aw-bits.
It's a bit different, see below:
static u32 dev_iommu_get_max_pasids(struct device *dev)
{
u32 max_pasids = 0, bits = 0;
int ret;
if (dev_is_pci(dev)) {
ret = pci_max_pasids(to_pci_dev(dev));
if (ret > 0)
max_pasids = ret;
} else {
ret = device_property_read_u32(dev, "pasid-num-bits", &bits);
if (!ret)
max_pasids = 1UL << bits;
}
return min_t(u32, max_pasids, dev->iommu->iommu_dev->max_pasids);
}
dev->iommu->max_pasids = dev_iommu_get_max_pasids(dev);
caps->max_pasid_log2 = ilog2(idev->dev->iommu->max_pasids);
caps->max_pasid_log2 is then exposed to guest as pasid bit value in virtual PCI
capability.
Then guest kernel does the same min() calculation.
got it. yes, vtd should check the bits reported via the ecap_reg.