--- /dev/null
+From 95d6c0857e54b788982746071130d822a795026b Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Wed, 18 Jul 2018 13:38:37 +0200
+Subject: cpufreq: intel_pstate: Register when ACPI PCCH is present
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+commit 95d6c0857e54b788982746071130d822a795026b upstream.
+
+Currently, intel_pstate doesn't register if _PSS is not present on
+HP Proliant systems, because it expects the firmware to take over
+CPU performance scaling in that case. However, if ACPI PCCH is
+present, the firmware expects the kernel to use it for CPU
+performance scaling and the pcc-cpufreq driver is loaded for that.
+
+Unfortunately, the firmware interface used by that driver is not
+scalable for fundamental reasons, so pcc-cpufreq is way suboptimal
+on systems with more than just a few CPUs. In fact, it is better to
+avoid using it at all.
+
+For this reason, modify intel_pstate to look for ACPI PCCH if _PSS
+is not present and register if it is there. Also prevent the
+pcc-cpufreq driver from trying to initialize itself if intel_pstate
+has been registered already.
+
+Fixes: fbbcdc0744da (intel_pstate: skip the driver if ACPI has power mgmt option)
+Reported-by: Andreas Herrmann <aherrmann@suse.com>
+Reviewed-by: Andreas Herrmann <aherrmann@suse.com>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Tested-by: Andreas Herrmann <aherrmann@suse.com>
+Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/cpufreq/intel_pstate.c | 17 ++++++++++++++++-
+ drivers/cpufreq/pcc-cpufreq.c | 4 ++++
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -2179,6 +2179,18 @@ static bool __init intel_pstate_no_acpi_
+ return true;
+ }
+
++static bool __init intel_pstate_no_acpi_pcch(void)
++{
++ acpi_status status;
++ acpi_handle handle;
++
++ status = acpi_get_handle(NULL, "\\_SB", &handle);
++ if (ACPI_FAILURE(status))
++ return true;
++
++ return !acpi_has_method(handle, "PCCH");
++}
++
+ static bool __init intel_pstate_has_acpi_ppc(void)
+ {
+ int i;
+@@ -2238,7 +2250,10 @@ static bool __init intel_pstate_platform
+
+ switch (plat_info[idx].data) {
+ case PSS:
+- return intel_pstate_no_acpi_pss();
++ if (!intel_pstate_no_acpi_pss())
++ return false;
++
++ return intel_pstate_no_acpi_pcch();
+ case PPC:
+ return intel_pstate_has_acpi_ppc() && !force_load;
+ }
+--- a/drivers/cpufreq/pcc-cpufreq.c
++++ b/drivers/cpufreq/pcc-cpufreq.c
+@@ -580,6 +580,10 @@ static int __init pcc_cpufreq_init(void)
+ {
+ int ret;
+
++ /* Skip initialization if another cpufreq driver is there. */
++ if (cpufreq_get_current_driver())
++ return 0;
++
+ if (acpi_disabled)
+ return 0;
+
--- /dev/null
+From ed6b4b5559769c6c5a0fcb3fac8a9e1f4e58c4ae Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
+Date: Mon, 25 Jun 2018 11:07:17 +0200
+Subject: drm/amdgpu: Reserve VM root shared fence slot for command submission (v3)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michel Dänzer <michel.daenzer@amd.com>
+
+commit ed6b4b5559769c6c5a0fcb3fac8a9e1f4e58c4ae upstream.
+
+Without this, there could not be enough slots, which could trigger the
+BUG_ON in reservation_object_add_shared_fence.
+
+v2:
+* Jump to the error label instead of returning directly (Jerry Zhang)
+v3:
+* Reserve slots for command submission after VM updates (Christian König)
+
+Cc: stable@vger.kernel.org
+Bugzilla: https://bugs.freedesktop.org/106418
+Reported-by: mikhail.v.gavrilov@gmail.com
+Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
+Signed-off-by: Junwei Zhang <Jerry.Zhang@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -925,6 +925,10 @@ static int amdgpu_cs_ib_vm_chunk(struct
+ r = amdgpu_bo_vm_update_pte(p);
+ if (r)
+ return r;
++
++ r = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv);
++ if (r)
++ return r;
+ }
+
+ return amdgpu_cs_sync_rings(p);
--- /dev/null
+From 96a85cc517a9ee4ae5e8d7f5a36cba05023784eb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 14 Jun 2018 20:56:25 +0300
+Subject: drm/i915: Fix hotplug irq ack on i965/g4x
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 96a85cc517a9ee4ae5e8d7f5a36cba05023784eb upstream.
+
+Just like with PIPESTAT, the edge triggered IIR on i965/g4x
+also causes problems for hotplug interrupts. To make sure
+we don't get the IIR port interrupt bit stuck low with the
+ISR bit high we must force an edge in ISR. Unfortunately
+we can't borrow the PIPESTAT trick and toggle the enable
+bits in PORT_HOTPLUG_EN as that act itself generates hotplug
+interrupts. Instead we just have to loop until we've cleared
+PORT_HOTPLUG_STAT, or we just give up and WARN.
+
+v2: Don't frob with PORT_HOTPLUG_EN
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20180614175625.1615-1-ville.syrjala@linux.intel.com
+Reviewed-by: Imre Deak <imre.deak@intel.com>
+(cherry picked from commit 0ba7c51a6fd80a89236f6ceb52e63f8a7f62bfd3)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_irq.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1967,10 +1967,38 @@ static void valleyview_pipestat_irq_hand
+
+ static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
+ {
+- u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
++ u32 hotplug_status = 0, hotplug_status_mask;
++ int i;
+
+- if (hotplug_status)
++ if (IS_G4X(dev_priv) ||
++ IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
++ hotplug_status_mask = HOTPLUG_INT_STATUS_G4X |
++ DP_AUX_CHANNEL_MASK_INT_STATUS_G4X;
++ else
++ hotplug_status_mask = HOTPLUG_INT_STATUS_I915;
++
++ /*
++ * We absolutely have to clear all the pending interrupt
++ * bits in PORT_HOTPLUG_STAT. Otherwise the ISR port
++ * interrupt bit won't have an edge, and the i965/g4x
++ * edge triggered IIR will not notice that an interrupt
++ * is still pending. We can't use PORT_HOTPLUG_EN to
++ * guarantee the edge as the act of toggling the enable
++ * bits can itself generate a new hotplug interrupt :(
++ */
++ for (i = 0; i < 10; i++) {
++ u32 tmp = I915_READ(PORT_HOTPLUG_STAT) & hotplug_status_mask;
++
++ if (tmp == 0)
++ return hotplug_status;
++
++ hotplug_status |= tmp;
+ I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
++ }
++
++ WARN_ONCE(1,
++ "PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
++ I915_READ(PORT_HOTPLUG_STAT));
+
+ return hotplug_status;
+ }
--- /dev/null
+From 37afe55b4ae0600deafe7c0e0e658593c4754f1b Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Fri, 13 Jul 2018 13:06:33 -0400
+Subject: drm/nouveau: Avoid looping through fake MST connectors
+
+From: Lyude Paul <lyude@redhat.com>
+
+commit 37afe55b4ae0600deafe7c0e0e658593c4754f1b upstream.
+
+When MST and atomic were introduced to nouveau, another structure that
+could contain a drm_connector embedded within it was introduced; struct
+nv50_mstc. This meant that we no longer would be able to simply loop
+through our connector list and assume that nouveau_connector() would
+return a proper pointer for each connector, since the assertion that
+all connectors coming from nouveau have a full nouveau_connector struct
+became invalid.
+
+Unfortunately, none of the actual code that looped through connectors
+ever got updated, which means that we've been causing invalid memory
+accesses for quite a while now.
+
+An example that was caught by KASAN:
+
+[ 201.038698] ==================================================================
+[ 201.038792] BUG: KASAN: slab-out-of-bounds in nvif_notify_get+0x190/0x1a0 [nouveau]
+[ 201.038797] Read of size 4 at addr ffff88076738c650 by task kworker/0:3/718
+[ 201.038800]
+[ 201.038822] CPU: 0 PID: 718 Comm: kworker/0:3 Tainted: G O 4.18.0-rc4Lyude-Test+ #1
+[ 201.038825] Hardware name: LENOVO 20EQS64N0B/20EQS64N0B, BIOS N1EET78W (1.51 ) 05/18/2018
+[ 201.038882] Workqueue: events nouveau_display_hpd_work [nouveau]
+[ 201.038887] Call Trace:
+[ 201.038894] dump_stack+0xa4/0xfd
+[ 201.038900] print_address_description+0x71/0x239
+[ 201.038929] ? nvif_notify_get+0x190/0x1a0 [nouveau]
+[ 201.038935] kasan_report.cold.6+0x242/0x2fe
+[ 201.038942] __asan_report_load4_noabort+0x19/0x20
+[ 201.038970] nvif_notify_get+0x190/0x1a0 [nouveau]
+[ 201.038998] ? nvif_notify_put+0x1f0/0x1f0 [nouveau]
+[ 201.039003] ? kmsg_dump_rewind_nolock+0xe4/0xe4
+[ 201.039049] nouveau_display_init.cold.12+0x34/0x39 [nouveau]
+[ 201.039089] ? nouveau_user_framebuffer_create+0x120/0x120 [nouveau]
+[ 201.039133] nouveau_display_resume+0x5c0/0x810 [nouveau]
+[ 201.039173] ? nvkm_client_ioctl+0x20/0x20 [nouveau]
+[ 201.039215] nouveau_do_resume+0x19f/0x570 [nouveau]
+[ 201.039256] nouveau_pmops_runtime_resume+0xd8/0x2a0 [nouveau]
+[ 201.039264] pci_pm_runtime_resume+0x130/0x250
+[ 201.039269] ? pci_restore_standard_config+0x70/0x70
+[ 201.039275] __rpm_callback+0x1f2/0x5d0
+[ 201.039279] ? rpm_resume+0x560/0x18a0
+[ 201.039283] ? pci_restore_standard_config+0x70/0x70
+[ 201.039287] ? pci_restore_standard_config+0x70/0x70
+[ 201.039291] ? pci_restore_standard_config+0x70/0x70
+[ 201.039296] rpm_callback+0x175/0x210
+[ 201.039300] ? pci_restore_standard_config+0x70/0x70
+[ 201.039305] rpm_resume+0xcc3/0x18a0
+[ 201.039312] ? rpm_callback+0x210/0x210
+[ 201.039317] ? __pm_runtime_resume+0x9e/0x100
+[ 201.039322] ? kasan_check_write+0x14/0x20
+[ 201.039326] ? do_raw_spin_lock+0xc2/0x1c0
+[ 201.039333] __pm_runtime_resume+0xac/0x100
+[ 201.039374] nouveau_display_hpd_work+0x67/0x1f0 [nouveau]
+[ 201.039380] process_one_work+0x7a0/0x14d0
+[ 201.039388] ? cancel_delayed_work_sync+0x20/0x20
+[ 201.039392] ? lock_acquire+0x113/0x310
+[ 201.039398] ? kasan_check_write+0x14/0x20
+[ 201.039402] ? do_raw_spin_lock+0xc2/0x1c0
+[ 201.039409] worker_thread+0x86/0xb50
+[ 201.039418] kthread+0x2e9/0x3a0
+[ 201.039422] ? process_one_work+0x14d0/0x14d0
+[ 201.039426] ? kthread_create_worker_on_cpu+0xc0/0xc0
+[ 201.039431] ret_from_fork+0x3a/0x50
+[ 201.039441]
+[ 201.039444] Allocated by task 79:
+[ 201.039449] save_stack+0x43/0xd0
+[ 201.039452] kasan_kmalloc+0xc4/0xe0
+[ 201.039456] kmem_cache_alloc_trace+0x10a/0x260
+[ 201.039494] nv50_mstm_add_connector+0x9a/0x340 [nouveau]
+[ 201.039504] drm_dp_add_port+0xff5/0x1fc0 [drm_kms_helper]
+[ 201.039511] drm_dp_send_link_address+0x4a7/0x740 [drm_kms_helper]
+[ 201.039518] drm_dp_check_and_send_link_address+0x1a7/0x210 [drm_kms_helper]
+[ 201.039525] drm_dp_mst_link_probe_work+0x71/0xb0 [drm_kms_helper]
+[ 201.039529] process_one_work+0x7a0/0x14d0
+[ 201.039533] worker_thread+0x86/0xb50
+[ 201.039537] kthread+0x2e9/0x3a0
+[ 201.039541] ret_from_fork+0x3a/0x50
+[ 201.039543]
+[ 201.039546] Freed by task 0:
+[ 201.039549] (stack is not available)
+[ 201.039551]
+[ 201.039555] The buggy address belongs to the object at ffff88076738c1a8
+ which belongs to the cache kmalloc-2048 of size 2048
+[ 201.039559] The buggy address is located 1192 bytes inside of
+ 2048-byte region [ffff88076738c1a8, ffff88076738c9a8)
+[ 201.039563] The buggy address belongs to the page:
+[ 201.039567] page:ffffea001d9ce200 count:1 mapcount:0 mapping:ffff88084000d0c0 index:0x0 compound_mapcount: 0
+[ 201.039573] flags: 0x8000000000008100(slab|head)
+[ 201.039578] raw: 8000000000008100 ffffea001da3be08 ffffea001da25a08 ffff88084000d0c0
+[ 201.039582] raw: 0000000000000000 00000000000d000d 00000001ffffffff 0000000000000000
+[ 201.039585] page dumped because: kasan: bad access detected
+[ 201.039588]
+[ 201.039591] Memory state around the buggy address:
+[ 201.039594] ffff88076738c500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 201.039598] ffff88076738c580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+[ 201.039601] >ffff88076738c600: 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc
+[ 201.039604] ^
+[ 201.039607] ffff88076738c680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 201.039611] ffff88076738c700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+[ 201.039613] ==================================================================
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Cc: stable@vger.kernel.org
+Cc: Karol Herbst <karolherbst@gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +-
+ drivers/gpu/drm/nouveau/nouveau_connector.h | 24 +++++++++++++++++++++++-
+ drivers/gpu/drm/nouveau/nouveau_display.c | 4 ++--
+ 3 files changed, 26 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -1213,7 +1213,7 @@ nouveau_connector_create(struct drm_devi
+ bool dummy;
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+- drm_for_each_connector_iter(connector, &conn_iter) {
++ nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
+ nv_connector = nouveau_connector(connector);
+ if (nv_connector->index == index) {
+ drm_connector_list_iter_end(&conn_iter);
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
+@@ -33,6 +33,7 @@
+ #include <drm/drm_encoder.h>
+ #include <drm/drm_dp_helper.h>
+ #include "nouveau_crtc.h"
++#include "nouveau_encoder.h"
+
+ struct nvkm_i2c_port;
+
+@@ -60,6 +61,27 @@ static inline struct nouveau_connector *
+ return container_of(con, struct nouveau_connector, base);
+ }
+
++static inline bool
++nouveau_connector_is_mst(struct drm_connector *connector)
++{
++ const struct nouveau_encoder *nv_encoder;
++ const struct drm_encoder *encoder;
++
++ if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
++ return false;
++
++ nv_encoder = find_encoder(connector, DCB_OUTPUT_ANY);
++ if (!nv_encoder)
++ return false;
++
++ encoder = &nv_encoder->base.base;
++ return encoder->encoder_type == DRM_MODE_ENCODER_DPMST;
++}
++
++#define nouveau_for_each_non_mst_connector_iter(connector, iter) \
++ drm_for_each_connector_iter(connector, iter) \
++ for_each_if(!nouveau_connector_is_mst(connector))
++
+ static inline struct nouveau_connector *
+ nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
+ {
+@@ -70,7 +92,7 @@ nouveau_crtc_connector_get(struct nouvea
+ struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
+
+ drm_connector_list_iter_begin(dev, &conn_iter);
+- drm_for_each_connector_iter(connector, &conn_iter) {
++ nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
+ if (connector->encoder && connector->encoder->crtc == crtc) {
+ nv_connector = nouveau_connector(connector);
+ break;
+--- a/drivers/gpu/drm/nouveau/nouveau_display.c
++++ b/drivers/gpu/drm/nouveau/nouveau_display.c
+@@ -415,7 +415,7 @@ nouveau_display_init(struct drm_device *
+
+ /* enable hotplug interrupts */
+ drm_connector_list_iter_begin(dev, &conn_iter);
+- drm_for_each_connector_iter(connector, &conn_iter) {
++ nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
+ struct nouveau_connector *conn = nouveau_connector(connector);
+ nvif_notify_get(&conn->hpd);
+ }
+@@ -446,7 +446,7 @@ nouveau_display_fini(struct drm_device *
+
+ /* disable hotplug interrupts */
+ drm_connector_list_iter_begin(dev, &conn_iter);
+- drm_for_each_connector_iter(connector, &conn_iter) {
++ nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
+ struct nouveau_connector *conn = nouveau_connector(connector);
+ nvif_notify_put(&conn->hpd);
+ }
--- /dev/null
+From 68fe23a626b67b56c912c496ea43ed537ea9708f Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Thu, 12 Jul 2018 13:02:54 -0400
+Subject: drm/nouveau: Remove bogus crtc check in pmops_runtime_idle
+
+From: Lyude Paul <lyude@redhat.com>
+
+commit 68fe23a626b67b56c912c496ea43ed537ea9708f upstream.
+
+This both uses the legacy modesetting structures in a racy manner, and
+additionally also doesn't even check the right variable (enabled != the
+CRTC is actually turned on for atomic).
+
+This fixes issues on my P50 regarding the dedicated GPU not entering
+runtime suspend.
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_drm.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
+@@ -866,22 +866,11 @@ nouveau_pmops_runtime_resume(struct devi
+ static int
+ nouveau_pmops_runtime_idle(struct device *dev)
+ {
+- struct pci_dev *pdev = to_pci_dev(dev);
+- struct drm_device *drm_dev = pci_get_drvdata(pdev);
+- struct nouveau_drm *drm = nouveau_drm(drm_dev);
+- struct drm_crtc *crtc;
+-
+ if (!nouveau_pmops_runtime()) {
+ pm_runtime_forbid(dev);
+ return -EBUSY;
+ }
+
+- list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
+- if (crtc->enabled) {
+- DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
+- return -EBUSY;
+- }
+- }
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_autosuspend(dev);
+ /* we don't want the main rpm_idle to call suspend - we want to autosuspend */
--- /dev/null
+From 22b76bbe089cd901f5260ecb9a3dc41f9edb97a0 Mon Sep 17 00:00:00 2001
+From: Lyude Paul <lyude@redhat.com>
+Date: Fri, 13 Jul 2018 13:06:32 -0400
+Subject: drm/nouveau: Use drm_connector_list_iter_* for iterating connectors
+
+From: Lyude Paul <lyude@redhat.com>
+
+commit 22b76bbe089cd901f5260ecb9a3dc41f9edb97a0 upstream.
+
+Every codepath in nouveau that loops through the connector list
+currently does so using the old method, which is prone to race
+conditions from MST connectors being created and destroyed. This has
+been causing a multitude of problems, including memory corruption from
+trying to access connectors that have already been freed!
+
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Cc: stable@vger.kernel.org
+Cc: Karol Herbst <karolherbst@gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 ++++--
+ drivers/gpu/drm/nouveau/nouveau_connector.c | 9 +++++++--
+ drivers/gpu/drm/nouveau/nouveau_connector.h | 14 ++++++++++----
+ drivers/gpu/drm/nouveau/nouveau_display.c | 10 ++++++++--
+ 4 files changed, 29 insertions(+), 10 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
++++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
+@@ -267,6 +267,7 @@ nouveau_backlight_init(struct drm_device
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct nvif_device *device = &drm->client.device;
+ struct drm_connector *connector;
++ struct drm_connector_list_iter conn_iter;
+
+ INIT_LIST_HEAD(&drm->bl_connectors);
+
+@@ -275,7 +276,8 @@ nouveau_backlight_init(struct drm_device
+ return 0;
+ }
+
+- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ drm_connector_list_iter_begin(dev, &conn_iter);
++ drm_for_each_connector_iter(connector, &conn_iter) {
+ if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
+ connector->connector_type != DRM_MODE_CONNECTOR_eDP)
+ continue;
+@@ -292,7 +294,7 @@ nouveau_backlight_init(struct drm_device
+ break;
+ }
+ }
+-
++ drm_connector_list_iter_end(&conn_iter);
+
+ return 0;
+ }
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -1208,14 +1208,19 @@ nouveau_connector_create(struct drm_devi
+ struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_connector *nv_connector = NULL;
+ struct drm_connector *connector;
++ struct drm_connector_list_iter conn_iter;
+ int type, ret = 0;
+ bool dummy;
+
+- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ drm_connector_list_iter_begin(dev, &conn_iter);
++ drm_for_each_connector_iter(connector, &conn_iter) {
+ nv_connector = nouveau_connector(connector);
+- if (nv_connector->index == index)
++ if (nv_connector->index == index) {
++ drm_connector_list_iter_end(&conn_iter);
+ return connector;
++ }
+ }
++ drm_connector_list_iter_end(&conn_iter);
+
+ nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
+ if (!nv_connector)
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
+@@ -65,14 +65,20 @@ nouveau_crtc_connector_get(struct nouvea
+ {
+ struct drm_device *dev = nv_crtc->base.dev;
+ struct drm_connector *connector;
++ struct drm_connector_list_iter conn_iter;
++ struct nouveau_connector *nv_connector = NULL;
+ struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
+
+- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+- if (connector->encoder && connector->encoder->crtc == crtc)
+- return nouveau_connector(connector);
++ drm_connector_list_iter_begin(dev, &conn_iter);
++ drm_for_each_connector_iter(connector, &conn_iter) {
++ if (connector->encoder && connector->encoder->crtc == crtc) {
++ nv_connector = nouveau_connector(connector);
++ break;
++ }
+ }
++ drm_connector_list_iter_end(&conn_iter);
+
+- return NULL;
++ return nv_connector;
+ }
+
+ struct drm_connector *
+--- a/drivers/gpu/drm/nouveau/nouveau_display.c
++++ b/drivers/gpu/drm/nouveau/nouveau_display.c
+@@ -406,6 +406,7 @@ nouveau_display_init(struct drm_device *
+ struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct drm_connector *connector;
++ struct drm_connector_list_iter conn_iter;
+ int ret;
+
+ ret = disp->init(dev);
+@@ -413,10 +414,12 @@ nouveau_display_init(struct drm_device *
+ return ret;
+
+ /* enable hotplug interrupts */
+- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ drm_connector_list_iter_begin(dev, &conn_iter);
++ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct nouveau_connector *conn = nouveau_connector(connector);
+ nvif_notify_get(&conn->hpd);
+ }
++ drm_connector_list_iter_end(&conn_iter);
+
+ /* enable flip completion events */
+ nvif_notify_get(&drm->flip);
+@@ -429,6 +432,7 @@ nouveau_display_fini(struct drm_device *
+ struct nouveau_display *disp = nouveau_display(dev);
+ struct nouveau_drm *drm = nouveau_drm(dev);
+ struct drm_connector *connector;
++ struct drm_connector_list_iter conn_iter;
+
+ if (!suspend) {
+ if (drm_drv_uses_atomic_modeset(dev))
+@@ -441,10 +445,12 @@ nouveau_display_fini(struct drm_device *
+ nvif_notify_put(&drm->flip);
+
+ /* disable hotplug interrupts */
+- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
++ drm_connector_list_iter_begin(dev, &conn_iter);
++ drm_for_each_connector_iter(connector, &conn_iter) {
+ struct nouveau_connector *conn = nouveau_connector(connector);
+ nvif_notify_put(&conn->hpd);
+ }
++ drm_connector_list_iter_end(&conn_iter);
+
+ drm_kms_helper_poll_disable(dev);
+ disp->fini(dev);
--- /dev/null
+From e1f1b1572e8db87a56609fd05bef76f98f0e456a Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Fri, 20 Jul 2018 17:53:45 -0700
+Subject: mm/huge_memory.c: fix data loss when splitting a file pmd
+
+From: Hugh Dickins <hughd@google.com>
+
+commit e1f1b1572e8db87a56609fd05bef76f98f0e456a upstream.
+
+__split_huge_pmd_locked() must check if the cleared huge pmd was dirty,
+and propagate that to PageDirty: otherwise, data may be lost when a huge
+tmpfs page is modified then split then reclaimed.
+
+How has this taken so long to be noticed? Because there was no problem
+when the huge page is written by a write system call (shmem_write_end()
+calls set_page_dirty()), nor when the page is allocated for a write fault
+(fault_dirty_shared_page() calls set_page_dirty()); but when allocated for
+a read fault (which MAP_POPULATE simulates), no set_page_dirty().
+
+Link: http://lkml.kernel.org/r/alpine.LSU.2.11.1807111741430.1106@eggly.anvils
+Fixes: d21b9e57c74c ("thp: handle file pages in split_huge_pmd()")
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Reported-by: Ashwin Chaugule <ashwinch@google.com>
+Reviewed-by: Yang Shi <yang.shi@linux.alibaba.com>
+Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: "Huang, Ying" <ying.huang@intel.com>
+Cc: <stable@vger.kernel.org> [4.8+]
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/huge_memory.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2087,6 +2087,8 @@ static void __split_huge_pmd_locked(stru
+ if (vma_is_dax(vma))
+ return;
+ page = pmd_page(_pmd);
++ if (!PageDirty(page) && pmd_dirty(_pmd))
++ set_page_dirty(page);
+ if (!PageReferenced(page) && pmd_young(_pmd))
+ SetPageReferenced(page);
+ page_remove_rmap(page, true);
--- /dev/null
+From 9f15bde671355c351cf20d9f879004b234353100 Mon Sep 17 00:00:00 2001
+From: Jing Xia <jing.xia.mail@gmail.com>
+Date: Fri, 20 Jul 2018 17:53:48 -0700
+Subject: mm: memcg: fix use after free in mem_cgroup_iter()
+
+From: Jing Xia <jing.xia.mail@gmail.com>
+
+commit 9f15bde671355c351cf20d9f879004b234353100 upstream.
+
+It was reported that a kernel crash happened in mem_cgroup_iter(), which
+can be triggered if the legacy cgroup-v1 non-hierarchical mode is used.
+
+Unable to handle kernel paging request at virtual address 6b6b6b6b6b6b8f
+......
+Call trace:
+ mem_cgroup_iter+0x2e0/0x6d4
+ shrink_zone+0x8c/0x324
+ balance_pgdat+0x450/0x640
+ kswapd+0x130/0x4b8
+ kthread+0xe8/0xfc
+ ret_from_fork+0x10/0x20
+
+ mem_cgroup_iter():
+ ......
+ if (css_tryget(css)) <-- crash here
+ break;
+ ......
+
+The crashing reason is that mem_cgroup_iter() uses the memcg object whose
+pointer is stored in iter->position, which has been freed before and
+filled with POISON_FREE(0x6b).
+
+And the root cause of the use-after-free issue is that
+invalidate_reclaim_iterators() fails to reset the value of iter->position
+to NULL when the css of the memcg is released in non- hierarchical mode.
+
+Link: http://lkml.kernel.org/r/1531994807-25639-1-git-send-email-jing.xia@unisoc.com
+Fixes: 6df38689e0e9 ("mm: memcontrol: fix possible memcg leak due to interrupted reclaim")
+Signed-off-by: Jing Xia <jing.xia.mail@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
+Cc: <chunyan.zhang@unisoc.com>
+Cc: Shakeel Butt <shakeelb@google.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memcontrol.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -850,7 +850,7 @@ static void invalidate_reclaim_iterators
+ int nid;
+ int i;
+
+- while ((memcg = parent_mem_cgroup(memcg))) {
++ for (; memcg; memcg = parent_mem_cgroup(memcg)) {
+ for_each_node(nid) {
+ mz = mem_cgroup_nodeinfo(memcg, nid);
+ for (i = 0; i <= DEF_PRIORITY; i++) {
--- /dev/null
+From b03897cf318dfc47de33a7ecbc7655584266f034 Mon Sep 17 00:00:00 2001
+From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
+Date: Wed, 18 Jul 2018 14:03:16 +0530
+Subject: powerpc/powernv: Fix save/restore of SPRG3 on entry/exit from stop (idle)
+
+From: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
+
+commit b03897cf318dfc47de33a7ecbc7655584266f034 upstream.
+
+On 64-bit servers, SPRN_SPRG3 and its userspace read-only mirror
+SPRN_USPRG3 are used as userspace VDSO write and read registers
+respectively.
+
+SPRN_SPRG3 is lost when we enter stop4 and above, and is currently not
+restored. As a result, any read from SPRN_USPRG3 returns zero on an
+exit from stop4 (Power9 only) and above.
+
+Thus in this situation, on POWER9, any call from sched_getcpu() always
+returns zero, as on powerpc, we call __kernel_getcpu() which relies
+upon SPRN_USPRG3 to report the CPU and NUMA node information.
+
+Fix this by restoring SPRN_SPRG3 on wake up from a deep stop state
+with the sprg_vdso value that is cached in PACA.
+
+Fixes: e1c1cfed5432 ("powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle")
+Cc: stable@vger.kernel.org # v4.14+
+Reported-by: Florian Weimer <fweimer@redhat.com>
+Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
+Reviewed-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/idle_book3s.S | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/powerpc/kernel/idle_book3s.S
++++ b/arch/powerpc/kernel/idle_book3s.S
+@@ -144,7 +144,9 @@ power9_restore_additional_sprs:
+ mtspr SPRN_MMCR1, r4
+
+ ld r3, STOP_MMCR2(r13)
++ ld r4, PACA_SPRG_VDSO(r13)
+ mtspr SPRN_MMCR2, r3
++ mtspr SPRN_SPRG3, r4
+ blr
+
+ /*
--- /dev/null
+From 5292221d6ddfed75e5b46cd42237a677094b99f3 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Tue, 10 Jul 2018 12:56:45 -0500
+Subject: Revert "drm/amd/display: Don't return ddc result and read_bytes in same return value"
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 5292221d6ddfed75e5b46cd42237a677094b99f3 upstream.
+
+This reverts commit 018d82e5f02ef3583411bcaa4e00c69786f46f19.
+
+This breaks DDC in certain cases. Revert for 4.18 and previous kernels.
+For 4.19, this is fixed with the following more extensive patches:
+drm/amd/display: Serialize is_dp_sink_present
+drm/amd/display: Break out function to simply read aux reply
+drm/amd/display: Return aux replies directly to DRM
+drm/amd/display: Right shift AUX reply value sooner than later
+drm/amd/display: Read AUX channel even if only status byte is returned
+
+Link: https://lists.freedesktop.org/archives/amd-gfx/2018-July/023788.html
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 20 ++++--------
+ drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c | 10 +-----
+ drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h | 5 +--
+ 3 files changed, 13 insertions(+), 22 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+@@ -83,22 +83,21 @@ static ssize_t dm_dp_aux_transfer(struct
+ enum i2c_mot_mode mot = (msg->request & DP_AUX_I2C_MOT) ?
+ I2C_MOT_TRUE : I2C_MOT_FALSE;
+ enum ddc_result res;
+- uint32_t read_bytes = msg->size;
++ ssize_t read_bytes;
+
+ if (WARN_ON(msg->size > 16))
+ return -E2BIG;
+
+ switch (msg->request & ~DP_AUX_I2C_MOT) {
+ case DP_AUX_NATIVE_READ:
+- res = dal_ddc_service_read_dpcd_data(
++ read_bytes = dal_ddc_service_read_dpcd_data(
+ TO_DM_AUX(aux)->ddc_service,
+ false,
+ I2C_MOT_UNDEF,
+ msg->address,
+ msg->buffer,
+- msg->size,
+- &read_bytes);
+- break;
++ msg->size);
++ return read_bytes;
+ case DP_AUX_NATIVE_WRITE:
+ res = dal_ddc_service_write_dpcd_data(
+ TO_DM_AUX(aux)->ddc_service,
+@@ -109,15 +108,14 @@ static ssize_t dm_dp_aux_transfer(struct
+ msg->size);
+ break;
+ case DP_AUX_I2C_READ:
+- res = dal_ddc_service_read_dpcd_data(
++ read_bytes = dal_ddc_service_read_dpcd_data(
+ TO_DM_AUX(aux)->ddc_service,
+ true,
+ mot,
+ msg->address,
+ msg->buffer,
+- msg->size,
+- &read_bytes);
+- break;
++ msg->size);
++ return read_bytes;
+ case DP_AUX_I2C_WRITE:
+ res = dal_ddc_service_write_dpcd_data(
+ TO_DM_AUX(aux)->ddc_service,
+@@ -139,9 +137,7 @@ static ssize_t dm_dp_aux_transfer(struct
+ r == DDC_RESULT_SUCESSFULL);
+ #endif
+
+- if (res != DDC_RESULT_SUCESSFULL)
+- return -EIO;
+- return read_bytes;
++ return msg->size;
+ }
+
+ static enum drm_connector_status
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
+@@ -629,14 +629,13 @@ bool dal_ddc_service_query_ddc_data(
+ return ret;
+ }
+
+-enum ddc_result dal_ddc_service_read_dpcd_data(
++ssize_t dal_ddc_service_read_dpcd_data(
+ struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
+ uint32_t address,
+ uint8_t *data,
+- uint32_t len,
+- uint32_t *read)
++ uint32_t len)
+ {
+ struct aux_payload read_payload = {
+ .i2c_over_aux = i2c,
+@@ -653,8 +652,6 @@ enum ddc_result dal_ddc_service_read_dpc
+ .mot = mot
+ };
+
+- *read = 0;
+-
+ if (len > DEFAULT_AUX_MAX_DATA_SIZE) {
+ BREAK_TO_DEBUGGER();
+ return DDC_RESULT_FAILED_INVALID_OPERATION;
+@@ -664,8 +661,7 @@ enum ddc_result dal_ddc_service_read_dpc
+ ddc->ctx->i2caux,
+ ddc->ddc_pin,
+ &command)) {
+- *read = command.payloads->length;
+- return DDC_RESULT_SUCESSFULL;
++ return (ssize_t)command.payloads->length;
+ }
+
+ return DDC_RESULT_FAILED_OPERATION;
+--- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
+@@ -102,14 +102,13 @@ bool dal_ddc_service_query_ddc_data(
+ uint8_t *read_buf,
+ uint32_t read_size);
+
+-enum ddc_result dal_ddc_service_read_dpcd_data(
++ssize_t dal_ddc_service_read_dpcd_data(
+ struct ddc_service *ddc,
+ bool i2c,
+ enum i2c_mot_mode mot,
+ uint32_t address,
+ uint8_t *data,
+- uint32_t len,
+- uint32_t *read);
++ uint32_t len);
+
+ enum ddc_result dal_ddc_service_write_dpcd_data(
+ struct ddc_service *ddc,
arc-fix-config_swap.patch
arc-configs-remove-config_initramfs_source-from-defconfigs.patch
arc-mm-allow-mprotect-to-make-stack-mappings-executable.patch
+mm-memcg-fix-use-after-free-in-mem_cgroup_iter.patch
+mm-huge_memory.c-fix-data-loss-when-splitting-a-file-pmd.patch
+cpufreq-intel_pstate-register-when-acpi-pcch-is-present.patch
+vfio-pci-fix-potential-spectre-v1.patch
+vfio-spapr-use-iommu-pageshift-rather-than-pagesize.patch
+stop_machine-disable-preemption-when-waking-two-stopper-threads.patch
+powerpc-powernv-fix-save-restore-of-sprg3-on-entry-exit-from-stop-idle.patch
+drm-amdgpu-reserve-vm-root-shared-fence-slot-for-command-submission-v3.patch
+drm-i915-fix-hotplug-irq-ack-on-i965-g4x.patch
+revert-drm-amd-display-don-t-return-ddc-result-and-read_bytes-in-same-return-value.patch
+drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch
+drm-nouveau-use-drm_connector_list_iter_-for-iterating-connectors.patch
+drm-nouveau-avoid-looping-through-fake-mst-connectors.patch
--- /dev/null
+From 9fb8d5dc4b649dd190e1af4ead670753e71bf907 Mon Sep 17 00:00:00 2001
+From: "Isaac J. Manjarres" <isaacm@codeaurora.org>
+Date: Tue, 3 Jul 2018 15:02:14 -0700
+Subject: stop_machine: Disable preemption when waking two stopper threads
+
+From: Isaac J. Manjarres <isaacm@codeaurora.org>
+
+commit 9fb8d5dc4b649dd190e1af4ead670753e71bf907 upstream.
+
+When cpu_stop_queue_two_works() begins to wake the stopper threads, it does
+so without preemption disabled, which leads to the following race
+condition:
+
+The source CPU calls cpu_stop_queue_two_works(), with cpu1 as the source
+CPU, and cpu2 as the destination CPU. When adding the stopper threads to
+the wake queue used in this function, the source CPU stopper thread is
+added first, and the destination CPU stopper thread is added last.
+
+When wake_up_q() is invoked to wake the stopper threads, the threads are
+woken up in the order that they are queued in, so the source CPU's stopper
+thread is woken up first, and it preempts the thread running on the source
+CPU.
+
+The stopper thread will then execute on the source CPU, disable preemption,
+and begin executing multi_cpu_stop(), and wait for an ack from the
+destination CPU's stopper thread, with preemption still disabled. Since the
+worker thread that woke up the stopper thread on the source CPU is affine
+to the source CPU, and preemption is disabled on the source CPU, that
+thread will never run to dequeue the destination CPU's stopper thread from
+the wake queue, and thus, the destination CPU's stopper thread will never
+run, causing the source CPU's stopper thread to wait forever, and stall.
+
+Disable preemption when waking the stopper threads in
+cpu_stop_queue_two_works().
+
+Fixes: 0b26351b910f ("stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock")
+Co-Developed-by: Prasad Sodagudi <psodagud@codeaurora.org>
+Signed-off-by: Prasad Sodagudi <psodagud@codeaurora.org>
+Co-Developed-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
+Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
+Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: peterz@infradead.org
+Cc: matt@codeblueprint.co.uk
+Cc: bigeasy@linutronix.de
+Cc: gregkh@linuxfoundation.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/1530655334-4601-1-git-send-email-isaacm@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/stop_machine.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/kernel/stop_machine.c
++++ b/kernel/stop_machine.c
+@@ -270,7 +270,11 @@ unlock:
+ goto retry;
+ }
+
+- wake_up_q(&wakeq);
++ if (!err) {
++ preempt_disable();
++ wake_up_q(&wakeq);
++ preempt_enable();
++ }
+
+ return err;
+ }
--- /dev/null
+From 0e714d27786ce1fb3efa9aac58abc096e68b1c2a Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Tue, 17 Jul 2018 12:39:00 -0500
+Subject: vfio/pci: Fix potential Spectre v1
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit 0e714d27786ce1fb3efa9aac58abc096e68b1c2a upstream.
+
+info.index can be indirectly controlled by user-space, hence leading
+to a potential exploitation of the Spectre variant 1 vulnerability.
+
+This issue was detected with the help of Smatch:
+
+drivers/vfio/pci/vfio_pci.c:734 vfio_pci_ioctl()
+warn: potential spectre issue 'vdev->region'
+
+Fix this by sanitizing info.index before indirectly using it to index
+vdev->region
+
+Notice that given that speculation windows are large, the policy is
+to kill the speculation on the first load and not worry if it can be
+completed with a dependent load/store [1].
+
+[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/vfio/pci/vfio_pci.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -28,6 +28,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/vfio.h>
+ #include <linux/vgaarb.h>
++#include <linux/nospec.h>
+
+ #include "vfio_pci_private.h"
+
+@@ -727,6 +728,9 @@ static long vfio_pci_ioctl(void *device_
+ if (info.index >=
+ VFIO_PCI_NUM_REGIONS + vdev->num_regions)
+ return -EINVAL;
++ info.index = array_index_nospec(info.index,
++ VFIO_PCI_NUM_REGIONS +
++ vdev->num_regions);
+
+ i = info.index - VFIO_PCI_NUM_REGIONS;
+
--- /dev/null
+From 1463edca6734d42ab4406fa2896e20b45478ea36 Mon Sep 17 00:00:00 2001
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+Date: Tue, 17 Jul 2018 17:19:12 +1000
+Subject: vfio/spapr: Use IOMMU pageshift rather than pagesize
+
+From: Alexey Kardashevskiy <aik@ozlabs.ru>
+
+commit 1463edca6734d42ab4406fa2896e20b45478ea36 upstream.
+
+The size is always equal to 1 page so let's use this. Later on this will
+be used for other checks which use page shifts to check the granularity
+of access.
+
+This should cause no behavioral change.
+
+Cc: stable@vger.kernel.org # v4.12+
+Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
+Acked-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/vfio/vfio_iommu_spapr_tce.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/vfio/vfio_iommu_spapr_tce.c
++++ b/drivers/vfio/vfio_iommu_spapr_tce.c
+@@ -457,13 +457,13 @@ static void tce_iommu_unuse_page(struct
+ }
+
+ static int tce_iommu_prereg_ua_to_hpa(struct tce_container *container,
+- unsigned long tce, unsigned long size,
++ unsigned long tce, unsigned long shift,
+ unsigned long *phpa, struct mm_iommu_table_group_mem_t **pmem)
+ {
+ long ret = 0;
+ struct mm_iommu_table_group_mem_t *mem;
+
+- mem = mm_iommu_lookup(container->mm, tce, size);
++ mem = mm_iommu_lookup(container->mm, tce, 1ULL << shift);
+ if (!mem)
+ return -EINVAL;
+
+@@ -487,7 +487,7 @@ static void tce_iommu_unuse_page_v2(stru
+ if (!pua)
+ return;
+
+- ret = tce_iommu_prereg_ua_to_hpa(container, *pua, IOMMU_PAGE_SIZE(tbl),
++ ret = tce_iommu_prereg_ua_to_hpa(container, *pua, tbl->it_page_shift,
+ &hpa, &mem);
+ if (ret)
+ pr_debug("%s: tce %lx at #%lx was not cached, ret=%d\n",
+@@ -611,7 +611,7 @@ static long tce_iommu_build_v2(struct tc
+ entry + i);
+
+ ret = tce_iommu_prereg_ua_to_hpa(container,
+- tce, IOMMU_PAGE_SIZE(tbl), &hpa, &mem);
++ tce, tbl->it_page_shift, &hpa, &mem);
+ if (ret)
+ break;
+