[PATCH 15/22] drm/i915/gvt: Split ppgtt_alloc_spt into two parts

changbin.du at intel.com changbin.du at intel.com
Wed Dec 20 07:48:28 UTC 2017


From: Changbin Du <changbin.du at intel.com>

We need a interface to allocate a pure shadow page which doesn't have
a guest page associated with. Such shadow page is used to shadow 2M
huge gtt entry.

Signed-off-by: Changbin Du <changbin.du at intel.com>
---
 drivers/gpu/drm/i915/gvt/gtt.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index de0dcd3..12fb611 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -724,10 +724,12 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt)
 	if (!hlist_unhashed(&spt->node))
 		hash_del(&spt->node);
 
-	if (spt->guest_page.oos_page)
-		detach_oos_page(spt->vgpu, spt->guest_page.oos_page);
+	if (spt->guest_page.gfn) {
+		if (spt->guest_page.oos_page)
+			detach_oos_page(spt->vgpu, spt->guest_page.oos_page);
 
-	intel_vgpu_unregister_page_track(spt->vgpu, spt->guest_page.gfn);
+		intel_vgpu_unregister_page_track(spt->vgpu, spt->guest_page.gfn);
+	}
 
 	list_del_init(&spt->post_shadow_list);
 	free_spt(spt);
@@ -792,14 +794,13 @@ static struct intel_vgpu_ppgtt_spt *intel_vgpu_find_spt_by_mfn(
 
 static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt);
 
+/* Allocate shadow page table without guest page. */
 static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
-		struct intel_vgpu *vgpu, int type, unsigned long gfn,
-		bool guest_pde_ips)
+		struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type)
 {
 	struct device *kdev = &vgpu->gvt->dev_priv->drm.pdev->dev;
 	struct intel_vgpu_ppgtt_spt *spt = NULL;
 	dma_addr_t daddr;
-	int ret;
 
 retry:
 	spt = alloc_spt(GFP_KERNEL | __GFP_ZERO);
@@ -829,6 +830,24 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
 	spt->shadow_page.vaddr = page_address(spt->shadow_page.page);
 	spt->shadow_page.mfn = daddr >> I915_GTT_PAGE_SHIFT;
 
+	INIT_HLIST_NODE(&spt->node);
+	hash_add(vgpu->gtt.spt_hash_table, &spt->node, spt->shadow_page.mfn);
+
+	return spt;
+}
+
+/* Allocate shadow page table associated with specific gfn. */
+static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt_gfn(
+		struct intel_vgpu *vgpu, intel_gvt_gtt_type_t type,
+		unsigned long gfn, bool guest_pde_ips)
+{
+	struct intel_vgpu_ppgtt_spt *spt;
+	int ret;
+
+	spt = ppgtt_alloc_spt(vgpu, type);
+	if (IS_ERR(spt))
+		return spt;
+
 	/*
 	 * Init guest_page.
 	 */
@@ -839,15 +858,12 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_alloc_spt(
 	ret = intel_vgpu_register_page_track(vgpu, spt->guest_page.gfn,
 					ppgtt_write_protection_handler, spt);
 	if (ret) {
-		free_spt(spt);
-		dma_unmap_page(kdev, daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+		ppgtt_free_spt(spt);
 		return ERR_PTR(ret);
 	}
 
-	INIT_HLIST_NODE(&spt->node);
-	hash_add(vgpu->gtt.spt_hash_table, &spt->node, spt->shadow_page.mfn);
-
 	trace_spt_alloc(vgpu->id, spt, type, spt->shadow_page.mfn, gfn);
+
 	return spt;
 }
 
@@ -991,7 +1007,7 @@ static struct intel_vgpu_ppgtt_spt *ppgtt_populate_spt_by_guest_entry(
 		if (we->type == GTT_TYPE_PPGTT_PDE_ENTRY)
 			ips = vgpu_ips_enabled(vgpu) && ops->test_ips(we);
 
-		spt = ppgtt_alloc_spt(vgpu, type, ops->get_pfn(we), ips);
+		spt = ppgtt_alloc_spt_gfn(vgpu, type, ops->get_pfn(we), ips);
 		if (IS_ERR(spt)) {
 			ret = PTR_ERR(spt);
 			goto fail;
-- 
2.7.4



More information about the intel-gvt-dev mailing list