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 ?
Jason