<p dir="ltr"><br>
On Jun 11, 2016 12:09 AM, "Andres Rodriguez" <<a href="mailto:andres.rodriguez@amd.com">andres.rodriguez@amd.com</a>> wrote:<br>
><br>
> When executing in a PCI passthrough based virtuzliation environemnt, the<br>
> hypervisor will usually attempt to send a PCIe bus reset signal to the<br>
> ASIC when the VM reboots. In this scenario, the card is not correctly<br>
> initialized, but we still consider it to be posted. Therefore, in a<br>
> passthrough based environemnt we should always post the card to guarantee<br>
> it is in a good state for driver initialization.<br>
><br>
> However, if we are operating in SR-IOV mode it is up to the GIM driver<br>
> to manage the asic state, therefore we should not post the card (and<br>
> shouldn't be able to do it either).<br>
><br>
> Signed-off-by: Andres Rodriguez <<a href="mailto:andres.rodriguez@amd.com">andres.rodriguez@amd.com</a>><br>
> ---<br>
>  drivers/gpu/drm/amd/amdgpu/amdgpu.h        |  7 +++++++<br>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 16 +++++++++++++++-<br>
>  drivers/gpu/drm/amd/amdgpu/cik.c           |  7 +++++++<br>
>  drivers/gpu/drm/amd/amdgpu/vi.c            | 15 +++++++++++++++<br>
>  4 files changed, 44 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> index 26fe670..fe71dea 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> @@ -1835,6 +1835,8 @@ struct amdgpu_asic_funcs {<br>
>         /* MM block clocks */<br>
>         int (*set_uvd_clocks)(struct amdgpu_device *adev, u32 vclk, u32 dclk);<br>
>         int (*set_vce_clocks)(struct amdgpu_device *adev, u32 evclk, u32 ecclk);<br>
> +       /* query virtual capabilities */<br>
> +       u32 (*get_virtual_caps)(struct amdgpu_device *adev);<br>
>  };<br>
><br>
>  /*<br>
> @@ -1932,8 +1934,12 @@ void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device);<br>
><br>
><br>
>  /* GPU virtualization */<br>
> +#define AMDGPU_VIRT_CAPS_SRIOV_EN       (1 << 0)<br>
> +#define AMDGPU_VIRT_CAPS_IS_VF          (1 << 1)<br>
>  struct amdgpu_virtualization {<br>
>         bool supports_sr_iov;<br>
> +       bool is_virtual;<br>
> +       u32 caps;<br>
>  };<br>
><br>
>  /*<br>
> @@ -2226,6 +2232,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)<br>
>  #define amdgpu_asic_get_xclk(adev) (adev)->asic_funcs->get_xclk((adev))<br>
>  #define amdgpu_asic_set_uvd_clocks(adev, v, d) (adev)->asic_funcs->set_uvd_clocks((adev), (v), (d))<br>
>  #define amdgpu_asic_set_vce_clocks(adev, ev, ec) (adev)->asic_funcs->set_vce_clocks((adev), (ev), (ec))<br>
> +#define amdgpu_asic_get_virtual_caps(adev) ((adev)->asic_funcs->get_virtual_caps((adev)))<br>
>  #define amdgpu_asic_get_gpu_clock_counter(adev) (adev)->asic_funcs->get_gpu_clock_counter((adev))<br>
>  #define amdgpu_asic_read_disabled_bios(adev) (adev)->asic_funcs->read_disabled_bios((adev))<br>
>  #define amdgpu_asic_read_bios_from_rom(adev, b, l) (adev)->asic_funcs->read_bios_from_rom((adev), (b), (l))<br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
> index b494212..629e4e3 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c<br>
> @@ -1392,6 +1392,14 @@ static int amdgpu_resume(struct amdgpu_device *adev)<br>
>         return 0;<br>
>  }<br>
><br>
> +static bool amdgpu_device_is_virtual(void)<br>
> +{<br>
> +#ifdef CONFIG_X86<br>
> +       return boot_cpu_has(X86_FEATURE_HYPERVISOR);<br>
> +#else<br>
> +       return false</p>
<p dir="ltr">Missing semicolon here...</p>
<p dir="ltr">> +#endif<br>
> +}<br>
><br>
>  /**<br>
>   * amdgpu_device_has_dal_support - check if dal is supported<br>
> @@ -1560,8 +1568,14 @@ int amdgpu_device_init(struct amdgpu_device *adev,<br>
>         adev->virtualization.supports_sr_iov =<br>
>                 amdgpu_atombios_has_gpu_virtualization_table(adev);<br>
><br>
> +       /* Check if we are executing in a virtualized environment */<br>
> +       adev->virtualization.is_virtual = amdgpu_device_is_virtual();<br>
> +       adev->virtualization.caps = amdgpu_asic_get_virtual_caps(adev);<br>
> +<br>
>         /* Post card if necessary */<br>
> -       if (!amdgpu_card_posted(adev)) {<br>
> +       if (!amdgpu_card_posted(adev) ||<br>
> +           (adev->virtualization.is_virtual &&<br>
> +            !adev->virtualization.caps & AMDGPU_VIRT_CAPS_SRIOV_EN)) {<br>
>                 if (!adev->bios) {<br>
>                         dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n");<br>
>                         return -EINVAL;<br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c<br>
> index 40f4fda..907bb28 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/cik.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/cik.c<br>
> @@ -963,6 +963,12 @@ static bool cik_read_bios_from_rom(struct amdgpu_device *adev,<br>
>         return true;<br>
>  }<br>
><br>
> +static u32 cik_get_virtual_caps(struct amdgpu_device *adev)<br>
> +{<br>
> +       /* CIK does not support SR-IOV */<br>
> +       return 0;<br>
> +}<br>
> +<br>
>  static const struct amdgpu_allowed_register_entry cik_allowed_read_registers[] = {<br>
>         {mmGRBM_STATUS, false},<br>
>         {mmGB_ADDR_CONFIG, false},<br>
> @@ -2176,6 +2182,7 @@ static const struct amdgpu_asic_funcs cik_asic_funcs =<br>
>         .get_xclk = &cik_get_xclk,<br>
>         .set_uvd_clocks = &cik_set_uvd_clocks,<br>
>         .set_vce_clocks = &cik_set_vce_clocks,<br>
> +       .get_virtual_caps = &cik_get_virtual_caps,<br>
>         /* these should be moved to their own ip modules */<br>
>         .get_gpu_clock_counter = &gfx_v7_0_get_gpu_clock_counter,<br>
>         .wait_for_mc_idle = &gmc_v7_0_mc_wait_for_idle,<br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c<br>
> index 1ac0c91..6a7d531 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/vi.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/vi.c<br>
> @@ -422,6 +422,20 @@ static bool vi_read_bios_from_rom(struct amdgpu_device *adev,<br>
>         return true;<br>
>  }<br>
><br>
> +static u32 vi_get_virtual_caps(struct amdgpu_device *adev)<br>
> +{<br>
> +       u32 caps = 0;<br>
> +       u32 reg = RREG32(mmBIF_IOV_FUNC_IDENTIFIER);<br>
> +<br>
> +       if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, IOV_ENABLE))<br>
> +               caps |= AMDGPU_VIRT_CAPS_SRIOV_EN;<br>
> +<br>
> +       if (REG_GET_FIELD(reg, BIF_IOV_FUNC_IDENTIFIER, FUNC_IDENTIFIER))<br>
> +               caps |= AMDGPU_VIRT_CAPS_IS_VF;<br>
> +<br>
> +       return caps;<br>
> +}<br>
> +<br>
>  static const struct amdgpu_allowed_register_entry tonga_allowed_read_registers[] = {<br>
>         {mmGB_MACROTILE_MODE7, true},<br>
>  };<br>
> @@ -1452,6 +1466,7 @@ static const struct amdgpu_asic_funcs vi_asic_funcs =<br>
>         .get_xclk = &vi_get_xclk,<br>
>         .set_uvd_clocks = &vi_set_uvd_clocks,<br>
>         .set_vce_clocks = &vi_set_vce_clocks,<br>
> +       .get_virtual_caps = &vi_get_virtual_caps,<br>
>         /* these should be moved to their own ip modules */<br>
>         .get_gpu_clock_counter = &gfx_v8_0_get_gpu_clock_counter,<br>
>         .wait_for_mc_idle = &gmc_v8_0_mc_wait_for_idle,<br>
> --<br>
> 2.8.4<br>
><br>
> _______________________________________________<br>
> dri-devel mailing list<br>
> <a href="mailto:dri-devel@lists.freedesktop.org">dri-devel@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/dri-devel">https://lists.freedesktop.org/mailman/listinfo/dri-devel</a><br>
</p>