aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2017-12-07 06:35:32 -0500
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2017-12-07 06:35:33 -0500
commitd85936ab62f902ab84be7a021aa013d4b5dfe292 (patch)
tree93e198d5800836cbbb28cb61702a7c967df1645c
parent7a8b70535037a7d8503d12c1a5abbbc8aa5d709a (diff)
parent11474e9091cf2002e948647fd9f63a7f027e488a (diff)
Merge tag 'gvt-fixes-2017-12-06' of https://github.com/intel/gvt-linux into drm-intel-fixes
gvt-fixes-2017-12-06 - Fix invalid hw reg read value for vGPU (Xiong) - Fix qemu warning on PCI ROM bar missing (Changbin) - Workaround preemption regression (Zhenyu) Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171206075105.wlh2ojubjczlstox@zhen-hp.sh.intel.com
-rw-r--r--drivers/gpu/drm/i915/gvt/cfg_space.c21
-rw-r--r--drivers/gpu/drm/i915/gvt/handlers.c47
-rw-r--r--drivers/gpu/drm/i915/gvt/mmio.h2
-rw-r--r--drivers/gpu/drm/i915/gvt/scheduler.c22
4 files changed, 81 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c
index ab19545d59a1..4ce2e6bd0680 100644
--- a/drivers/gpu/drm/i915/gvt/cfg_space.c
+++ b/drivers/gpu/drm/i915/gvt/cfg_space.c
@@ -208,6 +208,20 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
208 return 0; 208 return 0;
209} 209}
210 210
211static int emulate_pci_rom_bar_write(struct intel_vgpu *vgpu,
212 unsigned int offset, void *p_data, unsigned int bytes)
213{
214 u32 *pval = (u32 *)(vgpu_cfg_space(vgpu) + offset);
215 u32 new = *(u32 *)(p_data);
216
217 if ((new & PCI_ROM_ADDRESS_MASK) == PCI_ROM_ADDRESS_MASK)
218 /* We don't have rom, return size of 0. */
219 *pval = 0;
220 else
221 vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
222 return 0;
223}
224
211static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset, 225static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
212 void *p_data, unsigned int bytes) 226 void *p_data, unsigned int bytes)
213{ 227{
@@ -300,6 +314,11 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
300 } 314 }
301 315
302 switch (rounddown(offset, 4)) { 316 switch (rounddown(offset, 4)) {
317 case PCI_ROM_ADDRESS:
318 if (WARN_ON(!IS_ALIGNED(offset, 4)))
319 return -EINVAL;
320 return emulate_pci_rom_bar_write(vgpu, offset, p_data, bytes);
321
303 case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5: 322 case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
304 if (WARN_ON(!IS_ALIGNED(offset, 4))) 323 if (WARN_ON(!IS_ALIGNED(offset, 4)))
305 return -EINVAL; 324 return -EINVAL;
@@ -375,6 +394,8 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
375 pci_resource_len(gvt->dev_priv->drm.pdev, 0); 394 pci_resource_len(gvt->dev_priv->drm.pdev, 0);
376 vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size = 395 vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size =
377 pci_resource_len(gvt->dev_priv->drm.pdev, 2); 396 pci_resource_len(gvt->dev_priv->drm.pdev, 2);
397
398 memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
378} 399}
379 400
380/** 401/**
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 44cd5ff5e97d..1f840f6b81bb 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -137,17 +137,26 @@ static int new_mmio_info(struct intel_gvt *gvt,
137 return 0; 137 return 0;
138} 138}
139 139
140static int render_mmio_to_ring_id(struct intel_gvt *gvt, unsigned int reg) 140/**
141 * intel_gvt_render_mmio_to_ring_id - convert a mmio offset into ring id
142 * @gvt: a GVT device
143 * @offset: register offset
144 *
145 * Returns:
146 * Ring ID on success, negative error code if failed.
147 */
148int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
149 unsigned int offset)
141{ 150{
142 enum intel_engine_id id; 151 enum intel_engine_id id;
143 struct intel_engine_cs *engine; 152 struct intel_engine_cs *engine;
144 153
145 reg &= ~GENMASK(11, 0); 154 offset &= ~GENMASK(11, 0);
146 for_each_engine(engine, gvt->dev_priv, id) { 155 for_each_engine(engine, gvt->dev_priv, id) {
147 if (engine->mmio_base == reg) 156 if (engine->mmio_base == offset)
148 return id; 157 return id;
149 } 158 }
150 return -1; 159 return -ENODEV;
151} 160}
152 161
153#define offset_to_fence_num(offset) \ 162#define offset_to_fence_num(offset) \
@@ -1398,18 +1407,36 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset,
1398static int mmio_read_from_hw(struct intel_vgpu *vgpu, 1407static int mmio_read_from_hw(struct intel_vgpu *vgpu,
1399 unsigned int offset, void *p_data, unsigned int bytes) 1408 unsigned int offset, void *p_data, unsigned int bytes)
1400{ 1409{
1401 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; 1410 struct intel_gvt *gvt = vgpu->gvt;
1411 struct drm_i915_private *dev_priv = gvt->dev_priv;
1412 int ring_id;
1413 u32 ring_base;
1414
1415 ring_id = intel_gvt_render_mmio_to_ring_id(gvt, offset);
1416 /**
1417 * Read HW reg in following case
1418 * a. the offset isn't a ring mmio
1419 * b. the offset's ring is running on hw.
1420 * c. the offset is ring time stamp mmio
1421 */
1422 if (ring_id >= 0)
1423 ring_base = dev_priv->engine[ring_id]->mmio_base;
1424
1425 if (ring_id < 0 || vgpu == gvt->scheduler.engine_owner[ring_id] ||
1426 offset == i915_mmio_reg_offset(RING_TIMESTAMP(ring_base)) ||
1427 offset == i915_mmio_reg_offset(RING_TIMESTAMP_UDW(ring_base))) {
1428 mmio_hw_access_pre(dev_priv);
1429 vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
1430 mmio_hw_access_post(dev_priv);
1431 }
1402 1432
1403 mmio_hw_access_pre(dev_priv);
1404 vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
1405 mmio_hw_access_post(dev_priv);
1406 return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); 1433 return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
1407} 1434}
1408 1435
1409static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, 1436static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
1410 void *p_data, unsigned int bytes) 1437 void *p_data, unsigned int bytes)
1411{ 1438{
1412 int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); 1439 int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
1413 struct intel_vgpu_execlist *execlist; 1440 struct intel_vgpu_execlist *execlist;
1414 u32 data = *(u32 *)p_data; 1441 u32 data = *(u32 *)p_data;
1415 int ret = 0; 1442 int ret = 0;
@@ -1436,7 +1463,7 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
1436 void *p_data, unsigned int bytes) 1463 void *p_data, unsigned int bytes)
1437{ 1464{
1438 u32 data = *(u32 *)p_data; 1465 u32 data = *(u32 *)p_data;
1439 int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); 1466 int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
1440 bool enable_execlist; 1467 bool enable_execlist;
1441 1468
1442 write_vreg(vgpu, offset, p_data, bytes); 1469 write_vreg(vgpu, offset, p_data, bytes);
diff --git a/drivers/gpu/drm/i915/gvt/mmio.h b/drivers/gpu/drm/i915/gvt/mmio.h
index 32cd64ddad26..dbc04ad2c7a1 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.h
+++ b/drivers/gpu/drm/i915/gvt/mmio.h
@@ -65,6 +65,8 @@ struct intel_gvt_mmio_info {
65 struct hlist_node node; 65 struct hlist_node node;
66}; 66};
67 67
68int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
69 unsigned int reg);
68unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt); 70unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt);
69bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device); 71bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
70 72
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 3ac1dc97a7a0..69f8f0d155b9 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -131,6 +131,20 @@ static inline bool is_gvt_request(struct drm_i915_gem_request *req)
131 return i915_gem_context_force_single_submission(req->ctx); 131 return i915_gem_context_force_single_submission(req->ctx);
132} 132}
133 133
134static void save_ring_hw_state(struct intel_vgpu *vgpu, int ring_id)
135{
136 struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
137 u32 ring_base = dev_priv->engine[ring_id]->mmio_base;
138 i915_reg_t reg;
139
140 reg = RING_INSTDONE(ring_base);
141 vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
142 reg = RING_ACTHD(ring_base);
143 vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
144 reg = RING_ACTHD_UDW(ring_base);
145 vgpu_vreg(vgpu, i915_mmio_reg_offset(reg)) = I915_READ_FW(reg);
146}
147
134static int shadow_context_status_change(struct notifier_block *nb, 148static int shadow_context_status_change(struct notifier_block *nb,
135 unsigned long action, void *data) 149 unsigned long action, void *data)
136{ 150{
@@ -175,9 +189,12 @@ static int shadow_context_status_change(struct notifier_block *nb,
175 atomic_set(&workload->shadow_ctx_active, 1); 189 atomic_set(&workload->shadow_ctx_active, 1);
176 break; 190 break;
177 case INTEL_CONTEXT_SCHEDULE_OUT: 191 case INTEL_CONTEXT_SCHEDULE_OUT:
178 case INTEL_CONTEXT_SCHEDULE_PREEMPTED: 192 save_ring_hw_state(workload->vgpu, ring_id);
179 atomic_set(&workload->shadow_ctx_active, 0); 193 atomic_set(&workload->shadow_ctx_active, 0);
180 break; 194 break;
195 case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
196 save_ring_hw_state(workload->vgpu, ring_id);
197 break;
181 default: 198 default:
182 WARN_ON(1); 199 WARN_ON(1);
183 return NOTIFY_OK; 200 return NOTIFY_OK;
@@ -740,6 +757,9 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
740 if (IS_ERR(vgpu->shadow_ctx)) 757 if (IS_ERR(vgpu->shadow_ctx))
741 return PTR_ERR(vgpu->shadow_ctx); 758 return PTR_ERR(vgpu->shadow_ctx);
742 759
760 if (INTEL_INFO(vgpu->gvt->dev_priv)->has_logical_ring_preemption)
761 vgpu->shadow_ctx->priority = INT_MAX;
762
743 vgpu->shadow_ctx->engine[RCS].initialised = true; 763 vgpu->shadow_ctx->engine[RCS].initialised = true;
744 764
745 bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES); 765 bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);