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@xxxxxxxxx> --- 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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx