On Sat, 05 Sep 2020, Xiaolin Zhang <xiaolin.zh...@intel.com> wrote:
> To support vgpu pv features, a common shared memory is setup used for
> communication and data exchange between guest and host GVTg to reduce
> data access overhead and trap cost.
>
> guest i915 will allocate this common memory (1 page size) and then pass
> it's physical address to host GVTg through PVINFO register so that host
> GVTg can access this shared guest page meory without trap cost with
> hyperviser's facility.
>
> guest i915 will send VGT_G2V_SHARED_PAGE_SETUP notification to host GVTg
> once shared memory setup succcessfully finished.
>
> the layout of the shared_page also defined as well, the first part is the
> PV vervsion information used for compabilty support.
>
> Signed-off-by: Xiaolin Zhang <xiaolin.zh...@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c    |  2 +
>  drivers/gpu/drm/i915/i915_drv.h    |  4 +-
>  drivers/gpu/drm/i915/i915_pvinfo.h |  5 +-
>  drivers/gpu/drm/i915/i915_vgpu.c   | 94 
> ++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_vgpu.h   | 14 ++++++
>  5 files changed, 117 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 00292a8..5fbb4ab 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1071,6 +1071,8 @@ static void i915_driver_release(struct drm_device *dev)
>  
>       disable_rpm_wakeref_asserts(rpm);
>  
> +     intel_vgpu_destroy(dev_priv);
> +
>       i915_gem_driver_release(dev_priv);
>  
>       intel_memory_regions_driver_release(dev_priv);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 16d1b51..3cde2c5f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -809,7 +809,9 @@ struct i915_virtual_gpu {
>       bool active;
>       u32 caps;
>       u32 pv_caps;
> -};
> +
> +     struct i915_virtual_gpu_pv *pv;
> +} __packed;

I'm unsure why this struct should be packed.

>  
>  struct intel_cdclk_config {
>       unsigned int cdclk, vco, ref, bypass;
> diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h 
> b/drivers/gpu/drm/i915/i915_pvinfo.h
> index 8b0dc25..1d44876 100644
> --- a/drivers/gpu/drm/i915/i915_pvinfo.h
> +++ b/drivers/gpu/drm/i915/i915_pvinfo.h
> @@ -48,6 +48,7 @@ enum vgt_g2v_type {
>       VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY,
>       VGT_G2V_EXECLIST_CONTEXT_CREATE,
>       VGT_G2V_EXECLIST_CONTEXT_DESTROY,
> +     VGT_G2V_SHARED_PAGE_REGISTER,
>       VGT_G2V_MAX,
>  };
>  
> @@ -112,7 +113,9 @@ struct vgt_if {
>  
>       u32 pv_caps;
>  
> -     u32  rsv7[0x200 - 25];    /* pad to one page */
> +     u64 shared_page_gpa;
> +
> +     u32  rsv7[0x200 - 27];    /* pad to one page */
>  } __packed;
>  
>  #define vgtif_offset(x) (offsetof(struct vgt_if, x))
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.c 
> b/drivers/gpu/drm/i915/i915_vgpu.c
> index 10960125..8b2b451 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.c
> +++ b/drivers/gpu/drm/i915/i915_vgpu.c
> @@ -110,6 +110,17 @@ void intel_vgpu_detect(struct drm_i915_private *dev_priv)
>       pci_iounmap(pdev, shared_area);
>  }
>  
> +void intel_vgpu_destroy(struct drm_i915_private *i915)
> +{
> +     struct i915_virtual_gpu_pv *pv = i915->vgpu.pv;
> +
> +     if (!intel_vgpu_active(i915) || !pv)
> +             return;
> +
> +     __free_page(virt_to_page(pv->shared_page));
> +     kfree(pv);
> +}
> +
>  void intel_vgpu_register(struct drm_i915_private *i915)
>  {
>       /*
> @@ -360,6 +371,83 @@ int intel_vgt_balloon(struct i915_ggtt *ggtt)
>   */
>  
>  /*
> + * shared_page setup for VGPU PV features
> + */
> +static int intel_vgpu_setup_shared_page(struct drm_i915_private *i915,
> +             void __iomem *shared_area)
> +{
> +     void __iomem *addr;
> +     struct i915_virtual_gpu_pv *pv;
> +     struct gvt_shared_page *base;
> +     u64 gpa;
> +     u16 ver_maj, ver_min;
> +     int ret = 0;
> +
> +     /* We allocate 1 page shared between guest and GVT for data exchange.
> +      *       _______________________________
> +      *      |version                        |
> +      *      |_______________________________PAGE/8
> +      *      |                               |
> +      *      |_______________________________PAGE/4
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |_______________________________PAGE/2
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |                               |
> +      *      |_______________________________|
> +      *
> +      * 0 offset: PV version area
> +      */
> +
> +     base =  (struct gvt_shared_page *)get_zeroed_page(GFP_KERNEL);
> +     if (!base) {
> +             dev_info(i915->drm.dev, "out of memory for shared memory\n");
> +             return -ENOMEM;
> +     }
> +
> +     /* pass guest memory pa address to GVT and then read back to verify */
> +     gpa = __pa(base);
> +     addr = shared_area + vgtif_offset(shared_page_gpa);
> +     writeq(gpa, addr);
> +     if (gpa != readq(addr)) {
> +             dev_info(i915->drm.dev, "passed shared_page_gpa failed\n");
> +             ret = -EIO;
> +             goto err;
> +     }
> +
> +     addr = shared_area + vgtif_offset(g2v_notify);
> +     writel(VGT_G2V_SHARED_PAGE_REGISTER, addr);
> +
> +     ver_maj = base->ver_major;
> +     ver_min = base->ver_minor;
> +     if (ver_maj != PV_MAJOR || ver_min != PV_MINOR) {
> +             dev_info(i915->drm.dev, "VGPU PV version incompatible\n");
> +             ret = -EIO;
> +             goto err;
> +     }
> +
> +     pv = kzalloc(sizeof(struct i915_virtual_gpu_pv), GFP_KERNEL);
> +     if (!pv) {
> +             ret = -ENOMEM;
> +             goto err;
> +     }
> +
> +     DRM_INFO("vgpu PV ver major %d and minor %d\n", ver_maj, ver_min);

Please use drm_info(), and please polish the message for info
level. This looks like debug to me.

> +     i915->vgpu.pv = pv;
> +     pv->shared_page = base;
> +     return ret;
> +err:
> +     __free_page(virt_to_page(base));
> +     return ret;
> +}
> +
> +/*
>   * Config vgpu PV ops for different PV capabilities
>   */
>  void intel_vgpu_config_pv_caps(struct drm_i915_private *i915,
> @@ -395,5 +483,11 @@ bool intel_vgpu_detect_pv_caps(struct drm_i915_private 
> *i915,
>       if (!pvcaps)
>               return false;
>  
> +     if (intel_vgpu_setup_shared_page(i915, shared_area)) {
> +             i915->vgpu.pv_caps = 0;
> +             writel(0, shared_area + vgtif_offset(pv_caps));
> +             return false;
> +     }
> +
>       return true;
>  }
> diff --git a/drivers/gpu/drm/i915/i915_vgpu.h 
> b/drivers/gpu/drm/i915/i915_vgpu.h
> index 1b10175..aeef20f 100644
> --- a/drivers/gpu/drm/i915/i915_vgpu.h
> +++ b/drivers/gpu/drm/i915/i915_vgpu.h
> @@ -29,12 +29,26 @@
>  struct drm_i915_private;
>  struct i915_ggtt;
>  
> +#define PV_MAJOR        0
> +#define PV_MINOR        1
> +
>  /* define different PV capabilities */
>  enum pv_caps {
>       PV_NONE = 0,
>  };
>  
> +/* A common shared page(4KB) between GVTg and vgpu allocated by guest */
> +struct gvt_shared_page {

Prefix with intel_?

> +     u16 ver_major;
> +     u16 ver_minor;
> +};
> +
> +struct i915_virtual_gpu_pv {

Why i915_virtual_gpu instead of intel_vgpu like everywhere else?

> +     struct gvt_shared_page *shared_page;
> +};
> +
>  void intel_vgpu_detect(struct drm_i915_private *i915);
> +void intel_vgpu_destroy(struct drm_i915_private *i915);
>  bool intel_vgpu_active(struct drm_i915_private *i915);
>  void intel_vgpu_register(struct drm_i915_private *i915);
>  bool intel_vgpu_has_full_ppgtt(struct drm_i915_private *i915);

-- 
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to