> From: Tian, Kevin
> Sent: Thursday, November 20, 2025 7:56 AM
> 
> > 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.

and interestingly looking at "7.1.3 Fault Conditions and Remapping
Hardware Behavior for Various Requests", it doesn't define a fault
code due to failing check against mgaw for first-stage. Only about 
canonical.

that might be the reason why no iommu fault is reported...

Reply via email to