[Intel-gfx] [RFC 01/29] drm/i915/gvt: Introduce the basic architecture of GVT-g
Zhi Wang
zhi.a.wang at intel.com
Thu Jan 28 02:21:23 PST 2016
This patch introduces the very basic framework of GVT-g device model,
includes basic prototypes, definitions, initialization.
---
arch/x86/include/asm/xen/interface.h | 3 +
drivers/gpu/drm/i915/Kconfig | 16 ++
drivers/gpu/drm/i915/Makefile | 2 +
drivers/gpu/drm/i915/gvt/Makefile | 5 +
drivers/gpu/drm/i915/gvt/debug.h | 72 +++++++
drivers/gpu/drm/i915/gvt/fb_decoder.c | 34 ++++
drivers/gpu/drm/i915/gvt/fb_decoder.h | 110 ++++++++++
drivers/gpu/drm/i915/gvt/gvt.c | 366 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/gvt.h | 130 ++++++++++++
drivers/gpu/drm/i915/gvt/hypercall.h | 30 +++
drivers/gpu/drm/i915/gvt/mpt.h | 97 +++++++++
drivers/gpu/drm/i915/gvt/params.c | 29 +++
drivers/gpu/drm/i915/gvt/params.h | 34 ++++
drivers/gpu/drm/i915/gvt/reg.h | 34 ++++
drivers/gpu/drm/i915/i915_dma.c | 19 ++
drivers/gpu/drm/i915/i915_drv.h | 6 +
drivers/gpu/drm/i915/i915_vgpu.h | 3 +
include/xen/interface/xen.h | 1 +
18 files changed, 991 insertions(+)
create mode 100644 drivers/gpu/drm/i915/gvt/Makefile
create mode 100644 drivers/gpu/drm/i915/gvt/debug.h
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.c
create mode 100644 drivers/gpu/drm/i915/gvt/fb_decoder.h
create mode 100644 drivers/gpu/drm/i915/gvt/gvt.c
create mode 100644 drivers/gpu/drm/i915/gvt/gvt.h
create mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
create mode 100644 drivers/gpu/drm/i915/gvt/mpt.h
create mode 100644 drivers/gpu/drm/i915/gvt/params.c
create mode 100644 drivers/gpu/drm/i915/gvt/params.h
create mode 100644 drivers/gpu/drm/i915/gvt/reg.h
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index 62ca03e..6ff4986 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -73,6 +73,9 @@
#endif
#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
/* Explicitly size integers that represent pfns in the public interface
* with Xen so that on ARM we can have one ABI that works for 32 and 64
* bit guests. */
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 051eab3..89ff723 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -47,3 +47,19 @@ config DRM_I915_PRELIMINARY_HW_SUPPORT
option changes the default for that module option.
If in doubt, say "N".
+
+config I915_GVT
+ tristate "GVT-g host driver"
+ depends on DRM_I915
+ select IRQ_WORK
+ default y
+ help
+ Enabling GVT-g mediated graphics passthrough technique for Intel i915
+ based integrated graphics card. With GVT-g, it's possible to have one
+ integrated i915 device shared by multiple VMs. Performance critical
+ opterations such as apperture accesses and ring buffer operations
+ are pass-throughed to VM, with a minimal set of conflicting resources
+ (e.g. display settings) mediated by vGT driver. The benefit of vGT
+ is on both the performance, given that each VM could directly operate
+ its aperture space and submit commands like running on native, and
+ the feature completeness, given that a true GEN hardware is exposed.
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..d4df410 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -91,6 +91,8 @@ i915-y += dvo_ch7017.o \
intel_sdvo.o \
intel_tv.o
+obj-$(CONFIG_I915_GVT) += gvt/
+
# virtual gpu code
i915-y += i915_vgpu.o
diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
new file mode 100644
index 0000000..6935b78
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -0,0 +1,5 @@
+GVT_SOURCE := gvt.o params.o fb_decoder.o
+
+ccflags-y += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
+i915_gvt-y := $(GVT_SOURCE)
+obj-$(CONFIG_I915_GVT) += i915_gvt.o
diff --git a/drivers/gpu/drm/i915/gvt/debug.h b/drivers/gpu/drm/i915/gvt/debug.h
new file mode 100644
index 0000000..18e1467
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/debug.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef __GVT_DEBUG_H__
+#define __GVT_DEBUG_H__
+
+#define ASSERT(x) \
+ do { \
+ if (!(x)) { \
+ printk("Assert at %s line %d\n", \
+ __FILE__, __LINE__); \
+ } \
+ } while (0);
+
+#define ASSERT_NUM(x, y) \
+ do { \
+ if (!(x)) { \
+ printk("Assert at %s line %d para 0x%llx\n", \
+ __FILE__, __LINE__, (u64)y); \
+ } \
+ } while (0);
+
+#define gvt_info(fmt, args...) \
+ printk(KERN_INFO"[GVT-g] "fmt"\n", ##args)
+
+#define gvt_err(fmt, args...) \
+ printk(KERN_ERR"%s() - %d: "fmt"\n", __func__, __LINE__, ##args)
+
+#define gvt_warn(fmt, args...) \
+ printk(KERN_WARNING"%s() - %d: "fmt"\n", __func__, __LINE__, ##args)
+
+#define gvt_dbg(level, fmt, args...) do { \
+ if (gvt.debug & level) \
+ printk(KERN_DEBUG"%s() - %d: "fmt"\n", __func__, __LINE__, ##args); \
+ }while(0)
+
+enum {
+ GVT_DBG_CORE = (1 << 0),
+ GVT_DBG_MM = (1 << 1),
+ GVT_DBG_IRQ = (1 << 2),
+};
+
+#define gvt_dbg_core(fmt, args...) \
+ gvt_dbg(GVT_DBG_CORE, fmt, ##args)
+
+#define gvt_dbg_mm(fmt, args...) \
+ gvt_dbg(GVT_DBG_MM, fmt, ##args)
+
+#define gvt_dbg_irq(fmt, args...) \
+ gvt_dbg(GVT_DBG_IRQ, fmt, ##args)
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
new file mode 100644
index 0000000..a219819
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "gvt.h"
+
+int gvt_decode_fb_format(struct pgt_device *pdev, int vmid, struct gvt_fb_format *fb)
+{
+ return 0;
+}
+
+int gvt_fb_notifier_call_chain(unsigned long val, void *data)
+{
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.h b/drivers/gpu/drm/i915/gvt/fb_decoder.h
new file mode 100644
index 0000000..2c29ed4
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_FB_DECODER_H_
+#define _GVT_FB_DECODER_H_
+
+typedef enum {
+ FB_MODE_SET_START = 1,
+ FB_MODE_SET_END,
+ FB_DISPLAY_FLIP,
+}gvt_fb_event_t;
+
+typedef enum {
+ DDI_PORT_NONE = 0,
+ DDI_PORT_B = 1,
+ DDI_PORT_C = 2,
+ DDI_PORT_D = 3,
+ DDI_PORT_E = 4
+} ddi_port_t;
+
+struct pgt_device;
+
+struct gvt_fb_notify_msg {
+ unsigned vm_id;
+ unsigned pipe_id; /* id starting from 0 */
+ unsigned plane_id; /* primary, cursor, or sprite */
+};
+
+/* color space conversion and gamma correction are not included */
+struct gvt_primary_plane_format {
+ u8 enabled; /* plane is enabled */
+ u8 tiled; /* X-tiled */
+ u8 bpp; /* bits per pixel */
+ u32 hw_format; /* format field in the PRI_CTL register */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* framebuffer base in graphics memory */
+ u32 x_offset; /* in pixels */
+ u32 y_offset; /* in lines */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+ u32 stride; /* in bytes */
+};
+
+struct gvt_sprite_plane_format {
+ u8 enabled; /* plane is enabled */
+ u8 tiled; /* X-tiled */
+ u8 bpp; /* bits per pixel */
+ u32 hw_format; /* format field in the SPR_CTL register */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* sprite base in graphics memory */
+ u32 x_pos; /* in pixels */
+ u32 y_pos; /* in lines */
+ u32 x_offset; /* in pixels */
+ u32 y_offset; /* in lines */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+};
+
+struct gvt_cursor_plane_format {
+ u8 enabled;
+ u8 mode; /* cursor mode select */
+ u8 bpp; /* bits per pixel */
+ u32 drm_format; /* format in DRM definition */
+ u32 base; /* cursor base in graphics memory */
+ u32 x_pos; /* in pixels */
+ u32 y_pos; /* in lines */
+ u8 x_sign; /* X Position Sign */
+ u8 y_sign; /* Y Position Sign */
+ u32 width; /* in pixels */
+ u32 height; /* in lines */
+ u32 x_hot; /* in pixels */
+ u32 y_hot; /* in pixels */
+};
+
+struct gvt_pipe_format {
+ struct gvt_primary_plane_format primary;
+ struct gvt_sprite_plane_format sprite;
+ struct gvt_cursor_plane_format cursor;
+ ddi_port_t ddi_port; /* the DDI port that the pipe is connected to */
+};
+
+struct gvt_fb_format{
+ struct gvt_pipe_format pipes[I915_MAX_PIPES];
+};
+
+extern int gvt_fb_notifier_call_chain(unsigned long val, void *data);
+extern int gvt_decode_fb_format(struct pgt_device *pdev, int vmid,
+ struct gvt_fb_format *fb);
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
new file mode 100644
index 0000000..041d10f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <xen/xen.h>
+#include <linux/kthread.h>
+
+#include "gvt.h"
+
+struct gvt_host gvt_host;
+
+extern struct gvt_kernel_dm xengt_kdm;
+extern struct gvt_kernel_dm kvmgt_kdm;
+
+static const char *supported_hypervisors[] = {
+ [GVT_HYPERVISOR_TYPE_XEN] = "Xen Hypervisor",
+ [GVT_HYPERVISOR_TYPE_KVM] = "KVM",
+};
+
+static bool gvt_init_host(void)
+{
+ struct gvt_host *host = &gvt_host;
+
+ if (!gvt.enable) {
+ gvt_dbg_core("GVT-g has been disabled by kernel parameter");
+ return false;
+ }
+
+ if (host->initialized) {
+ gvt_err("GVT-g has already been initialized!");
+ return false;
+ }
+
+ if (xen_initial_domain()) {
+ /* Xen Dom0 */
+ host->kdm = try_then_request_module(symbol_get(xengt_kdm), "xengt");
+ host->hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
+ } else if(xen_domain()) {
+ /* Xen DomU */
+ return false;
+ } else {
+ /* not in Xen. Try KVMGT */
+ host->kdm = try_then_request_module(symbol_get(kvmgt_kdm), "kvm");
+ host->hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
+ }
+
+ if (!host->kdm)
+ return false;
+
+ if (!hypervisor_detect_host())
+ return false;
+
+ gvt_info("Running with hypervisor %s in host mode",
+ supported_hypervisors[host->hypervisor_type]);
+
+ idr_init(&host->device_idr);
+ mutex_init(&host->device_idr_lock);
+
+ host->initialized = true;
+ return true;
+}
+
+static bool init_device_info(struct pgt_device *pdev)
+{
+ struct gvt_device_info *info = &pdev->device_info;
+
+ if (!IS_BROADWELL(pdev->dev_priv)) {
+ gvt_err("Unsupported GEN device");
+ return false;
+ }
+
+ if (IS_BROADWELL(pdev->dev_priv)) {
+ info->max_gtt_gm_sz = (1UL << 32);
+ /*
+ * The layout of BAR0 in BDW:
+ * |< - MMIO 2MB ->|<- Reserved 6MB ->|<- MAX GTT 8MB->|
+ *
+ * GTT offset in BAR0 starts from 8MB to 16MB, and
+ * Whatever GTT size is configured in BIOS,
+ * the size of BAR0 is always 16MB. The actual configured
+ * GTT size can be found in GMCH_CTRL.
+ */
+ info->gtt_start_offset = (1UL << 23);
+ info->max_gtt_size = (1UL << 23);
+ info->gtt_entry_size = 8;
+ info->gtt_entry_size_shift = 3;
+ info->gmadr_bytes_in_cmd = 8;
+ }
+
+ gvt_info("Device info:");
+ printk(" max_gtt_gm_sz: %llx\n", info->max_gtt_gm_sz);
+ printk(" max_gtt_size: %x\n", info->max_gtt_size);
+ printk(" gtt_size_entry: %x\n", info->gtt_entry_size);
+ printk(" gtt_entry_size_shift: %x\n", info->gtt_entry_size_shift);
+ printk(" gtt_start_offset: %x\n", info->gtt_start_offset);
+ printk(" gtt_end_offset: %x\n", info->gtt_end_offset);
+
+ return true;
+}
+
+static void init_initial_cfg_space_state(struct pgt_device *pdev)
+{
+ struct pci_dev *pci_dev = pdev->dev_priv->dev->pdev;
+ int i;
+
+ gvt_dbg_core("init initial cfg space, id %d", pdev->id);
+
+ for (i = 0; i < GVT_CFG_SPACE_SZ; i += 4)
+ pci_read_config_dword(pci_dev, i,
+ (u32 *)&pdev->initial_cfg_space[i]);
+
+ for (i = 0; i < 3; i++) {
+ pdev->bar_size[i] = pci_resource_len(pci_dev, i * 2);
+ gvt_info("bar %d size: %llx", i, pdev->bar_size[i]);
+ }
+}
+
+static void clean_initial_mmio_state(struct pgt_device *pdev)
+{
+ if (pdev->gttmmio_va) {
+ iounmap(pdev->gttmmio_va);
+ pdev->gttmmio_va = NULL;
+ }
+
+ if (pdev->gmadr_va) {
+ iounmap(pdev->gmadr_va);
+ pdev->gmadr_va = NULL;
+ }
+}
+
+static bool init_initial_mmio_state(struct pgt_device *pdev)
+{
+ u64 bar0, bar1;
+
+ gvt_dbg_core("init initial mmio state, id %d", pdev->id);
+
+ bar0 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR0];
+ bar1 = *(u64 *)&pdev->initial_cfg_space[GVT_REG_CFG_SPACE_BAR1];
+
+ pdev->gttmmio_base = bar0 & ~0xf;
+ pdev->mmio_size = 2 * 1024 * 1024;
+ pdev->reg_num = pdev->mmio_size / 4;
+ pdev->gmadr_base = bar1 & ~0xf;
+
+ pdev->gttmmio_va = ioremap(pdev->gttmmio_base, pdev->bar_size[0]);
+ if (!pdev->gttmmio_va) {
+ gvt_err("fail to map GTTMMIO BAR.");
+ return false;
+ }
+
+ pdev->gmadr_va = ioremap(pdev->gmadr_base, pdev->bar_size[2]);
+ if (!pdev->gmadr_va) {
+ gvt_err("fail to map GMADR BAR.");
+ goto err;
+ }
+
+ gvt_info("bar0: 0x%llx, bar1: 0x%llx", bar0, bar1);
+ gvt_info("mmio size: %x", pdev->mmio_size);
+ gvt_info("gttmmio: 0x%llx, gmadr: 0x%llx", pdev->gttmmio_base, pdev->gmadr_base);
+ gvt_info("gttmmio_va: %p", pdev->gttmmio_va);
+ gvt_info("gmadr_va: %p", pdev->gmadr_va);
+
+ return true;
+err:
+ clean_initial_mmio_state(pdev);
+ return false;
+}
+
+static int gvt_service_thread(void *data)
+{
+ struct pgt_device *pdev = (struct pgt_device *)data;
+ int r;
+
+ gvt_dbg_core("service thread start, pgt %d", pdev->id);
+
+ while(!kthread_should_stop()) {
+ r = wait_event_interruptible(pdev->service_thread_wq,
+ kthread_should_stop() || pdev->service_request);
+
+ if (kthread_should_stop())
+ break;
+
+ if (r) {
+ gvt_warn("service thread is waken up by unexpected signal.");
+ continue;
+ }
+ }
+ return 0;
+}
+
+static void clean_service_thread(struct pgt_device *pdev)
+{
+ if (pdev->service_thread) {
+ kthread_stop(pdev->service_thread);
+ pdev->service_thread = NULL;
+ }
+}
+
+static bool init_service_thread(struct pgt_device *pdev)
+{
+ init_waitqueue_head(&pdev->service_thread_wq);
+
+ pdev->service_thread = kthread_run(gvt_service_thread,
+ pdev, "gvt_service_thread%d", pdev->id);
+
+ if (!pdev->service_thread) {
+ gvt_err("fail to start service thread.");
+ return false;
+ }
+
+ return true;
+}
+
+static void clean_pgt_device(struct pgt_device *pdev)
+{
+ clean_service_thread(pdev);
+ clean_initial_mmio_state(pdev);
+}
+
+static bool init_pgt_device(struct pgt_device *pdev, struct drm_i915_private *dev_priv)
+{
+ if (!init_device_info(pdev))
+ return false;
+
+ init_initial_cfg_space_state(pdev);
+
+ if (!init_initial_mmio_state(pdev))
+ goto err;
+
+ if (!init_service_thread(pdev))
+ goto err;
+
+ return true;
+err:
+ clean_pgt_device(pdev);
+ return false;
+}
+
+static bool post_init_pgt_device(struct pgt_device *pdev)
+{
+ return true;
+}
+
+static void free_pgt_device(struct pgt_device *pdev)
+{
+ struct gvt_host *host = &gvt_host;
+
+ mutex_lock(&host->device_idr_lock);
+ idr_remove(&host->device_idr, pdev->id);
+ mutex_unlock(&host->device_idr_lock);
+
+ vfree(pdev);
+}
+
+static struct pgt_device *alloc_pgt_device(struct drm_i915_private *dev_priv)
+{
+ struct gvt_host *host = &gvt_host;
+ struct pgt_device *pdev = NULL;
+
+ pdev = vzalloc(sizeof(*pdev));
+ if (!pdev) {
+ gvt_err("fail to allocate memory for pgt device.");
+ return NULL;
+ }
+
+ mutex_lock(&host->device_idr_lock);
+ pdev->id = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
+ mutex_unlock(&host->device_idr_lock);
+
+ if (pdev->id < 0) {
+ gvt_err("fail to allocate pgt device id.");
+ goto err;
+ }
+
+ mutex_init(&pdev->lock);
+ pdev->dev_priv = dev_priv;
+ idr_init(&pdev->instance_idr);
+
+ return pdev;
+err:
+ free_pgt_device(pdev);
+ return NULL;
+}
+
+void gvt_destroy_pgt_device(void *private_data)
+{
+ struct pgt_device *pdev = (struct pgt_device *)private_data;
+
+ clean_pgt_device(pdev);
+ free_pgt_device(pdev);
+}
+
+void *gvt_create_pgt_device(struct drm_i915_private *dev_priv)
+{
+ struct pgt_device *pdev = NULL;
+ struct gvt_host *host = &gvt_host;
+
+ if (!host->initialized && !gvt_init_host()) {
+ gvt_err("gvt_init_host fail");
+ return NULL;
+ }
+
+ gvt_dbg_core("create new pgt device, i915 dev_priv: %p", dev_priv);
+
+ pdev = alloc_pgt_device(dev_priv);
+ if (!pdev) {
+ gvt_err("fail to allocate memory for pgt device.");
+ goto err;
+ }
+
+ gvt_dbg_core("init pgt device, id %d", pdev->id);
+
+ if (!init_pgt_device(pdev, dev_priv)) {
+ gvt_err("fail to init physical device state.");
+ goto err;
+ }
+
+ gvt_dbg_core("pgt device creation done, id %d", pdev->id);
+
+ return pdev;
+err:
+ if (pdev) {
+ gvt_destroy_pgt_device(pdev);
+ pdev = NULL;
+ }
+ return NULL;
+}
+
+bool gvt_post_init_pgt_device(void *private_data)
+{
+ struct pgt_device *pdev = (struct pgt_device *)private_data;
+ struct gvt_host *host = &gvt_host;
+
+ if (!host->initialized) {
+ gvt_err("gvt_host haven't been initialized.");
+ return false;
+ }
+
+ gvt_dbg_core("post init pgt device %d", pdev->id);
+
+ if (!post_init_pgt_device(pdev)) {
+ gvt_err("fail to post init physical device state.");
+ return false;
+ }
+
+ return true;
+}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
new file mode 100644
index 0000000..6c85bba
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_H_
+#define _GVT_H_
+
+#include "i915_drv.h"
+#include "i915_vgpu.h"
+
+#include "debug.h"
+#include "params.h"
+#include "reg.h"
+#include "hypercall.h"
+#include "mpt.h"
+#include "fb_decoder.h"
+
+#define GVT_MAX_VGPU 8
+
+enum {
+ GVT_HYPERVISOR_TYPE_XEN = 0,
+ GVT_HYPERVISOR_TYPE_KVM,
+};
+
+struct gvt_host {
+ bool initialized;
+ int hypervisor_type;
+ struct mutex device_idr_lock;
+ struct idr device_idr;
+ struct gvt_kernel_dm *kdm;
+};
+
+extern struct gvt_host gvt_host;
+
+/* Describe the limitation of HW.*/
+struct gvt_device_info {
+ u64 max_gtt_gm_sz;
+ u32 gtt_start_offset;
+ u32 gtt_end_offset;
+ u32 max_gtt_size;
+ u32 gtt_entry_size;
+ u32 gtt_entry_size_shift;
+ u32 gmadr_bytes_in_cmd;
+};
+
+struct vgt_device {
+ int id;
+ int vm_id;
+ struct pgt_device *pdev;
+ bool warn_untrack;
+};
+
+struct pgt_device {
+ struct mutex lock;
+ int id;
+
+ struct drm_i915_private *dev_priv;
+ struct idr instance_idr;
+
+ struct gvt_device_info device_info;
+
+ u8 initial_cfg_space[GVT_CFG_SPACE_SZ];
+ u64 bar_size[GVT_BAR_NUM];
+
+ u64 gttmmio_base;
+ void *gttmmio_va;
+
+ u64 gmadr_base;
+ void *gmadr_va;
+
+ u32 mmio_size;
+ u32 reg_num;
+
+ wait_queue_head_t service_thread_wq;
+ struct task_struct *service_thread;
+ unsigned long service_request;
+};
+
+static inline u32 gvt_mmio_read(struct pgt_device *pdev,
+ u32 reg)
+{
+ struct drm_i915_private *dev_priv = pdev->dev_priv;
+ i915_reg_t tmp = {.reg = reg};
+ return I915_READ(tmp);
+}
+
+static inline void gvt_mmio_write(struct pgt_device *pdev,
+ u32 reg, u32 val)
+{
+ struct drm_i915_private *dev_priv = pdev->dev_priv;
+ i915_reg_t tmp = {.reg = reg};
+ I915_WRITE(tmp, val);
+}
+
+static inline u64 gvt_mmio_read64(struct pgt_device *pdev,
+ u32 reg)
+{
+ struct drm_i915_private *dev_priv = pdev->dev_priv;
+ i915_reg_t tmp = {.reg = reg};
+ return I915_READ64(tmp);
+}
+
+static inline void gvt_mmio_write64(struct pgt_device *pdev,
+ u32 reg, u64 val)
+{
+ struct drm_i915_private *dev_priv = pdev->dev_priv;
+ i915_reg_t tmp = {.reg = reg};
+ I915_WRITE64(tmp, val);
+}
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
new file mode 100644
index 0000000..0a41874
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_HYPERCALL_H_
+#define _GVT_HYPERCALL_H_
+
+struct gvt_kernel_dm {
+};
+
+#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
new file mode 100644
index 0000000..bbe4465
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_MPT_H_
+#define _GVT_MPT_H_
+
+struct vgt_device;
+
+static inline unsigned long hypervisor_g2m_pfn(struct vgt_device *vgt,
+ unsigned long g_pfn)
+{
+ return 0;
+}
+
+static inline int hypervisor_pause_domain(struct vgt_device *vgt)
+{
+ return 0;
+}
+
+static inline int hypervisor_shutdown_domain(struct vgt_device *vgt)
+{
+ return 0;
+}
+
+static inline int hypervisor_set_trap_area(struct vgt_device *vgt,
+ uint64_t start, uint64_t end, bool map)
+{
+ return 0;
+}
+
+static inline bool hypervisor_detect_host(void)
+{
+ return false;
+}
+
+static inline int hypervisor_virt_to_mfn(void *addr)
+{
+ return 0;
+}
+
+static inline void *hypervisor_mfn_to_virt(int mfn)
+{
+ return NULL;
+}
+
+static inline void hypervisor_inject_msi(struct vgt_device *vgt)
+{
+ return;
+}
+
+static inline int hypervisor_hvm_init(struct vgt_device *vgt)
+{
+ return 0;
+}
+
+static inline void hypervisor_hvm_exit(struct vgt_device *vgt)
+{
+}
+
+static inline void *hypervisor_gpa_to_va(struct vgt_device *vgt, unsigned long gpa)
+{
+ return NULL;
+}
+
+static inline bool hypervisor_read_va(struct vgt_device *vgt, void *va,
+ void *val, int len, int atomic)
+{
+ return false;
+}
+
+static inline bool hypervisor_write_va(struct vgt_device *vgt, void *va,
+ void *val, int len, int atomic)
+{
+ return false;
+}
+
+#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/params.c b/drivers/gpu/drm/i915/gvt/params.c
new file mode 100644
index 0000000..dfc33c3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/params.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "gvt.h"
+
+struct gvt_kernel_params gvt = {
+ .enable = true,
+ .debug = 0,
+};
diff --git a/drivers/gpu/drm/i915/gvt/params.h b/drivers/gpu/drm/i915/gvt/params.h
new file mode 100644
index 0000000..d2955b9
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/params.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_PARAMS_H_
+#define _GVT_PARAMS_H_
+
+struct gvt_kernel_params {
+ bool enable;
+ int debug;
+};
+
+extern struct gvt_kernel_params gvt;
+
+#endif
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
new file mode 100644
index 0000000..d363b74
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/reg.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _GVT_REG_H
+#define _GVT_REG_H
+
+#define GVT_CFG_SPACE_SZ 256
+#define GVT_BAR_NUM 4
+
+#define GVT_REG_CFG_SPACE_BAR0 0x10
+#define GVT_REG_CFG_SPACE_BAR1 0x18
+#define GVT_REG_CFG_SPACE_BAR2 0x20
+
+#endif
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 4725e8d..eca8e50 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -943,6 +943,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_uncore_init(dev);
+ dev_priv->vgpu.host_private_data = gvt_create_pgt_device(dev_priv);
+ if(intel_gvt_host_active(dev))
+ DRM_INFO("GVT-g is running in host mode\n");
+
ret = i915_gem_gtt_init(dev);
if (ret)
goto out_freecsr;
@@ -1067,6 +1071,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_power_well;
}
+ if (intel_gvt_host_active(dev)) {
+ if (!gvt_post_init_pgt_device(dev_priv->vgpu.host_private_data)) {
+ DRM_ERROR("failed to post init pgt device\n");
+ goto out_power_well;
+ }
+ }
+
/*
* Notify a valid surface after modesetting,
* when running inside a VM.
@@ -1117,6 +1128,10 @@ out_gtt:
i915_global_gtt_cleanup(dev);
out_freecsr:
intel_csr_ucode_fini(dev_priv);
+ if (intel_gvt_host_active(dev)) {
+ gvt_destroy_pgt_device(dev_priv->vgpu.host_private_data);
+ dev_priv->vgpu.host_private_data = NULL;
+ }
intel_uncore_fini(dev);
pci_iounmap(dev->pdev, dev_priv->regs);
put_bridge:
@@ -1165,6 +1180,10 @@ int i915_driver_unload(struct drm_device *dev)
intel_modeset_cleanup(dev);
+ if (intel_gvt_host_active(dev)) {
+ gvt_destroy_pgt_device(dev_priv->vgpu.host_private_data);
+ dev_priv->vgpu.host_private_data = NULL;
+ }
/*
* free the memory space allocated for the child device
* config parsed from VBT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 01cc982..db3c79b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1673,6 +1673,7 @@ struct i915_workarounds {
struct i915_virtual_gpu {
bool active;
+ void *host_private_data;
};
struct i915_execbuffer_params {
@@ -2747,6 +2748,11 @@ static inline bool intel_vgpu_active(struct drm_device *dev)
return to_i915(dev)->vgpu.active;
}
+static inline bool intel_gvt_host_active(struct drm_device *dev)
+{
+ return to_i915(dev)->vgpu.host_private_data ? true : false;
+}
+
void
i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
u32 status_mask);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index 3c83b47..942490a 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -113,5 +113,8 @@ struct vgt_if {
extern void i915_check_vgpu(struct drm_device *dev);
extern int intel_vgt_balloon(struct drm_device *dev);
extern void intel_vgt_deballoon(void);
+extern void *gvt_create_pgt_device(struct drm_i915_private *dev_priv);
+extern bool gvt_post_init_pgt_device(void *private_data);
+extern void gvt_destroy_pgt_device(void *private_data);
#endif /* _I915_VGPU_H_ */
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index d133112..78a38f1 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -28,6 +28,7 @@
#define __XEN_PUBLIC_XEN_H__
#include <asm/xen/interface.h>
+#include <linux/types.h>
/*
* XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
--
1.9.1
More information about the Intel-gfx
mailing list