From 2007cc46f06bdc44f5a0589bb7ef6f0c8b704ebe Mon Sep 17 00:00:00 2001 From: Dan Ziemba Date: Mon, 13 Jun 2016 18:43:18 -0400 Subject: [PATCH] Updated i915 vga arbiter patch --- .SRCINFO | 6 +- ...ted-i915-vga-arbiter-patch-for-4.6.2.patch | 196 ++++++++++++++++++ PKGBUILD | 6 +- i915_317.patch | 137 ------------ 4 files changed, 202 insertions(+), 143 deletions(-) create mode 100644 0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch delete mode 100644 i915_317.patch diff --git a/.SRCINFO b/.SRCINFO index 0fe366e..ba1c5d1 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,5 +1,5 @@ # Generated by mksrcinfo v8 -# Mon Jun 13 22:24:33 UTC 2016 +# Mon Jun 13 22:42:39 UTC 2016 pkgbase = linux-vfio pkgver = 4.6.2 pkgrel = 1 @@ -24,7 +24,7 @@ pkgbase = linux-vfio source = change-default-console-loglevel.patch source = 0001-linux-4.6-rtlwifi-fix-atomic.patch source = override_for_missing_acs_capabilities.patch - source = i915_317.patch + source = 0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch sha256sums = a93771cd5a8ad27798f22e9240538dfea48d3a2bf2a6a6ab415de3f02d25d866 sha256sums = SKIP sha256sums = 0dc509a19c68ab547a62158bf2017965b843854b63be46ae039c37724dccca21 @@ -35,7 +35,7 @@ pkgbase = linux-vfio sha256sums = 1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99 sha256sums = ae0d16e81a915fae130125ba9d0b6fd2427e06f50b8b9514abc4029efe61ee98 sha256sums = 975f79348119bfba8dd972a9fbfe6b38484c45bfd228f2f6d48a0c02426ba149 - sha256sums = b5a8eebbe75e1801b35d2f5197eba6f57123c224e09e97a7eb526f1fa58ac918 + sha256sums = 6dc172c2ef277223aa59806a2edda7efc4f94d2bf68b6bf2b1d0413e84b9e260 pkgname = linux-vfio pkgdesc = The Linux kernel and modules with patches to enable GPU passthrough with KVM diff --git a/0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch b/0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch new file mode 100644 index 0000000..19787c6 --- /dev/null +++ b/0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch @@ -0,0 +1,196 @@ +From 44d8022a2ff1e71bffba431877949ecf827ea9f2 Mon Sep 17 00:00:00 2001 +From: Dan Ziemba +Date: Mon, 13 Jun 2016 18:09:36 -0400 +Subject: [PATCH] Updated i915 vga arbiter patch for 4.6.2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is an updated version of Alex Williamson's patch from: +https://lkml.org/lkml/2014/5/9/517 +I don't have i915 graphics, so this is completely untested. + +Original commit message follows: +--- +Commit 81b5c7bc found that the current VGA arbiter support in i915 +only works for ancient GMCH-based IGD devices and attempted to update +support for newer HD devices. Unfortunately newer devices cannot +completely opt-out of VGA arbitration like the old devices could. +The VGA I/O space cannot be disabled internally. The only way to +route VGA I/O elsewhere is by disabling I/O at the device PCI command +register. This means that with commit 81b5c7bc and multiple VGA +adapters, the VGA arbiter will report that multiple VGA devices are +participating in arbitration, Xorg will notice this and disable DRI. +Therefore, 81b5c7bc was reverted because DRI is more important than +being correct. + +There is however an actual need for i915 to correctly participate in +VGA arbitration; VGA device assignment. If we want to use VFIO to +assign a VGA device to a virtual machine, we need to be able to +access the VGA resources of that device. By adding an i915 module +option we can allow i915 to continue with its charade by default, but +also allow an easy path for users who require working VGA arbitration. +Hopefully Xorg can someday be taught to behave better with multiple +VGA devices. + +This also rolls in reverted commit 6e1b4fda, which corrected an +ordering issue with 81b5c7bc by delaying the disabling of VGA memory +until after vgacon->fbcon handoff. + +Signed-off-by: Alex Williamson +Cc: Ville Syrjälä +Cc: Daniel Vetter +Cc: Dave Airlie +--- + drivers/gpu/drm/i915/i915_dma.c | 22 +++++++++++++++++++--- + drivers/gpu/drm/i915/i915_params.c | 5 +++++ + drivers/gpu/drm/i915/i915_params.h | 1 + + drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/i915/intel_drv.h | 2 ++ + 5 files changed, 57 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c +index 1c6d227..43bce33 100644 +--- a/drivers/gpu/drm/i915/i915_dma.c ++++ b/drivers/gpu/drm/i915/i915_dma.c +@@ -380,10 +380,20 @@ static int i915_load_modeset_init(struct drm_device *dev) + * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), + * then we do not take part in VGA arbitration and the + * vga_client_register() fails with -ENODEV. ++ * ++ * NB. The set_decode callback here actually only works on GMCH ++ * devices, on newer HD devices we can only disable VGA MMIO space. ++ * Disabling VGA I/O space requires disabling I/O in the PCI command ++ * register. Nonetheless, we like to pretend that we participate in ++ * VGA arbitration and can dynamically disable VGA I/O space because ++ * this makes X happy, even though it's a complete lie. + */ +- ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); +- if (ret && ret != -ENODEV) +- goto out; ++ if (!i915.enable_hd_vgaarb || !HAS_PCH_SPLIT(dev)) { ++ ret = vga_client_register(dev->pdev, dev, NULL, ++ i915_vga_set_decode); ++ if (ret && ret != -ENODEV) ++ goto out; ++ } + + intel_register_dsm_handler(); + +@@ -423,6 +433,12 @@ static int i915_load_modeset_init(struct drm_device *dev) + if (ret) + goto cleanup_gem; + ++ /* ++ * Must do this after fbcon init so that ++ * vgacon_save_screen() works during the handover. ++ */ ++ i915_disable_vga_mem(dev); ++ + /* Only enable hotplug handling once the fbdev is fully set up. */ + intel_hpd_init(dev_priv); + +diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c +index 278c9c4..e0a3e08 100644 +--- a/drivers/gpu/drm/i915/i915_params.c ++++ b/drivers/gpu/drm/i915/i915_params.c +@@ -49,6 +49,7 @@ struct i915_params i915 __read_mostly = { + .invert_brightness = 0, + .disable_display = 0, + .enable_cmd_parser = 1, ++ .enable_hd_vgaarb = false, + .use_mmio_flip = 0, + .mmio_debug = 0, + .verbose_state_checks = 1, +@@ -171,6 +172,10 @@ module_param_named_unsafe(enable_cmd_parser, i915.enable_cmd_parser, int, 0600); + MODULE_PARM_DESC(enable_cmd_parser, + "Enable command parsing (1=enabled [default], 0=disabled)"); + ++module_param_named(enable_hd_vgaarb, i915.enable_hd_vgaarb, bool, 0444); ++MODULE_PARM_DESC(enable_hd_vgaarb, ++ "Enable support for VGA arbitration on Intel HD IGD. (default: false)"); ++ + module_param_named_unsafe(use_mmio_flip, i915.use_mmio_flip, int, 0600); + MODULE_PARM_DESC(use_mmio_flip, + "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); +diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h +index bd5026b..f7c9769 100644 +--- a/drivers/gpu/drm/i915/i915_params.h ++++ b/drivers/gpu/drm/i915/i915_params.h +@@ -56,6 +56,7 @@ struct i915_params { + bool load_detect_test; + bool reset; + bool disable_display; ++ bool enable_hd_vgaarb; + bool enable_guc_submission; + bool verbose_state_checks; + bool nuclear_pageflip; +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7741efb..ddb94bb 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -15252,6 +15252,33 @@ static void i915_disable_vga(struct drm_device *dev) + POSTING_READ(vga_reg); + } + ++static void i915_enable_vga_mem(struct drm_device *dev) ++{ ++ /* Enable VGA memory on Intel HD */ ++ if (i915.enable_hd_vgaarb && HAS_PCH_SPLIT(dev)) { ++ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); ++ outb(inb(VGA_MSR_READ) | VGA_MSR_MEM_EN, VGA_MSR_WRITE); ++ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | ++ VGA_RSRC_LEGACY_MEM | ++ VGA_RSRC_NORMAL_IO | ++ VGA_RSRC_NORMAL_MEM); ++ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); ++ } ++} ++ ++void i915_disable_vga_mem(struct drm_device *dev) ++{ ++ /* Disable VGA memory on Intel HD */ ++ if (i915.enable_hd_vgaarb && HAS_PCH_SPLIT(dev)) { ++ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); ++ outb(inb(VGA_MSR_READ) & ~VGA_MSR_MEM_EN, VGA_MSR_WRITE); ++ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | ++ VGA_RSRC_NORMAL_IO | ++ VGA_RSRC_NORMAL_MEM); ++ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); ++ } ++} ++ + void intel_modeset_init_hw(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -15689,6 +15716,7 @@ void i915_redisable_vga_power_on(struct drm_device *dev) + if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { + DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); + i915_disable_vga(dev); ++ i915_disable_vga_mem(dev); + } + } + +@@ -16074,6 +16102,8 @@ void intel_modeset_cleanup(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_connector *connector; + ++ i915_enable_vga_mem(dev); ++ + intel_disable_gt_powersave(dev); + + intel_backlight_unregister(dev); +diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h +index 3a30b37..7723927 100644 +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -1623,4 +1623,6 @@ void intel_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state); + extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; + ++extern void i915_disable_vga_mem(struct drm_device *dev); ++ + #endif /* __INTEL_DRV_H__ */ +-- +2.8.3 + diff --git a/PKGBUILD b/PKGBUILD index 3f01896..c3eefa9 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -20,7 +20,7 @@ source=("https://www.kernel.org/pub/linux/kernel/v4.x/${_srcname}.tar.xz" 'change-default-console-loglevel.patch' '0001-linux-4.6-rtlwifi-fix-atomic.patch' 'override_for_missing_acs_capabilities.patch' - 'i915_317.patch') + '0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch') sha256sums=('a93771cd5a8ad27798f22e9240538dfea48d3a2bf2a6a6ab415de3f02d25d866' 'SKIP' '0dc509a19c68ab547a62158bf2017965b843854b63be46ae039c37724dccca21' @@ -31,7 +31,7 @@ sha256sums=('a93771cd5a8ad27798f22e9240538dfea48d3a2bf2a6a6ab415de3f02d25d866' '1256b241cd477b265a3c2d64bdc19ffe3c9bbcee82ea3994c590c2c76e767d99' 'ae0d16e81a915fae130125ba9d0b6fd2427e06f50b8b9514abc4029efe61ee98' '975f79348119bfba8dd972a9fbfe6b38484c45bfd228f2f6d48a0c02426ba149' - 'b5a8eebbe75e1801b35d2f5197eba6f57123c224e09e97a7eb526f1fa58ac918') + '6dc172c2ef277223aa59806a2edda7efc4f94d2bf68b6bf2b1d0413e84b9e260') validpgpkeys=( 'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds '647F28654894E3BD457199BE38DBBDC86092693E' # Greg Kroah-Hartman @@ -65,7 +65,7 @@ prepare() { # patches for vga arbiter fix in intel systems echo '==> Applying i915 VGA arbitration patch' - patch -Np1 -i "${srcdir}/i915_317.patch" + patch -p1 -i "${srcdir}/0001-Updated-i915-vga-arbiter-patch-for-4.6.2.patch" # Overrides for missing acs capabilities echo '==> Applying ACS override patch' diff --git a/i915_317.patch b/i915_317.patch deleted file mode 100644 index 249f0b7..0000000 --- a/i915_317.patch +++ /dev/null @@ -1,137 +0,0 @@ -diff -rupN linux-3.17.old/drivers/gpu/drm/i915/i915_dma.c linux-3.17/drivers/gpu/drm/i915/i915_dma.c ---- linux-3.17.old/drivers/gpu/drm/i915/i915_dma.c 2014-10-05 17:23:04.000000000 -0200 -+++ linux-3.17/drivers/gpu/drm/i915/i915_dma.c 2014-10-08 13:25:35.261920170 -0200 -@@ -1316,10 +1316,20 @@ static int i915_load_modeset_init(struct - * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), - * then we do not take part in VGA arbitration and the - * vga_client_register() fails with -ENODEV. -+ * -+ * NB. The set_decode callback here actually only works on GMCH -+ * devices, on newer HD devices we can only disable VGA MMIO space. -+ * Disabling VGA I/O space requires disabling I/O in the PCI command -+ * register. Nonetheless, we like to pretend that we participate in -+ * VGA arbitration and can dynamically disable VGA I/O space because -+ * this makes X happy, even though it's a complete lie. - */ -- ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); -- if (ret && ret != -ENODEV) -- goto out; -+ if (!i915.enable_hd_vgaarb || !HAS_PCH_SPLIT(dev)) { -+ ret = vga_client_register(dev->pdev, dev, NULL, -+ i915_vga_set_decode); -+ if (ret && ret != -ENODEV) -+ goto out; -+ } - - intel_register_dsm_handler(); - -@@ -1369,6 +1379,12 @@ static int i915_load_modeset_init(struct - if (ret) - goto cleanup_gem; - -+ /* -+ * Must do this after fbcon init so that -+ * vgacon_save_screen() works during the handover. -+ */ -+ i915_disable_vga_mem(dev); -+ - /* Only enable hotplug handling once the fbdev is fully set up. */ - intel_hpd_init(dev); - -diff -rupN linux-3.17.old/drivers/gpu/drm/i915/i915_drv.h linux-3.17/drivers/gpu/drm/i915/i915_drv.h ---- linux-3.17.old/drivers/gpu/drm/i915/i915_drv.h 2014-10-05 17:23:04.000000000 -0200 -+++ linux-3.17/drivers/gpu/drm/i915/i915_drv.h 2014-10-08 13:26:45.200867353 -0200 -@@ -2147,6 +2147,7 @@ struct i915_params { - bool reset; - bool disable_display; - bool disable_vtd_wa; -+ bool enable_hd_vgaarb; - bool enable_guc_submission; - int guc_log_level; - }; -diff -rupN linux-3.17.old/drivers/gpu/drm/i915/i915_params.c linux-3.17/drivers/gpu/drm/i915/i915_params.c ---- linux-3.17.old/drivers/gpu/drm/i915/i915_params.c 2014-10-05 17:23:04.000000000 -0200 -+++ linux-3.17/drivers/gpu/drm/i915/i915_params.c 2014-10-08 13:28:08.960803683 -0200 -@@ -48,6 +48,7 @@ struct i915_params i915 __read_mostly = - .disable_display = 0, - .enable_cmd_parser = 1, - .disable_vtd_wa = 0, -+ .enable_hd_vgaarb = false, - .use_mmio_flip = 0, - .mmio_debug = 0, - }; -@@ -159,6 +160,10 @@ module_param_named(enable_cmd_parser, i9 - MODULE_PARM_DESC(enable_cmd_parser, - "Enable command parsing (1=enabled [default], 0=disabled)"); - -+module_param_named(enable_hd_vgaarb, i915.enable_hd_vgaarb, bool, 0444); -+MODULE_PARM_DESC(enable_hd_vgaarb, -+ "Enable support for VGA arbitration on Intel HD IGD. (default: false)"); -+ - module_param_named_unsafe(use_mmio_flip, i915.use_mmio_flip, int, 0600); - MODULE_PARM_DESC(use_mmio_flip, - "use MMIO flips (-1=never, 0=driver discretion [default], 1=always)"); -diff -rupN linux-3.17.old/drivers/gpu/drm/i915/intel_display.c linux-3.17/drivers/gpu/drm/i915/intel_display.c ---- linux-3.17.old/drivers/gpu/drm/i915/intel_display.c 2014-10-05 17:23:04.000000000 -0200 -+++ linux-3.17/drivers/gpu/drm/i915/intel_display.c 2014-10-08 13:25:35.416920053 -0200 -@@ -12554,6 +12554,33 @@ static void i915_disable_vga(struct drm_ - POSTING_READ(vga_reg); - } - -+static void i915_enable_vga_mem(struct drm_device *dev) -+{ -+ /* Enable VGA memory on Intel HD */ -+ if (i915.enable_hd_vgaarb && HAS_PCH_SPLIT(dev)) { -+ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); -+ outb(inb(VGA_MSR_READ) | VGA_MSR_MEM_EN, VGA_MSR_WRITE); -+ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | -+ VGA_RSRC_LEGACY_MEM | -+ VGA_RSRC_NORMAL_IO | -+ VGA_RSRC_NORMAL_MEM); -+ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); -+ } -+} -+ -+void i915_disable_vga_mem(struct drm_device *dev) -+{ -+ /* Disable VGA memory on Intel HD */ -+ if (i915.enable_hd_vgaarb && HAS_PCH_SPLIT(dev)) { -+ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); -+ outb(inb(VGA_MSR_READ) & ~VGA_MSR_MEM_EN, VGA_MSR_WRITE); -+ vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | -+ VGA_RSRC_NORMAL_IO | -+ VGA_RSRC_NORMAL_MEM); -+ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); -+ } -+} -+ - void intel_modeset_init_hw(struct drm_device *dev) - { - intel_prepare_ddi(dev); -@@ -12891,6 +12918,7 @@ void i915_redisable_vga_power_on(struct - if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { - DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); - i915_disable_vga(dev); -+ i915_disable_vga_mem(dev); - } - } - -@@ -13144,6 +13172,8 @@ void intel_modeset_cleanup(struct drm_de - - intel_disable_fbc(dev); - -+ i915_enable_vga_mem(dev); -+ - intel_disable_gt_powersave(dev); - - ironlake_teardown_rc6(dev); -diff -rupN linux-3.17.old/drivers/gpu/drm/i915/intel_drv.h linux-3.17/drivers/gpu/drm/i915/intel_drv.h ---- linux-3.17.old/drivers/gpu/drm/i915/intel_drv.h 2014-10-05 17:23:04.000000000 -0200 -+++ linux-3.17/drivers/gpu/drm/i915/intel_drv.h 2014-10-08 13:25:35.416920053 -0200 -@@ -1102,4 +1102,6 @@ int intel_sprite_get_colorkey(struct drm - /* intel_tv.c */ - void intel_tv_init(struct drm_device *dev); - -+extern void i915_disable_vga_mem(struct drm_device *dev); -+ - #endif /* __INTEL_DRV_H__ */