[Intel-gfx] [RFC 02/10] drm/i915/gvt: get ready of memory for pvmmio

Xiaolin Zhang xiaolin.zhang at intel.com
Thu Sep 27 16:37:47 UTC 2018


To enable pvmmio feature, we need to prepare one 4K shared page
which will be accessed by both guest and backend i915 driver.

guest i915 allocate one page memory and then the guest physical address is
passed to backend i915 driver through PVINFO register so that backend i915
driver can access this shared page without hypeviser trap cost for shared
data exchagne via hyperviser read_gpa functionality.

Signed-off-by: Xiaolin Zhang <xiaolin.zhang at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c    |  5 +++++
 drivers/gpu/drm/i915/i915_drv.h    |  3 +++
 drivers/gpu/drm/i915/i915_pvinfo.h | 25 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/i915_vgpu.c   | 17 +++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index ade9bca..815a4dd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -885,6 +885,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv)
 		return -ENODEV;
 
 	spin_lock_init(&dev_priv->irq_lock);
+	spin_lock_init(&dev_priv->shared_page_lock);
 	spin_lock_init(&dev_priv->gpu_error.lock);
 	mutex_init(&dev_priv->backlight_lock);
 	spin_lock_init(&dev_priv->uncore.lock);
@@ -987,6 +988,8 @@ static void i915_mmio_cleanup(struct drm_i915_private *dev_priv)
 
 	intel_teardown_mchbar(dev_priv);
 	pci_iounmap(pdev, dev_priv->regs);
+	if (intel_vgpu_active(dev_priv) && dev_priv->shared_page)
+		free_pages((unsigned long)dev_priv->shared_page, 0);
 }
 
 /**
@@ -1029,6 +1032,8 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
 	return 0;
 
 err_uncore:
+	if (intel_vgpu_active(dev_priv) && dev_priv->shared_page)
+		free_pages((unsigned long)dev_priv->shared_page, 0);
 	intel_uncore_fini(dev_priv);
 err_bridge:
 	pci_dev_put(dev_priv->bridge_dev);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 174d618..76d7e9c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -56,6 +56,7 @@
 
 #include "i915_params.h"
 #include "i915_reg.h"
+#include "i915_pvinfo.h"
 #include "i915_utils.h"
 
 #include "intel_bios.h"
@@ -1623,6 +1624,8 @@ struct drm_i915_private {
 	resource_size_t stolen_usable_size;	/* Total size minus reserved ranges */
 
 	void __iomem *regs;
+	struct gvt_shared_page *shared_page;
+	spinlock_t shared_page_lock;
 
 	struct intel_uncore uncore;
 
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
index 697e998..ab839a7 100644
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
@@ -49,6 +49,25 @@ enum vgt_g2v_type {
 	VGT_G2V_MAX,
 };
 
+struct pv_ppgtt_update {
+	u64 pdp;
+	u64 start;
+	u64 length;
+	u32 cache_level;
+};
+
+/*
+ * shared page(4KB) between gvt and VM, could be allocated by guest driver
+ * or a fixed location in PCI bar 0 region
+ */
+struct gvt_shared_page {
+	u32 elsp_data[4];
+	u32 reg_addr;
+	u32 disable_irq;
+	struct pv_ppgtt_update pv_ppgtt;
+	u32 rsvd2[0x400 - 13];
+};
+
 #define VGPU_PVMMIO(vgpu) vgpu_vreg_t(vgpu, vgtif_reg(enable_pvmmio))
 
 /*
@@ -120,8 +139,12 @@ struct vgt_if {
 	u32 execlist_context_descriptor_lo;
 	u32 execlist_context_descriptor_hi;
 	u32 enable_pvmmio;
+	struct {
+		u32 lo;
+		u32 hi;
+	} shared_page_gpa;
 
-	u32  rsv7[0x200 - 25];    /* pad to one page */
+	u32  rsv7[0x200 - 27];    /* pad to one page */
 } __packed;
 
 #define vgtif_reg(x) \
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index d22c5ca..10ae94b 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -62,6 +62,7 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
 {
 	u64 magic;
 	u16 version_major;
+	u64 shared_page_gpa;
 
 	BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE);
 
@@ -89,6 +90,22 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv)
 	dev_priv->vgpu.active = true;
 	DRM_INFO("Virtual GPU for Intel GVT-g detected with pvmmio 0x%x\n",
 		i915_modparams.enable_pvmmio);
+
+	if (intel_vgpu_active(dev_priv) && i915_modparams.enable_pvmmio) {
+		dev_priv->shared_page =  (struct gvt_shared_page *)
+				__get_free_pages(GFP_KERNEL | __GFP_ZERO, 0);
+		if (!dev_priv->shared_page) {
+			DRM_ERROR("out of memory for shared page memory\n");
+			return;
+		}
+		shared_page_gpa = __pa(dev_priv->shared_page);
+		__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.lo),
+				lower_32_bits(shared_page_gpa));
+		__raw_i915_write32(dev_priv, vgtif_reg(shared_page_gpa.hi),
+				upper_32_bits(shared_page_gpa));
+		DRM_INFO("VGPU shared page enabled\n");
+	}
+
 }
 
 bool intel_vgpu_has_full_48bit_ppgtt(struct drm_i915_private *dev_priv)
-- 
1.8.3.1



More information about the Intel-gfx mailing list