[Intel-gfx] [PATCH] drm/i915/gvt/kvmgt: Fix the build failure in kvmgt.
Previously, commit 531810caa9f4 ("KVM: x86/mmu: Use an rwlock for the x86 MMU") replaced KVM's mmu_lock with type rwlock_t. This will cause a build failure in kvmgt, which uses the same lock when trying to add/ remove some GFNs to/from the page tracker. Fix it with write_lock/unlocks in kvmgt. Reported-by: Stephen Rothwell Signed-off-by: Yu Zhang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 60f1a386dd06..b4348256ae95 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1703,7 +1703,7 @@ static int kvmgt_page_track_add(unsigned long handle, u64 gfn) return -EINVAL; } - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); if (kvmgt_gfn_is_write_protected(info, gfn)) goto out; @@ -1712,7 +1712,7 @@ static int kvmgt_page_track_add(unsigned long handle, u64 gfn) kvmgt_protect_table_add(info, gfn); out: - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); srcu_read_unlock(&kvm->srcu, idx); return 0; } @@ -1737,7 +1737,7 @@ static int kvmgt_page_track_remove(unsigned long handle, u64 gfn) return -EINVAL; } - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); if (!kvmgt_gfn_is_write_protected(info, gfn)) goto out; @@ -1746,7 +1746,7 @@ static int kvmgt_page_track_remove(unsigned long handle, u64 gfn) kvmgt_protect_table_del(info, gfn); out: - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); srcu_read_unlock(&kvm->srcu, idx); return 0; } @@ -1772,7 +1772,7 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm, struct kvmgt_guest_info *info = container_of(node, struct kvmgt_guest_info, track_node); - spin_lock(&kvm->mmu_lock); + write_lock(&kvm->mmu_lock); for (i = 0; i < slot->npages; i++) { gfn = slot->base_gfn + i; if (kvmgt_gfn_is_write_protected(info, gfn)) { @@ -1781,7 +1781,7 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm, kvmgt_protect_table_del(info, gfn); } } - spin_unlock(&kvm->mmu_lock); + write_unlock(&kvm->mmu_lock); } static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm) -- 2.17.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 6/8] drm/i915: Disable power management for i915 driver in VM
In XenGT, GPU power management is controlled by host i915 driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 50cf96b..3a80557 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5304,6 +5304,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 7/8] drm/i915: Create vGPU specific write MMIO to reduce traps
In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers running in the VM with Intel GVT-g enhancement. v2: take Chris' comments: - register the mmio hooks in intel_uncore_init() v3: take Daniel's comments: - use macros to assign mmio write functions for vGPU Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index cae27bb..b76c21d 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -727,6 +727,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ + REG_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -821,6 +829,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -828,6 +840,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -939,6 +952,9 @@ void intel_uncore_init(struct drm_device *dev) break; } + if (intel_vgpu_active(dev)) + ASSIGN_WRITE_MMIO_VFUNCS(vgpu); + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 6/8] drm/i915: Disable power management for i915 driver in VM
With Intel GVT-g, GPU power management is controlled by host driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. v2: take Chris' comments: - do not special case this to gen6+ Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3bc5d93..3722bd4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5314,6 +5314,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 5/8] drm/i915: Add the display switch logic for vGPU in i915 driver
Display switch logic is added to notify the host side that current vGPU have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in the host side. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. v2: - move the notification code outside the 'else' in load sequence - remove the notification code in intel_crtc_set_config() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_vgpu.h | 7 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9a73533..06daa5c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include #include @@ -1780,6 +1781,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->ums.mm_suspended = 1; } + if (intel_vgpu_active(dev)) { + /* +* Notify a valid surface after modesetting, +* when running inside a VM. +*/ + struct drm_i915_private *dev_priv = to_i915(dev); + + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + } + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index f538b18..9d35fb8 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -80,6 +80,13 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *) NULL)->x) +/* vGPU display status to be used by the host side */ +enum vgt_display_status { + VGT_DRV_DISPLAY_NOT_READY = 0, + VGT_DRV_DISPLAY_READY, /* ready for display switch */ +}; + + extern void i915_check_vgpu(struct drm_device *dev); extern int intel_vgt_balloon(struct drm_device *dev); extern void intel_vgt_deballoon(void); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled
The current Intel GVT-g only supports alias ppgtt. And the emulation is done in the host by first trapping PP_DIR_BASE mmio accesses. Updating PP_DIR_BASE by using instructions such as MI_LOAD_REGISTER_IMM are hard to detect and are not supported in current code. Therefore this patch also added a new callback routine - vgpu_mm_switch() to set the PP_DIR_BASE by mmio writes. v2: take Chris' comments: - move the code into sanitize_enable_ppgtt() Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 2dfac13..55307eb 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -44,6 +44,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) if (IS_GEN8(dev)) has_full_ppgtt = false; /* XXX why? */ + if (intel_vgpu_active(dev)) + has_full_ppgtt = false; /* emulation is too hard */ + if (enable_ppgtt == 0 || !has_aliasing_ppgtt) return 0; @@ -733,6 +736,16 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } +static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, +struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + return 0; +} + static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *ring) { @@ -1059,6 +1072,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) } else BUG(); + if (intel_vgpu_active(dev)) + ppgtt->switch_mm = vgpu_mm_switch; + ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through. This page contains the shared information between i915 driver and the host emulator. For now, this structure utilizes an area of 4K bypes on HSW GPU's unused MMIO space to support existing production. Future hardware will have the reserved window architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. Thereafter a flag, vgpu.active is set, and intel_vgpu_active() is used by checking this flag to conclude if GPU is virtualized with Intel GVT-g. By now, intel_vgpu_active() will return true, only when the driver is running as a guest in the Intel GVT-g enhanced environment on HSW platform. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() v3: take Daniel's comments: - move the i915/vgt interfaces into a new i915_vgpu.c - update makefile - add kerneldoc to functions which are non-static - add a DOC: section describing some of the high-level design - update drm docbook other changes: - rename i915_vgt_if.h to i915_vgpu.h Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- Documentation/DocBook/drm.tmpl | 5 +++ drivers/gpu/drm/i915/Makefile | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/i915_vgpu.c| 85 + drivers/gpu/drm/i915/i915_vgpu.h| 85 + drivers/gpu/drm/i915/intel_uncore.c | 3 ++ 6 files changed, 192 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 64d9c1e..e4db4cf 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3832,6 +3832,11 @@ int num_ioctls; !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support +!Idrivers/gpu/drm/i915/i915_vgpu.c + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 891e584..d9aa5ca 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -79,6 +79,9 @@ i915-y += dvo_ch7017.o \ intel_sdvo.o \ intel_tv.o +# virtual gpu code +i915-y += i915_vgpu.o + # legacy horrors i915-y += i915_dma.o \ i915_ums.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54691bc..e1e221e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1470,6 +1470,10 @@ struct i915_workarounds { u32 count; }; +struct i915_virtual_gpu { + bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1482,6 +1486,8 @@ struct drm_i915_private { struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2311,6 +2317,11 @@ extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ + return to_i915(dev)->vgpu.active; +} + 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.c b/drivers/gpu/drm/i915/i915_vgpu.c new file mode 100644 index 000..3f6b797 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -0,0 +1,85 @@ +/* + * Copyright(c) 2011-2014 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 copi
[Intel-gfx] [PATCH v3 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM
Framebuffer compression is disabled when driver detects it's running in a Intel GVT-g enlightened VM, because FBC is not emulated and there is no stolen memory for a vGPU. v2: take Chris' comments: - move the code into intel_update_fbc() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7a69eba..3bc5d93 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -544,6 +544,10 @@ void intel_update_fbc(struct drm_device *dev) return; } + /* disable framebuffer compression in vGPU */ + if (intel_vgpu_active(dev)) + i915.enable_fbc = 0; + /* * If FBC is already on, we just have to verify that we can * keep it that way... -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 0/8] Add enlightenments for vGPU
Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, will be sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures or queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vGPU in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vGPU in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vGPU specific write MMIO to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/i915_dma.c | 11 ++ drivers/gpu/drm/i915/i915_drv.h | 11 ++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 33 - drivers/gpu/drm/i915/i915_vgpu.c| 234 drivers/gpu/drm/i915/i915_vgpu.h| 94 +++ drivers/gpu/drm/i915/intel_pm.c | 8 ++ drivers/gpu/drm/i915/intel_uncore.c | 19 +++ 10 files changed, 420 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 3/8] drm/i915: Partition the fence registers for vGPU in i915 driver
With Intel GVT-g, the fence registers are partitioned by multiple vGPU instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's running in a VM. And the allocated fence number is provided in PV INFO page structure. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1de94cc..0c8b32e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -29,6 +29,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" #include @@ -5014,6 +5015,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic
With Intel GVT-g, the global graphic memory space is partitioned by multiple vGPU instances in different VMs. The ballooning code is called in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vGPUs as reserved. v2: take Chris and Daniel's comments: - no guard page between different VMs - use drm_mm_reserve_node() to do the reservation for ballooning, instead of the previous drm_mm_insert_node_in_range_generic() v3: take Daniel's comments: - move ballooning functions into i915_vgpu.c - add kerneldoc to ballooning functions Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++- drivers/gpu/drm/i915/i915_vgpu.c| 149 drivers/gpu/drm/i915/i915_vgpu.h| 2 + 3 files changed, 165 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index de12017..2dfac13 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -27,6 +27,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" @@ -1683,6 +1684,16 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, /* Subtract the guard page ... */ drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); + + dev_priv->gtt.base.start = start; + dev_priv->gtt.base.total = end - start; + + if (intel_vgpu_active(dev)) { + ret = intel_vgt_balloon(dev); + if (ret) + return ret; + } + if (!HAS_LLC(dev)) dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; @@ -1702,9 +1713,6 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, vma->bound |= GLOBAL_BIND; } - dev_priv->gtt.base.start = start; - dev_priv->gtt.base.total = end - start; - /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", @@ -1756,6 +1764,9 @@ void i915_global_gtt_cleanup(struct drm_device *dev) } if (drm_mm_initialized(&vm->mm)) { + if (intel_vgpu_active(dev)) + intel_vgt_deballoon(); + 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 3f6b797..ff5fba3 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -83,3 +83,152 @@ void i915_check_vgpu(struct drm_device *dev) dev_priv->vgpu.active = true; DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); } + +struct _balloon_info_ { + /* +* There are up to 2 regions per low/high graphic memory that +* might be ballooned. Here, index 0/1 is for low +* graphic memory, 2/3 for high graphic memory. +*/ + struct drm_mm_node space[4]; +} bl_info; + +/** + * intel_vgt_deballoon - deballoon reserved graphics address trunks + * + * This function is called to deallocate the ballooned-out graphic memory, when + * driver is unloaded or when ballooning fails. + */ +void intel_vgt_deballoon(void) +{ + int i; + + DRM_INFO("VGT deballoon.\n"); + + for (i = 0; i < 4; i++) { + if (bl_info.space[i].allocated) + drm_mm_remove_node(&bl_info.space[i]); + } + + memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, +struct drm_mm_node *node, +unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + + if (start == end) + return -EINVAL; + + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KB.\n", +start, end, size / 1024); + + node->start = start; + node->size = size; + + return drm_mm_reserve_node(mm, node); +} + +/** + * intel_vgt_balloon - balloon out reserved graphics address trunks + * @dev: drm device + * + * This function is called at the initialization stage, to balloon out the + * graphic address space allocated to other VMs, by marking these spaces as + * reserved. + * + * The ballooning related knowledges(starting address and size of the low/high + * graphic memory) are depicted in the vgt_if structure in a reserved MMIO + * range. + * + * Returns: + * zero on success, non-zero if configuration invalid or ballooning failed + */ +int intel_vgt_balloon(struct dr
Re: [Intel-gfx] [PATCH v3 0/8] Add enlightenments for vGPU
On 11/14/2014 6:17 PM, Daniel Vetter wrote: On Thu, Nov 13, 2014 at 08:02:41PM +0800, Yu Zhang wrote: Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, will be sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures or queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. I think this looks good now overall, so please find someone from the i915 kernel team to review the details. You might need to poke managers to make that happen ;-) -Daniel Thanks a lot, Daniel. This is great. :-) Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic
On 11/14/2014 6:16 PM, Daniel Vetter wrote: On Thu, Nov 13, 2014 at 08:02:43PM +0800, Yu Zhang wrote: + if (low_gm_base < ggtt_vm->start + || low_gm_end > dev_priv->gtt.mappable_end + || high_gm_base < dev_priv->gtt.mappable_end + || high_gm_end > ggtt_vm_end) { Nit: Logical operators like || or && should be at the end of the previous line, not at the beginning of the new line. checkpatch would have noticed this one. -Daniel Got it. Thank you. :-) Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
Thank you very much for your thorough review, Tvrtko. :) On 12/12/2014 1:33 AM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through. This page contains the shared information between i915 driver and the host emulator. For now, this structure utilizes an area of 4K bypes on HSW GPU's unused MMIO space to support bytes Got it. Thanks. existing production. Future hardware will have the reserved window It is slightly unclear to me what "existing production" means? Our current gpu virtualization implementation for HSW. It's compared with future implematations for BDW etc. architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. Thereafter a flag, vgpu.active is set, and intel_vgpu_active() is used by checking this flag to conclude if GPU is virtualized with Intel GVT-g. By now, intel_vgpu_active() will return true, only when the driver is running as a guest in the Intel GVT-g enhanced environment on HSW platform. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() v3: take Daniel's comments: - move the i915/vgt interfaces into a new i915_vgpu.c - update makefile - add kerneldoc to functions which are non-static - add a DOC: section describing some of the high-level design - update drm docbook other changes: - rename i915_vgt_if.h to i915_vgpu.h Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- Documentation/DocBook/drm.tmpl | 5 +++ drivers/gpu/drm/i915/Makefile | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/i915_vgpu.c| 85 + drivers/gpu/drm/i915/i915_vgpu.h| 85 + drivers/gpu/drm/i915/intel_uncore.c | 3 ++ 6 files changed, 192 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 64d9c1e..e4db4cf 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3832,6 +3832,11 @@ int num_ioctls; !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support +!Idrivers/gpu/drm/i915/i915_vgpu.c + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 891e584..d9aa5ca 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -79,6 +79,9 @@ i915-y += dvo_ch7017.o \ intel_sdvo.o \ intel_tv.o +# virtual gpu code +i915-y += i915_vgpu.o + # legacy horrors i915-y += i915_dma.o \ i915_ums.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54691bc..e1e221e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1470,6 +1470,10 @@ struct i915_workarounds { u32 count; }; +struct i915_virtual_gpu { +bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1482,6 +1486,8 @@ struct drm_i915_private { struct intel_uncore uncore; +struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2311,6 +2317,11 @@ extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ +return to_i915(dev)->vgpu.active; +} + 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.c b/drivers/gpu/drm/i915/i915_vgpu.c new file mode 100644 index 000..3f6b797 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -0,0 +1,85 @@ +/* + * Copyright(c) 2011-2014 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,
Re: [Intel-gfx] [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic
On 12/12/2014 9:00 PM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: With Intel GVT-g, the global graphic memory space is partitioned by multiple vGPU instances in different VMs. The ballooning code is called in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vGPUs as reserved. v2: take Chris and Daniel's comments: - no guard page between different VMs - use drm_mm_reserve_node() to do the reservation for ballooning, instead of the previous drm_mm_insert_node_in_range_generic() v3: take Daniel's comments: - move ballooning functions into i915_vgpu.c - add kerneldoc to ballooning functions Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++- drivers/gpu/drm/i915/i915_vgpu.c| 149 drivers/gpu/drm/i915/i915_vgpu.h| 2 + 3 files changed, 165 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index de12017..2dfac13 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -27,6 +27,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" @@ -1683,6 +1684,16 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, /* Subtract the guard page ... */ drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); + +dev_priv->gtt.base.start = start; +dev_priv->gtt.base.total = end - start; + +if (intel_vgpu_active(dev)) { +ret = intel_vgt_balloon(dev); +if (ret) +return ret; +} + Out of curiosity, what will be the mechanism to prevent a vGPU instance from ignoring the ballooning data? Must be something in the hypervisor blocking pass-through access to such domains? Well, although we have range check logic in the host side(which checks the legality of a GM address), the correctness of a GM from vGPU side are supposed to be guaranteed by the drm mm allocator - all those ballooned out spaces are marked as reserved. And probably GPU reset should also be disallowed for vGPU instances? if (!HAS_LLC(dev)) dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; @@ -1702,9 +1713,6 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, vma->bound |= GLOBAL_BIND; } -dev_priv->gtt.base.start = start; -dev_priv->gtt.base.total = end - start; - /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", @@ -1756,6 +1764,9 @@ void i915_global_gtt_cleanup(struct drm_device *dev) } if (drm_mm_initialized(&vm->mm)) { +if (intel_vgpu_active(dev)) +intel_vgt_deballoon(); + 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 3f6b797..ff5fba3 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -83,3 +83,152 @@ void i915_check_vgpu(struct drm_device *dev) dev_priv->vgpu.active = true; DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); } + +struct _balloon_info_ { +/* + * There are up to 2 regions per low/high graphic memory that + * might be ballooned. Here, index 0/1 is for low + * graphic memory, 2/3 for high graphic memory. + */ +struct drm_mm_node space[4]; +} bl_info; This should be static I think. Yes, you are right. +/** + * intel_vgt_deballoon - deballoon reserved graphics address trunks + * + * This function is called to deallocate the ballooned-out graphic memory, when + * driver is unloaded or when ballooning fails. + */ +void intel_vgt_deballoon(void) +{ +int i; + +DRM_INFO("VGT deballoon.\n"); Would debug be more appropriate? I don't see much value of saying this on driver unload - it's not that it is optional at this point. OK. :) Also for all logging, is intended human readable name VGT or vGT? If the latter it would be nicer to log it in that form. Well, I prefer VGT. :) + +for (i = 0; i < 4; i++) { +if (bl_info.space[i].allocated) +drm_mm_remove_node(&bl_info.space[i]); +} + +memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, + struct drm_mm_node *node, + unsigned long start, unsigned long end) +{ +unsigned long size = end - start; + +if (start == end) +return -EINVAL; + +DRM_INFO("balloon space: r
Re: [Intel-gfx] [PATCH v3 3/8] drm/i915: Partition the fence registers for vGPU in i915 driver
On 12/12/2014 9:07 PM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: With Intel GVT-g, the fence registers are partitioned by multiple vGPU instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's running in a VM. And the allocated fence number is provided in PV INFO page structure. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1de94cc..0c8b32e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -29,6 +29,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" #include @@ -5014,6 +5015,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; +if (intel_vgpu_active(dev)) +dev_priv->num_fence_regs = +I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); You don't need a start offset and number of allocated fences per domain? The PV INFO structure is shared between each vgpu and host, so I guess this is per domain? Not sure if I get your exact meaning. :) Regards, B.R. Yu Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
On 12/16/2014 9:19 PM, Tvrtko Ursulin wrote: On 12/16/2014 12:51 PM, Yu, Zhang wrote: Thank you very much for your thorough review, Tvrtko. :) On 12/12/2014 1:33 AM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through. This page contains the shared information between i915 driver and the host emulator. For now, this structure utilizes an area of 4K bypes on HSW GPU's unused MMIO space to support bytes Got it. Thanks. existing production. Future hardware will have the reserved window It is slightly unclear to me what "existing production" means? Our current gpu virtualization implementation for HSW. It's compared with future implematations for BDW etc. So maybe instead of "existing production" say "currently supported hardware" or similar? How about we remove "to support existing production" in this sentence? The "currently supported hardware" seems a bit redundant. :) architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. Thereafter a flag, vgpu.active is set, and intel_vgpu_active() is used by checking this flag to conclude if GPU is virtualized with Intel GVT-g. By now, intel_vgpu_active() will return true, only when the driver is running as a guest in the Intel GVT-g enhanced environment on HSW platform. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() v3: take Daniel's comments: - move the i915/vgt interfaces into a new i915_vgpu.c - update makefile - add kerneldoc to functions which are non-static - add a DOC: section describing some of the high-level design - update drm docbook other changes: - rename i915_vgt_if.h to i915_vgpu.h Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- Documentation/DocBook/drm.tmpl | 5 +++ drivers/gpu/drm/i915/Makefile | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 11 + drivers/gpu/drm/i915/i915_vgpu.c| 85 + drivers/gpu/drm/i915/i915_vgpu.h| 85 + drivers/gpu/drm/i915/intel_uncore.c | 3 ++ 6 files changed, 192 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 64d9c1e..e4db4cf 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3832,6 +3832,11 @@ int num_ioctls; !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support +!Idrivers/gpu/drm/i915/i915_vgpu.c + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 891e584..d9aa5ca 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -79,6 +79,9 @@ i915-y += dvo_ch7017.o \ intel_sdvo.o \ intel_tv.o +# virtual gpu code +i915-y += i915_vgpu.o + # legacy horrors i915-y += i915_dma.o \ i915_ums.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54691bc..e1e221e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1470,6 +1470,10 @@ struct i915_workarounds { u32 count; }; +struct i915_virtual_gpu { +bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1482,6 +1486,8 @@ struct drm_i915_private { struct intel_uncore uncore; +struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2311,6 +2317,11 @@ extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ +return to_i915(dev)->vgpu.active; +} + 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.c b/drivers/gpu/drm/i915/i915_vgpu.c new file mode 100644 index 000..3f6b797 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -0,0 +1,85 @@ +/* + * Cop
Re: [Intel-gfx] [PATCH v3 2/8] drm/i915: Adds graphic address space ballooning logic
On 12/16/2014 11:15 PM, Tvrtko Ursulin wrote: Hi, On 12/16/2014 02:39 PM, Gerd Hoffmann wrote: Out of curiosity, what will be the mechanism to prevent a vGPU instance from ignoring the ballooning data? Must be something in the hypervisor blocking pass-through access to such domains? Well, although we have range check logic in the host side(which checks the legality of a GM address), the correctness of a GM from vGPU side Oh, I thought that part is direct for performance reasons (avoiding translation). It's not then? are supposed to be guaranteed by the drm mm allocator - all those ballooned out spaces are marked as reserved. I was thinking about a malicious i915 driver instance, or simply a bug in DRM or i915 which breaks the blocked ranges assumption. Cover letter had a link to a longish paper explaining how all this works in detail. Short summary: * Direct access is denied by simply mapping only the guests piece of memory into the guest address space. * Indirect access (via exec buffer commands) is denied by verifying the exec buffer commands (map read-only + verify + hand over to the hardware when checks pass). * The ballooning basically makes the guest aware what the offset for its piece of memory has, so the references in the execbuffer don't need to be translated, only verified. Thanks, I did read the blog and powerpoint from the link, but didn't find what you wrote below even after the second read. Probably missed due to lack of domain knowledge. Anyway, I just wanted to hear that the DRM allocation range is not the only thing preventing access outside the allocated range. :) Thanks, Tvrtko & Gerd. DRM allocation range is not the only guarantee. We also have range check functions in our host code. MMIO accesses and ring buffer commands will be checked/scanned in the host side to see if there's any illegal GM address. Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM
On 12/12/2014 9:13 PM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: Framebuffer compression is disabled when driver detects it's running in a Intel GVT-g enlightened VM, because FBC is not emulated and there is no stolen memory for a vGPU. v2: take Chris' comments: - move the code into intel_update_fbc() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7a69eba..3bc5d93 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -544,6 +544,10 @@ void intel_update_fbc(struct drm_device *dev) return; } +/* disable framebuffer compression in vGPU */ +if (intel_vgpu_active(dev)) +i915.enable_fbc = 0; + /* * If FBC is already on, we just have to verify that we can * keep it that way... Looks like you'll need to rebase this one, I see no intel_update_fbc in my tree. :( OK. I'll rebase this in next version. :) Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 5/8] drm/i915: Add the display switch logic for vGPU in i915 driver
On 12/15/2014 4:16 PM, Daniel Vetter wrote: On Thu, Nov 13, 2014 at 08:02:46PM +0800, Yu Zhang wrote: Display switch logic is added to notify the host side that current vGPU have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in the host side. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. v2: - move the notification code outside the 'else' in load sequence - remove the notification code in intel_crtc_set_config() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_vgpu.h | 7 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9a73533..06daa5c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include #include @@ -1780,6 +1781,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->ums.mm_suspended = 1; } + if (intel_vgpu_active(dev)) { + /* +* Notify a valid surface after modesetting, +* when running inside a VM. +*/ + struct drm_i915_private *dev_priv = to_i915(dev); + + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + } + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index f538b18..9d35fb8 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -80,6 +80,13 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *) NULL)->x) +/* vGPU display status to be used by the host side */ +enum vgt_display_status { + VGT_DRV_DISPLAY_NOT_READY = 0, + VGT_DRV_DISPLAY_READY, /* ready for display switch */ +}; Nitpick: Since this is a virtual register I prefer we use plain #defines with explicit codes for everything instead of enums. Makes it clearer which values are used and all that. -Daniel Got it. #define will be used. And I will rebase this patch. Thanks Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 6/8] drm/i915: Disable power management for i915 driver in VM
On 12/12/2014 9:27 PM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: With Intel GVT-g, GPU power management is controlled by host driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. v2: take Chris' comments: - do not special case this to gen6+ Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3bc5d93..3722bd4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5314,6 +5314,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; +/* Powersaving is controlled by the host when inside a VM */ +if (intel_vgpu_active(dev)) +return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); I was looking for potential call sites of this which come earlier than i915_check_vgpu. Didn't find any but found RPS (intel_pm_setup) - what's with that - should it be disabled as well? IIUC, the intel_pm_setup() only add the intel_gen6_powersave_work() to the delayed_resume_work queue. Real call of this routine will be delayed to intel_enable_gt_powersave(). So I guess no necessary to do anything in intel_pm_setup(). :) Otherwise, Reviewed-by: Tvrtko Ursulin B.R. Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 7/8] drm/i915: Create vGPU specific write MMIO to reduce traps
On 12/12/2014 9:31 PM, Tvrtko Ursulin wrote: On 11/13/2014 12:02 PM, Yu Zhang wrote: In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped necessary Thanks. and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers running in the VM with Intel GVT-g enhancement. v2: take Chris' comments: - register the mmio hooks in intel_uncore_init() v3: take Daniel's comments: - use macros to assign mmio write functions for vGPU Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index cae27bb..b76c21d 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -727,6 +727,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ +REG_WRITE_HEADER; \ +__raw_i915_write##x(dev_priv, reg, val); \ +REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -821,6 +829,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -828,6 +840,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -939,6 +952,9 @@ void intel_uncore_init(struct drm_device *dev) break; } +if (intel_vgpu_active(dev)) +ASSIGN_WRITE_MMIO_VFUNCS(vgpu); + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS Maybe I am missing something obvious, but why are read variants not needed? Wah. You got me. Guess I missed this during rebase. Thank you, Tvrtko. Regards, Tvrtko B.R. Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v3 3/8] drm/i915: Partition the fence registers for vGPU in i915 driver
On 12/17/2014 7:06 PM, Gerd Hoffmann wrote: Hi, It's not possible to allow guests direct access to the fence registers though. And if every fence register access traps into the hypervisor anyway the hypervisor can easily map the guest virtual fence to host physical fence, so there is no need to tell the guest which fences it owns, the number of fences is enough. That exactly is the part I don't understand - if it is not required to tell the guest which fences it owns, why it is required to say how many? There is a fixed assignment of fences to guests, so it's a fixed number. But as the hypervisor is involved in any fence access anyway there is no need for the guest to know which of the fences it owns, the hypervisor can remap that transparently for the guest, without performance penalty. Thanks Gerd. Exactly. Although fence registers are parititioned to vGPU, it is not necessary for a vGPU to know the physical mmio addresses of the allocated fence registers. For example, vGPU 1 with fence size 4 can access the fence registers from 0x10-10001f; at the same time, vGPU 2 with fence size 8 can access the fence registers from 0x10-0x10003f. Although this seems conflicting, it does not matter. Because these mmio addresses are all supposed to be trapped in the host side, which will keep a record of the real fence offset of different vGPUs(say 0 for vGPU 1 and 4 for vGPU 2), and then does the remapping. Therefore, the physical operations on the fence register will be performed by host code on different ones(say, 0x10-10001fh for vGPU 1 and 0x100020-0x10005f for vGPU 2). With this scheme it could be one guest wants more and can't get them even if no one else is using any. If not limited they could be dynamically allocated by the hypervisor, no? Should be possible as extension, but I think[1] for now the goal is to stay as close as possible to physical hardware, where you can't dynamically allocate fences in the first place. Yes. By now we have feature to configure the fence numbers for a vGPU. But we do not support the dynamical allocations. cheers, Gerd [1] Not being deeply involved into vgpu development, just reviewing the bits with some kvm background. Thanks Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 0/8] Add enlightenments for vGPU
This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, will be sent out in other patches. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory without hypervisor's intervention, e.g. filling textures or queuing commands. However with the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses without complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (with some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource, XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vGPU in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vGPU in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vGPU specific MMIO operations to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/i915/Makefile | 3 + drivers/gpu/drm/i915/i915_dma.c | 8 ++ drivers/gpu/drm/i915/i915_drv.h | 10 ++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 33 - drivers/gpu/drm/i915/i915_vgpu.c| 264 drivers/gpu/drm/i915/i915_vgpu.h| 91 + drivers/gpu/drm/i915/intel_fbc.c| 4 + drivers/gpu/drm/i915/intel_pm.c | 4 + drivers/gpu/drm/i915/intel_uncore.c | 34 + 11 files changed, 458 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through. This page contains the shared information between i915 driver and the host emulator. For now, this structure utilizes an area of 4K bytes on HSW GPU's unused MMIO space. Future hardware will have the reserved window architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. Thereafter a flag, vgpu.active is set, and intel_vgpu_active() is used by checking this flag to conclude if GPU is virtualized with Intel GVT-g. By now, intel_vgpu_active() will return true, only when the driver is running as a guest in the Intel GVT-g enhanced environment on HSW platform. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() v3: take Daniel's comments: - move the i915/vgt interfaces into a new i915_vgpu.c - update makefile - add kerneldoc to functions which are non-static - add a DOC: section describing some of the high-level design - update drm docbook other changes: - rename i915_vgt_if.h to i915_vgpu.h v4: take Tvrtko's comments: - fix a typo in commit message - add debug message when vgt version mismatches - rename low_gmadr/high_gmadr to mappable/non-mappable in PV INFO structure Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- Documentation/DocBook/drm.tmpl | 5 +++ drivers/gpu/drm/i915/Makefile | 3 ++ drivers/gpu/drm/i915/i915_drv.h | 10 + drivers/gpu/drm/i915/i915_vgpu.c| 86 + drivers/gpu/drm/i915/i915_vgpu.h| 85 drivers/gpu/drm/i915/intel_uncore.c | 3 ++ 6 files changed, 192 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgpu.c create mode 100644 drivers/gpu/drm/i915/i915_vgpu.h diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 03f1985..249f0c9 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3979,6 +3979,11 @@ int num_ioctls; !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts !Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts + +Intel GVT-g Guest Support(vGPU) +!Pdrivers/gpu/drm/i915/i915_vgpu.c Intel GVT-g guest support +!Idrivers/gpu/drm/i915/i915_vgpu.c + Display Hardware Handling diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index f019225..f025e7f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -83,6 +83,9 @@ i915-y += dvo_ch7017.o \ intel_sdvo.o \ intel_tv.o +# virtual gpu code +i915-y += i915_vgpu.o + # legacy horrors i915-y += i915_dma.o \ i915_ums.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c0b8644..9bc0c9e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1640,6 +1640,10 @@ struct i915_workarounds { u32 count; }; +struct i915_virtual_gpu { + bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1652,6 +1656,8 @@ struct drm_i915_private { struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2583,6 +2589,10 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv, void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv, enum forcewake_domains domains); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ + return to_i915(dev)->vgpu.active; +} void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c new file mode 100644 index 000..995a600 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -0,0 +1,86 @@ +/* + * Copyright(c) 2011-2015 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
[Intel-gfx] [PATCH v4 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled
The current Intel GVT-g only supports alias ppgtt. And the emulation is done in the host by first trapping PP_DIR_BASE mmio accesses. Updating PP_DIR_BASE by using instructions such as MI_LOAD_REGISTER_IMM are hard to detect and are not supported in current code. Therefore this patch also adds a new callback routine - vgpu_mm_switch() to set the PP_DIR_BASE by mmio writes. v2: take Chris' comments: - move the code into sanitize_enable_ppgtt() v4: take Tvrtko's comments: - fix the parenthesis alignment warning Signed-off-by: Yu Zhang Signed-off-by: Jike Song Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 057f905..e54b2a0 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -104,6 +104,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) has_aliasing_ppgtt = INTEL_INFO(dev)->gen >= 6; has_full_ppgtt = INTEL_INFO(dev)->gen >= 7; + if (intel_vgpu_active(dev)) + has_full_ppgtt = false; /* emulation is too hard */ + /* * We don't allow disabling PPGTT for gen9+ as it's a requirement for * execlists, the sole mechanism available to submit work. @@ -798,6 +801,16 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } +static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, + struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + return 0; +} + static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *ring) { @@ -1127,6 +1140,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) } else BUG(); + if (intel_vgpu_active(dev)) + ppgtt->switch_mm = vgpu_mm_switch; + ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 6/8] drm/i915: Disable power management for i915 driver in VM
With Intel GVT-g, GPU power management is controlled by host driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. v2: take Chris' comments: - do not special case this to gen6+ Signed-off-by: Yu Zhang Signed-off-by: Jike Song Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3c64810..177ff97 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5623,6 +5623,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 2/8] drm/i915: Adds graphic address space ballooning logic
With Intel GVT-g, the global graphic memory space is partitioned by multiple vGPU instances in different VMs. The ballooning code is called in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vGPUs as reserved. With ballooning, host side does not need to translate a grahpic address from guest view to host view. By now, current implementation only support the static ballooning, but in the future, with more cooperation from guest driver, the same interfaces can be extended to grow/shrink the guest graphic memory dynamically. v2: take Chris and Daniel's comments: - no guard page between different VMs - use drm_mm_reserve_node() to do the reservation for ballooning, instead of the previous drm_mm_insert_node_in_range_generic() v3: take Daniel's comments: - move ballooning functions into i915_vgpu.c - add kerneldoc to ballooning functions v4: take Tvrtko's comments: - more accurate comments and commit message Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++- drivers/gpu/drm/i915/i915_vgpu.c| 178 drivers/gpu/drm/i915/i915_vgpu.h| 2 + 3 files changed, 194 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b48b586..057f905 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -27,6 +27,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" @@ -1756,6 +1757,16 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, /* Subtract the guard page ... */ drm_mm_init(&ggtt_vm->mm, start, end - start - PAGE_SIZE); + + dev_priv->gtt.base.start = start; + dev_priv->gtt.base.total = end - start; + + if (intel_vgpu_active(dev)) { + ret = intel_vgt_balloon(dev); + if (ret) + return ret; + } + if (!HAS_LLC(dev)) dev_priv->gtt.base.mm.color_adjust = i915_gtt_color_adjust; @@ -1775,9 +1786,6 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev, vma->bound |= GLOBAL_BIND; } - dev_priv->gtt.base.start = start; - dev_priv->gtt.base.total = end - start; - /* Clear any non-preallocated blocks */ drm_mm_for_each_hole(entry, &ggtt_vm->mm, hole_start, hole_end) { DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n", @@ -1829,6 +1837,9 @@ void i915_global_gtt_cleanup(struct drm_device *dev) } if (drm_mm_initialized(&vm->mm)) { + if (intel_vgpu_active(dev)) + intel_vgt_deballoon(); + 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 995a600..5eee75b 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -84,3 +84,181 @@ void i915_check_vgpu(struct drm_device *dev) dev_priv->vgpu.active = true; DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); } + +struct _balloon_info_ { + /* +* There are up to 2 regions per mappable/unmappable graphic +* memory that might be ballooned. Here, index 0/1 is for mappable +* graphic memory, 2/3 for unmappable graphic memory. +*/ + struct drm_mm_node space[4]; +}; + +static struct _balloon_info_ bl_info; + +/** + * intel_vgt_deballoon - deballoon reserved graphics address trunks + * + * This function is called to deallocate the ballooned-out graphic memory, when + * driver is unloaded or when ballooning fails. + */ +void intel_vgt_deballoon(void) +{ + int i; + + DRM_DEBUG("VGT deballoon.\n"); + + for (i = 0; i < 4; i++) { + if (bl_info.space[i].allocated) + drm_mm_remove_node(&bl_info.space[i]); + } + + memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, +struct drm_mm_node *node, +unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + + if (start == end) + return -EINVAL; + + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KiB.\n", +start, end, size / 1024); + + node->start = start; + node->size = size; + + return drm_mm_reserve_node(mm, node); +} + +/** + * intel_vgt_balloon - balloon out reserved graphics address trunks + * @dev: d
[Intel-gfx] [PATCH v4 3/8] drm/i915: Partition the fence registers for vGPU in i915 driver
With Intel GVT-g, the fence registers are partitioned by multiple vGPU instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's running in a VM. Accesses to the fence registers from vGPU will be trapped and remapped by the host side. And the allocated fence number is provided in PV INFO page structure. By now, the value of fence number is fixed, but in the future we can relax this limitation, to allocate the fence registers dynamically from host side. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c26d36c..1765989 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -29,6 +29,7 @@ #include #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include "intel_drv.h" #include @@ -4987,6 +4988,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 5/8] drm/i915: Add the display switch logic for vGPU in i915 driver
Display switch logic is added to notify the host side that current vGPU have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in the host side. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. v2: - move the notification code outside the 'else' in load sequence - remove the notification code in intel_crtc_set_config() v4: - code rebase, no need to define another dev_priv - use #define instead of enum for display readiness Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_dma.c | 8 drivers/gpu/drm/i915/i915_vgpu.h | 4 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1a46787..5804aa5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include #include "i915_drv.h" +#include "i915_vgpu.h" #include "i915_trace.h" #include #include @@ -842,6 +843,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } } + /* +* Notify a valid surface after modesetting, +* when running inside a VM. +*/ + if (intel_vgpu_active(dev)) + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgpu.h b/drivers/gpu/drm/i915/i915_vgpu.h index 3ed01a7..0db9ccf 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.h +++ b/drivers/gpu/drm/i915/i915_vgpu.h @@ -80,6 +80,10 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *)NULL)->x) +/* vGPU display status to be used by the host side */ +#define VGT_DRV_DISPLAY_NOT_READY 0 +#define VGT_DRV_DISPLAY_READY 1 /* ready for display switch */ + extern void i915_check_vgpu(struct drm_device *dev); extern int intel_vgt_balloon(struct drm_device *dev); extern void intel_vgt_deballoon(void); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 7/8] drm/i915: Create vGPU specific MMIO operations to reduce traps
In the virtualized environment, forcewake operations are not necessary for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio access handlers are added to directly call the __raw_i915_read/write, therefore will reduce many traps and increase the overall performance for drivers running in the VM with Intel GVT-g enhancement. v2: take Chris' comments: - register the mmio hooks in intel_uncore_init() v3: take Daniel's comments: - use macros to assign mmio write functions for vGPU v4: take Tvrtko's comments: - also use mmio hooks for read operations Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian k --- drivers/gpu/drm/i915/intel_uncore.c | 31 +++ 1 file changed, 31 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d95419d..1b8d8ce 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -641,6 +641,14 @@ static inline void __force_wake_get(struct drm_i915_private *dev_priv, dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains); } +#define __vgpu_read(x) \ +static u##x \ +vgpu_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ + GEN6_READ_HEADER(x); \ + val = __raw_i915_read##x(dev_priv, reg); \ + GEN6_READ_FOOTER; \ +} + #define __gen6_read(x) \ static u##x \ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ @@ -704,6 +712,10 @@ gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \ GEN6_READ_FOOTER; \ } +__vgpu_read(8) +__vgpu_read(16) +__vgpu_read(32) +__vgpu_read(64) __gen9_read(8) __gen9_read(16) __gen9_read(32) @@ -725,6 +737,7 @@ __gen6_read(64) #undef __chv_read #undef __vlv_read #undef __gen6_read +#undef __vgpu_read #undef GEN6_READ_FOOTER #undef GEN6_READ_HEADER @@ -808,6 +821,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) GEN6_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void vgpu_write##x(struct drm_i915_private *dev_priv, \ + off_t reg, u##x val, bool trace) { \ + GEN6_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + GEN6_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -925,12 +946,17 @@ __gen6_write(8) __gen6_write(16) __gen6_write(32) __gen6_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __gen9_write #undef __chv_write #undef __gen8_write #undef __hsw_write #undef __gen6_write +#undef __vgpu_write #undef GEN6_WRITE_FOOTER #undef GEN6_WRITE_HEADER @@ -1133,6 +1159,11 @@ void intel_uncore_init(struct drm_device *dev) break; } + if (intel_vgpu_active(dev)) { + ASSIGN_WRITE_MMIO_VFUNCS(vgpu); + ASSIGN_READ_MMIO_VFUNCS(vgpu); + } + i915_check_and_clear_faults(dev); } #undef ASSIGN_WRITE_MMIO_VFUNCS -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v4 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM
Framebuffer compression is disabled when driver detects it's running in a Intel GVT-g enlightened VM, because FBC is not emulated and there is no stolen memory for a vGPU. v2: take Chris' comments: - move the code into intel_update_fbc() v4: take Tvrtko's comments: - rebase the code into intel_fbc_update() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/intel_fbc.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 7341e87..ee65731 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -505,6 +505,10 @@ void intel_fbc_update(struct drm_device *dev) if (!HAS_FBC(dev)) return; + /* disable framebuffer compression in vGPU */ + if (intel_vgpu_active(dev)) + i915.enable_fbc = 0; + if (i915.enable_fbc < 0) { if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) DRM_DEBUG_KMS("disabled per chip default\n"); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 0/8] Add enlightenments for vGPU
On 2/10/2015 8:11 PM, Tvrtko Ursulin wrote: On 02/10/2015 11:05 AM, Yu Zhang wrote: This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, will be sent out in other patches. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory without hypervisor's intervention, e.g. filling textures or queuing commands. However with the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses without complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (with some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource, XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vGPU in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vGPU in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vGPU specific MMIO operations to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled All my comments have been addressed (and I especially like the ASCII diagram of the memory space!) so you can put my r-b on all the patches from this series: Reviewed-by: Tvrtko Ursulin Thank you very much, Tvrtko. This is great. :-) Btw, should I resend another version patch series, which add the "Reviewed-by" line, or will Daniel directly merge these patches and add the "Reviewed-by" at that time? I'm willing to take whatever actions necessary, but I'm not familiar with this process. Thanks again. :) Yu Regards, Tvrtko ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v4 0/8] Add enlightenments for vGPU
On 2/11/2015 4:06 PM, Daniel Vetter wrote: On Tue, Feb 10, 2015 at 12:11:02PM +, Tvrtko Ursulin wrote: On 02/10/2015 11:05 AM, Yu Zhang wrote: This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, will be sent out in other patches. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory without hypervisor's intervention, e.g. filling textures or queuing commands. However with the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions >from allocation. Then vgt module only needs to scan and validate graphics addresses without complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (with some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource, XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vGPU in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vGPU in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vGPU specific MMIO operations to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled All my comments have been addressed (and I especially like the ASCII diagram of the memory space!) so you can put my r-b on all the patches from this series: Reviewed-by: Tvrtko Ursulin All merged, thanks for patches&review. -Daniel Got it. Thank you, Daniel! :) Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 2/8] drm/i915: Adds graphic address space ballooning logic
On 9/26/2014 4:48 PM, Chris Wilson wrote: On Fri, Sep 26, 2014 at 04:26:20PM +0800, Zhang, Yu wrote: Hi Chris & Daniel, Thanks for your comments. Following are my understandings about the changes needed for this patch: 1> We do not need the guard page anymore between different VMs. For the very last physical GTT entry, let's keep it pointing to a guard page. 2> To reserve the GMs in our balloon code, drm_mm_reserve_node() is preferred than the current drm_mm_insert_node_in_range_generic(). Am I correct? Please correct me if anything wrong. Thanks! :) Agreed. If you care to respin the patch, I'll see if anything else alarms me ;-) Got it. Thank you, Chris. -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
On 9/29/2014 7:44 PM, Jike Song wrote: On 09/19/2014 03:25 PM, Chris Wilson wrote: Now, given that these are simply trapped memory access, wouldn't it be simply to have: struct i915_virtual_gpu { struct vgt_if *if; } vgu; static inline bool intel_vgpu_active(struct drm_i915_private *i915) { return i915->vgpu.if; } then you have constructs like void i915_check_vgpu(struct drm_i915_private *i915) { struct vgt_if *if; if = i915->regs + VGT_PVINFO_PAGE; if (if->magic != VGT_MAGIC) return; if (INTEL_VGT_IF_VERSION != INTEL_VGT_IF_VERSION_ENCODE(if->version_major, if->version_minor)) return; i915->vgpu.if = if; } And later, for example: if (intel_vgpu_active(dev_priv)) dev_priv->num_fence_regs = dev_priv->vgpu.if->fence_num; Hi Chris, sorry that I didn't understand you correctly. After discussion with Yu today, I realized that unfortunately, the vgt_if can't be dereferenced directly. There are several reasons: - dereferencing a MMIO address will be complained by sparse(1) - for Guest VM, such accesses will be trapped by hypervisor, and hence emulated correctly; However this doesn't work for Host(e.g. Domain 0 of Xen, the Linux host KVM resides in). For host, we used a proactive mechanism to redirect i915 MMIO accesses to vgt, the GPU device-model, for the sake of central management & sharing among VMs, including host. Given that, though technically your code works for Guest, but after the integration of host support of iGVT, we still need to use I915_READ/I915_WRITE then. The host patches is soon to posted for your review :) I should have realized that earlier, sorry! Hi Chris, Sorry, I also should have noticed this issue earlier. To my understanding, the reason you proposed to use the "struct vgt_if *if" in struct vgpu, to replace the previous vgpu_active, is to simplify the mmio accesses in our patches. This suggestion works fine from the guest & native point of view. However, just like Jike's mail said, this change may not work for the host side, which also need to visit the PVINFO page from time to time. So, could we still keep the vgpu_active flag when detecting virtual gpu, and read the mmio registers in PVINFO structure by I915_READ? Thanks Yu -Chris -- Thanks, Jike ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
On 9/29/2014 8:40 PM, Jike Song wrote: On 09/29/2014 08:16 PM, Chris Wilson wrote: On Mon, Sep 29, 2014 at 07:44:56PM +0800, Jike Song wrote: On 09/19/2014 03:25 PM, Chris Wilson wrote: Now, given that these are simply trapped memory access, wouldn't it be simply to have: struct i915_virtual_gpu { struct vgt_if *if; } vgu; static inline bool intel_vgpu_active(struct drm_i915_private *i915) { return i915->vgpu.if; } then you have constructs like void i915_check_vgpu(struct drm_i915_private *i915) { struct vgt_if *if; if = i915->regs + VGT_PVINFO_PAGE; if (if->magic != VGT_MAGIC) return; if (INTEL_VGT_IF_VERSION != INTEL_VGT_IF_VERSION_ENCODE(if->version_major, if->version_minor)) return; i915->vgpu.if = if; } And later, for example: if (intel_vgpu_active(dev_priv)) dev_priv->num_fence_regs = dev_priv->vgpu.if->fence_num; Hi Chris, sorry that I didn't understand you correctly. After discussion with Yu today, I realized that unfortunately, the vgt_if can't be dereferenced directly. There are several reasons: - dereferencing a MMIO address will be complained by sparse(1) - for Guest VM, such accesses will be trapped by hypervisor, and hence emulated correctly; However this doesn't work for Host(e.g. Domain 0 of Xen, the Linux host KVM resides in). For host, we used a proactive mechanism to redirect i915 MMIO accesses to vgt, the GPU device-model, for the sake of central management & sharing among VMs, including host. You only need to be careful during vgpu detection. After that you know everything is safe. If you do the detection during intel_uncore_init(), or similar, you can use raw mmio access and explict sparse annotations to do the right thing. -Chris Hi Chris, Thanks for your suggestion, however, it addressed issue #1 but not issue #2. I'd like to give a detailed explanation :) For Guest i915 driver, when accessing a MMIO reg, it goes: whatever I915_READ/readl or direct dereferencing(addr) addr is translated to gpa(guest physical address) by guest paging structure hypervisor trapped the gpa access and forward it to vgt vgt_emulate_read32(vgt instance of guest, gpa) The real problem is, when running as the host gpu driver, i915 MMIO/GTT accesses are: 1) every difficult to trap, say the domain 0 of Xen hypervisor; or 2) impossible to trap, say KVM(In KVM, the host i915 is running in the very same privilege level and root mode as KVM hypervisor.) So, for Host i915 driver, when accessing a MMIO reg, it goes: I915_READ(addr) gen6_read32(addr) offset = addr - dev_priv->regs vgt_mmio_readl(the vgt instance of host, offset) .. some processing .. if (passed-throuth) readl(offset + dev_priv->regs) else pa = BAR0 + offset vgt_emulate_read32(vgt instance of host, pa) The vgt_if corresponds to the PVINFO page, not passed-through(actually it doesn't physically exist), should fall into the "else" above. Given that ... Yes we can dereference pointers for guest here, but consider that we'll deal with host in the future ... Hi Chris, Any comments on this issue? The host side patches were sent out by Jike last week. As you can see in his patch, the I915_READ/WRITEs are redefined, and the MMIO accesses are mediated to vgt, by offset of the regs, instead of by read/write (dev_priv->regs + offset) for host i915. So, in order to let i915 in the host side access the PVINFO page successfully, could we still use the I915_READ/WRTE, and keep the vgpu_active flag when detecting virtual gpu? :) Thanks Yu -- Thanks, Jike ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 0/8] Add enlightenments for vGPU
Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, were sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures and queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vgpu in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vgpu in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vgpu specific write MMIO to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_drv.h | 12 +++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 186 +++- drivers/gpu/drm/i915/i915_vgt_if.h | 93 ++ drivers/gpu/drm/i915/intel_pm.c | 8 ++ drivers/gpu/drm/i915/intel_uncore.c | 22 + 7 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 7/8] drm/i915: Create vgpu specific write MMIO to reduce traps
In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers runing in the VM with Intel GVT-g enhancement. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d5f39f3..ec6d5ce 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -719,6 +719,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ + REG_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -813,6 +821,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -820,6 +832,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -950,6 +963,13 @@ void intel_uncore_init(struct drm_device *dev) dev_priv->uncore.funcs.mmio_readq = gen4_read64; break; } + + if (intel_vgpu_active(dev)) { + dev_priv->uncore.funcs.mmio_writeb = vgpu_write8; + dev_priv->uncore.funcs.mmio_writew = vgpu_write16; + dev_priv->uncore.funcs.mmio_writel = vgpu_write32; + dev_priv->uncore.funcs.mmio_writeq = vgpu_write64; + } } void intel_uncore_fini(struct drm_device *dev) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 3/8] drm/i915: Partition the fence registers for vgpu in i915 driver
In XenGT, the fence registers are partitioned by multiple vgpu instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's runing in a VM. And the allocated fence numbers is provided in PV INFO page structure. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e9c783d..a0eec59 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -28,6 +28,7 @@ #include #include #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" @@ -4988,6 +4989,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 2/8] drm/i915: Adds graphic address space ballooning logic
In XenGT, the global graphic memory space is partitioned by multiple vgpu instances in different VMs. The ballooning code is added in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vgpus as reserved. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem_gtt.c | 144 +++- 1 file changed, 141 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 39c2d13..90757ab 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -31,6 +31,134 @@ #include "i915_trace.h" #include "intel_drv.h" +struct _balloon_info_ { + /* +* There are up to 2 regions per low/high GM that +* might be ballooned. Here, index 0/1 is for low +* GM, 2/3 for high GM. +*/ + struct drm_mm_node space[4]; +} bl_info; + +void intel_vgt_deballoon(void) +{ + int i; + + DRM_INFO("VGT deballoon.\n"); + + for (i = 0; i < 4; i++) { + if (bl_info.space[i].allocated) + drm_mm_remove_node(&bl_info.space[i]); + } + + memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, +struct drm_mm_node *node, +unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + + if (start == end) + return -EINVAL; + + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KB.\n", +start, end, size / 1024); + + node->start = start; + node->size = size; + + return drm_mm_reserve_node(mm, node); +} + +static int intel_vgt_balloon(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total; + + unsigned long low_gm_base, low_gm_size, low_gm_end; + unsigned long high_gm_base, high_gm_size, high_gm_end; + int ret; + + low_gm_base = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_base)); + low_gm_size = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_size)); + high_gm_base = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_base)); + high_gm_size = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_size)); + + low_gm_end = low_gm_base + low_gm_size; + high_gm_end = high_gm_base + high_gm_size; + + DRM_INFO("VGT ballooning configuration:\n"); + DRM_INFO("Low GM: base 0x%lx size %ldKB\n", +low_gm_base, low_gm_size / 1024); + DRM_INFO("High GM: base 0x%lx size %ldKB\n", +high_gm_base, high_gm_size / 1024); + + if (low_gm_base < ggtt_vm->start + || low_gm_end > dev_priv->gtt.mappable_end + || high_gm_base < dev_priv->gtt.mappable_end + || high_gm_end > ggtt_vm_end) { + DRM_ERROR("Invalid ballooning configuration!\n"); + return -EINVAL; + } + + memset(&bl_info, 0, sizeof(bl_info)); + + /* High GM ballooning */ + if (high_gm_base > dev_priv->gtt.mappable_end) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[2], + dev_priv->gtt.mappable_end, + high_gm_base); + + if (ret) + goto err; + } + + /* +* No need to partition out the last physical page, +* because it is reserved to the guard page. +*/ + if (high_gm_end < ggtt_vm_end - PAGE_SIZE) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[3], + high_gm_end, + ggtt_vm_end - PAGE_SIZE); + if (ret) + goto err; + } + + /* Low GM ballooning */ + if (low_gm_base > ggtt_vm->start) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[0], + ggtt_vm->start, low_gm_base); + + if (ret) + goto err; + } + + if (low_gm_end < dev_priv->gtt.mappable_end) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[1], + low_gm_end, + dev_priv->gtt.mappable_end); + +
[Intel-gfx] [PATCH v2 5/8] drm/i915: Add the display switch logic for vgpu in i915 driver
Display switch logic is added to notify the vgt mediator that current vgpu have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in vgt mediator. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/i915_dma.c| 11 +++ drivers/gpu/drm/i915/i915_vgt_if.h | 8 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 85d14e1..3a42b11 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -35,6 +35,7 @@ #include #include "intel_drv.h" #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include @@ -1780,6 +1781,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->ums.mm_suspended = 1; } + if (intel_vgpu_active(dev)) { + /* +* Notify a valid surface after modesetting, +* when running inside a VM. +*/ + struct drm_i915_private *dev_priv = to_i915(dev); + + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + } + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgt_if.h b/drivers/gpu/drm/i915/i915_vgt_if.h index fa45d28..633f98a 100644 --- a/drivers/gpu/drm/i915/i915_vgt_if.h +++ b/drivers/gpu/drm/i915/i915_vgt_if.h @@ -82,4 +82,12 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *) NULL)->x) +/* + * The information set by the guest gfx driver, through the display_ready field + */ +enum vgt_display_status { + VGT_DRV_DISPLAY_NOT_READY = 0, + VGT_DRV_DISPLAY_READY, /* ready for display switch */ +}; + #endif /* _I915_VGT_IF_H_ */ -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM
Framebuffer compression is disabled when driver detects it's running in XenGT VM, because XenGT does not provide emulations for FBC related operations, and we do not expose stolen memory to the VM. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index daa99e7..50cf96b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -544,6 +544,10 @@ void intel_update_fbc(struct drm_device *dev) return; } + /* disable framebuffer compression in vgt */ + if (intel_vgpu_active(dev)) + i915.enable_fbc = 0; + /* * If FBC is already on, we just have to verify that we can * keep it that way... -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through(previously known as XenGT). This page contains the shared information between i915 driver and the mediator. For now, this structure utilizes an area of 4K bypes on HSW GPU's unused MMIO space to support existing production. Future hardware will have the reserved window architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. If true, the pointer, vgpu.vgt_info is initialized, and intel_vgpu_active() is used by checking this pointer to conclude if gpu is virtualized with Intel GVT-g. By now, it will return true only when the driver is running in the XenGT environment on HSW. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_drv.h | 12 ++ drivers/gpu/drm/i915/i915_gem_gtt.c | 26 drivers/gpu/drm/i915/i915_vgt_if.h | 85 + drivers/gpu/drm/i915/intel_uncore.c | 2 + 4 files changed, 125 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ac6232b..ef6dadd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1448,6 +1448,10 @@ struct i915_frontbuffer_tracking { unsigned flip_bits; }; +struct i915_virtual_gpu { + bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1460,6 +1464,8 @@ struct drm_i915_private { struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2303,6 +2309,12 @@ extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); +extern void i915_check_vgpu(struct drm_device *dev); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ + return to_i915(dev)->vgpu.active; +} + void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index e0bcba0..39c2d13 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -26,10 +26,36 @@ #include #include #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +void i915_check_vgpu(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + uint64_t magic; + uint32_t version; + + BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); + + if (!IS_HASWELL(dev)) + return; + + magic = readq(dev_priv->regs + vgtif_reg(magic)); + if (magic != VGT_MAGIC) + return; + + version = INTEL_VGT_IF_VERSION_ENCODE( + readw(dev_priv->regs + vgtif_reg(version_major)), + readw(dev_priv->regs + vgtif_reg(version_minor))); + if (version != INTEL_VGT_IF_VERSION) + return; + + dev_priv->vgpu.active = true; + DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); +} + static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv); static void chv_setup_private_ppat(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_vgt_if.h b/drivers/gpu/drm/i915/i915_vgt_if.h new file mode 100644 index 000..fa45d28 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgt_if.h @@ -0,0 +1,85 @@ +/* + * Interface between Gfx driver and vgt mediator for Intel GVT-g + * + * Copyright(c) 2011-2014 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
[Intel-gfx] [PATCH v2 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled
The current XenGT only supports alias ppgtt. And the emulation is done in XenGT host by first trapping PP_DIR_BASE mmio accesses. Updating PP_DIR_BASE by using instructions such as MI_LOAD_REGISTER_IMM are hard to detect and are not supported in current XenGT. Therefore this patch also added a new callback routine - vgpu_mm_switch() to set the PP_DIR_BASE by mmio writes. Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 90757ab..a731896 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -197,6 +197,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) if (IS_GEN8(dev)) has_full_ppgtt = false; /* XXX why? */ + if (intel_vgpu_active(dev)) + has_full_ppgtt = false; /* emulation is too hard */ + if (enable_ppgtt == 0 || !has_aliasing_ppgtt) return 0; @@ -886,6 +889,16 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } +static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, +struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + return 0; +} + static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *ring) { @@ -1212,6 +1225,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) } else BUG(); + if (intel_vgpu_active(dev)) + ppgtt->switch_mm = vgpu_mm_switch; + ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 6/8] drm/i915: Disable power management for i915 driver in VM
In XenGT, GPU power management is controlled by host i915 driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 50cf96b..3a80557 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5304,6 +5304,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 3/8] drm/i915: Partition the fence registers for vgpu in i915 driver
In XenGT, the fence registers are partitioned by multiple vgpu instances in different VMs. Routine i915_gem_load() is modified to reset the num_fence_regs, when the driver detects it's runing in a VM. And the allocated fence numbers is provided in PV INFO page structure. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e9c783d..a0eec59 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -28,6 +28,7 @@ #include #include #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" @@ -4988,6 +4989,10 @@ i915_gem_load(struct drm_device *dev) else dev_priv->num_fence_regs = 8; + if (intel_vgpu_active(dev)) + dev_priv->num_fence_regs = + I915_READ(vgtif_reg(avail_rs.fence_num)); + /* Initialize fence registers to zero */ INIT_LIST_HEAD(&dev_priv->mm.fence_list); i915_gem_restore_fences(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 0/8] Add enlightenments for vGPU
Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, were sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures and queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vgpu in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vgpu in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vgpu specific write MMIO to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_drv.h | 12 +++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 186 +++- drivers/gpu/drm/i915/i915_vgt_if.h | 93 ++ drivers/gpu/drm/i915/intel_pm.c | 8 ++ drivers/gpu/drm/i915/intel_uncore.c | 22 + 7 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 2/8] drm/i915: Adds graphic address space ballooning logic
In XenGT, the global graphic memory space is partitioned by multiple vgpu instances in different VMs. The ballooning code is added in i915_gem_setup_global_gtt(), utilizing the drm mm allocator APIs to mark the graphic address space which are partitioned out to other vgpus as reserved. v2: take Chris and Daniel's comments: - no guard page between different VMs - use drm_mm_reserve_node() to do the reservation for ballooning, instead of the previous drm_mm_insert_node_in_range_generic() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhi Wang Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_gem_gtt.c | 144 +++- 1 file changed, 141 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 39c2d13..90757ab 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -31,6 +31,134 @@ #include "i915_trace.h" #include "intel_drv.h" +struct _balloon_info_ { + /* +* There are up to 2 regions per low/high GM that +* might be ballooned. Here, index 0/1 is for low +* GM, 2/3 for high GM. +*/ + struct drm_mm_node space[4]; +} bl_info; + +void intel_vgt_deballoon(void) +{ + int i; + + DRM_INFO("VGT deballoon.\n"); + + for (i = 0; i < 4; i++) { + if (bl_info.space[i].allocated) + drm_mm_remove_node(&bl_info.space[i]); + } + + memset(&bl_info, 0, sizeof(bl_info)); +} + +static int vgt_balloon_space(struct drm_mm *mm, +struct drm_mm_node *node, +unsigned long start, unsigned long end) +{ + unsigned long size = end - start; + + if (start == end) + return -EINVAL; + + DRM_INFO("balloon space: range [ 0x%lx - 0x%lx ] %lu KB.\n", +start, end, size / 1024); + + node->start = start; + node->size = size; + + return drm_mm_reserve_node(mm, node); +} + +static int intel_vgt_balloon(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + struct i915_address_space *ggtt_vm = &dev_priv->gtt.base; + unsigned long ggtt_vm_end = ggtt_vm->start + ggtt_vm->total; + + unsigned long low_gm_base, low_gm_size, low_gm_end; + unsigned long high_gm_base, high_gm_size, high_gm_end; + int ret; + + low_gm_base = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_base)); + low_gm_size = I915_READ(vgtif_reg(avail_rs.low_gmadr.my_size)); + high_gm_base = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_base)); + high_gm_size = I915_READ(vgtif_reg(avail_rs.high_gmadr.my_size)); + + low_gm_end = low_gm_base + low_gm_size; + high_gm_end = high_gm_base + high_gm_size; + + DRM_INFO("VGT ballooning configuration:\n"); + DRM_INFO("Low GM: base 0x%lx size %ldKB\n", +low_gm_base, low_gm_size / 1024); + DRM_INFO("High GM: base 0x%lx size %ldKB\n", +high_gm_base, high_gm_size / 1024); + + if (low_gm_base < ggtt_vm->start + || low_gm_end > dev_priv->gtt.mappable_end + || high_gm_base < dev_priv->gtt.mappable_end + || high_gm_end > ggtt_vm_end) { + DRM_ERROR("Invalid ballooning configuration!\n"); + return -EINVAL; + } + + memset(&bl_info, 0, sizeof(bl_info)); + + /* High GM ballooning */ + if (high_gm_base > dev_priv->gtt.mappable_end) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[2], + dev_priv->gtt.mappable_end, + high_gm_base); + + if (ret) + goto err; + } + + /* +* No need to partition out the last physical page, +* because it is reserved to the guard page. +*/ + if (high_gm_end < ggtt_vm_end - PAGE_SIZE) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[3], + high_gm_end, + ggtt_vm_end - PAGE_SIZE); + if (ret) + goto err; + } + + /* Low GM ballooning */ + if (low_gm_base > ggtt_vm->start) { + ret = vgt_balloon_space(&ggtt_vm->mm, + &bl_info.space[0], + ggtt_vm->start, low_gm_base); + + if (ret) + goto err; + } + + if (low_gm_end < dev_priv->gtt.mappable_end) { + ret = vgt_ballo
[Intel-gfx] [PATCH v2 1/8] drm/i915: Introduce a PV INFO page structure for Intel GVT-g.
Introduce a PV INFO structure, to facilitate the Intel GVT-g technology, which is a GPU virtualization solution with mediated pass-through(previously known as XenGT). This page contains the shared information between i915 driver and the mediator. For now, this structure utilizes an area of 4K bypes on HSW GPU's unused MMIO space to support existing production. Future hardware will have the reserved window architecturally defined, and layout of the page will be added in future BSpec. The i915 driver load routine detects if it is running in a VM by reading the contents of this PV INFO page. If true, the pointer, vgpu.vgt_info is initialized, and intel_vgpu_active() is used by checking this pointer to conclude if gpu is virtualized with Intel GVT-g. By now, it will return true only when the driver is running in the XenGT environment on HSW. v2: take Chris' comments: - call the i915_check_vgpu() in intel_uncore_init() - sanitize i915_check_vgpu() by adding BUILD_BUG_ON() and debug info take Daniel's comments: - put the definition of PV INFO into a new header - i915_vgt_if.h other changes: - access mmio regs by readq/readw in i915_check_vgpu() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Eddie Dong --- drivers/gpu/drm/i915/i915_drv.h | 12 ++ drivers/gpu/drm/i915/i915_gem_gtt.c | 26 drivers/gpu/drm/i915/i915_vgt_if.h | 85 + drivers/gpu/drm/i915/intel_uncore.c | 2 + 4 files changed, 125 insertions(+) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ac6232b..ef6dadd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1448,6 +1448,10 @@ struct i915_frontbuffer_tracking { unsigned flip_bits; }; +struct i915_virtual_gpu { + bool active; +}; + struct drm_i915_private { struct drm_device *dev; struct kmem_cache *slab; @@ -1460,6 +1464,8 @@ struct drm_i915_private { struct intel_uncore uncore; + struct i915_virtual_gpu vgpu; + struct intel_gmbus gmbus[GMBUS_NUM_PORTS]; @@ -2303,6 +2309,12 @@ extern void intel_uncore_check_errors(struct drm_device *dev); extern void intel_uncore_fini(struct drm_device *dev); extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore); +extern void i915_check_vgpu(struct drm_device *dev); +static inline bool intel_vgpu_active(struct drm_device *dev) +{ + return to_i915(dev)->vgpu.active; +} + void i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 status_mask); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index e0bcba0..39c2d13 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -26,10 +26,36 @@ #include #include #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +void i915_check_vgpu(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + uint64_t magic; + uint32_t version; + + BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); + + if (!IS_HASWELL(dev)) + return; + + magic = readq(dev_priv->regs + vgtif_reg(magic)); + if (magic != VGT_MAGIC) + return; + + version = INTEL_VGT_IF_VERSION_ENCODE( + readw(dev_priv->regs + vgtif_reg(version_major)), + readw(dev_priv->regs + vgtif_reg(version_minor))); + if (version != INTEL_VGT_IF_VERSION) + return; + + dev_priv->vgpu.active = true; + DRM_INFO("Virtual GPU for Intel GVT-g detected.\n"); +} + static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv); static void chv_setup_private_ppat(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_vgt_if.h b/drivers/gpu/drm/i915/i915_vgt_if.h new file mode 100644 index 000..fa45d28 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_vgt_if.h @@ -0,0 +1,85 @@ +/* + * Interface between Gfx driver and vgt mediator for Intel GVT-g + * + * Copyright(c) 2011-2014 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 s
[Intel-gfx] [PATCH v2 5/8] drm/i915: Add the display switch logic for vgpu in i915 driver
Display switch logic is added to notify the vgt mediator that current vgpu have a valid surface to show. It does so by writing the display_ready field in PV INFO page, and then will be handled in vgt mediator. This is useful to avoid trickiness when the VM's framebuffer is being accessed in the middle of VM modesetting, e.g. compositing the framebuffer in the host side. v2: - move the notification code outside the 'else' in load sequence - remove the notification code in intel_crtc_set_config() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/i915_dma.c| 11 +++ drivers/gpu/drm/i915/i915_vgt_if.h | 8 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 85d14e1..3a42b11 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -35,6 +35,7 @@ #include #include "intel_drv.h" #include +#include "i915_vgt_if.h" #include "i915_drv.h" #include "i915_trace.h" #include @@ -1780,6 +1781,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->ums.mm_suspended = 1; } + if (intel_vgpu_active(dev)) { + /* +* Notify a valid surface after modesetting, +* when running inside a VM. +*/ + struct drm_i915_private *dev_priv = to_i915(dev); + + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + } + i915_setup_sysfs(dev); if (INTEL_INFO(dev)->num_pipes) { diff --git a/drivers/gpu/drm/i915/i915_vgt_if.h b/drivers/gpu/drm/i915/i915_vgt_if.h index fa45d28..633f98a 100644 --- a/drivers/gpu/drm/i915/i915_vgt_if.h +++ b/drivers/gpu/drm/i915/i915_vgt_if.h @@ -82,4 +82,12 @@ struct vgt_if { #define vgtif_reg(x) \ (VGT_PVINFO_PAGE + (long)&((struct vgt_if *) NULL)->x) +/* + * The information set by the guest gfx driver, through the display_ready field + */ +enum vgt_display_status { + VGT_DRV_DISPLAY_NOT_READY = 0, + VGT_DRV_DISPLAY_READY, /* ready for display switch */ +}; + #endif /* _I915_VGT_IF_H_ */ -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 4/8] drm/i915: Disable framebuffer compression for i915 driver in VM
Framebuffer compression is disabled when driver detects it's running in XenGT VM, because XenGT does not provide emulations for FBC related operations, and we do not expose stolen memory to the VM. v2: take Chris' comments: - move the code into intel_update_fbc() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Zhiyuan Lv --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index daa99e7..50cf96b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -544,6 +544,10 @@ void intel_update_fbc(struct drm_device *dev) return; } + /* disable framebuffer compression in vgt */ + if (intel_vgpu_active(dev)) + i915.enable_fbc = 0; + /* * If FBC is already on, we just have to verify that we can * keep it that way... -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 7/8] drm/i915: Create vgpu specific write MMIO to reduce traps
In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers runing in the VM with Intel GVT-g enhancement. v2: take Chris' comments: - register the mmio hooks in intel_uncore_init() Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d5f39f3..ec6d5ce 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -719,6 +719,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ + REG_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -813,6 +821,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -820,6 +832,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -950,6 +963,13 @@ void intel_uncore_init(struct drm_device *dev) dev_priv->uncore.funcs.mmio_readq = gen4_read64; break; } + + if (intel_vgpu_active(dev)) { + dev_priv->uncore.funcs.mmio_writeb = vgpu_write8; + dev_priv->uncore.funcs.mmio_writew = vgpu_write16; + dev_priv->uncore.funcs.mmio_writel = vgpu_write32; + dev_priv->uncore.funcs.mmio_writeq = vgpu_write64; + } } void intel_uncore_fini(struct drm_device *dev) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 6/8] drm/i915: Disable power management for i915 driver in VM
In XenGT, GPU power management is controlled by host i915 driver, so there is no need to provide virtualized GPU PM support. In the future it might be useful to gather VM input for freq boost, but now let's disable it simply. v2: take Chris' comments: - do not special case this to gen6+ Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/intel_pm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 50cf96b..3a80557 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5304,6 +5304,10 @@ void intel_enable_gt_powersave(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + /* Powersaving is controlled by the host when inside a VM */ + if (intel_vgpu_active(dev)) + return; + if (IS_IRONLAKE_M(dev)) { mutex_lock(&dev->struct_mutex); ironlake_enable_drps(dev); -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 8/8] drm/i915: Support alias ppgtt in VM if ppgtt is enabled
The current XenGT only supports alias ppgtt. And the emulation is done in XenGT host by first trapping PP_DIR_BASE mmio accesses. Updating PP_DIR_BASE by using instructions such as MI_LOAD_REGISTER_IMM are hard to detect and are not supported in current XenGT. Therefore this patch also added a new callback routine - vgpu_mm_switch() to set the PP_DIR_BASE by mmio writes. v2: take Chris' comments: - move the code into sanitize_enable_ppgtt() Signed-off-by: Yu Zhang Signed-off-by: Jike Song --- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 90757ab..a731896 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -197,6 +197,9 @@ static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) if (IS_GEN8(dev)) has_full_ppgtt = false; /* XXX why? */ + if (intel_vgpu_active(dev)) + has_full_ppgtt = false; /* emulation is too hard */ + if (enable_ppgtt == 0 || !has_aliasing_ppgtt) return 0; @@ -886,6 +889,16 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } +static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, +struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); + + I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G); + I915_WRITE(RING_PP_DIR_BASE(ring), get_pd_offset(ppgtt)); + return 0; +} + static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct intel_engine_cs *ring) { @@ -1212,6 +1225,9 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) } else BUG(); + if (intel_vgpu_active(dev)) + ppgtt->switch_mm = vgpu_mm_switch; + ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 0/8] Add enlightenments for vGPU
Hi Daniel, Thanks a lot for your reply. Indeed, I sent two v2 patches, because the format of the first v2 patchset is incorrect - I forgot to add the what changed part in those messages. :) Yu On 10/22/2014 12:16 AM, Daniel Vetter wrote: On Fri, Oct 17, 2014 at 01:37:11PM +0800, Yu Zhang wrote: Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, were sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures and queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vgpu in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vgpu in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vgpu specific write MMIO to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_drv.h | 12 +++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 186 +++- drivers/gpu/drm/i915/i915_vgt_if.h | 93 ++ drivers/gpu/drm/i915/intel_pm.c | 8 ++ drivers/gpu/drm/i915/intel_uncore.c | 22 + 7 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h I seem to have two v2 versions of this patch series. Anything changed or why the resend? I didn't see any comment on the older version ... -Daniel ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 0/8] Add enlightenments for vGPU
On 10/22/2014 12:51 AM, Daniel Vetter wrote: On Tue, Oct 21, 2014 at 06:16:26PM +0200, Daniel Vetter wrote: On Fri, Oct 17, 2014 at 01:37:11PM +0800, Yu Zhang wrote: Intel GVT-g (previously known as XenGT), is a complete GPU virtualization solution with mediated pass-through for 4th generation Intel Core processors - Haswell platform. This technology presents a virtual full-fledged GPU to each Virtual Machine (VM). VMs can directly access performance-critical resources, without intervention from the hypervisor in most cases, while privileged operations from VMs are trap-and-emulated at minimal cost. For detail, please refer to https://01.org/xen/blogs/wangbo85/2014/intel-gvt-gxengt-pubic-release This patch set includes necessary code changes when i915 driver runs inside a VM. Though ideally we can run an unmodified i915 driver in VM, adding such enlightenments can greatly reduce the virtualization complexity in orders of magnitude. Code changes for the host side, which includes the actual Intel GVT-g implementation, were sent out in another patchset. The primary change introduced here is to implement so-called "address space ballooning" technique. XenGT partitions global graphics memory among multiple VMs, so each VM can directly access a portion of the memory w/o hypervisor's intervention, e.g. filling textures and queuing commands. However w/ the partitioning an unmodified i915 driver would assume a smaller graphics memory starting from address ZERO, so requires XenGT core module (vgt) to translate the graphics address between 'guest view' and 'host view', for all registers and command opcodes which contain a graphics memory address. To reduce the complexity, XenGT introduces "address space ballooning", by telling the exact partitioning knowledge to each guest i915 driver, which then reserves and prevents non-allocated portions from allocation. Then vgt module only needs to scan and validate graphics addresses w/o complexity of translation. Note: The partitioning of global graphics memory may break some applications, with large objects in the aperture, because current userspace assumes half of the aperture usable. That would need separate fix either in user space (e.g. remove assumption in mesa) or in kernel (w/ some faulting mechanism). The partitioning knowledge is conveyed through a reserved MMIO range, called PVINFO, which will be architecturally reserved in future hardware generations. Another information carried through PVINFO is about the number of fence registers. As a global resource XenGT also partitions them among VMs. Other changes are trivial as optimizations, to either reduce the trap overhead or disable power management features which don't make sense in a virtualized environment. Yu Zhang (8): drm/i915: Introduce a PV INFO page structure for Intel GVT-g. drm/i915: Adds graphic address space ballooning logic drm/i915: Partition the fence registers for vgpu in i915 driver drm/i915: Disable framebuffer compression for i915 driver in VM drm/i915: Add the display switch logic for vgpu in i915 driver drm/i915: Disable power management for i915 driver in VM drm/i915: Create vgpu specific write MMIO to reduce traps drm/i915: Support alias ppgtt in VM if ppgtt is enabled drivers/gpu/drm/i915/i915_dma.c | 11 +++ drivers/gpu/drm/i915/i915_drv.h | 12 +++ drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/i915_gem_gtt.c | 186 +++- drivers/gpu/drm/i915/i915_vgt_if.h | 93 ++ drivers/gpu/drm/i915/intel_pm.c | 8 ++ drivers/gpu/drm/i915/intel_uncore.c | 22 + 7 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_vgt_if.h I seem to have two v2 versions of this patch series. Anything changed or why the resend? I didn't see any comment on the older version ... Well, looked through it anyway. On a high level this looks good for the vgt integration for guests. I think we need some polish though still, specifically for documentation. - Please extract all the various intel_vgt_* functions spread all over the tree into a new i915_vgt_if.c (or intel_vgt.c, but then the header should be changed, too I think). - Please add kerneldoc to all the functions which are non-static and so used by the driver outside of your kernel module. - Please add a DOC: section detailing some of the high-level design considerations of vGT and also put that into the new file. I think in the future we should also keep the guest<->host abi revisions in there (i.e. the stuff in PV_INFO). Sure. Thanks! - Please pull all the new documentation together and integrate it into the i915 section of the drm docbook. A good place is probably a new subsection "Paravirtualized Guest Support (vGPU)" under the driver core section. How about subsection name "Intel
Re: [Intel-gfx] [PATCH v2 7/8] drm/i915: Create vgpu specific write MMIO to reduce traps
On 10/22/2014 12:40 AM, Daniel Vetter wrote: On Thu, Oct 16, 2014 at 02:24:27PM +0800, Yu Zhang wrote: In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers runing in the VM with Intel GVT-g enhancement. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d5f39f3..ec6d5ce 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -719,6 +719,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ + REG_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -813,6 +821,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -820,6 +832,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -950,6 +963,13 @@ void intel_uncore_init(struct drm_device *dev) dev_priv->uncore.funcs.mmio_readq = gen4_read64; break; } + + if (intel_vgpu_active(dev)) { + dev_priv->uncore.funcs.mmio_writeb = vgpu_write8; + dev_priv->uncore.funcs.mmio_writew = vgpu_write16; + dev_priv->uncore.funcs.mmio_writel = vgpu_write32; + dev_priv->uncore.funcs.mmio_writeq = vgpu_write64; Someone should write a cool macro which uses prepocessor string concatenation so that we can compress this all to ASSIGN_WRITE_MMIO_VFUNCS(vgpu) Then throw in an ASSIGN_READ_MMIO_VFUNC which looks similarly and this might actually be pretty. Just an idea for some follow-up cleanup. -Daniel Thanks Daniel. Do you mean something like this: #define ASSIGN_WRITE_MMIO_VFUNCS(x) \ do {\ dev_priv->uncore.funcs.mmio_writeb = x##_write8;\ dev_priv->uncore.funcs.mmio_writew = x##_write16; \ dev_priv->uncore.funcs.mmio_writel = x##_write32; \ dev_priv->uncore.funcs.mmio_writeq = x##_write64; \ } while (0) and then we can use ASSIGN_WRITE_MMIO_VFUNCS(hsw) for hsw and ASSIGN_WRITE_MMIO_VFUNCS(vgpu) for vgpu, etc? + } } void intel_uncore_fini(struct drm_device *dev) -- 1.9.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v2 7/8] drm/i915: Create vgpu specific write MMIO to reduce traps
On 10/22/2014 11:33 PM, Daniel Vetter wrote: On Wed, Oct 22, 2014 at 08:27:50PM +0800, Yu, Zhang wrote: On 10/22/2014 12:40 AM, Daniel Vetter wrote: On Thu, Oct 16, 2014 at 02:24:27PM +0800, Yu Zhang wrote: In the virtualized environment, forcewake operations are not necessory for the driver, because mmio accesses will be trapped and emulated by the host side, and real forcewake operations are also done in the host. New mmio write handlers are added to directly call the __raw_i915_write, therefore will reduce many traps and increase the overall performance for drivers runing in the VM with Intel GVT-g enhancement. Signed-off-by: Yu Zhang Signed-off-by: Jike Song Signed-off-by: Kevin Tian --- drivers/gpu/drm/i915/intel_uncore.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index d5f39f3..ec6d5ce 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -719,6 +719,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) REG_WRITE_FOOTER; \ } +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \ + REG_WRITE_HEADER; \ + __raw_i915_write##x(dev_priv, reg, val); \ + REG_WRITE_FOOTER; \ +} + static const u32 gen8_shadowed_regs[] = { FORCEWAKE_MT, GEN6_RPNSWREQ, @@ -813,6 +821,10 @@ __gen4_write(8) __gen4_write(16) __gen4_write(32) __gen4_write(64) +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) +__vgpu_write(64) #undef __chv_write #undef __gen8_write @@ -820,6 +832,7 @@ __gen4_write(64) #undef __gen6_write #undef __gen5_write #undef __gen4_write +#undef __vgpu_write #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER @@ -950,6 +963,13 @@ void intel_uncore_init(struct drm_device *dev) dev_priv->uncore.funcs.mmio_readq = gen4_read64; break; } + + if (intel_vgpu_active(dev)) { + dev_priv->uncore.funcs.mmio_writeb = vgpu_write8; + dev_priv->uncore.funcs.mmio_writew = vgpu_write16; + dev_priv->uncore.funcs.mmio_writel = vgpu_write32; + dev_priv->uncore.funcs.mmio_writeq = vgpu_write64; Someone should write a cool macro which uses prepocessor string concatenation so that we can compress this all to ASSIGN_WRITE_MMIO_VFUNCS(vgpu) Then throw in an ASSIGN_READ_MMIO_VFUNC which looks similarly and this might actually be pretty. Just an idea for some follow-up cleanup. -Daniel Thanks Daniel. Do you mean something like this: #define ASSIGN_WRITE_MMIO_VFUNCS(x) \ do {\ dev_priv->uncore.funcs.mmio_writeb = x##_write8;\ dev_priv->uncore.funcs.mmio_writew = x##_write16; \ dev_priv->uncore.funcs.mmio_writel = x##_write32; \ dev_priv->uncore.funcs.mmio_writeq = x##_write64; \ } while (0) and then we can use ASSIGN_WRITE_MMIO_VFUNCS(hsw) for hsw and ASSIGN_WRITE_MMIO_VFUNCS(vgpu) for vgpu, etc? Yup. Plus the version for assigning READ vfuncs (on many platforms they don't match up). Probably best if you do this conversion as a prep patch before the vgt series so that I can merge it right away. -Daniel Sure, thanks. I 'll send this patch later, before our v3 vgpu patch series. :) Yu ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915: use macros to assign mmio access functions
Signed-off-by: Yu Zhang --- drivers/gpu/drm/i915/intel_uncore.c | 76 ++--- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0b0f4f8..9b228e3 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -823,6 +823,22 @@ __gen4_write(64) #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER +#define ASSIGN_WRITE_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_writeb = x##_write8; \ + dev_priv->uncore.funcs.mmio_writew = x##_write16; \ + dev_priv->uncore.funcs.mmio_writel = x##_write32; \ + dev_priv->uncore.funcs.mmio_writeq = x##_write64; \ +} while (0) + +#define ASSIGN_READ_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_readb = x##_read8; \ + dev_priv->uncore.funcs.mmio_readw = x##_read16; \ + dev_priv->uncore.funcs.mmio_readl = x##_read32; \ + dev_priv->uncore.funcs.mmio_readq = x##_read64; \ +} while (0) + void intel_uncore_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -879,73 +895,37 @@ void intel_uncore_init(struct drm_device *dev) switch (INTEL_INFO(dev)->gen) { default: if (IS_CHERRYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_writeb = chv_write8; - dev_priv->uncore.funcs.mmio_writew = chv_write16; - dev_priv->uncore.funcs.mmio_writel = chv_write32; - dev_priv->uncore.funcs.mmio_writeq = chv_write64; - dev_priv->uncore.funcs.mmio_readb = chv_read8; - dev_priv->uncore.funcs.mmio_readw = chv_read16; - dev_priv->uncore.funcs.mmio_readl = chv_read32; - dev_priv->uncore.funcs.mmio_readq = chv_read64; + ASSIGN_WRITE_MMIO_VFUNCS(chv); + ASSIGN_READ_MMIO_VFUNCS(chv); } else { - dev_priv->uncore.funcs.mmio_writeb = gen8_write8; - dev_priv->uncore.funcs.mmio_writew = gen8_write16; - dev_priv->uncore.funcs.mmio_writel = gen8_write32; - dev_priv->uncore.funcs.mmio_writeq = gen8_write64; - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + ASSIGN_WRITE_MMIO_VFUNCS(gen8); + ASSIGN_READ_MMIO_VFUNCS(gen6); } break; case 7: case 6: if (IS_HASWELL(dev)) { - dev_priv->uncore.funcs.mmio_writeb = hsw_write8; - dev_priv->uncore.funcs.mmio_writew = hsw_write16; - dev_priv->uncore.funcs.mmio_writel = hsw_write32; - dev_priv->uncore.funcs.mmio_writeq = hsw_write64; + ASSIGN_WRITE_MMIO_VFUNCS(hsw); } else { - dev_priv->uncore.funcs.mmio_writeb = gen6_write8; - dev_priv->uncore.funcs.mmio_writew = gen6_write16; - dev_priv->uncore.funcs.mmio_writel = gen6_write32; - dev_priv->uncore.funcs.mmio_writeq = gen6_write64; + ASSIGN_WRITE_MMIO_VFUNCS(gen6); } if (IS_VALLEYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_readb = vlv_read8; - dev_priv->uncore.funcs.mmio_readw = vlv_read16; - dev_priv->uncore.funcs.mmio_readl = vlv_read32; - dev_priv->uncore.funcs.mmio_readq = vlv_read64; + ASSIGN_READ_MMIO_VFUNCS(vlv); } else { - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + ASSIGN_READ_MMIO_VFUNCS(gen6); } break; case 5: - dev_priv->uncore.funcs.mmio_writeb = gen5_write8; - dev_priv->uncore.funcs.mmio_writew = gen5_write16; - dev_priv->uncore.funcs.mmio_writel = gen5_write32; - dev_priv->uncore.funcs.mmio_writeq = gen5_write64; - dev_priv->uncore.funcs.mmio_readb = gen5_read8; - dev_priv->uncore.funcs.mmio_readw =
Re: [Intel-gfx] [PATCH] drm/i915: use macros to assign mmio access functions
On 10/23/2014 8:28 PM, Daniel Vetter wrote: On Thu, Oct 23, 2014 at 03:28:24PM +0800, Yu Zhang wrote: Empty commit messages aren't good. Even for really simple refactoring please explain in 1-2 sentences the motivation for the patch, since the change itself doesn't really say that. For this one I've added something while merging. Signed-off-by: Yu Zhang --- drivers/gpu/drm/i915/intel_uncore.c | 76 ++--- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 0b0f4f8..9b228e3 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -823,6 +823,22 @@ __gen4_write(64) #undef REG_WRITE_FOOTER #undef REG_WRITE_HEADER +#define ASSIGN_WRITE_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_writeb = x##_write8; \ + dev_priv->uncore.funcs.mmio_writew = x##_write16; \ + dev_priv->uncore.funcs.mmio_writel = x##_write32; \ + dev_priv->uncore.funcs.mmio_writeq = x##_write64; \ +} while (0) + +#define ASSIGN_READ_MMIO_VFUNCS(x) \ +do { \ + dev_priv->uncore.funcs.mmio_readb = x##_read8; \ + dev_priv->uncore.funcs.mmio_readw = x##_read16; \ + dev_priv->uncore.funcs.mmio_readl = x##_read32; \ + dev_priv->uncore.funcs.mmio_readq = x##_read64; \ +} while (0) Usually we #undef such temporary macros again after the last user. I've added that, too. Queued for -next, thanks for the patch. -Daniel Ha. Thank you very much for your advice and help, Daniel. I have seen your merge, and will pay attention in future patches. This is my first patch in the open source community. :) - Yu + void intel_uncore_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -879,73 +895,37 @@ void intel_uncore_init(struct drm_device *dev) switch (INTEL_INFO(dev)->gen) { default: if (IS_CHERRYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_writeb = chv_write8; - dev_priv->uncore.funcs.mmio_writew = chv_write16; - dev_priv->uncore.funcs.mmio_writel = chv_write32; - dev_priv->uncore.funcs.mmio_writeq = chv_write64; - dev_priv->uncore.funcs.mmio_readb = chv_read8; - dev_priv->uncore.funcs.mmio_readw = chv_read16; - dev_priv->uncore.funcs.mmio_readl = chv_read32; - dev_priv->uncore.funcs.mmio_readq = chv_read64; + ASSIGN_WRITE_MMIO_VFUNCS(chv); + ASSIGN_READ_MMIO_VFUNCS(chv); } else { - dev_priv->uncore.funcs.mmio_writeb = gen8_write8; - dev_priv->uncore.funcs.mmio_writew = gen8_write16; - dev_priv->uncore.funcs.mmio_writel = gen8_write32; - dev_priv->uncore.funcs.mmio_writeq = gen8_write64; - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6_read16; - dev_priv->uncore.funcs.mmio_readl = gen6_read32; - dev_priv->uncore.funcs.mmio_readq = gen6_read64; + ASSIGN_WRITE_MMIO_VFUNCS(gen8); + ASSIGN_READ_MMIO_VFUNCS(gen6); } break; case 7: case 6: if (IS_HASWELL(dev)) { - dev_priv->uncore.funcs.mmio_writeb = hsw_write8; - dev_priv->uncore.funcs.mmio_writew = hsw_write16; - dev_priv->uncore.funcs.mmio_writel = hsw_write32; - dev_priv->uncore.funcs.mmio_writeq = hsw_write64; + ASSIGN_WRITE_MMIO_VFUNCS(hsw); } else { - dev_priv->uncore.funcs.mmio_writeb = gen6_write8; - dev_priv->uncore.funcs.mmio_writew = gen6_write16; - dev_priv->uncore.funcs.mmio_writel = gen6_write32; - dev_priv->uncore.funcs.mmio_writeq = gen6_write64; + ASSIGN_WRITE_MMIO_VFUNCS(gen6); } if (IS_VALLEYVIEW(dev)) { - dev_priv->uncore.funcs.mmio_readb = vlv_read8; - dev_priv->uncore.funcs.mmio_readw = vlv_read16; - dev_priv->uncore.funcs.mmio_readl = vlv_read32; - dev_priv->uncore.funcs.mmio_readq = vlv_read64; + ASSIGN_READ_MMIO_VFUNCS(vlv); } else { - dev_priv->uncore.funcs.mmio_readb = gen6_read8; - dev_priv->uncore.funcs.mmio_readw = gen6