On 11/19/2025 12:13 AM, Jason Gunthorpe wrote:
Also, the tests fail consistently and are not sporadic.
 From these logs I see the below fragment, noting this:

  gem_exec_gttfil-1010    [004] .N...    50.126420: map: IOMMU: 
iova=0x00003fffffc00000 - 0x0000400000000000 paddr=0x00000001b9400000 
size=4194304
                                                                     
^^^^^^^^^^^^^^^^^^^
Which is the high IOVA.. It has bit 45 set. I fed this mapping into
the kunit and it does map successfully.

It is not high enough to get into anything special about sign extend,
the driver sets:

        if (cap_fl5lp_support(iommu->cap))
                cfg.common.hw_max_vasz_lg2 = 57;
        else
                cfg.common.hw_max_vasz_lg2 = 48;

Maybe this code is wrong? Baolu what did you get for this log:

  [   50.126166] i915 0000:00:02.0: Using 46-bit DMA addresses

In your force second stage test? Is it 46? Second stage uses different
code to compute vasz_lg2 and is sensitive to magw:

        if (mgaw >= 48 && (sagaw & BIT(3)))
                return min(57, mgaw);
        else if (mgaw >= 39 && (sagaw & BIT(2)))
                return min(48, mgaw);
        else if (mgaw >= 30 && (sagaw & BIT(1)))
                return min(39, mgaw);

Maybe this is the issue?

When first stage translation is used,

        cfg.common.hw_max_vasz_lg2 = 48

When second stage translation is used,

        cfg.common.hw_max_vasz_lg2 = 42

Interesting thing is if I hardcode

        cfg.common.hw_max_vasz_lg2 = 42

for the first stage translation, it works.

The only change that I have made to achieve this likes below:

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 2d2f64ce2bc6..a505bba8dcc7 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2813,10 +2813,13 @@ intel_iommu_domain_alloc_first_stage(struct device *dev,
        if (IS_ERR(dmar_domain))
                return ERR_CAST(dmar_domain);

+#if 0
        if (cap_fl5lp_support(iommu->cap))
                cfg.common.hw_max_vasz_lg2 = 57;
        else
                cfg.common.hw_max_vasz_lg2 = 48;
+#endif
+       cfg.common.hw_max_vasz_lg2 = 42;
        cfg.common.hw_max_oasz_lg2 = 52;
        cfg.common.features = BIT(PT_FEAT_SIGN_EXTEND) |
                              BIT(PT_FEAT_FLUSH_RANGE);

Thanks,
baolu

Reply via email to