• 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
gtt.c 63.9 KB