> From: Jan Beulich <jbeul...@suse.com>
> Sent: Tuesday, November 23, 2021 9:40 PM
> 
> Bit 0 of the capability register field has become reserved at or before

Bit 0 of 'SAGAW' in the capability register ...

> spec version 2.2. Treat it as such. Replace the effective open-coding of
> find_first_set_bit(). Adjust local variable types.
> 
> Signed-off-by: Jan Beulich <jbeul...@suse.com>
> ---
> Strictly speaking IOMMUs supporting only 3-level tables ought to result
> in guests seeing a suitably reduced physical address width in CPUID.
> And then the same would apply to restrictions resulting from MGAW.

Yes. I remember there was some old discussion in Qemu community
for whether guest physical addr width should be based on IOMMU
constraints when passthrough device is used. But it didn't go anywhere
(and I cannot find the link...)

anyway with above comment fixed:

        Reviewed-by: Kevin Tian <kevin.t...@intel.com>

> 
> --- a/xen/drivers/passthrough/vtd/iommu.c
> +++ b/xen/drivers/passthrough/vtd/iommu.c
> @@ -356,7 +356,7 @@ static uint64_t domain_pgd_maddr(struct
>          pgd_maddr = hd->arch.vtd.pgd_maddr;
>      }
> 
> -    /* Skip top levels of page tables for 2- and 3-level DRHDs. */
> +    /* Skip top level(s) of page tables for less-than-maximum level DRHDs. */
>      for ( agaw = level_to_agaw(4);
>            agaw != level_to_agaw(nr_pt_levels);
>            agaw-- )
> @@ -1183,8 +1183,7 @@ static int __init iommu_set_interrupt(st
>  int __init iommu_alloc(struct acpi_drhd_unit *drhd)
>  {
>      struct vtd_iommu *iommu;
> -    unsigned long sagaw, nr_dom;
> -    int agaw;
> +    unsigned int sagaw, agaw = 0, nr_dom;
> 
>      iommu = xzalloc(struct vtd_iommu);
>      if ( iommu == NULL )
> @@ -1237,14 +1236,13 @@ int __init iommu_alloc(struct acpi_drhd_
>          return -ENODEV;
>      }
> 
> -    /* Calculate number of pagetable levels: between 2 and 4. */
> +    /* Calculate number of pagetable levels: 3 or 4. */
>      sagaw = cap_sagaw(iommu->cap);
> -    for ( agaw = level_to_agaw(4); agaw >= 0; agaw-- )
> -        if ( test_bit(agaw, &sagaw) )
> -            break;
> -    if ( agaw < 0 )
> +    if ( sagaw & 6 )
> +        agaw = find_first_set_bit(sagaw & 6);
> +    if ( !agaw )
>      {
> -        printk(XENLOG_ERR VTDPREFIX "IOMMU: unsupported sagaw %lx\n",
> sagaw);
> +        printk(XENLOG_ERR VTDPREFIX "IOMMU: unsupported sagaw %x\n",
> sagaw);
>          print_iommu_regs(drhd);
>          return -ENODEV;
>      }

Reply via email to