Skip to content

Commit d85936a

Browse files
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 <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 7a8b705 + 11474e9 commit d85936a

File tree

4 files changed

+81
-11
lines changed

4 files changed

+81
-11
lines changed

drivers/gpu/drm/i915/gvt/cfg_space.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,20 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
208208
return 0;
209209
}
210210

211+
static 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+
211225
static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
212226
void *p_data, unsigned int bytes)
213227
{
@@ -300,6 +314,11 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
300314
}
301315

302316
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+
303322
case PCI_BASE_ADDRESS_0 ... PCI_BASE_ADDRESS_5:
304323
if (WARN_ON(!IS_ALIGNED(offset, 4)))
305324
return -EINVAL;
@@ -375,6 +394,8 @@ void intel_vgpu_init_cfg_space(struct intel_vgpu *vgpu,
375394
pci_resource_len(gvt->dev_priv->drm.pdev, 0);
376395
vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].size =
377396
pci_resource_len(gvt->dev_priv->drm.pdev, 2);
397+
398+
memset(vgpu_cfg_space(vgpu) + PCI_ROM_ADDRESS, 0, 4);
378399
}
379400

380401
/**

drivers/gpu/drm/i915/gvt/handlers.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,26 @@ static int new_mmio_info(struct intel_gvt *gvt,
137137
return 0;
138138
}
139139

140-
static 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+
*/
148+
int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
149+
unsigned int offset)
141150
{
142151
enum intel_engine_id id;
143152
struct intel_engine_cs *engine;
144153

145-
reg &= ~GENMASK(11, 0);
154+
offset &= ~GENMASK(11, 0);
146155
for_each_engine(engine, gvt->dev_priv, id) {
147-
if (engine->mmio_base == reg)
156+
if (engine->mmio_base == offset)
148157
return id;
149158
}
150-
return -1;
159+
return -ENODEV;
151160
}
152161

153162
#define offset_to_fence_num(offset) \
@@ -1398,18 +1407,36 @@ static int skl_lcpll_write(struct intel_vgpu *vgpu, unsigned int offset,
13981407
static int mmio_read_from_hw(struct intel_vgpu *vgpu,
13991408
unsigned int offset, void *p_data, unsigned int bytes)
14001409
{
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+
}
14021432

1403-
mmio_hw_access_pre(dev_priv);
1404-
vgpu_vreg(vgpu, offset) = I915_READ(_MMIO(offset));
1405-
mmio_hw_access_post(dev_priv);
14061433
return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);
14071434
}
14081435

14091436
static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
14101437
void *p_data, unsigned int bytes)
14111438
{
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);
14131440
struct intel_vgpu_execlist *execlist;
14141441
u32 data = *(u32 *)p_data;
14151442
int ret = 0;
@@ -1436,7 +1463,7 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
14361463
void *p_data, unsigned int bytes)
14371464
{
14381465
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);
14401467
bool enable_execlist;
14411468

14421469
write_vreg(vgpu, offset, p_data, bytes);

drivers/gpu/drm/i915/gvt/mmio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ struct intel_gvt_mmio_info {
6565
struct hlist_node node;
6666
};
6767

68+
int intel_gvt_render_mmio_to_ring_id(struct intel_gvt *gvt,
69+
unsigned int reg);
6870
unsigned long intel_gvt_get_device_type(struct intel_gvt *gvt);
6971
bool intel_gvt_match_device(struct intel_gvt *gvt, unsigned long device);
7072

drivers/gpu/drm/i915/gvt/scheduler.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,20 @@ static inline bool is_gvt_request(struct drm_i915_gem_request *req)
131131
return i915_gem_context_force_single_submission(req->ctx);
132132
}
133133

134+
static 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+
134148
static int shadow_context_status_change(struct notifier_block *nb,
135149
unsigned long action, void *data)
136150
{
@@ -175,9 +189,12 @@ static int shadow_context_status_change(struct notifier_block *nb,
175189
atomic_set(&workload->shadow_ctx_active, 1);
176190
break;
177191
case INTEL_CONTEXT_SCHEDULE_OUT:
178-
case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
192+
save_ring_hw_state(workload->vgpu, ring_id);
179193
atomic_set(&workload->shadow_ctx_active, 0);
180194
break;
195+
case INTEL_CONTEXT_SCHEDULE_PREEMPTED:
196+
save_ring_hw_state(workload->vgpu, ring_id);
197+
break;
181198
default:
182199
WARN_ON(1);
183200
return NOTIFY_OK;
@@ -740,6 +757,9 @@ int intel_vgpu_init_gvt_context(struct intel_vgpu *vgpu)
740757
if (IS_ERR(vgpu->shadow_ctx))
741758
return PTR_ERR(vgpu->shadow_ctx);
742759

760+
if (INTEL_INFO(vgpu->gvt->dev_priv)->has_logical_ring_preemption)
761+
vgpu->shadow_ctx->priority = INT_MAX;
762+
743763
vgpu->shadow_ctx->engine[RCS].initialised = true;
744764

745765
bitmap_zero(vgpu->shadow_ctx_desc_updated, I915_NUM_ENGINES);

0 commit comments

Comments
 (0)