Updated i915 vga arbiter patch

This commit is contained in:
Dan Ziemba 2016-06-13 18:43:18 -04:00
parent d84146369b
commit 2007cc46f0
4 changed files with 202 additions and 143 deletions

View File

@ -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

View File

@ -0,0 +1,196 @@
From 44d8022a2ff1e71bffba431877949ecf827ea9f2 Mon Sep 17 00:00:00 2001
From: Dan Ziemba <zman0900@gmail.com>
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 <alex.williamson@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@redhat.com>
---
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

View File

@ -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'

View File

@ -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__ */