From: Greg Kroah-Hartman Date: Sun, 22 Jul 2018 17:28:33 +0000 (+0200) Subject: 4.17-stable patches X-Git-Tag: v4.4.144~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8b2b8c882a153d61a345c473b983cfcb2c00d1fe;p=thirdparty%2Fkernel%2Fstable-queue.git 4.17-stable patches added patches: cpufreq-intel_pstate-register-when-acpi-pcch-is-present.patch drm-amdgpu-reserve-vm-root-shared-fence-slot-for-command-submission-v3.patch drm-i915-fix-hotplug-irq-ack-on-i965-g4x.patch drm-nouveau-avoid-looping-through-fake-mst-connectors.patch drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch drm-nouveau-use-drm_connector_list_iter_-for-iterating-connectors.patch mm-huge_memory.c-fix-data-loss-when-splitting-a-file-pmd.patch mm-memcg-fix-use-after-free-in-mem_cgroup_iter.patch powerpc-powernv-fix-save-restore-of-sprg3-on-entry-exit-from-stop-idle.patch revert-drm-amd-display-don-t-return-ddc-result-and-read_bytes-in-same-return-value.patch stop_machine-disable-preemption-when-waking-two-stopper-threads.patch vfio-pci-fix-potential-spectre-v1.patch vfio-spapr-use-iommu-pageshift-rather-than-pagesize.patch --- diff --git a/queue-4.17/cpufreq-intel_pstate-register-when-acpi-pcch-is-present.patch b/queue-4.17/cpufreq-intel_pstate-register-when-acpi-pcch-is-present.patch new file mode 100644 index 00000000000..907497d772f --- /dev/null +++ b/queue-4.17/cpufreq-intel_pstate-register-when-acpi-pcch-is-present.patch @@ -0,0 +1,85 @@ +From 95d6c0857e54b788982746071130d822a795026b Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 18 Jul 2018 13:38:37 +0200 +Subject: cpufreq: intel_pstate: Register when ACPI PCCH is present + +From: Rafael J. Wysocki + +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 +Reviewed-by: Andreas Herrmann +Acked-by: Srinivas Pandruvada +Tested-by: Andreas Herrmann +Cc: 4.16+ # 4.16+ +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + diff --git a/queue-4.17/drm-amdgpu-reserve-vm-root-shared-fence-slot-for-command-submission-v3.patch b/queue-4.17/drm-amdgpu-reserve-vm-root-shared-fence-slot-for-command-submission-v3.patch new file mode 100644 index 00000000000..379a6e49b65 --- /dev/null +++ b/queue-4.17/drm-amdgpu-reserve-vm-root-shared-fence-slot-for-command-submission-v3.patch @@ -0,0 +1,46 @@ +From ed6b4b5559769c6c5a0fcb3fac8a9e1f4e58c4ae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +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 + +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 +Signed-off-by: Junwei Zhang +Reviewed-by: Christian König +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.17/drm-i915-fix-hotplug-irq-ack-on-i965-g4x.patch b/queue-4.17/drm-i915-fix-hotplug-irq-ack-on-i965-g4x.patch new file mode 100644 index 00000000000..b5ca322906d --- /dev/null +++ b/queue-4.17/drm-i915-fix-hotplug-irq-ack-on-i965-g4x.patch @@ -0,0 +1,78 @@ +From 96a85cc517a9ee4ae5e8d7f5a36cba05023784eb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +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ä + +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ä +Link: https://patchwork.freedesktop.org/patch/msgid/20180614175625.1615-1-ville.syrjala@linux.intel.com +Reviewed-by: Imre Deak +(cherry picked from commit 0ba7c51a6fd80a89236f6ceb52e63f8a7f62bfd3) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-4.17/drm-nouveau-avoid-looping-through-fake-mst-connectors.patch b/queue-4.17/drm-nouveau-avoid-looping-through-fake-mst-connectors.patch new file mode 100644 index 00000000000..ff81c9a222d --- /dev/null +++ b/queue-4.17/drm-nouveau-avoid-looping-through-fake-mst-connectors.patch @@ -0,0 +1,199 @@ +From 37afe55b4ae0600deafe7c0e0e658593c4754f1b Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Fri, 13 Jul 2018 13:06:33 -0400 +Subject: drm/nouveau: Avoid looping through fake MST connectors + +From: Lyude Paul + +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 +Cc: stable@vger.kernel.org +Cc: Karol Herbst +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #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); + } diff --git a/queue-4.17/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch b/queue-4.17/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch new file mode 100644 index 00000000000..47398d28241 --- /dev/null +++ b/queue-4.17/drm-nouveau-remove-bogus-crtc-check-in-pmops_runtime_idle.patch @@ -0,0 +1,51 @@ +From 68fe23a626b67b56c912c496ea43ed537ea9708f Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Thu, 12 Jul 2018 13:02:54 -0400 +Subject: drm/nouveau: Remove bogus crtc check in pmops_runtime_idle + +From: Lyude Paul + +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 +Cc: stable@vger.kernel.org +Reviewed-by: Daniel Vetter +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-4.17/drm-nouveau-use-drm_connector_list_iter_-for-iterating-connectors.patch b/queue-4.17/drm-nouveau-use-drm_connector_list_iter_-for-iterating-connectors.patch new file mode 100644 index 00000000000..a644572f1b4 --- /dev/null +++ b/queue-4.17/drm-nouveau-use-drm_connector_list_iter_-for-iterating-connectors.patch @@ -0,0 +1,154 @@ +From 22b76bbe089cd901f5260ecb9a3dc41f9edb97a0 Mon Sep 17 00:00:00 2001 +From: Lyude Paul +Date: Fri, 13 Jul 2018 13:06:32 -0400 +Subject: drm/nouveau: Use drm_connector_list_iter_* for iterating connectors + +From: Lyude Paul + +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 +Cc: stable@vger.kernel.org +Cc: Karol Herbst +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.17/mm-huge_memory.c-fix-data-loss-when-splitting-a-file-pmd.patch b/queue-4.17/mm-huge_memory.c-fix-data-loss-when-splitting-a-file-pmd.patch new file mode 100644 index 00000000000..e0715a05464 --- /dev/null +++ b/queue-4.17/mm-huge_memory.c-fix-data-loss-when-splitting-a-file-pmd.patch @@ -0,0 +1,46 @@ +From e1f1b1572e8db87a56609fd05bef76f98f0e456a Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +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 + +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 +Reported-by: Ashwin Chaugule +Reviewed-by: Yang Shi +Reviewed-by: Kirill A. Shutemov +Cc: "Huang, Ying" +Cc: [4.8+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.17/mm-memcg-fix-use-after-free-in-mem_cgroup_iter.patch b/queue-4.17/mm-memcg-fix-use-after-free-in-mem_cgroup_iter.patch new file mode 100644 index 00000000000..860affa2657 --- /dev/null +++ b/queue-4.17/mm-memcg-fix-use-after-free-in-mem_cgroup_iter.patch @@ -0,0 +1,64 @@ +From 9f15bde671355c351cf20d9f879004b234353100 Mon Sep 17 00:00:00 2001 +From: Jing Xia +Date: Fri, 20 Jul 2018 17:53:48 -0700 +Subject: mm: memcg: fix use after free in mem_cgroup_iter() + +From: Jing Xia + +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 +Acked-by: Michal Hocko +Cc: Johannes Weiner +Cc: Vladimir Davydov +Cc: +Cc: Shakeel Butt +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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++) { diff --git a/queue-4.17/powerpc-powernv-fix-save-restore-of-sprg3-on-entry-exit-from-stop-idle.patch b/queue-4.17/powerpc-powernv-fix-save-restore-of-sprg3-on-entry-exit-from-stop-idle.patch new file mode 100644 index 00000000000..fa170b18c5f --- /dev/null +++ b/queue-4.17/powerpc-powernv-fix-save-restore-of-sprg3-on-entry-exit-from-stop-idle.patch @@ -0,0 +1,48 @@ +From b03897cf318dfc47de33a7ecbc7655584266f034 Mon Sep 17 00:00:00 2001 +From: "Gautham R. Shenoy" +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 + +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 +Signed-off-by: Gautham R. Shenoy +Reviewed-by: Michael Ellerman +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + + /* diff --git a/queue-4.17/revert-drm-amd-display-don-t-return-ddc-result-and-read_bytes-in-same-return-value.patch b/queue-4.17/revert-drm-amd-display-don-t-return-ddc-result-and-read_bytes-in-same-return-value.patch new file mode 100644 index 00000000000..9b8f567a786 --- /dev/null +++ b/queue-4.17/revert-drm-amd-display-don-t-return-ddc-result-and-read_bytes-in-same-return-value.patch @@ -0,0 +1,147 @@ +From 5292221d6ddfed75e5b46cd42237a677094b99f3 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +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 + +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 +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-4.17/series b/queue-4.17/series index cd8eb3793df..7122b5ec6c2 100644 --- a/queue-4.17/series +++ b/queue-4.17/series @@ -19,3 +19,16 @@ arcv2-save-accl-reg-pair-by-default.patch 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 diff --git a/queue-4.17/stop_machine-disable-preemption-when-waking-two-stopper-threads.patch b/queue-4.17/stop_machine-disable-preemption-when-waking-two-stopper-threads.patch new file mode 100644 index 00000000000..d6db9db8b6f --- /dev/null +++ b/queue-4.17/stop_machine-disable-preemption-when-waking-two-stopper-threads.patch @@ -0,0 +1,69 @@ +From 9fb8d5dc4b649dd190e1af4ead670753e71bf907 Mon Sep 17 00:00:00 2001 +From: "Isaac J. Manjarres" +Date: Tue, 3 Jul 2018 15:02:14 -0700 +Subject: stop_machine: Disable preemption when waking two stopper threads + +From: Isaac J. Manjarres + +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 +Signed-off-by: Prasad Sodagudi +Co-Developed-by: Pavankumar Kondeti +Signed-off-by: Pavankumar Kondeti +Signed-off-by: Isaac J. Manjarres +Signed-off-by: Thomas Gleixner +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 + +--- + 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; + } diff --git a/queue-4.17/vfio-pci-fix-potential-spectre-v1.patch b/queue-4.17/vfio-pci-fix-potential-spectre-v1.patch new file mode 100644 index 00000000000..06f594d3afc --- /dev/null +++ b/queue-4.17/vfio-pci-fix-potential-spectre-v1.patch @@ -0,0 +1,55 @@ +From 0e714d27786ce1fb3efa9aac58abc096e68b1c2a Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Tue, 17 Jul 2018 12:39:00 -0500 +Subject: vfio/pci: Fix potential Spectre v1 + +From: Gustavo A. R. Silva + +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 +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #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; + diff --git a/queue-4.17/vfio-spapr-use-iommu-pageshift-rather-than-pagesize.patch b/queue-4.17/vfio-spapr-use-iommu-pageshift-rather-than-pagesize.patch new file mode 100644 index 00000000000..43a1db99b74 --- /dev/null +++ b/queue-4.17/vfio-spapr-use-iommu-pageshift-rather-than-pagesize.patch @@ -0,0 +1,62 @@ +From 1463edca6734d42ab4406fa2896e20b45478ea36 Mon Sep 17 00:00:00 2001 +From: Alexey Kardashevskiy +Date: Tue, 17 Jul 2018 17:19:12 +1000 +Subject: vfio/spapr: Use IOMMU pageshift rather than pagesize + +From: Alexey Kardashevskiy + +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 +Acked-by: Alex Williamson +Signed-off-by: Alexey Kardashevskiy +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + 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; +