aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChangbin Du <changbin.du@intel.com>2018-01-30 00:51:31 -0500
committerRodrigo Vivi <rodrigo.vivi@intel.com>2018-02-06 14:41:27 -0500
commitd480b28a41a628e356dbacfa1c9f6d05b9baf838 (patch)
tree91063217f3bb888abf035ea0c245586e912e6b47
parent9212b13f28374815d9def65e3c877a35092e1c6e (diff)
drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on
When add 'x-no-mmap=on' for vfio-pci option, aperture access in guest is emulated. But the vgpu_aperture_rw() function take wrong offset when do memcpy, since vgpu->gm.aperture_va is not the base of entire aperture. This mistake cause GPU command in guest get lost and so the seqno is not updated in engine HWSP. This patch fix this, and it also move the emulation code to kvmgt. Because only vfio need to emulate it. Put aperture rw to MMIO emulation path breaks assumptions in xengt. v2: Remove PAGE_ALIGN for size (zhenyu) Fixes: f090a00df9ec ("drm/i915/gvt: Add emulation for BAR2 (aperture) with normal file RW approach") Signed-off-by: Changbin Du <changbin.du@intel.com> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
-rw-r--r--drivers/gpu/drm/i915/gvt/cfg_space.c15
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c36
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio.c42
4 files changed, 35 insertions, 59 deletions
diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c
index 97bfc00d2a82..c62346fdc05d 100644
--- a/drivers/gpu/drm/i915/gvt/cfg_space.c
+++ b/drivers/gpu/drm/i915/gvt/cfg_space.c
@@ -119,16 +119,6 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map)
119 if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked) 119 if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked)
120 return 0; 120 return 0;
121 121
122 if (map) {
123 vgpu->gm.aperture_va = memremap(aperture_pa, aperture_sz,
124 MEMREMAP_WC);
125 if (!vgpu->gm.aperture_va)
126 return -ENOMEM;
127 } else {
128 memunmap(vgpu->gm.aperture_va);
129 vgpu->gm.aperture_va = NULL;
130 }
131
132 val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2]; 122 val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2];
133 if (val & PCI_BASE_ADDRESS_MEM_TYPE_64) 123 if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
134 val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2); 124 val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);
@@ -141,11 +131,8 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map)
141 aperture_pa >> PAGE_SHIFT, 131 aperture_pa >> PAGE_SHIFT,
142 aperture_sz >> PAGE_SHIFT, 132 aperture_sz >> PAGE_SHIFT,
143 map); 133 map);
144 if (ret) { 134 if (ret)
145 memunmap(vgpu->gm.aperture_va);
146 vgpu->gm.aperture_va = NULL;
147 return ret; 135 return ret;
148 }
149 136
150 vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map; 137 vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map;
151 return 0; 138 return 0;
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index c88c48989822..39bfe81f79ab 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -82,7 +82,6 @@ struct intel_gvt_device_info {
82struct intel_vgpu_gm { 82struct intel_vgpu_gm {
83 u64 aperture_sz; 83 u64 aperture_sz;
84 u64 hidden_sz; 84 u64 hidden_sz;
85 void *aperture_va;
86 struct drm_mm_node low_gm_node; 85 struct drm_mm_node low_gm_node;
87 struct drm_mm_node high_gm_node; 86 struct drm_mm_node high_gm_node;
88}; 87};
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index eb92572056c3..801a3375c7b4 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -651,6 +651,39 @@ static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, uint64_t off,
651 return ret; 651 return ret;
652} 652}
653 653
654static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, uint64_t off)
655{
656 return off >= vgpu_aperture_offset(vgpu) &&
657 off < vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu);
658}
659
660static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t off,
661 void *buf, unsigned long count, bool is_write)
662{
663 void *aperture_va;
664
665 if (!intel_vgpu_in_aperture(vgpu, off) ||
666 !intel_vgpu_in_aperture(vgpu, off + count)) {
667 gvt_vgpu_err("Invalid aperture offset %llu\n", off);
668 return -EINVAL;
669 }
670
671 aperture_va = io_mapping_map_wc(&vgpu->gvt->dev_priv->ggtt.iomap,
672 ALIGN_DOWN(off, PAGE_SIZE),
673 count + offset_in_page(off));
674 if (!aperture_va)
675 return -EIO;
676
677 if (is_write)
678 memcpy(aperture_va + offset_in_page(off), buf, count);
679 else
680 memcpy(buf, aperture_va + offset_in_page(off), count);
681
682 io_mapping_unmap(aperture_va);
683
684 return 0;
685}
686
654static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf, 687static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
655 size_t count, loff_t *ppos, bool is_write) 688 size_t count, loff_t *ppos, bool is_write)
656{ 689{
@@ -679,8 +712,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
679 buf, count, is_write); 712 buf, count, is_write);
680 break; 713 break;
681 case VFIO_PCI_BAR2_REGION_INDEX: 714 case VFIO_PCI_BAR2_REGION_INDEX:
682 ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_2, pos, 715 ret = intel_vgpu_aperture_rw(vgpu, pos, buf, count, is_write);
683 buf, count, is_write);
684 break; 716 break;
685 case VFIO_PCI_BAR1_REGION_INDEX: 717 case VFIO_PCI_BAR1_REGION_INDEX:
686 case VFIO_PCI_BAR3_REGION_INDEX: 718 case VFIO_PCI_BAR3_REGION_INDEX:
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
index 562b5ad857a4..5c869e3fdf3b 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.c
+++ b/drivers/gpu/drm/i915/gvt/mmio.c
@@ -56,38 +56,6 @@ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa)
56 (reg >= gvt->device_info.gtt_start_offset \ 56 (reg >= gvt->device_info.gtt_start_offset \
57 && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt)) 57 && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt))
58 58
59static bool vgpu_gpa_is_aperture(struct intel_vgpu *vgpu, uint64_t gpa)
60{
61 u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2);
62 u64 aperture_sz = vgpu_aperture_sz(vgpu);
63
64 return gpa >= aperture_gpa && gpa < aperture_gpa + aperture_sz;
65}
66
67static int vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t gpa,
68 void *pdata, unsigned int size, bool is_read)
69{
70 u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2);
71 u64 offset = gpa - aperture_gpa;
72
73 if (!vgpu_gpa_is_aperture(vgpu, gpa + size - 1)) {
74 gvt_vgpu_err("Aperture rw out of range, offset %llx, size %d\n",
75 offset, size);
76 return -EINVAL;
77 }
78
79 if (!vgpu->gm.aperture_va) {
80 gvt_vgpu_err("BAR is not enabled\n");
81 return -ENXIO;
82 }
83
84 if (is_read)
85 memcpy(pdata, vgpu->gm.aperture_va + offset, size);
86 else
87 memcpy(vgpu->gm.aperture_va + offset, pdata, size);
88 return 0;
89}
90
91static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa, 59static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa,
92 void *p_data, unsigned int bytes, bool read) 60 void *p_data, unsigned int bytes, bool read)
93{ 61{
@@ -144,11 +112,6 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
144 } 112 }
145 mutex_lock(&gvt->lock); 113 mutex_lock(&gvt->lock);
146 114
147 if (vgpu_gpa_is_aperture(vgpu, pa)) {
148 ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, true);
149 goto out;
150 }
151
152 offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); 115 offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
153 116
154 if (WARN_ON(bytes > 8)) 117 if (WARN_ON(bytes > 8))
@@ -222,11 +185,6 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
222 185
223 mutex_lock(&gvt->lock); 186 mutex_lock(&gvt->lock);
224 187
225 if (vgpu_gpa_is_aperture(vgpu, pa)) {
226 ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, false);
227 goto out;
228 }
229
230 offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa); 188 offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
231 189
232 if (WARN_ON(bytes > 8)) 190 if (WARN_ON(bytes > 8))