> From: Jason Gunthorpe <[email protected]> > Sent: Thursday, November 20, 2025 2:51 AM > > On Wed, Nov 19, 2025 at 09:31:50AM +0000, Tian, Kevin wrote: > > > old way: > > > > if (first_stage) > > domain->domain.geometry.aperture_end = > __DOMAIN_MAX_ADDR(domain->gaw - 1); > > else > > domain->domain.geometry.aperture_end = > __DOMAIN_MAX_ADDR(domain->gaw); > > > > i.e. both are initialized around domain->gaw. > > > > but the new way has difference between first-stage and second-stage as > > Jason pointed out already. > > > > Baolu, what is the number in "Using xxx-bit DMA addresses" when > > using second-stage? > > He said 42. > > Indeed Chaitanya's dmesg has this: > > [ 0.079787] DMAR: Host address width 42 > > Which I think explains the bug. The dmar->width is being ignored by > the driver except for that print. > > > my understanding of various 'gaw' fields are only about second stage, but > > maybe there is something we overlooked... > > That is what the spec says: > > MGAW: Maximum Guest Address Width > > This field indicates the maximum guest physical address width > supported by second-stage translation in remapping hardware. The > Maximum Guest Address Width (MGAW) is computed as (N+1), > where N is the valued reported in this field. For example, a hardware > implementation supporting 48-bit MGAW reports a value of 47 > (101111b) in this fiel > > Seems very clear it is related to the second stage in that paragraph.. > > So, I think what has happened here is the old driver mis-used mgaw for > the first stage: > > addr_width = agaw_to_width(iommu->agaw); > if (addr_width > cap_mgaw(iommu->cap)) > addr_width = cap_mgaw(iommu->cap); > domain->gaw = addr_width; > > And fully ignored dmar->width, which happened to work because mgaw < > dmar->width > > So we should be using dmar->width to constrain the first stage and > expect that mgaw is less than dmar->width ? >
dmar->width is the host address width, i.e. for OA. so it's irrelevant to the input iova here. I checked the spec again, looks the statements in it are inconsistent " 3.6 First-Stage Translation First-stage translation restricts the input-address to a canonical address (i.e., address bits 63:N have the same value as address bit [N-1], where N is 48 bits with 4-level paging and 57 bits with 5-level paging). Requests subject to first-stage translation by remapping hardware are subject to canonical address checking as a pre-condition for first-stage translation, and a violation is treated as a translation-fault. Software using first-stage translation structures to translate an IO Virtual Address (IOVA) must use canonical addresses. Additionally, software must limit addresses to less than the minimum of MGAW and the lower canonical address width implied by FSPM (i.e., 47-bit when FSPM is 4-level and 56-bit when FSPM is 5-level) " so it's indeed restricted by mgaw. I'll check back with our spec owner to get it fixed.
