Commit f6c499ec authored by Daniel Vetter's avatar Daniel Vetter

Merge tag 'gvt-next-2016-10-27' of https://github.com/01org/gvt-linux into drm-intel-next-queued

gvt-next-2016-10-27

- Resolve current left build issue with ACPI=n and 32bit kernel
- TLB workaround from Arkadiusz
- vGPU reset fix from Ping
- workload scheduler nesting sleep fix from Changbin
- more misc fixes for sparse warnings and cleanups
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
parents 1c00164d e45d7b7f
...@@ -87,6 +87,7 @@ config DRM_I915_USERPTR ...@@ -87,6 +87,7 @@ config DRM_I915_USERPTR
config DRM_I915_GVT config DRM_I915_GVT
bool "Enable Intel GVT-g graphics virtualization host support" bool "Enable Intel GVT-g graphics virtualization host support"
depends on DRM_I915 depends on DRM_I915
depends on 64BIT
default n default n
help help
Choose this option if you want to enable Intel GVT-g graphics Choose this option if you want to enable Intel GVT-g graphics
......
...@@ -1145,7 +1145,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s, ...@@ -1145,7 +1145,7 @@ static int skl_decode_mi_display_flip(struct parser_exec_state *s,
info->event = PRIMARY_B_FLIP_DONE; info->event = PRIMARY_B_FLIP_DONE;
break; break;
case MI_DISPLAY_FLIP_SKL_PLANE_1_C: case MI_DISPLAY_FLIP_SKL_PLANE_1_C:
info->pipe = PIPE_B; info->pipe = PIPE_C;
info->event = PRIMARY_C_FLIP_DONE; info->event = PRIMARY_C_FLIP_DONE;
break; break;
default: default:
...@@ -1201,20 +1201,19 @@ static int gen8_update_plane_mmio_from_mi_display_flip( ...@@ -1201,20 +1201,19 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = s->vgpu->gvt->dev_priv;
struct intel_vgpu *vgpu = s->vgpu; struct intel_vgpu *vgpu = s->vgpu;
#define write_bits(reg, e, s, v) do { \ set_mask_bits(&vgpu_vreg(vgpu, info->surf_reg), GENMASK(31, 12),
vgpu_vreg(vgpu, reg) &= ~GENMASK(e, s); \ info->surf_val << 12);
vgpu_vreg(vgpu, reg) |= (v << s); \ if (IS_SKYLAKE(dev_priv)) {
} while (0) set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(9, 0),
info->stride_val);
write_bits(info->surf_reg, 31, 12, info->surf_val); set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(12, 10),
if (IS_SKYLAKE(dev_priv)) info->tile_val << 10);
write_bits(info->stride_reg, 9, 0, info->stride_val); } else {
else set_mask_bits(&vgpu_vreg(vgpu, info->stride_reg), GENMASK(15, 6),
write_bits(info->stride_reg, 15, 6, info->stride_val); info->stride_val << 6);
write_bits(info->ctrl_reg, IS_SKYLAKE(dev_priv) ? 12 : 10, set_mask_bits(&vgpu_vreg(vgpu, info->ctrl_reg), GENMASK(10, 10),
10, info->tile_val); info->tile_val << 10);
}
#undef write_bits
vgpu_vreg(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++; vgpu_vreg(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++;
intel_vgpu_trigger_virtual_event(vgpu, info->event); intel_vgpu_trigger_virtual_event(vgpu, info->event);
......
...@@ -276,7 +276,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index) ...@@ -276,7 +276,7 @@ static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
pte = readq(addr); pte = readq(addr);
#else #else
pte = ioread32(addr); pte = ioread32(addr);
pte |= ioread32(addr + 4) << 32; pte |= (u64)ioread32(addr + 4) << 32;
#endif #endif
return pte; return pte;
} }
...@@ -1944,7 +1944,7 @@ static int create_scratch_page(struct intel_vgpu *vgpu) ...@@ -1944,7 +1944,7 @@ static int create_scratch_page(struct intel_vgpu *vgpu)
mfn = intel_gvt_hypervisor_virt_to_mfn(vaddr); mfn = intel_gvt_hypervisor_virt_to_mfn(vaddr);
if (mfn == INTEL_GVT_INVALID_ADDR) { if (mfn == INTEL_GVT_INVALID_ADDR) {
gvt_err("fail to translate vaddr:0x%llx\n", (u64)vaddr); gvt_err("fail to translate vaddr: 0x%p\n", vaddr);
__free_page(gtt->scratch_page); __free_page(gtt->scratch_page);
gtt->scratch_page = NULL; gtt->scratch_page = NULL;
return -ENXIO; return -ENXIO;
......
...@@ -65,6 +65,8 @@ struct intel_gvt_io_emulation_ops intel_gvt_io_emulation_ops = { ...@@ -65,6 +65,8 @@ struct intel_gvt_io_emulation_ops intel_gvt_io_emulation_ops = {
*/ */
int intel_gvt_init_host(void) int intel_gvt_init_host(void)
{ {
int ret;
if (intel_gvt_host.initialized) if (intel_gvt_host.initialized)
return 0; return 0;
...@@ -90,7 +92,8 @@ int intel_gvt_init_host(void) ...@@ -90,7 +92,8 @@ int intel_gvt_init_host(void)
return -EINVAL; return -EINVAL;
/* Try to detect if we're running in host instead of VM. */ /* Try to detect if we're running in host instead of VM. */
if (!intel_gvt_hypervisor_detect_host()) ret = intel_gvt_hypervisor_detect_host();
if (ret)
return -ENODEV; return -ENODEV;
gvt_dbg_core("Running with hypervisor %s in host mode\n", gvt_dbg_core("Running with hypervisor %s in host mode\n",
...@@ -103,19 +106,20 @@ int intel_gvt_init_host(void) ...@@ -103,19 +106,20 @@ int intel_gvt_init_host(void)
static void init_device_info(struct intel_gvt *gvt) static void init_device_info(struct intel_gvt *gvt)
{ {
struct intel_gvt_device_info *info = &gvt->device_info; struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = gvt->dev_priv->drm.pdev;
if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) { if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
info->max_support_vgpus = 8; info->max_support_vgpus = 8;
info->cfg_space_size = 256; info->cfg_space_size = 256;
info->mmio_size = 2 * 1024 * 1024; info->mmio_size = 2 * 1024 * 1024;
info->mmio_bar = 0; info->mmio_bar = 0;
info->msi_cap_offset = IS_SKYLAKE(gvt->dev_priv) ? 0xac : 0x90;
info->gtt_start_offset = 8 * 1024 * 1024; info->gtt_start_offset = 8 * 1024 * 1024;
info->gtt_entry_size = 8; info->gtt_entry_size = 8;
info->gtt_entry_size_shift = 3; info->gtt_entry_size_shift = 3;
info->gmadr_bytes_in_cmd = 8; info->gmadr_bytes_in_cmd = 8;
info->max_surface_size = 36 * 1024 * 1024; info->max_surface_size = 36 * 1024 * 1024;
} }
info->msi_cap_offset = pdev->msi_cap;
} }
static int gvt_service_thread(void *data) static int gvt_service_thread(void *data)
......
...@@ -382,6 +382,8 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu); ...@@ -382,6 +382,8 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu);
int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa); int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa);
int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci); int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci);
int setup_vgpu_mmio(struct intel_vgpu *vgpu);
void populate_pvinfo_page(struct intel_vgpu *vgpu);
#include "mpt.h" #include "mpt.h"
......
...@@ -239,7 +239,11 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -239,7 +239,11 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset,
vgpu->resetting = true; vgpu->resetting = true;
intel_vgpu_stop_schedule(vgpu); intel_vgpu_stop_schedule(vgpu);
if (scheduler->current_vgpu == vgpu) { /*
* The current_vgpu will set to NULL after stopping the
* scheduler when the reset is triggered by current vgpu.
*/
if (scheduler->current_vgpu == NULL) {
mutex_unlock(&vgpu->gvt->lock); mutex_unlock(&vgpu->gvt->lock);
intel_gvt_wait_vgpu_idle(vgpu); intel_gvt_wait_vgpu_idle(vgpu);
mutex_lock(&vgpu->gvt->lock); mutex_lock(&vgpu->gvt->lock);
...@@ -247,6 +251,16 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -247,6 +251,16 @@ static int handle_device_reset(struct intel_vgpu *vgpu, unsigned int offset,
intel_vgpu_reset_execlist(vgpu, bitmap); intel_vgpu_reset_execlist(vgpu, bitmap);
/* full GPU reset */
if (bitmap == 0xff) {
mutex_unlock(&vgpu->gvt->lock);
intel_vgpu_clean_gtt(vgpu);
mutex_lock(&vgpu->gvt->lock);
setup_vgpu_mmio(vgpu);
populate_pvinfo_page(vgpu);
intel_vgpu_init_gtt(vgpu);
}
vgpu->resetting = false; vgpu->resetting = false;
return 0; return 0;
...@@ -258,6 +272,7 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -258,6 +272,7 @@ static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
u32 data; u32 data;
u64 bitmap = 0; u64 bitmap = 0;
write_vreg(vgpu, offset, p_data, bytes);
data = vgpu_vreg(vgpu, offset); data = vgpu_vreg(vgpu, offset);
if (data & GEN6_GRDOM_FULL) { if (data & GEN6_GRDOM_FULL) {
...@@ -1305,7 +1320,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -1305,7 +1320,7 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset); int ring_id = render_mmio_to_ring_id(vgpu->gvt, offset);
struct intel_vgpu_execlist *execlist; struct intel_vgpu_execlist *execlist;
u32 data = *(u32 *)p_data; u32 data = *(u32 *)p_data;
int ret; int ret = 0;
if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1)) if (WARN_ON(ring_id < 0 || ring_id > I915_NUM_ENGINES - 1))
return -EINVAL; return -EINVAL;
...@@ -1313,12 +1328,15 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -1313,12 +1328,15 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
execlist = &vgpu->execlist[ring_id]; execlist = &vgpu->execlist[ring_id];
execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data; execlist->elsp_dwords.data[execlist->elsp_dwords.index] = data;
if (execlist->elsp_dwords.index == 3) if (execlist->elsp_dwords.index == 3) {
ret = intel_vgpu_submit_execlist(vgpu, ring_id); ret = intel_vgpu_submit_execlist(vgpu, ring_id);
if(ret)
gvt_err("fail submit workload on ring %d\n", ring_id);
}
++execlist->elsp_dwords.index; ++execlist->elsp_dwords.index;
execlist->elsp_dwords.index &= 0x3; execlist->elsp_dwords.index &= 0x3;
return 0; return ret;
} }
static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
......
...@@ -163,7 +163,7 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa) ...@@ -163,7 +163,7 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa)
*/ */
void intel_gvt_clean_opregion(struct intel_gvt *gvt) void intel_gvt_clean_opregion(struct intel_gvt *gvt)
{ {
iounmap(gvt->opregion.opregion_va); memunmap(gvt->opregion.opregion_va);
gvt->opregion.opregion_va = NULL; gvt->opregion.opregion_va = NULL;
} }
...@@ -181,8 +181,8 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt) ...@@ -181,8 +181,8 @@ int intel_gvt_init_opregion(struct intel_gvt *gvt)
pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION, pci_read_config_dword(gvt->dev_priv->drm.pdev, INTEL_GVT_PCI_OPREGION,
&gvt->opregion.opregion_pa); &gvt->opregion.opregion_pa);
gvt->opregion.opregion_va = acpi_os_ioremap(gvt->opregion.opregion_pa, gvt->opregion.opregion_va = memremap(gvt->opregion.opregion_pa,
INTEL_GVT_OPREGION_SIZE); INTEL_GVT_OPREGION_SIZE, MEMREMAP_WB);
if (!gvt->opregion.opregion_va) { if (!gvt->opregion.opregion_va) {
gvt_err("fail to map host opregion\n"); gvt_err("fail to map host opregion\n");
return -EFAULT; return -EFAULT;
......
...@@ -118,6 +118,7 @@ static u32 gen9_render_mocs_L3[32]; ...@@ -118,6 +118,7 @@ static u32 gen9_render_mocs_L3[32];
static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
{ {
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
enum forcewake_domains fw;
i915_reg_t reg; i915_reg_t reg;
u32 regs[] = { u32 regs[] = {
[RCS] = 0x4260, [RCS] = 0x4260,
...@@ -135,11 +136,25 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id) ...@@ -135,11 +136,25 @@ static void handle_tlb_pending_event(struct intel_vgpu *vgpu, int ring_id)
reg = _MMIO(regs[ring_id]); reg = _MMIO(regs[ring_id]);
I915_WRITE(reg, 0x1); /* WaForceWakeRenderDuringMmioTLBInvalidate:skl
* we need to put a forcewake when invalidating RCS TLB caches,
* otherwise device can go to RC6 state and interrupt invalidation
* process
*/
fw = intel_uncore_forcewake_for_reg(dev_priv, reg,
FW_REG_READ | FW_REG_WRITE);
if (ring_id == RCS && IS_SKYLAKE(dev_priv))
fw |= FORCEWAKE_RENDER;
if (wait_for_atomic((I915_READ(reg) == 0), 50)) intel_uncore_forcewake_get(dev_priv, fw);
I915_WRITE_FW(reg, 0x1);
if (wait_for_atomic((I915_READ_FW(reg) == 0), 50))
gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id); gvt_err("timeout in invalidate ring (%d) tlb\n", ring_id);
intel_uncore_forcewake_put(dev_priv, fw);
gvt_dbg_core("invalidate TLB for ring %d\n", ring_id); gvt_dbg_core("invalidate TLB for ring %d\n", ring_id);
} }
...@@ -162,6 +177,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id) ...@@ -162,6 +177,7 @@ static void load_mocs(struct intel_vgpu *vgpu, int ring_id)
if (!IS_SKYLAKE(dev_priv)) if (!IS_SKYLAKE(dev_priv))
return; return;
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
gen9_render_mocs[ring_id][i] = I915_READ(offset); gen9_render_mocs[ring_id][i] = I915_READ(offset);
I915_WRITE(offset, vgpu_vreg(vgpu, offset)); I915_WRITE(offset, vgpu_vreg(vgpu, offset));
...@@ -199,6 +215,7 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id) ...@@ -199,6 +215,7 @@ static void restore_mocs(struct intel_vgpu *vgpu, int ring_id)
if (!IS_SKYLAKE(dev_priv)) if (!IS_SKYLAKE(dev_priv))
return; return;
offset.reg = regs[ring_id];
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
vgpu_vreg(vgpu, offset) = I915_READ(offset); vgpu_vreg(vgpu, offset) = I915_READ(offset);
I915_WRITE(offset, gen9_render_mocs[ring_id][i]); I915_WRITE(offset, gen9_render_mocs[ring_id][i]);
......
...@@ -402,19 +402,24 @@ static int workload_thread(void *priv) ...@@ -402,19 +402,24 @@ static int workload_thread(void *priv)
struct intel_vgpu_workload *workload = NULL; struct intel_vgpu_workload *workload = NULL;
int ret; int ret;
bool need_force_wake = IS_SKYLAKE(gvt->dev_priv); bool need_force_wake = IS_SKYLAKE(gvt->dev_priv);
DEFINE_WAIT_FUNC(wait, woken_wake_function);
kfree(p); kfree(p);
gvt_dbg_core("workload thread for ring %d started\n", ring_id); gvt_dbg_core("workload thread for ring %d started\n", ring_id);
while (!kthread_should_stop()) { while (!kthread_should_stop()) {
ret = wait_event_interruptible(scheduler->waitq[ring_id], add_wait_queue(&scheduler->waitq[ring_id], &wait);
kthread_should_stop() || do {
(workload = pick_next_workload(gvt, ring_id))); workload = pick_next_workload(gvt, ring_id);
if (workload)
WARN_ON_ONCE(ret); break;
wait_woken(&wait, TASK_INTERRUPTIBLE,
if (kthread_should_stop()) MAX_SCHEDULE_TIMEOUT);
} while (!kthread_should_stop());
remove_wait_queue(&scheduler->waitq[ring_id], &wait);
if (!workload)
break; break;
mutex_lock(&scheduler_mutex); mutex_lock(&scheduler_mutex);
......
...@@ -41,7 +41,7 @@ static void clean_vgpu_mmio(struct intel_vgpu *vgpu) ...@@ -41,7 +41,7 @@ static void clean_vgpu_mmio(struct intel_vgpu *vgpu)
vgpu->mmio.vreg = vgpu->mmio.sreg = NULL; vgpu->mmio.vreg = vgpu->mmio.sreg = NULL;
} }
static int setup_vgpu_mmio(struct intel_vgpu *vgpu) int setup_vgpu_mmio(struct intel_vgpu *vgpu)
{ {
struct intel_gvt *gvt = vgpu->gvt; struct intel_gvt *gvt = vgpu->gvt;
const struct intel_gvt_device_info *info = &gvt->device_info; const struct intel_gvt_device_info *info = &gvt->device_info;
...@@ -103,7 +103,7 @@ static void setup_vgpu_cfg_space(struct intel_vgpu *vgpu, ...@@ -103,7 +103,7 @@ static void setup_vgpu_cfg_space(struct intel_vgpu *vgpu,
} }
} }
static void populate_pvinfo_page(struct intel_vgpu *vgpu) void populate_pvinfo_page(struct intel_vgpu *vgpu)
{ {
/* setup the ballooning information */ /* setup the ballooning information */
vgpu_vreg64(vgpu, vgtif_reg(magic)) = VGT_MAGIC; vgpu_vreg64(vgpu, vgtif_reg(magic)) = VGT_MAGIC;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment