diff mbox

[RFC,3/8] drm/i915: add the vgt implementation of MMIO/GTT mediations

Message ID 1412071538-19059-4-git-send-email-jike.song@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jike Song Sept. 30, 2014, 10:05 a.m. UTC
vgt mediates GPU operations from host i915, in the same way as
mediating GPU operations from normal VMs. This way vgt can
have centralized management about sharing among host and other
VMs. To achieve that, we add a hook in critical wrapper interfaces
(MMIO/GTT).

This patch only adds the MMIO/GTT accessing functions, without
changing the existing i915 MMIO/GTT access behaviors.

Signed-off-by: Jike Song <jike.song@intel.com>
---
 drivers/gpu/drm/i915/i915_vgt.h |  21 ++++++++
 drivers/gpu/drm/i915/vgt/vgt.c  | 105 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 126 insertions(+)

Comments

Tian, Kevin Sept. 30, 2014, 4:34 p.m. UTC | #1
> From: Song, Jike
> Sent: Tuesday, September 30, 2014 3:06 AM
> 
> vgt mediates GPU operations from host i915, in the same way as
> mediating GPU operations from normal VMs. This way vgt can
> have centralized management about sharing among host and other
> VMs. To achieve that, we add a hook in critical wrapper interfaces
> (MMIO/GTT).
> 
> This patch only adds the MMIO/GTT accessing functions, without
> changing the existing i915 MMIO/GTT access behaviors.
> 
> Signed-off-by: Jike Song <jike.song@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_vgt.h |  21 ++++++++
>  drivers/gpu/drm/i915/vgt/vgt.c  | 105
> ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 126 insertions(+)
> 

...

> +void i915_vgt_record_priv(struct drm_i915_private *priv)
> +{
> +	dev_priv = priv;
> +}
> --

Suppose above can be carried in i915_start_vgt, instead of adding
a new interface?

Thanks
Kevin
Jike Song Oct. 1, 2014, 10:58 a.m. UTC | #2
On 10/1/2014 12:34 AM, Tian, Kevin wrote:
>> +void i915_vgt_record_priv(struct drm_i915_private *priv)
>> +{
>> +	dev_priv = priv;
>> +}
>> --
>
> Suppose above can be carried in i915_start_vgt, instead of adding
> a new interface?
>
> Thanks
> Kevin

Should be not? since the drm_device is not yet allocated in 
i915_driver_load.

--
Thanks,
Jike
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_vgt.h b/drivers/gpu/drm/i915/i915_vgt.h
index c6a4144..03e7f00 100644
--- a/drivers/gpu/drm/i915/i915_vgt.h
+++ b/drivers/gpu/drm/i915/i915_vgt.h
@@ -1,9 +1,14 @@ 
 #ifndef _I915_VGT_H_
 #define _I915_VGT_H_
 
+struct drm_i915_private;
+
 #ifdef CONFIG_I915_IGVT
 
 bool i915_start_vgt(struct pci_dev *);
+void i915_vgt_record_priv(struct drm_i915_private *);
+bool vgt_emulate_host_read(u32, void *, int, bool, bool);
+bool vgt_emulate_host_write(u32, void *, int, bool, bool);
 
 #else /* !CONFIG_I915_IGVT */
 
@@ -12,6 +17,22 @@  static inline bool i915_start_vgt(struct pci_dev *pdev)
 	return false;
 }
 
+static inline void i915_vgt_record_priv(struct drm_i915_private *priv)
+{
+}
+
+static inline bool vgt_emulate_host_read(u32 reg, void *val, int len,
+			bool is_gtt, bool trace)
+{
+	return false;
+}
+
+static inline bool vgt_emulate_host_write(u32 reg, void *val, int len,
+			bool is_gtt, bool trace)
+{
+	return false;
+}
+
 #endif /* CONFIG_I915_IGVT */
 
 #endif
diff --git a/drivers/gpu/drm/i915/vgt/vgt.c b/drivers/gpu/drm/i915/vgt/vgt.c
index 07ccee6..f33baf3 100644
--- a/drivers/gpu/drm/i915/vgt/vgt.c
+++ b/drivers/gpu/drm/i915/vgt/vgt.c
@@ -2,8 +2,12 @@ 
 #include <linux/kthread.h>
 #include <linux/pci.h>
 
+#include "../i915_drv.h"
 #include "vgt.h"
 
+const static bool vgt_integration_done = false;
+static struct drm_i915_private *dev_priv = NULL;
+
 
 /**
  * Initialize Intel GVT-g
@@ -16,3 +20,104 @@  bool i915_start_vgt(struct pci_dev *pdev)
 	/* vgt is not yet integrated, this only means testing */
 	return false;
 }
+
+static bool vgt_mmio_read(off_t reg, void *val, int len, bool trace)
+{
+	switch (len) {
+	case 1:
+		*(u8 *)val = dev_priv->uncore.funcs.mmio_readb(dev_priv,
+					reg, trace);
+		break;
+	case 2:
+		*(u16 *)val = dev_priv->uncore.funcs.mmio_readw(dev_priv,
+				reg, trace);
+		break;
+	case 4:
+		*(u32 *)val = dev_priv->uncore.funcs.mmio_readl(dev_priv,
+					reg, trace);
+		break;
+	case 8:
+		*(u64 *)val = dev_priv->uncore.funcs.mmio_readq(dev_priv,
+					reg, trace);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static bool vgt_mmio_write(off_t reg, void *val, int len, bool trace)
+{
+	switch (len) {
+	case 1:
+		dev_priv->uncore.funcs.mmio_writeb(dev_priv,
+					reg, *(u8 *)val, trace);
+		break;
+	case 2:
+		dev_priv->uncore.funcs.mmio_writew(dev_priv,
+					reg, *(u16 *)val, trace);
+		break;
+	case 4:
+		dev_priv->uncore.funcs.mmio_writel(dev_priv,
+					reg, *(u32 *)val, trace);
+		break;
+	case 8:
+		dev_priv->uncore.funcs.mmio_writeq(dev_priv,
+					reg, *(u64 *)val, trace);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static bool vgt_gtt_read(off_t reg, void *val, int len)
+{
+	switch (len) {
+	case 4:
+		*(u32 *)val = readl(reg + dev_priv->gtt.gsm);
+		break;
+	case 8:
+		*(u64 *)val = readq(reg + dev_priv->gtt.gsm);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static bool vgt_gtt_write(off_t reg, void *val, int len)
+{
+	switch (len) {
+	case 4:
+		writel(*(u32 *)val, reg + dev_priv->gtt.gsm);
+		break;
+	case 8:
+		writeq(*(u64 *)val, reg + dev_priv->gtt.gsm);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+bool vgt_emulate_host_read(u32 reg, void *val, int len, bool is_gtt,
+			bool trace)
+{
+	if (!vgt_integration_done)
+		return is_gtt ? vgt_gtt_read(reg, val, len) :
+				vgt_mmio_read(reg, val, len, trace);
+}
+
+bool vgt_emulate_host_write(u32 reg, void *val, int len, bool is_gtt,
+			bool trace)
+{
+	if (!vgt_integration_done)
+		return is_gtt ? vgt_gtt_write(reg, val, len) :
+				vgt_mmio_write(reg, val, len, trace);
+}
+
+void i915_vgt_record_priv(struct drm_i915_private *priv)
+{
+	dev_priv = priv;
+}