diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gtt.c | 58 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gtt.h | 2 |
2 files changed, 60 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 23296547da95..4efec8fa6c1d 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c | |||
@@ -1592,6 +1592,7 @@ static struct intel_vgpu_mm *intel_vgpu_create_ggtt_mm(struct intel_vgpu *vgpu) | |||
1592 | vgpu_free_mm(mm); | 1592 | vgpu_free_mm(mm); |
1593 | return ERR_PTR(-ENOMEM); | 1593 | return ERR_PTR(-ENOMEM); |
1594 | } | 1594 | } |
1595 | mm->ggtt_mm.last_partial_off = -1UL; | ||
1595 | 1596 | ||
1596 | return mm; | 1597 | return mm; |
1597 | } | 1598 | } |
@@ -1616,6 +1617,7 @@ void _intel_vgpu_mm_release(struct kref *mm_ref) | |||
1616 | invalidate_ppgtt_mm(mm); | 1617 | invalidate_ppgtt_mm(mm); |
1617 | } else { | 1618 | } else { |
1618 | vfree(mm->ggtt_mm.virtual_ggtt); | 1619 | vfree(mm->ggtt_mm.virtual_ggtt); |
1620 | mm->ggtt_mm.last_partial_off = -1UL; | ||
1619 | } | 1621 | } |
1620 | 1622 | ||
1621 | vgpu_free_mm(mm); | 1623 | vgpu_free_mm(mm); |
@@ -1868,6 +1870,62 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, | |||
1868 | memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, | 1870 | memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data, |
1869 | bytes); | 1871 | bytes); |
1870 | 1872 | ||
1873 | /* If ggtt entry size is 8 bytes, and it's split into two 4 bytes | ||
1874 | * write, we assume the two 4 bytes writes are consecutive. | ||
1875 | * Otherwise, we abort and report error | ||
1876 | */ | ||
1877 | if (bytes < info->gtt_entry_size) { | ||
1878 | if (ggtt_mm->ggtt_mm.last_partial_off == -1UL) { | ||
1879 | /* the first partial part*/ | ||
1880 | ggtt_mm->ggtt_mm.last_partial_off = off; | ||
1881 | ggtt_mm->ggtt_mm.last_partial_data = e.val64; | ||
1882 | return 0; | ||
1883 | } else if ((g_gtt_index == | ||
1884 | (ggtt_mm->ggtt_mm.last_partial_off >> | ||
1885 | info->gtt_entry_size_shift)) && | ||
1886 | (off != ggtt_mm->ggtt_mm.last_partial_off)) { | ||
1887 | /* the second partial part */ | ||
1888 | |||
1889 | int last_off = ggtt_mm->ggtt_mm.last_partial_off & | ||
1890 | (info->gtt_entry_size - 1); | ||
1891 | |||
1892 | memcpy((void *)&e.val64 + last_off, | ||
1893 | (void *)&ggtt_mm->ggtt_mm.last_partial_data + | ||
1894 | last_off, bytes); | ||
1895 | |||
1896 | ggtt_mm->ggtt_mm.last_partial_off = -1UL; | ||
1897 | } else { | ||
1898 | int last_offset; | ||
1899 | |||
1900 | gvt_vgpu_err("failed to populate guest ggtt entry: abnormal ggtt entry write sequence, last_partial_off=%lx, offset=%x, bytes=%d, ggtt entry size=%d\n", | ||
1901 | ggtt_mm->ggtt_mm.last_partial_off, off, | ||
1902 | bytes, info->gtt_entry_size); | ||
1903 | |||
1904 | /* set host ggtt entry to scratch page and clear | ||
1905 | * virtual ggtt entry as not present for last | ||
1906 | * partially write offset | ||
1907 | */ | ||
1908 | last_offset = ggtt_mm->ggtt_mm.last_partial_off & | ||
1909 | (~(info->gtt_entry_size - 1)); | ||
1910 | |||
1911 | ggtt_get_host_entry(ggtt_mm, &m, last_offset); | ||
1912 | ggtt_invalidate_pte(vgpu, &m); | ||
1913 | ops->set_pfn(&m, gvt->gtt.scratch_mfn); | ||
1914 | ops->clear_present(&m); | ||
1915 | ggtt_set_host_entry(ggtt_mm, &m, last_offset); | ||
1916 | ggtt_invalidate(gvt->dev_priv); | ||
1917 | |||
1918 | ggtt_get_guest_entry(ggtt_mm, &e, last_offset); | ||
1919 | ops->clear_present(&e); | ||
1920 | ggtt_set_guest_entry(ggtt_mm, &e, last_offset); | ||
1921 | |||
1922 | ggtt_mm->ggtt_mm.last_partial_off = off; | ||
1923 | ggtt_mm->ggtt_mm.last_partial_data = e.val64; | ||
1924 | |||
1925 | return 0; | ||
1926 | } | ||
1927 | } | ||
1928 | |||
1871 | if (ops->test_present(&e)) { | 1929 | if (ops->test_present(&e)) { |
1872 | gfn = ops->get_pfn(&e); | 1930 | gfn = ops->get_pfn(&e); |
1873 | m = e; | 1931 | m = e; |
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index 3792f2b7f4ff..97e62647418a 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h | |||
@@ -150,6 +150,8 @@ struct intel_vgpu_mm { | |||
150 | } ppgtt_mm; | 150 | } ppgtt_mm; |
151 | struct { | 151 | struct { |
152 | void *virtual_ggtt; | 152 | void *virtual_ggtt; |
153 | unsigned long last_partial_off; | ||
154 | u64 last_partial_data; | ||
153 | } ggtt_mm; | 155 | } ggtt_mm; |
154 | }; | 156 | }; |
155 | }; | 157 | }; |