@@ -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
@@ -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;
+}
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(+)