1. 21 Nov, 2018 1 commit
  2. 31 Oct, 2018 1 commit
    • Hang Yuan's avatar
      drm/i915/gvt: support inconsecutive partial gtt entry write · bc0686ff
      Hang Yuan authored
      Previously we assumed two 4-byte writes to the same PTE coming in sequence.
      But recently we observed inconsecutive partial write happening as well. So
      this patch enhances the previous solution. It now uses a list to save more
      partial writes. If one partial write can be combined with another one in
      the list to construct a full PTE, update its shadow entry. Otherwise, save
      the partial write in the list.
      
      v2: invalidate old entry and flush ggtt (Zhenyu)
      v3: split old ggtt page unmap to another patch (Zhenyu)
      v4: refine codes (Zhenyu)
      Signed-off-by: default avatarHang Yuan <hang.yuan@linux.intel.com>
      Cc: Yan Zhao <yan.y.zhao@intel.com>
      Cc: Xiaolin Zhang <xiaolin.zhang@intel.com>
      Cc: Zhenyu Wang <zhenyu.z.wang@intel.com>
      Reviewed-by: default avatarXiaolin Zhang <xiaolin.zhang@intel.com>
      Signed-off-by: Zhenyu Wang's avatarZhenyu Wang <zhenyuw@linux.intel.com>
      bc0686ff
  3. 08 Oct, 2018 1 commit
  4. 07 Aug, 2018 1 commit
  5. 09 Jul, 2018 12 commits
  6. 02 Jul, 2018 1 commit
    • Zhao Yan's avatar
      drm/i915/gvt: fix a bug of partially write ggtt enties · 510fe10b
      Zhao Yan authored
      when guest writes ggtt entries, it could write 8 bytes a time if
      gtt_entry_size is 8. But, qemu could split the 8 bytes into 2 consecutive
      4-byte writes.
      
      If each 4-byte partial write could trigger a host ggtt write, it is very
      possible that a wrong combination is written to the host ggtt. E.g.
      the higher 4 bytes is the old value, but the lower 4 bytes is the new
      value, and this 8-byte combination is wrong but written to the ggtt, thus
      causing bugs.
      
      To handle this condition, we just record the first 4-byte write, then wait
      until the second 4-byte write comes and write the combined 64-bit data to
      host ggtt table.
      
      To save memory space and to spot partial write as early as possible, we
      don't keep this information for every ggtt index. Instread, we just record
      the last ggtt write position, and assume the two 4-byte writes come in
      consecutively for each vgpu.
      
      This assumption is right based on the characteristic of ggtt entry which
      stores memory address. When gtt_entry_size is 8, the guest memory physical
      address should be 64 bits, so any sane guest driver should write 8-byte
      long data at a time, so 2 consecutive 4-byte writes at the same ggtt index
      should be trapped in gvt.
      
      v2:
      when incomplete ggtt entry write is located, e.g.
          1. guest only writes 4 bytes at a ggtt offset and no long writes the
             rest 4 bytes.
          2. guest writes 4 bytes of a ggtt offset, then write at other ggtt
             offsets, then return back to write the left 4 bytes of the first
             ggtt offset.
      add error handling logic to remap host entry to scratch page, and mark
      guest virtual ggtt entry as not present.  (zhenyu wang)
      Signed-off-by: default avatarZhao Yan <yan.y.zhao@intel.com>
      Signed-off-by: Zhenyu Wang's avatarZhenyu Wang <zhenyuw@linux.intel.com>
      510fe10b
  7. 13 Jun, 2018 1 commit
  8. 12 Jun, 2018 1 commit
    • Kees Cook's avatar
      treewide: Use array_size() in vzalloc() · fad953ce
      Kees Cook authored
      The vzalloc() function has no 2-factor argument form, so multiplication
      factors need to be wrapped in array_size(). This patch replaces cases of:
      
              vzalloc(a * b)
      
      with:
              vzalloc(array_size(a, b))
      
      as well as handling cases of:
      
              vzalloc(a * b * c)
      
      with:
      
              vzalloc(array3_size(a, b, c))
      
      This does, however, attempt to ignore constant size factors like:
      
              vzalloc(4 * 1024)
      
      though any constants defined via macros get caught up in the conversion.
      
      Any factors with a sizeof() of "unsigned char", "char", and "u8" were
      dropped, since they're redundant.
      
      The Coccinelle script used for this was:
      
      // Fix redundant parens around sizeof().
      @@
      type TYPE;
      expression THING, E;
      @@
      
      (
        vzalloc(
      -	(sizeof(TYPE)) * E
      +	sizeof(TYPE) * E
        , ...)
      |
        vzalloc(
      -	(sizeof(THING)) * E
      +	sizeof(THING) * E
        , ...)
      )
      
      // Drop single-byte sizes and redundant parens.
      @@
      expression COUNT;
      typedef u8;
      typedef __u8;
      @@
      
      (
        vzalloc(
      -	sizeof(u8) * (COUNT)
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(__u8) * (COUNT)
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(char) * (COUNT)
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(unsigned char) * (COUNT)
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(u8) * COUNT
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(__u8) * COUNT
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(char) * COUNT
      +	COUNT
        , ...)
      |
        vzalloc(
      -	sizeof(unsigned char) * COUNT
      +	COUNT
        , ...)
      )
      
      // 2-factor product with sizeof(type/expression) and identifier or constant.
      @@
      type TYPE;
      expression THING;
      identifier COUNT_ID;
      constant COUNT_CONST;
      @@
      
      (
        vzalloc(
      -	sizeof(TYPE) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * (COUNT_ID)
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * COUNT_ID
      +	array_size(COUNT_ID, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * (COUNT_CONST)
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * COUNT_CONST
      +	array_size(COUNT_CONST, sizeof(THING))
        , ...)
      )
      
      // 2-factor product, only identifiers.
      @@
      identifier SIZE, COUNT;
      @@
      
        vzalloc(
      -	SIZE * COUNT
      +	array_size(COUNT, SIZE)
        , ...)
      
      // 3-factor product with 1 sizeof(type) or sizeof(expression), with
      // redundant parens removed.
      @@
      expression THING;
      identifier STRIDE, COUNT;
      type TYPE;
      @@
      
      (
        vzalloc(
      -	sizeof(TYPE) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(TYPE))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * (COUNT) * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * (COUNT) * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * COUNT * (STRIDE)
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      |
        vzalloc(
      -	sizeof(THING) * COUNT * STRIDE
      +	array3_size(COUNT, STRIDE, sizeof(THING))
        , ...)
      )
      
      // 3-factor product with 2 sizeof(variable), with redundant parens removed.
      @@
      expression THING1, THING2;
      identifier COUNT;
      type TYPE1, TYPE2;
      @@
      
      (
        vzalloc(
      -	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
        , ...)
      |
        vzalloc(
      -	sizeof(THING1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        vzalloc(
      -	sizeof(THING1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * COUNT
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      |
        vzalloc(
      -	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
      +	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
        , ...)
      )
      
      // 3-factor product, only identifiers, with redundant parens removed.
      @@
      identifier STRIDE, SIZE, COUNT;
      @@
      
      (
        vzalloc(
      -	(COUNT) * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	COUNT * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	COUNT * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	(COUNT) * (STRIDE) * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	COUNT * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	(COUNT) * STRIDE * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	(COUNT) * (STRIDE) * (SIZE)
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      |
        vzalloc(
      -	COUNT * STRIDE * SIZE
      +	array3_size(COUNT, STRIDE, SIZE)
        , ...)
      )
      
      // Any remaining multi-factor products, first at least 3-factor products
      // when they're not all constants...
      @@
      expression E1, E2, E3;
      constant C1, C2, C3;
      @@
      
      (
        vzalloc(C1 * C2 * C3, ...)
      |
        vzalloc(
      -	E1 * E2 * E3
      +	array3_size(E1, E2, E3)
        , ...)
      )
      
      // And then all remaining 2 factors products when they're not all constants.
      @@
      expression E1, E2;
      constant C1, C2;
      @@
      
      (
        vzalloc(C1 * C2, ...)
      |
        vzalloc(
      -	E1 * E2
      +	array_size(E1, E2)
        , ...)
      )
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      fad953ce
  9. 11 Jun, 2018 1 commit
  10. 30 Mar, 2018 2 commits
    • Changbin Du's avatar
      drm/i915/gvt: Cancel dma map when resetting ggtt entries · f4c43db3
      Changbin Du authored
      Ditto, don't forget ggtt entries during reset.
      Signed-off-by: default avatarChangbin Du <changbin.du@intel.com>
      Signed-off-by: Zhenyu Wang's avatarZhenyu Wang <zhenyuw@linux.intel.com>
      f4c43db3
    • Changbin Du's avatar
      drm/i915/gvt: Missed to cancel dma map for ggtt entries · 7598e870
      Changbin Du authored
      We have canceled dma map for ppgtt entries. Also we need to do it for
      ggtt entries when them are invalidated.
      
      This can fix task hung issue as:
      [13517.791767] INFO: task gvt_service_thr:1081 blocked for more than 120 seconds.
      [13517.792584] Not tainted 4.14.15+ #3
      [13517.793417] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
      [13517.794267] gvt_service_thr D 0 1081 2 0x80000000
      [13517.795132] Call Trace:
      [13517.795996] ? __schedule+0x493/0x77b
      [13517.796859] schedule+0x79/0x82
      [13517.797740] schedule_preempt_disabled+0x5/0x6
      [13517.798614] __mutex_lock.isra.0+0x2b5/0x445
      [13517.799504] ? __switch_to_asm+0x24/0x60
      [13517.800381] ? intel_gvt_cleanup+0x10/0x10
      [13517.801261] ? intel_gvt_schedule+0x19/0x2b9
      [13517.802107] intel_gvt_schedule+0x19/0x2b9
      [13517.802954] ? intel_gvt_cleanup+0x10/0x10
      [13517.803824] gvt_service_thread+0xe3/0x10d
      [13517.804704] ? wait_woken+0x68/0x68
      [13517.805588] kthread+0x118/0x120
      [13517.806478] ? kthread_create_on_node+0x3a/0x3a
      [13517.807381] ? call_usermodehelper_exec_async+0x113/0x11a
      [13517.808307] ret_from_fork+0x35/0x40
      
      v3: split out ggtt reset case.
      v2: also unmap ggtt during reset.
      Signed-off-by: default avatarChangbin Du <changbin.du@intel.com>
      Signed-off-by: Zhenyu Wang's avatarZhenyu Wang <zhenyuw@linux.intel.com>
      7598e870
  11. 19 Mar, 2018 2 commits
  12. 06 Mar, 2018 16 commits