[Intel-gfx] [RFCv3 02/15] drm/i915/gvt: Introduce the basic architecture of GVT-g
Zhi Wang
zhi.a.wang at intel.com
Fri Mar 11 10:59:33 UTC 2016
This patch introduces the very basic framework of GVT-g device model,
includes basic prototypes, definitions, initialization.
v3:
Take Joonas' comments:
- Change file name i915_gvt.* to intel_gvt.*
- Move GVT kernel parameter into intel_gvt.c
- Remove redundant debug macros
- Change error handling style
- Add introductions for some stub functions
- Introduce drm/i915_gvt.h.
Take Kevin's comments:
- Move GVT-g host/guest check into intel_vgt_balloon in i915_gem_gtt.c
v2:
- Introduce i915_gvt.c.
It's necessary to introduce the stubs between i915 driver and GVT-g host,
as GVT-g components is configurable in kernel config. When disabled, the
stubs here do nothing.
Take Joonas' comments:
- Replace boolean return value with int.
- Replace customized info/warn/debug macros with DRM macros.
- Document all non-static functions like i915.
- Remove empty and unused functions.
- Replace magic number with marcos.
- Set GVT-g in kernel config to "n" by default.
Signed-off-by: Zhi Wang <zhi.a.wang at intel.com>
---
drivers/gpu/drm/i915/Kconfig | 15 +++
drivers/gpu/drm/i915/Makefile | 2 +
drivers/gpu/drm/i915/gvt/Makefile | 5 +
drivers/gpu/drm/i915/gvt/debug.h | 36 ++++++
drivers/gpu/drm/i915/gvt/gvt.c | 231 +++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/gvt.h | 82 +++++++++++++
drivers/gpu/drm/i915/gvt/hypercall.h | 38 ++++++
drivers/gpu/drm/i915/gvt/mpt.h | 51 ++++++++
drivers/gpu/drm/i915/i915_dma.c | 15 +++
drivers/gpu/drm/i915/i915_drv.h | 12 ++
drivers/gpu/drm/i915/i915_gem_gtt.c | 11 +-
drivers/gpu/drm/i915/i915_vgpu.c | 10 +-
drivers/gpu/drm/i915/i915_vgpu.h | 2 +-
drivers/gpu/drm/i915/intel_gvt.c | 120 ++++++++++++++++++
drivers/gpu/drm/i915/intel_gvt.h | 54 ++++++++
include/drm/i915_gvt.h | 32 +++++
16 files changed, 706 insertions(+), 10 deletions(-)
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/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/intel_gvt.c
create mode 100644 drivers/gpu/drm/i915/intel_gvt.h
create mode 100644 include/drm/i915_gvt.h
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 20a5d04..26fdc33 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -56,3 +56,18 @@ config DRM_I915_USERPTR
selected to enabled full userptr support.
If in doubt, say "Y".
+
+config DRM_I915_GVT
+ tristate "Intel GVT-g host driver"
+ depends on DRM_I915
+ default n
+ 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..9927465 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_DRM_I915_GVT) += intel_gvt.o 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..09f59c3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -0,0 +1,5 @@
+GVT_SOURCE := gvt.o
+
+ccflags-y += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
+i915_gvt-y := $(GVT_SOURCE)
+obj-$(CONFIG_DRM_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..5b067d2
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/debug.h
@@ -0,0 +1,36 @@
+/*
+ * 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 gvt_info(fmt, args...) \
+ DRM_INFO("gvt: "fmt, ##args)
+
+#define gvt_err(fmt, args...) \
+ DRM_ERROR("gvt: "fmt, ##args)
+
+#define gvt_dbg_core(fmt, args...) \
+ DRM_DEBUG_DRIVER("gvt: core: "fmt, ##args)
+
+#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..bf16e85
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -0,0 +1,231 @@
+/*
+ * 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 <linux/types.h>
+#include <xen/xen.h>
+#include <linux/kthread.h>
+
+#include "gvt.h"
+
+struct gvt_host gvt_host;
+
+static const char * const supported_hypervisors[] = {
+ [GVT_HYPERVISOR_TYPE_XEN] = "Xen",
+ [GVT_HYPERVISOR_TYPE_KVM] = "KVM",
+};
+
+static int gvt_init_host(void)
+{
+ if (WARN(gvt_host.initialized, "GVT host has been initialized!\n"))
+ return -EINVAL;
+
+ /* Xen DOM U */
+ if (xen_domain() && !xen_initial_domain())
+ return -ENODEV;
+
+ if (xen_initial_domain()) {
+ /* Xen Dom0 */
+ gvt_host.kdm = try_then_request_module(
+ symbol_get(xengt_kdm), "xengt");
+ gvt_host.hypervisor_type = GVT_HYPERVISOR_TYPE_XEN;
+ } else {
+ /* not in Xen. Try KVMGT */
+ gvt_host.kdm = try_then_request_module(
+ symbol_get(kvmgt_kdm), "kvm");
+ gvt_host.hypervisor_type = GVT_HYPERVISOR_TYPE_KVM;
+ }
+
+ if (!gvt_host.kdm) {
+ gvt_err("Fail to load any MPT modules.\n");
+ return -EINVAL;
+ }
+
+ if (!gvt_hypervisor_detect_host())
+ return -ENODEV;
+
+ gvt_info("Running with hypervisor %s in host mode\n",
+ supported_hypervisors[gvt_host.hypervisor_type]);
+
+ idr_init(&gvt_host.device_idr);
+ mutex_init(&gvt_host.device_idr_lock);
+
+ gvt_host.initialized = true;
+ return 0;
+}
+
+static int init_device_info(struct intel_gvt *pdev)
+{
+ struct gvt_device_info *info = &pdev->device_info;
+
+ if (IS_BROADWELL(pdev->dev_priv)) {
+ info->max_gtt_gm_sz = (1ULL << 32); /* 4GB */
+ /*
+ * 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); /* 8MB */
+ info->max_gtt_size = (1UL << 23); /* 8MB */
+ info->gtt_entry_size = 8;
+ info->gtt_entry_size_shift = 3;
+ info->gmadr_bytes_in_cmd = 8;
+ info->mmio_size = 2 * 1024 * 1024; /* 2MB */
+ info->max_support_vgpu = 8;
+ }
+
+ if (WARN_ON(info->max_support_vgpu > GVT_MAX_VGPU))
+ info->max_support_vgpu = GVT_MAX_VGPU;
+
+ return 0;
+}
+
+static void free_gvt_device(struct intel_gvt *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 intel_gvt *alloc_gvt_device(struct drm_i915_private *dev_priv)
+{
+ struct gvt_host *host = &gvt_host;
+ struct intel_gvt *pdev = NULL;
+ int ret;
+
+ pdev = vzalloc(sizeof(*pdev));
+ if (!pdev)
+ return ERR_PTR(-ENOMEM);
+
+ mutex_lock(&host->device_idr_lock);
+ ret = idr_alloc(&host->device_idr, pdev, 0, 0, GFP_KERNEL);
+ mutex_unlock(&host->device_idr_lock);
+
+ if (ret)
+ goto err;
+
+ pdev->id = ret;
+ mutex_init(&pdev->lock);
+ pdev->dev_priv = dev_priv;
+ idr_init(&pdev->vgpu_idr);
+
+ return pdev;
+err:
+ free_gvt_device(pdev);
+ return ERR_PTR(ret);
+}
+
+/**
+ * gvt_destroy_device - destroy a GVT device
+ * @gvt_device: gvt device
+ *
+ * This function is called at the driver unloading stage, to destroy a
+ * GVT device and free the related resources.
+ *
+ * Returns:
+ * None
+ */
+void gvt_destroy_device(void *gvt_device)
+{
+ struct intel_gvt *pdev = (struct intel_gvt *)gvt_device;
+
+ free_gvt_device(pdev);
+}
+
+/**
+ * gvt_create_device - create a GVT device
+ * @dev: drm device
+ *
+ * This function is called at the initialization stage, to create a
+ * GVT device and initialize necessary GVT components for it.
+ *
+ * Returns:
+ * pointer to the intel gvt device structure, NULL if failed.
+ */
+void *gvt_create_device(void *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ struct intel_gvt *pdev = NULL;
+ int ret;
+
+ if (!gvt_host.initialized) {
+ ret = gvt_init_host();
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
+ gvt_dbg_core("create new gvt device, i915 dev_priv: %p\n", dev_priv);
+
+ pdev = alloc_gvt_device(dev_priv);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto err_alloc_gvt_device;
+ }
+
+ gvt_dbg_core("init gvt device, id %d\n", pdev->id);
+
+ ret = init_device_info(pdev);
+ if (ret)
+ goto err_init_device_info;
+
+ gvt_dbg_core("gvt device creation done, id %d\n", pdev->id);
+
+ return pdev;
+
+err_init_device_info:
+ free_gvt_device(pdev);
+err_alloc_gvt_device:
+ return ERR_PTR(ret);
+}
+
+/**
+ * gvt_post_init_device - post init a GVT device
+ * @dev: drm device
+ *
+ * This function is called at the end of the initialization stage, to
+ * post-initialize a GVT device and initialize necessary GVT components
+ * rely on i915 components.
+ *
+ * Returns:
+ * zero on success, non-zero if failed.
+ */
+int gvt_post_init_device(void *gvt_device)
+{
+ struct intel_gvt *pdev = (struct intel_gvt *)gvt_device;
+
+ if (!gvt_host.initialized) {
+ gvt_err("GVT host hasn't been initialized\n");
+ return -ENODEV;
+ }
+
+ gvt_dbg_core("post init gvt device %d\n", pdev->id);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
new file mode 100644
index 0000000..5f5b25e
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -0,0 +1,82 @@
+/*
+ * 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 "hypercall.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;
+ u32 mmio_size;
+ u32 max_support_vgpu;
+};
+
+struct intel_vgpu {
+ struct intel_gvt *pdev;
+ int id;
+ int vm_id;
+ bool warn_untrack;
+};
+
+struct intel_gvt {
+ struct mutex lock;
+ int id;
+
+ struct drm_i915_private *dev_priv;
+ struct idr vgpu_idr;
+
+ struct gvt_device_info device_info;
+};
+
+#include "mpt.h"
+
+#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..3fefcc3
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -0,0 +1,38 @@
+/*
+ * 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_
+
+/*
+ * Specific GVT-g MPT modules function collections. Currently GVT-g supports
+ * both Xen and KVM by providing dedicated hypervisor-related MPT modules.
+ */
+struct gvt_kernel_dm {
+ int (*detect_host)(void);
+};
+
+extern struct gvt_kernel_dm xengt_kdm;
+extern struct gvt_kernel_dm kvmgt_kdm;
+
+#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..8edde2f
--- /dev/null
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -0,0 +1,51 @@
+/*
+ * 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_
+
+/**
+ * DOC: Hypervisor Service APIs for GVT-g Core Logic
+ *
+ * This is the glue layer between specific hypervisor MPT modules and GVT-g core
+ * logic. Each kind of hypervisor MPT module provides a collection of function
+ * callbacks via gvt_kernel_dm and will be attached to GVT host when driver
+ * loading. GVT-g core logic will call these APIs to request specific services
+ * from hypervisor.
+ */
+
+/**
+ * gvt_hypervisor_detect_host - check if GVT-g is running within hypervisor
+ * host/privilged domain
+ *
+ * Returns:
+ * Zero on success, -ENODEV if current kernel is running inside a VM
+ */
+static inline int gvt_hypervisor_detect_host(void)
+{
+ if (WARN_ON(!gvt_host.kdm))
+ return -ENODEV;
+ return gvt_host.kdm->detect_host();
+}
+
+#endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 1c6d227..c34a4a1 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -35,6 +35,7 @@
#include "intel_drv.h"
#include <drm/i915_drm.h>
#include "i915_drv.h"
+#include "intel_gvt.h"
#include "i915_vgpu.h"
#include "i915_trace.h"
#include <linux/pci.h>
@@ -1045,6 +1046,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
intel_uncore_init(dev);
+ ret = intel_gvt_init(dev);
+ if (ret)
+ goto out_gvt_cleanup;
+
ret = i915_gem_gtt_init(dev);
if (ret)
goto out_uncore_fini;
@@ -1135,6 +1140,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_power_well;
}
+ ret = intel_gvt_post_init(dev);
+ if (ret) {
+ DRM_ERROR("failed to post init pgt device\n");
+ goto out_power_well;
+ }
+
/*
* Notify a valid surface after modesetting,
* when running inside a VM.
@@ -1176,6 +1187,8 @@ out_gem_unload:
io_mapping_free(dev_priv->gtt.mappable);
out_gtt:
i915_global_gtt_cleanup(dev);
+out_gvt_cleanup:
+ intel_gvt_cleanup(dev);
out_uncore_fini:
intel_uncore_fini(dev);
i915_mmio_cleanup(dev);
@@ -1223,6 +1236,8 @@ int i915_driver_unload(struct drm_device *dev)
intel_modeset_cleanup(dev);
+ intel_gvt_cleanup(dev);
+
/*
* 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 9e76bfc..88f9041 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1709,6 +1709,10 @@ struct i915_workarounds {
u32 hw_whitelist_count[I915_NUM_RINGS];
};
+struct i915_gvt {
+ void *gvt_device;
+};
+
struct i915_virtual_gpu {
bool active;
};
@@ -1748,6 +1752,8 @@ struct drm_i915_private {
struct i915_virtual_gpu vgpu;
+ struct i915_gvt gvt;
+
struct intel_guc guc;
struct intel_csr csr;
@@ -2785,6 +2791,12 @@ void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
enum forcewake_domains domains);
void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
+
+static inline bool intel_gvt_active(struct drm_device *dev)
+{
+ return to_i915(dev)->gvt.gvt_device ? true : false;
+}
+
static inline bool intel_vgpu_active(struct drm_device *dev)
{
return to_i915(dev)->vgpu.active;
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 9127f8f..d03fe61 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2734,11 +2734,9 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
i915_address_space_init(ggtt_vm, dev_priv);
ggtt_vm->total += PAGE_SIZE;
- if (intel_vgpu_active(dev)) {
- ret = intel_vgt_balloon(dev);
- if (ret)
- return ret;
- }
+ ret = intel_vgt_balloon(dev);
+ if (ret)
+ return ret;
if (!HAS_LLC(dev))
ggtt_vm->mm.color_adjust = i915_gtt_color_adjust;
@@ -2833,8 +2831,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev)
i915_gem_cleanup_stolen(dev);
if (drm_mm_initialized(&vm->mm)) {
- if (intel_vgpu_active(dev))
- intel_vgt_deballoon();
+ intel_vgt_deballoon(dev);
drm_mm_takedown(&vm->mm);
list_del(&vm->global_link);
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index dea7429..836defe 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -102,10 +102,13 @@ static struct _balloon_info_ bl_info;
* This function is called to deallocate the ballooned-out graphic memory, when
* driver is unloaded or when ballooning fails.
*/
-void intel_vgt_deballoon(void)
+void intel_vgt_deballoon(struct drm_device *dev)
{
int i;
+ if (!intel_vgpu_active(dev) && !intel_gvt_active(dev))
+ return;
+
DRM_DEBUG("VGT deballoon.\n");
for (i = 0; i < 4; i++) {
@@ -188,6 +191,9 @@ int intel_vgt_balloon(struct drm_device *dev)
unsigned long unmappable_base, unmappable_size, unmappable_end;
int ret;
+ if (!intel_vgpu_active(dev) && !intel_gvt_active(dev))
+ return 0;
+
mappable_base = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.base));
mappable_size = I915_READ(vgtif_reg(avail_rs.mappable_gmadr.size));
unmappable_base = I915_READ(vgtif_reg(avail_rs.nonmappable_gmadr.base));
@@ -259,6 +265,6 @@ int intel_vgt_balloon(struct drm_device *dev)
err:
DRM_ERROR("VGT balloon fail\n");
- intel_vgt_deballoon();
+ intel_vgt_deballoon(dev);
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h
index a3b06f3..484acc2 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.h
+++ b/drivers/gpu/drm/i915/i915_vgpu.h
@@ -28,6 +28,6 @@
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 intel_vgt_deballoon(struct drm_device *dev);
#endif /* _I915_VGPU_H_ */
diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c
new file mode 100644
index 0000000..a89b0ad
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_gvt.c
@@ -0,0 +1,120 @@
+/*
+ * 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 "i915_drv.h"
+#include "intel_gvt.h"
+
+/**
+ * DOC: Intel GVT-g host support
+ *
+ * Intel GVT-g is a graphics virtualization technology which shares the
+ * GPU among multiple virtual machines on a time-sharing basis. Each
+ * virtual machine is presented a virtual GPU (vGPU), which has equivalent
+ * features as the underlying physical GPU (pGPU), so i915 driver can run
+ * seamlessly in a virtual machine. This file provides the englightments
+ * of GVT and the necessary components used by GVT in i915 driver.
+ */
+
+struct gvt_kernel_params gvt = {
+ .enable = false,
+};
+
+/* i915.gvt_enable */
+module_param_named(gvt_enable, gvt.enable, bool, 0600);
+MODULE_PARM_DESC(gvt_enable, "Enable Intel GVT-g host support");
+
+static bool is_supported_device(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ if (IS_BROADWELL(dev_priv))
+ return true;
+
+ return false;
+}
+/**
+ * intel_gvt_init - initialize GVT components at the beginning of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the beginning of the initialization stage,
+ * to initialize the GVT components that have to be initialized
+ * before HW gets touched by other i915 components.
+ */
+int intel_gvt_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ if (!gvt.enable) {
+ DRM_DEBUG_DRIVER("GVT-g is disabled by kernel params\n");
+ return 0;
+ }
+
+ if (!is_supported_device(dev)) {
+ DRM_DEBUG_DRIVER("Unsupported device. GVT-g is disabled\n");
+ return 0;
+ }
+
+ dev_priv->gvt.gvt_device = gvt_create_device(dev);
+ if (intel_gvt_active(dev))
+ DRM_DEBUG_DRIVER("GVT-g is running in host mode\n");
+
+ return 0;
+}
+
+/**
+ * intel_gvt_post_init - initialize GVT components at the end of i915
+ * driver loading.
+ * @dev: drm device *
+ *
+ * This function is called at the end of the initialization stage,
+ * to initialize the GVT components that have to be initialized after
+ * other i915 components are ready.
+ */
+int intel_gvt_post_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ if (!intel_gvt_active(dev))
+ return 0;
+
+ return gvt_post_init_device(dev_priv->gvt.gvt_device);
+}
+
+/**
+ * intel_gvt_cleanup - cleanup GVT components when i915 driver is unloading
+ * @dev: drm device *
+ *
+ * This function is called at the i915 driver unloading stage, to shutdown
+ * GVT components and release the related resources.
+ */
+void intel_gvt_cleanup(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = to_i915(dev);
+
+ if (!intel_gvt_active(dev))
+ return;
+
+ gvt_destroy_device(dev_priv->gvt.gvt_device);
+ dev_priv->gvt.gvt_device = NULL;
+}
diff --git a/drivers/gpu/drm/i915/intel_gvt.h b/drivers/gpu/drm/i915/intel_gvt.h
new file mode 100644
index 0000000..9be5a4f
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_gvt.h
@@ -0,0 +1,54 @@
+/*
+ * 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 _INTEL_GVT_H_
+#define _INTEL_GVT_H_
+
+#ifdef CONFIG_DRM_I915_GVT
+
+#include <drm/i915_gvt.h>
+
+struct gvt_kernel_params {
+ bool enable;
+};
+
+extern struct gvt_kernel_params gvt;
+
+extern int intel_gvt_init(struct drm_device *dev);
+extern int intel_gvt_post_init(struct drm_device *dev);
+extern void intel_gvt_cleanup(struct drm_device *dev);
+#else
+static inline int intel_gvt_init(struct drm_device *dev)
+{
+ return 0;
+}
+static inline int intel_gvt_post_init(struct drm_device *dev)
+{
+ return 0;
+}
+static inline void intel_gvt_cleanup(struct drm_device *dev)
+{
+}
+#endif
+
+#endif /* _INTEL_GVT_H_ */
diff --git a/include/drm/i915_gvt.h b/include/drm/i915_gvt.h
new file mode 100644
index 0000000..28c8d7a
--- /dev/null
+++ b/include/drm/i915_gvt.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
+ * 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, sub license, 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 _I915_GVT_H
+#define _I915_GVT_H
+
+extern void *gvt_create_device(void *dev);
+extern int gvt_post_init_device(void *gvt_device);
+extern void gvt_destroy_device(void *gvt_device);
+
+#endif /* _I915_GVT_H */
--
1.9.1
More information about the Intel-gfx
mailing list