Merge tag 'gvt-gt-next-2021-01-18' of https://github.com/intel/gvt-linux into drm...
authorJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Thu, 21 Jan 2021 13:10:16 +0000 (15:10 +0200)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Thu, 21 Jan 2021 13:10:17 +0000 (15:10 +0200)
gvt-gt-next-2021-01-18

- GVT cmd parser enhancement against guest context (Yan)

Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
From: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210118050739.GY15982@zhen-hp.sh.intel.com
1  2 
drivers/gpu/drm/i915/gvt/gvt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/mmio.h
drivers/gpu/drm/i915/gvt/vgpu.c

  #ifndef _GVT_H_
  #define _GVT_H_
  
 +#include <uapi/linux/pci_regs.h>
 +
 +#include "i915_drv.h"
 +
  #include "debug.h"
  #include "hypercall.h"
  #include "mmio.h"
@@@ -60,7 -56,7 +60,7 @@@ struct intel_gvt_host 
        struct device *dev;
        bool initialized;
        int hypervisor_type;
 -      struct intel_gvt_mpt *mpt;
 +      const struct intel_gvt_mpt *mpt;
  };
  
  extern struct intel_gvt_host intel_gvt_host;
@@@ -248,7 -244,7 +248,7 @@@ struct gvt_mmio_block 
  #define INTEL_GVT_MMIO_HASH_BITS 11
  
  struct intel_gvt_mmio {
-       u8 *mmio_attribute;
+       u16 *mmio_attribute;
  /* Register contains RO bits */
  #define F_RO          (1 << 0)
  /* Register contains graphics address */
  #define F_CMD_ACCESS  (1 << 3)
  /* This reg has been accessed by a VM */
  #define F_ACCESSED    (1 << 4)
 -/* This reg has been accessed through GPU commands */
 +/* This reg requires save & restore during host PM suspend/resume */
 +#define F_PM_SAVE     (1 << 5)
 +/* This reg could be accessed by unaligned address */
  #define F_UNALIGN     (1 << 6)
  /* This reg is in GVT's mmio save-restor list and in hardware
   * logical context image
   */
  #define F_SR_IN_CTX   (1 << 7)
+ /* Value of command write of this reg needs to be patched */
+ #define F_CMD_WRITE_PATCH     (1 << 8)
  
        struct gvt_mmio_block *mmio_block;
        unsigned int num_mmio_block;
@@@ -333,6 -329,7 +335,7 @@@ struct intel_gvt 
                u32 *mocs_mmio_offset_list;
                u32 mocs_mmio_offset_list_cnt;
        } engine_mmio_list;
+       bool is_reg_whitelist_updated;
  
        struct dentry *debugfs_root;
  };
@@@ -416,6 -413,9 +419,9 @@@ int intel_gvt_load_firmware(struct inte
  #define vgpu_fence_base(vgpu) (vgpu->fence.base)
  #define vgpu_fence_sz(vgpu) (vgpu->fence.size)
  
+ /* ring context size i.e. the first 0x50 dwords*/
+ #define RING_CTX_SIZE 320
  struct intel_vgpu_creation_params {
        __u64 handle;
        __u64 low_gm_sz;  /* in MB */
@@@ -687,11 -687,39 +693,40 @@@ static inline void intel_gvt_mmio_set_s
  }
  
  void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu);
+ /**
+  * intel_gvt_mmio_set_cmd_write_patch -
+  *                            mark an MMIO if its cmd write needs to be
+  *                            patched
+  * @gvt: a GVT device
+  * @offset: register offset
+  *
+  */
+ static inline void intel_gvt_mmio_set_cmd_write_patch(
+                       struct intel_gvt *gvt, unsigned int offset)
+ {
+       gvt->mmio.mmio_attribute[offset >> 2] |= F_CMD_WRITE_PATCH;
+ }
+ /**
+  * intel_gvt_mmio_is_cmd_write_patch - check if an mmio's cmd access needs to
+  * be patched
+  * @gvt: a GVT device
+  * @offset: register offset
+  *
+  * Returns:
+  * True if GPU commmand write to an MMIO should be patched
+  */
+ static inline bool intel_gvt_mmio_is_cmd_write_patch(
+                       struct intel_gvt *gvt, unsigned int offset)
+ {
+       return gvt->mmio.mmio_attribute[offset >> 2] & F_CMD_WRITE_PATCH;
+ }
  void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu);
  void intel_gvt_debugfs_init(struct intel_gvt *gvt);
  void intel_gvt_debugfs_clean(struct intel_gvt *gvt);
  
 +int intel_gvt_pm_resume(struct intel_gvt *gvt);
  
  #include "trace.h"
  #include "mpt.h"
@@@ -83,7 -83,7 +83,7 @@@ static void write_vreg(struct intel_vgp
        memcpy(&vgpu_vreg(vgpu, offset), p_data, bytes);
  }
  
- static struct intel_gvt_mmio_info *find_mmio_info(struct intel_gvt *gvt,
+ struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt,
                                                  unsigned int offset)
  {
        struct intel_gvt_mmio_info *e;
@@@ -96,7 -96,7 +96,7 @@@
  }
  
  static int new_mmio_info(struct intel_gvt *gvt,
-               u32 offset, u8 flags, u32 size,
+               u32 offset, u16 flags, u32 size,
                u32 addr_mask, u32 ro_mask, u32 device,
                gvt_mmio_func read, gvt_mmio_func write)
  {
                        return -ENOMEM;
  
                info->offset = i;
-               p = find_mmio_info(gvt, info->offset);
+               p = intel_gvt_find_mmio_info(gvt, info->offset);
                if (p) {
                        WARN(1, "dup mmio definition offset %x\n",
                                info->offset);
@@@ -1965,7 -1965,8 +1965,8 @@@ static int init_generic_mmio_info(struc
  
        /* RING MODE */
  #define RING_REG(base) _MMIO((base) + 0x29c)
-       MMIO_RING_DFH(RING_REG, D_ALL, F_MODE_MASK | F_CMD_ACCESS, NULL,
+       MMIO_RING_DFH(RING_REG, D_ALL,
+               F_MODE_MASK | F_CMD_ACCESS | F_CMD_WRITE_PATCH, NULL,
                ring_mode_mmio_write);
  #undef RING_REG
  
@@@ -2885,8 -2886,8 +2886,8 @@@ static int init_bdw_mmio_info(struct in
        MMIO_DFH(_MMIO(0xb10c), D_BDW, F_CMD_ACCESS, NULL, NULL);
        MMIO_D(_MMIO(0xb110), D_BDW);
  
-       MMIO_F(_MMIO(0x24d0), 48, F_CMD_ACCESS, 0, 0, D_BDW_PLUS,
-               NULL, force_nonpriv_write);
+       MMIO_F(_MMIO(0x24d0), 48, F_CMD_ACCESS | F_CMD_WRITE_PATCH, 0, 0,
+               D_BDW_PLUS, NULL, force_nonpriv_write);
  
        MMIO_D(_MMIO(0x44484), D_BDW_PLUS);
        MMIO_D(_MMIO(0x4448c), D_BDW_PLUS);
@@@ -3120,10 -3121,9 +3121,10 @@@ static int init_skl_mmio_info(struct in
        MMIO_DFH(TRVATTL3PTRDW(2), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
        MMIO_DFH(TRVATTL3PTRDW(3), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
        MMIO_DFH(TRVADR, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL);
 -      MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS,
 -              NULL, gen9_trtte_write);
 -      MMIO_DH(_MMIO(0x4dfc), D_SKL_PLUS, NULL, gen9_trtt_chicken_write);
 +      MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS | F_PM_SAVE,
 +               NULL, gen9_trtte_write);
 +      MMIO_DFH(_MMIO(0x4dfc), D_SKL_PLUS, F_PM_SAVE,
 +               NULL, gen9_trtt_chicken_write);
  
        MMIO_D(_MMIO(0x46430), D_SKL_PLUS);
  
@@@ -3626,7 -3626,7 +3627,7 @@@ int intel_vgpu_mmio_reg_rw(struct intel
        /*
         * Normal tracked MMIOs.
         */
-       mmio_info = find_mmio_info(gvt, offset);
+       mmio_info = intel_gvt_find_mmio_info(gvt, offset);
        if (!mmio_info) {
                gvt_dbg_mmio("untracked MMIO %08x len %d\n", offset, bytes);
                goto default_rw;
@@@ -3672,39 -3672,3 +3673,39 @@@ default_rw
                intel_vgpu_default_mmio_read(vgpu, offset, pdata, bytes) :
                intel_vgpu_default_mmio_write(vgpu, offset, pdata, bytes);
  }
 +
 +void intel_gvt_restore_fence(struct intel_gvt *gvt)
 +{
 +      struct intel_vgpu *vgpu;
 +      int i, id;
 +
 +      idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
 +              mmio_hw_access_pre(gvt->gt);
 +              for (i = 0; i < vgpu_fence_sz(vgpu); i++)
 +                      intel_vgpu_write_fence(vgpu, i, vgpu_vreg64(vgpu, fence_num_to_offset(i)));
 +              mmio_hw_access_post(gvt->gt);
 +      }
 +}
 +
 +static int mmio_pm_restore_handler(struct intel_gvt *gvt, u32 offset, void *data)
 +{
 +      struct intel_vgpu *vgpu = data;
 +      struct drm_i915_private *dev_priv = gvt->gt->i915;
 +
 +      if (gvt->mmio.mmio_attribute[offset >> 2] & F_PM_SAVE)
 +              intel_uncore_write(&dev_priv->uncore, _MMIO(offset), vgpu_vreg(vgpu, offset));
 +
 +      return 0;
 +}
 +
 +void intel_gvt_restore_mmio(struct intel_gvt *gvt)
 +{
 +      struct intel_vgpu *vgpu;
 +      int id;
 +
 +      idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) {
 +              mmio_hw_access_pre(gvt->gt);
 +              intel_gvt_for_each_tracked_mmio(gvt, mmio_pm_restore_handler, vgpu);
 +              mmio_hw_access_post(gvt->gt);
 +      }
 +}
@@@ -80,6 -80,9 +80,9 @@@ int intel_gvt_for_each_tracked_mmio(str
        int (*handler)(struct intel_gvt *gvt, u32 offset, void *data),
        void *data);
  
+ struct intel_gvt_mmio_info *intel_gvt_find_mmio_info(struct intel_gvt *gvt,
+                                                 unsigned int offset);
  int intel_vgpu_init_mmio(struct intel_vgpu *vgpu);
  void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr);
  void intel_vgpu_clean_mmio(struct intel_vgpu *vgpu);
@@@ -104,8 -107,4 +107,8 @@@ int intel_vgpu_mmio_reg_rw(struct intel
  
  int intel_vgpu_mask_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
                                  void *p_data, unsigned int bytes);
 +
 +void intel_gvt_restore_fence(struct intel_gvt *gvt);
 +void intel_gvt_restore_mmio(struct intel_gvt *gvt);
 +
  #endif
@@@ -393,7 -393,7 +393,7 @@@ static struct intel_vgpu *__intel_gvt_c
        mutex_init(&vgpu->dmabuf_lock);
        INIT_LIST_HEAD(&vgpu->dmabuf_obj_list_head);
        INIT_RADIX_TREE(&vgpu->page_track_tree, GFP_KERNEL);
 -      idr_init(&vgpu->object_idr);
 +      idr_init_base(&vgpu->object_idr, 1);
        intel_vgpu_init_cfg_space(vgpu, param->primary);
        vgpu->d3_entered = false;
  
  
        if (IS_BROADWELL(dev_priv))
                ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B);
 -      else
 +      /* FixMe: Re-enable APL/BXT once vfio_edid enabled */
 +      else if (!IS_BROXTON(dev_priv))
                ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D);
        if (ret)
                goto out_clean_sched_policy;
@@@ -500,9 -499,11 +500,11 @@@ struct intel_vgpu *intel_gvt_create_vgp
  
        mutex_lock(&gvt->lock);
        vgpu = __intel_gvt_create_vgpu(gvt, &param);
-       if (!IS_ERR(vgpu))
+       if (!IS_ERR(vgpu)) {
                /* calculate left instance change for types */
                intel_gvt_update_vgpu_types(gvt);
+               intel_gvt_update_reg_whitelist(vgpu);
+       }
        mutex_unlock(&gvt->lock);
  
        return vgpu;