Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79b11b64 authored by Jani Nikula's avatar Jani Nikula
Browse files

Merge tag 'gvt-fixes-2017-01-10' of https://github.com/01org/gvt-linux 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: default avatarJani Nikula <jani.nikula@intel.com>
parents a121103c 9631739f
Loading
Loading
Loading
Loading
+0 −7
Original line number Original line Diff line number Diff line
@@ -37,13 +37,6 @@
#include "i915_drv.h"
#include "i915_drv.h"
#include "gvt.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)
static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
{
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct intel_gvt *gvt = vgpu->gvt;
+17 −37
Original line number Original line Diff line number Diff line
@@ -240,15 +240,8 @@ static inline int get_pse_type(int type)
static u64 read_pte64(struct drm_i915_private *dev_priv, unsigned long index)
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;
	void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
	u64 pte;


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


static void write_pte64(struct drm_i915_private *dev_priv,
static void write_pte64(struct drm_i915_private *dev_priv,
@@ -256,12 +249,8 @@ static void write_pte64(struct drm_i915_private *dev_priv,
{
{
	void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;
	void __iomem *addr = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + index;


#ifdef writeq
	writeq(pte, addr);
	writeq(pte, addr);
#else

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


	mm = kzalloc(sizeof(*mm), GFP_ATOMIC);
	mm = kzalloc(sizeof(*mm), GFP_KERNEL);
	if (!mm) {
	if (!mm) {
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto fail;
		goto fail;
@@ -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;
	struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
	int page_entry_num = GTT_PAGE_SIZE >>
	int page_entry_num = GTT_PAGE_SIZE >>
				vgpu->gvt->device_info.gtt_entry_size_shift;
				vgpu->gvt->device_info.gtt_entry_size_shift;
	struct page *scratch_pt;
	void *scratch_pt;
	unsigned long mfn;
	unsigned long mfn;
	int i;
	int i;
	void *p;


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


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


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


@@ -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
	 * scratch_pt[type] indicate the scratch pt/scratch page used by the
	 * 'type' pt.
	 * 'type' pt.
	 * e.g. scratch_pt[GTT_TYPE_PPGTT_PDE_PT] is used by
	 * 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.
	 * is GTT_TYPE_PPGTT_PTE_PT, and full filled by scratch page mfn.
	 */
	 */
	if (type > GTT_TYPE_PPGTT_PTE_PT && type < GTT_TYPE_MAX) {
	if (type > GTT_TYPE_PPGTT_PTE_PT && type < GTT_TYPE_MAX) {
@@ -1936,11 +1921,9 @@ static int alloc_scratch_pages(struct intel_vgpu *vgpu,
			se.val64 |= PPAT_CACHED_INDEX;
			se.val64 |= PPAT_CACHED_INDEX;


		for (i = 0; i < page_entry_num; i++)
		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;
	return 0;
}
}


@@ -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 intel_gvt_init_gtt(struct intel_gvt *gvt)
{
{
	int ret;
	int ret;
	void *page_addr;
	void *page;


	gvt_dbg_core("init gtt\n");
	gvt_dbg_core("init gtt\n");


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


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

	gvt->gtt.scratch_ggtt_mfn =
		intel_gvt_hypervisor_virt_to_mfn(page_addr);
	if (gvt->gtt.scratch_ggtt_mfn == INTEL_GVT_INVALID_ADDR) {
	if (gvt->gtt.scratch_ggtt_mfn == INTEL_GVT_INVALID_ADDR) {
		gvt_err("fail to translate scratch ggtt page\n");
		gvt_err("fail to translate scratch ggtt page\n");
		__free_page(gvt->gtt.scratch_ggtt_page);
		__free_page(gvt->gtt.scratch_ggtt_page);
+7 −1
Original line number Original line Diff line number Diff line
@@ -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_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
	intel_gvt_clean_vgpu_types(gvt);
	intel_gvt_clean_vgpu_types(gvt);


	idr_destroy(&gvt->vgpu_idr);

	kfree(dev_priv->gvt);
	kfree(dev_priv->gvt);
	dev_priv->gvt = NULL;
	dev_priv->gvt = NULL;
}
}
@@ -237,6 +239,8 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)


	gvt_dbg_core("init gvt device\n");
	gvt_dbg_core("init gvt device\n");


	idr_init(&gvt->vgpu_idr);

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


@@ -244,7 +248,7 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)


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


	ret = intel_gvt_load_firmware(gvt);
	ret = intel_gvt_load_firmware(gvt);
	if (ret)
	if (ret)
@@ -313,6 +317,8 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
	intel_gvt_free_firmware(gvt);
	intel_gvt_free_firmware(gvt);
out_clean_mmio_info:
out_clean_mmio_info:
	intel_gvt_clean_mmio_info(gvt);
	intel_gvt_clean_mmio_info(gvt);
out_clean_idr:
	idr_destroy(&gvt->vgpu_idr);
	kfree(gvt);
	kfree(gvt);
	return ret;
	return ret;
}
}
+6 −7
Original line number Original line Diff line number Diff line
@@ -93,7 +93,8 @@ static void write_vreg(struct intel_vgpu *vgpu, unsigned int offset,
static int new_mmio_info(struct intel_gvt *gvt,
static int new_mmio_info(struct intel_gvt *gvt,
		u32 offset, u32 flags, u32 size,
		u32 offset, u32 flags, u32 size,
		u32 addr_mask, u32 ro_mask, u32 device,
		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;
	struct intel_gvt_mmio_info *info, *p;
	u32 start, end, i;
	u32 start, end, i;
@@ -219,7 +220,7 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu,
		default:
		default:
			/*should not hit here*/
			/*should not hit here*/
			gvt_err("invalid forcewake offset 0x%x\n", offset);
			gvt_err("invalid forcewake offset 0x%x\n", offset);
			return 1;
			return -EINVAL;
		}
		}
	} else {
	} else {
		ack_reg_offset = FORCEWAKE_ACK_HSW_REG;
		ack_reg_offset = FORCEWAKE_ACK_HSW_REG;
@@ -974,7 +975,7 @@ static int sbi_data_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
	return 0;
	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)
		void *p_data, unsigned int bytes)
{
{
	u32 data;
	u32 data;
@@ -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,
static int gvt_reg_tlb_control_handler(struct intel_vgpu *vgpu,
		unsigned int offset, void *p_data, unsigned int bytes)
		unsigned int offset, void *p_data, unsigned int bytes)
{
{
	int rc = 0;
	unsigned int id = 0;
	unsigned int id = 0;


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


	return rc;
	return 0;
}
}


static int ring_reset_ctl_write(struct intel_vgpu *vgpu,
static int ring_reset_ctl_write(struct intel_vgpu *vgpu,
+10 −4
Original line number Original line Diff line number Diff line
@@ -398,6 +398,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
	struct intel_vgpu_type *type;
	struct intel_vgpu_type *type;
	struct device *pdev;
	struct device *pdev;
	void *gvt;
	void *gvt;
	int ret;


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


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


	INIT_WORK(&vgpu->vdev.release_work, intel_vgpu_release_work);
	INIT_WORK(&vgpu->vdev.release_work, intel_vgpu_release_work);
@@ -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",
	gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
		     dev_name(mdev_dev(mdev)));
		     dev_name(mdev_dev(mdev)));
	return 0;
	ret = 0;

out:
	return ret;
}
}


static int intel_vgpu_remove(struct mdev_device *mdev)
static int intel_vgpu_remove(struct mdev_device *mdev)
Loading