On Wed, Oct 15, 2025 at 5:56 PM Ellen Pan <[email protected]> wrote:
>
> 1. Added VF logic in amdgpu_virt to init IP discovery using the offsets from 
> dynamic(v2) critical regions;
> 2. Added VF logic in amdgpu_virt to init bios image using the offsets from 
> dynamic(v2) critical regions;
>
> Signed-off-by: Ellen Pan <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c      | 34 ++++++++++++-----
>  drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 23 ++++++++++--
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c      | 37 +++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h      |  2 +
>  4 files changed, 83 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> index 00e96419fcda..070fd61f8463 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
> @@ -96,11 +96,12 @@ void amdgpu_bios_release(struct amdgpu_device *adev)
>   * part of the system bios.  On boot, the system bios puts a
>   * copy of the igp rom at the start of vram if a discrete card is
>   * present.
> - * For SR-IOV, the vbios image is also put in VRAM in the VF.
> + * For SR-IOV, if dynamic critical region is not enabled,
> + * the vbios image is also put at the start of VRAM in the VF.
>   */
>  static bool amdgpu_read_bios_from_vram(struct amdgpu_device *adev)
>  {
> -       uint8_t __iomem *bios;
> +       uint8_t __iomem *bios = NULL;
>         resource_size_t vram_base;
>         resource_size_t size = 256 * 1024; /* ??? */
>
> @@ -114,18 +115,33 @@ static bool amdgpu_read_bios_from_vram(struct 
> amdgpu_device *adev)
>
>         adev->bios = NULL;
>         vram_base = pci_resource_start(adev->pdev, 0);
> -       bios = ioremap_wc(vram_base, size);
> -       if (!bios)
> -               return false;
>
>         adev->bios = kmalloc(size, GFP_KERNEL);
> -       if (!adev->bios) {
> -               iounmap(bios);
> +       if (!adev->bios)
>                 return false;
> +
> +       /* For SRIOV with dynamic critical region is enabled,
> +        * the vbios image is put at a dynamic offset of VRAM in the VF.
> +        * If dynamic critical region is disabled, follow the existing logic 
> as on baremetal.
> +        */
> +       if (amdgpu_sriov_vf(adev) && adev->virt.is_dynamic_crit_regn_enabled) 
> {
> +               if (amdgpu_virt_get_dynamic_data_info(adev,
> +                               AMD_SRIOV_MSG_VBIOS_IMG_TABLE_ID, adev->bios, 
> &size)) {
> +                       amdgpu_bios_release(adev);
> +                       return false;
> +               }
> +       } else {
> +               bios = ioremap_wc(vram_base, size);
> +               if (!bios) {
> +                       amdgpu_bios_release(adev);
> +                       return false;
> +               }
> +
> +               memcpy_fromio(adev->bios, bios, size);
> +               iounmap(bios);
>         }
> +
>         adev->bios_size = size;
> -       memcpy_fromio(adev->bios, bios, size);
> -       iounmap(bios);
>
>         if (!check_atom_bios(adev, size)) {
>                 amdgpu_bios_release(adev);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> index 4e75334f3b3a..1809deb86797 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
> @@ -303,14 +303,29 @@ static int amdgpu_discovery_read_binary_from_mem(struct 
> amdgpu_device *adev,
>          * then it is not required to be reserved.
>          */
>         if (sz_valid) {
> -               uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;
> -               amdgpu_device_vram_access(adev, pos, (uint32_t *)binary,
> -                                         adev->discovery.size, false);
> -               adev->discovery.reserve_tmr = true;
> +               if (amdgpu_sriov_vf(adev) && 
> adev->virt.is_dynamic_crit_regn_enabled) {
> +                       /* For SRIOV VFs with dynamic critical region enabled,
> +                        * we will get the IPD binary via below call.
> +                        * If dynamic critical is disabled, fall through to 
> normal seq.
> +                        */
> +                       if (amdgpu_virt_get_dynamic_data_info(adev,
> +                                               AMD_SRIOV_MSG_IPD_TABLE_ID, 
> binary,
> +                                               (uint64_t 
> *)&adev->mman.discovery_tmr_size)) {

I think this is adev->discovery.size now after Lijo's latest changes.
@Lazar, Lijo I think we can remove adev->mman.discovery_tmr_size.
It's no longer used by anything.  With that fixed,
Reviewed-by: Alex Deucher <[email protected]>

> +                               ret = -EINVAL;
> +                               goto exit;
> +                       }
> +               } else {
> +                       uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;
> +
> +                       amdgpu_device_vram_access(adev, pos, (uint32_t 
> *)binary,
> +                                       adev->discovery.size, false);
> +                       adev->discovery.reserve_tmr = true;
> +               }
>         } else {
>                 ret = amdgpu_discovery_read_binary_from_sysmem(adev, binary);
>         }
>
> +exit:
>         if (ret)
>                 dev_err(adev->dev,
>                         "failed to read discovery info from memory, vram size 
> read: %llx",
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> index 12659990abe0..15157ed5df29 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
> @@ -999,6 +999,14 @@ int amdgpu_virt_init_critical_region(struct 
> amdgpu_device *adev)
>                 goto out;
>         }
>
> +       /* Validation for critical region info */
> +       if (adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb > 
> DISCOVERY_TMR_SIZE) {
> +               dev_err(adev->dev, "Invalid IP discovery size: 0x%x\n",
> +                               
> adev->virt.crit_regn_tbl[AMD_SRIOV_MSG_IPD_TABLE_ID].size_kb);
> +               r = -EINVAL;
> +               goto out;
> +       }
> +
>         /* reserved memory starts from crit region base offset with the size 
> of 5MB */
>         adev->mman.fw_vram_usage_start_offset = adev->virt.crit_regn.offset;
>         adev->mman.fw_vram_usage_size = adev->virt.crit_regn.size_kb << 10;
> @@ -1017,6 +1025,35 @@ int amdgpu_virt_init_critical_region(struct 
> amdgpu_device *adev)
>         return r;
>  }
>
> +int amdgpu_virt_get_dynamic_data_info(struct amdgpu_device *adev,
> +       int data_id, uint8_t *binary, uint64_t *size)
> +{
> +       uint32_t data_offset = 0;
> +       uint32_t data_size = 0;
> +       enum amd_sriov_msg_table_id_enum data_table_id = data_id;
> +
> +       if (data_table_id >= AMD_SRIOV_MSG_MAX_TABLE_ID)
> +               return -EINVAL;
> +
> +       data_offset = adev->virt.crit_regn_tbl[data_table_id].offset;
> +       data_size = adev->virt.crit_regn_tbl[data_table_id].size_kb << 10;
> +
> +       /* Validate on input params */
> +       if (!binary || !size || *size < (uint64_t)data_size)
> +               return -EINVAL;
> +
> +       /* Proceed to copy the dynamic content */
> +       amdgpu_device_vram_access(adev,
> +                       (uint64_t)data_offset, (uint32_t *)binary, data_size, 
> false);
> +       *size = (uint64_t)data_size; // update the size as out param.
> +
> +       dev_dbg(adev->dev,
> +               "Got %s info from dynamic crit_region_table at offset 0x%x 
> with size of 0x%x bytes.\n",
> +               amdgpu_virt_dynamic_crit_table_name[data_id], data_offset, 
> data_size);
> +
> +       return 0;
> +}
> +
>  void amdgpu_virt_init(struct amdgpu_device *adev)
>  {
>         bool is_sriov = false;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> index 8d03a8620de9..2a13cc892a13 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
> @@ -442,6 +442,8 @@ void amdgpu_virt_fini_data_exchange(struct amdgpu_device 
> *adev);
>  void amdgpu_virt_init(struct amdgpu_device *adev);
>
>  int amdgpu_virt_init_critical_region(struct amdgpu_device *adev);
> +int amdgpu_virt_get_dynamic_data_info(struct amdgpu_device *adev,
> +       int data_id, uint8_t *binary, uint64_t *size);
>
>  bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev);
>  int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev);
> --
> 2.34.1
>

Reply via email to