Skip to content

Commit

Permalink
Merge tag 'gvt-fixes-2017-01-10' of https://github.com/01org/gvt-linux
Browse files Browse the repository at this point in the history
…into drm-intel-fixes

GVT-g fixes from Zhenya, "Please pull GVT-g device model fixes for
rc4. This is based on rc3 with new vfio/mdev interface change."

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Jani Nikula committed Jan 10, 2017
2 parents a121103 + 9631739 commit 79b11b6
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 87 deletions.
7 changes: 0 additions & 7 deletions drivers/gpu/drm/i915/gvt/aperture_gm.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@
#include "i915_drv.h"
#include "gvt.h"

#define MB_TO_BYTES(mb) ((mb) << 20ULL)
#define BYTES_TO_MB(b) ((b) >> 20ULL)

#define HOST_LOW_GM_SIZE MB_TO_BYTES(128)
#define HOST_HIGH_GM_SIZE MB_TO_BYTES(384)
#define HOST_FENCE 4

static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
{
struct intel_gvt *gvt = vgpu->gvt;
Expand Down
54 changes: 17 additions & 37 deletions drivers/gpu/drm/i915/gvt/gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,28 +240,17 @@ static inline int get_pse_type(int type)
static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
{
void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
u64 pte;

#ifdef readq
pte = readq(addr);
#else
pte = ioread32(addr);
pte |= (u64)ioread32(addr + 4) << 32;
#endif
return pte;
return readq(addr);
}

static void write_pte64(struct drm_i915_private *dev_priv,
unsigned long index, u64 pte)
{
void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;

#ifdef writeq
writeq(pte, addr);
#else
iowrite32((u32)pte, addr);
iowrite32(pte >> 32, addr + 4);
#endif

I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
POSTING_READ(GFX_FLSH_CNTL_GEN6);
}
Expand Down Expand Up @@ -1380,8 +1369,7 @@ static int gen8_mm_alloc_page_table(struct intel_vgpu_mm *mm)
info->gtt_entry_size;
mem = kzalloc(mm->has_shadow_page_table ?
mm->page_table_entry_size * 2
: mm->page_table_entry_size,
GFP_ATOMIC);
: mm->page_table_entry_size, GFP_KERNEL);
if (!mem)
return -ENOMEM;
mm->virtual_page_table = mem;
Expand Down Expand Up @@ -1532,7 +1520,7 @@ struct intel_vgpu_mm *intel_vgpu_create_mm(struct intel_vgpu *vgpu,
struct intel_vgpu_mm *mm;
int ret;

mm = kzalloc(sizeof(*mm), GFP_ATOMIC);
mm = kzalloc(sizeof(*mm), GFP_KERNEL);
if (!mm) {
ret = -ENOMEM;
goto fail;
Expand Down Expand Up @@ -1886,30 +1874,27 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
int page_entry_num = GTT_PAGE_SIZE >>
vgpu->gvt->device_info.gtt_entry_size_shift;
struct page *scratch_pt;
void *scratch_pt;
unsigned long mfn;
int i;
void *p;

if (WARN_ON(type < GTT_TYPE_PPGTT_PTE_PT || type >= GTT_TYPE_MAX))
return -EINVAL;

scratch_pt = alloc_page(GFP_KERNEL | GFP_ATOMIC | __GFP_ZERO);
scratch_pt = (void *)get_zeroed_page(GFP_KERNEL);
if (!scratch_pt) {
gvt_err("fail to allocate scratch page\n");
return -ENOMEM;
}

p = kmap_atomic(scratch_pt);
mfn = intel_gvt_hypervisor_virt_to_mfn(p);
mfn = intel_gvt_hypervisor_virt_to_mfn(scratch_pt);
if (mfn == INTEL_GVT_INVALID_ADDR) {
gvt_err("fail to translate vaddr:0x%llx\n", (u64)p);
kunmap_atomic(p);
__free_page(scratch_pt);
gvt_err("fail to translate vaddr:0x%lx\n", (unsigned long)scratch_pt);
free_page((unsigned long)scratch_pt);
return -EFAULT;
}
gtt->scratch_pt[type].page_mfn = mfn;
gtt->scratch_pt[type].page = scratch_pt;
gtt->scratch_pt[type].page = virt_to_page(scratch_pt);
gvt_dbg_mm("vgpu%d create scratch_pt: type %d mfn=0x%lx\n",
vgpu->id, type, mfn);

Expand All @@ -1918,7 +1903,7 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
* scratch_pt[type] indicate the scratch pt/scratch page used by the
* 'type' pt.
* e.g. scratch_pt[GTT_TYPE_PPGTT_PDE_PT] is used by
* GTT_TYPE_PPGTT_PDE_PT level pt, that means this scatch_pt it self
* GTT_TYPE_PPGTT_PDE_PT level pt, that means this scratch_pt it self
* is GTT_TYPE_PPGTT_PTE_PT, and full filled by scratch page mfn.
*/
if (type > GTT_TYPE_PPGTT_PTE_PT && type < GTT_TYPE_MAX) {
Expand All @@ -1936,11 +1921,9 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
se.val64 |= PPAT_CACHED_INDEX;

for (i = 0; i < page_entry_num; i++)
ops->set_entry(p, &se, i, false, 0, vgpu);
ops->set_entry(scratch_pt, &se, i, false, 0, vgpu);
}

kunmap_atomic(p);

return 0;
}

Expand Down Expand Up @@ -2208,7 +2191,7 @@ int intel_vgpu_g2v_destroy_ppgtt_mm(struct intel_vgpu *vgpu,
int intel_gvt_init_gtt(struct intel_gvt *gvt)
{
int ret;
void *page_addr;
void *page;

gvt_dbg_core("init gtt\n");

Expand All @@ -2221,17 +2204,14 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
return -ENODEV;
}

gvt->gtt.scratch_ggtt_page =
alloc_page(GFP_KERNEL | GFP_ATOMIC | __GFP_ZERO);
if (!gvt->gtt.scratch_ggtt_page) {
page = (void *)get_zeroed_page(GFP_KERNEL);
if (!page) {
gvt_err("fail to allocate scratch ggtt page\n");
return -ENOMEM;
}
gvt->gtt.scratch_ggtt_page = virt_to_page(page);

page_addr = page_address(gvt->gtt.scratch_ggtt_page);

gvt->gtt.scratch_ggtt_mfn =
intel_gvt_hypervisor_virt_to_mfn(page_addr);
gvt->gtt.scratch_ggtt_mfn = intel_gvt_hypervisor_virt_to_mfn(page);
if (gvt->gtt.scratch_ggtt_mfn == INTEL_GVT_INVALID_ADDR) {
gvt_err("fail to translate scratch ggtt page\n");
__free_page(gvt->gtt.scratch_ggtt_page);
Expand Down
8 changes: 7 additions & 1 deletion drivers/gpu/drm/i915/gvt/gvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
intel_gvt_clean_vgpu_types(gvt);

idr_destroy(&gvt->vgpu_idr);

kfree(dev_priv->gvt);
dev_priv->gvt = NULL;
}
Expand Down Expand Up @@ -237,14 +239,16 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)

gvt_dbg_core("init gvt device\n");

idr_init(&gvt->vgpu_idr);

mutex_init(&gvt->lock);
gvt->dev_priv = dev_priv;

init_device_info(gvt);

ret = intel_gvt_setup_mmio_info(gvt);
if (ret)
return ret;
goto out_clean_idr;

ret = intel_gvt_load_firmware(gvt);
if (ret)
Expand Down Expand Up @@ -313,6 +317,8 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
intel_gvt_free_firmware(gvt);
out_clean_mmio_info:
intel_gvt_clean_mmio_info(gvt);
out_clean_idr:
idr_destroy(&gvt->vgpu_idr);
kfree(gvt);
return ret;
}
13 changes: 6 additions & 7 deletions drivers/gpu/drm/i915/gvt/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ static void write_vreg(struct intel_vgpu *vgpu, unsigned int offset,
static int new_mmio_info(struct intel_gvt *gvt,
u32 offset, u32 flags, u32 size,
u32 addr_mask, u32 ro_mask, u32 device,
void *read, void *write)
int (*read)(struct intel_vgpu *, unsigned int, void *, unsigned int),
int (*write)(struct intel_vgpu *, unsigned int, void *, unsigned int))
{
struct intel_gvt_mmio_info *info, *p;
u32 start, end, i;
Expand Down Expand Up @@ -219,7 +220,7 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu,
default:
/*should not hit here*/
gvt_err("invalid forcewake offset 0x%x\n", offset);
return 1;
return -EINVAL;
}
} else {
ack_reg_offset = FORCEWAKE_ACK_HSW_REG;
Expand Down Expand Up @@ -974,7 +975,7 @@ static int sbi_data_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
return 0;
}

static bool sbi_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
static int sbi_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
void *p_data, unsigned int bytes)
{
u32 data;
Expand Down Expand Up @@ -1366,7 +1367,6 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
static int gvt_reg_tlb_control_handler(struct intel_vgpu *vgpu,
unsigned int offset, void *p_data, unsigned int bytes)
{
int rc = 0;
unsigned int id = 0;

write_vreg(vgpu, offset, p_data, bytes);
Expand All @@ -1389,12 +1389,11 @@ static int gvt_reg_tlb_control_handler(struct intel_vgpu *vgpu,
id = VECS;
break;
default:
rc = -EINVAL;
break;
return -EINVAL;
}
set_bit(id, (void *)vgpu->tlb_handle_pending);

return rc;
return 0;
}

static int ring_reset_ctl_write(struct intel_vgpu *vgpu,
Expand Down
14 changes: 10 additions & 4 deletions drivers/gpu/drm/i915/gvt/kvmgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
struct intel_vgpu_type *type;
struct device *pdev;
void *gvt;
int ret;

pdev = mdev_parent_dev(mdev);
gvt = kdev_to_i915(pdev)->gvt;
Expand All @@ -406,13 +407,15 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
if (!type) {
gvt_err("failed to find type %s to create\n",
kobject_name(kobj));
return -EINVAL;
ret = -EINVAL;
goto out;
}

vgpu = intel_gvt_ops->vgpu_create(gvt, type);
if (IS_ERR_OR_NULL(vgpu)) {
gvt_err("create intel vgpu failed\n");
return -EINVAL;
ret = vgpu == NULL ? -EFAULT : PTR_ERR(vgpu);
gvt_err("failed to create intel vgpu: %d\n", ret);
goto out;
}

INIT_WORK(&vgpu->vdev.release_work, intel_vgpu_release_work);
Expand All @@ -422,7 +425,10 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)

gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
dev_name(mdev_dev(mdev)));
return 0;
ret = 0;

out:
return ret;
}

static int intel_vgpu_remove(struct mdev_device *mdev)
Expand Down
31 changes: 16 additions & 15 deletions drivers/gpu/drm/i915/gvt/mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,25 +125,12 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
if (WARN_ON(!reg_is_mmio(gvt, offset + bytes - 1)))
goto err;

mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4));
if (!mmio && !vgpu->mmio.disable_warn_untrack) {
gvt_err("vgpu%d: read untracked MMIO %x len %d val %x\n",
vgpu->id, offset, bytes, *(u32 *)p_data);

if (offset == 0x206c) {
gvt_err("------------------------------------------\n");
gvt_err("vgpu%d: likely triggers a gfx reset\n",
vgpu->id);
gvt_err("------------------------------------------\n");
vgpu->mmio.disable_warn_untrack = true;
}
}

if (!intel_gvt_mmio_is_unalign(gvt, offset)) {
if (WARN_ON(!IS_ALIGNED(offset, bytes)))
goto err;
}

mmio = intel_gvt_find_mmio_info(gvt, rounddown(offset, 4));
if (mmio) {
if (!intel_gvt_mmio_is_unalign(gvt, mmio->offset)) {
if (WARN_ON(offset + bytes > mmio->offset + mmio->size))
Expand All @@ -152,9 +139,23 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
goto err;
}
ret = mmio->read(vgpu, offset, p_data, bytes);
} else
} else {
ret = intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes);

if (!vgpu->mmio.disable_warn_untrack) {
gvt_err("vgpu%d: read untracked MMIO %x(%dB) val %x\n",
vgpu->id, offset, bytes, *(u32 *)p_data);

if (offset == 0x206c) {
gvt_err("------------------------------------------\n");
gvt_err("vgpu%d: likely triggers a gfx reset\n",
vgpu->id);
gvt_err("------------------------------------------\n");
vgpu->mmio.disable_warn_untrack = true;
}
}
}

if (ret)
goto err;

Expand Down
8 changes: 4 additions & 4 deletions drivers/gpu/drm/i915/gvt/opregion.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ static int init_vgpu_opregion(struct intel_vgpu *vgpu, u32 gpa)
vgpu->id))
return -EINVAL;

vgpu_opregion(vgpu)->va = (void *)__get_free_pages(GFP_ATOMIC |
GFP_DMA32 | __GFP_ZERO,
INTEL_GVT_OPREGION_PORDER);
vgpu_opregion(vgpu)->va = (void *)__get_free_pages(GFP_KERNEL |
__GFP_ZERO,
get_order(INTEL_GVT_OPREGION_SIZE));

if (!vgpu_opregion(vgpu)->va)
return -ENOMEM;
Expand Down Expand Up @@ -97,7 +97,7 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_XEN) {
map_vgpu_opregion(vgpu, false);
free_pages((unsigned long)vgpu_opregion(vgpu)->va,
INTEL_GVT_OPREGION_PORDER);
get_order(INTEL_GVT_OPREGION_SIZE));

vgpu_opregion(vgpu)->va = NULL;
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/i915/gvt/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@
#define INTEL_GVT_OPREGION_PARM 0x204

#define INTEL_GVT_OPREGION_PAGES 2
#define INTEL_GVT_OPREGION_PORDER 1
#define INTEL_GVT_OPREGION_SIZE (2 * 4096)
#define INTEL_GVT_OPREGION_SIZE (INTEL_GVT_OPREGION_PAGES * PAGE_SIZE)

#define VGT_SPRSTRIDE(pipe) _PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B)

Expand Down
Loading

0 comments on commit 79b11b6

Please sign in to comment.