Re: [PATCH v6 06/24] iommu/amd: Map vIOMMU VF and VF Control MMIO BARs

From: Vasant Hegde

Date: Mon Oct 19 2026 - 07:31:32 EST




On 9/30/2026 2:53 PM, Suravee Suthikulpanit wrote:
> Enable hardware vIOMMU on an IOMMU by locating its PCI vendor-specific
> capability (VSC), reading the VF and VF Control BAR addresses, and
> mapping them for host access (256MB VF, 4MB VF Control).
>
> VF Control covers the first 4K of guest IOMMU MMIO (control registers,
> trapped by QEMU). VF MMIO covers the third 4K (virtualized by the
> IOMMU). Per-guest bases use the Guest ID from the previous patch.
>
> Reject a VSC VF or VF Control BAR that is disabled or decodes to
> physical address zero before mapping MMIO.
>
> Set AMD_IOMMU_FLAG_VIOMMU_EN after the VF BARs are mapped. Export
> MMIO map helpers. Call amd_viommu_uninit() from IOMMU teardown
> before free_iommu_buffers() so MMIO and the command buffer remain.
>
> Release the reserved MMIO region if ioremap() fails so VF/VFCTRL map
> errors do not leak request_mem_region() for the life of the machine.
>
> Skip the host release in iommu_unmap_mmio_space() when mmio_base is
> NULL, so a failed ioremap() is not released twice.
>
> Signed-off-by: Vasant Hegde <vasant.hegde@xxxxxxx>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
> ---


.../...

> +
> + pci_read_config_dword(iommu->dev, vsc + MMIO_VSC_VF_CNTL_BAR_LO_OFFSET, &lo);
> + pci_read_config_dword(iommu->dev, vsc + MMIO_VSC_VF_CNTL_BAR_HI_OFFSET, &hi);
> + vf_cntl_phys = hi;
> + vf_cntl_phys = (vf_cntl_phys << 32) | lo;
> + if (!(vf_cntl_phys & 1)) {
> + pr_err(FW_BUG "vf_cntl_phys disabled\n");
> + return -EINVAL;
> + }
> + vf_cntl_phys &= ~1ULL;
> + if (!vf_cntl_phys) {
> + pr_err(FW_BUG "vf_cntl_phys address is zero\n");
> + return -EINVAL;
> + }
> +
> + /* Mapping 256MB of VF and 4MB of VF_CNTL BARs */
> + iommu->vf_base = iommu_map_mmio_space(vf_phys, VIOMMU_VF_MMIO_MAP_SIZE);
> + if (!iommu->vf_base) {
> + pr_err("Can't reserve vf_base\n");
> + goto err_out;
> + }
> + iommu->vf_base_phys = vf_phys;
> +
> + iommu->vfctrl_base = iommu_map_mmio_space(vf_cntl_phys, VIOMMU_VF_CNTL_MMIO_MAP_SIZE);
> + if (!iommu->vfctrl_base) {
> + pr_err("Can't reserve vfctrl_base\n");
> + goto err_out;

Nothing to cleanup here. You can replace goto with return.

-Vasant