From: Greg Kroah-Hartman Date: Mon, 22 May 2017 17:03:55 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v3.18.55~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=42c8150898e3c279f5052b9953596fd18d179441;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: cdc-acm-fix-possible-invalid-access-when-processing-notification.patch drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch drm-amdgpu-make-display-watermark-calculations-more-accurate.patch drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch iio-dac-ad7303-fix-channel-description.patch of-fdt-add-missing-allocation-failure-check.patch of-fix-sparse-warning-in-of_pci_range_parser_one.patch ohci-pci-add-qemu-quirk.patch proc-fix-unbalanced-hard-link-numbers.patch --- diff --git a/queue-4.4/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch b/queue-4.4/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch new file mode 100644 index 00000000000..219bcd95063 --- /dev/null +++ b/queue-4.4/cdc-acm-fix-possible-invalid-access-when-processing-notification.patch @@ -0,0 +1,52 @@ +From 1bb9914e1730417d530de9ed37e59efdc647146b Mon Sep 17 00:00:00 2001 +From: Tobias Herzog +Date: Thu, 30 Mar 2017 22:15:10 +0200 +Subject: cdc-acm: fix possible invalid access when processing notification + +From: Tobias Herzog + +commit 1bb9914e1730417d530de9ed37e59efdc647146b upstream. + +Notifications may only be 8 bytes long. Accessing the 9th and +10th byte of unimplemented/unknown notifications may be insecure. +Also check the length of known notifications before accessing anything +behind the 8th byte. + +Signed-off-by: Tobias Herzog +Acked-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -311,6 +311,12 @@ static void acm_ctrl_irq(struct urb *urb + break; + + case USB_CDC_NOTIFY_SERIAL_STATE: ++ if (le16_to_cpu(dr->wLength) != 2) { ++ dev_dbg(&acm->control->dev, ++ "%s - malformed serial state\n", __func__); ++ break; ++ } ++ + newctrl = get_unaligned_le16(data); + + if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) { +@@ -347,11 +353,10 @@ static void acm_ctrl_irq(struct urb *urb + + default: + dev_dbg(&acm->control->dev, +- "%s - unknown notification %d received: index %d " +- "len %d data0 %d data1 %d\n", ++ "%s - unknown notification %d received: index %d len %d\n", + __func__, +- dr->bNotificationType, dr->wIndex, +- dr->wLength, data[0], data[1]); ++ dr->bNotificationType, dr->wIndex, dr->wLength); ++ + break; + } + exit: diff --git a/queue-4.4/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch b/queue-4.4/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch new file mode 100644 index 00000000000..27b078faa8d --- /dev/null +++ b/queue-4.4/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch @@ -0,0 +1,120 @@ +From e190ed1ea7458e446230de4113cc5d53b8dc4ec8 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Wed, 29 Mar 2017 22:09:12 +0200 +Subject: drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations. + +From: Mario Kleiner + +commit e190ed1ea7458e446230de4113cc5d53b8dc4ec8 upstream. + +At dot clocks > approx. 250 Mhz, some of these calcs will overflow and +cause miscalculation of latency watermarks, and for some overflows also +divide-by-zero driver crash ("divide error: 0000 [#1] PREEMPT SMP" in +"dce_v10_0_latency_watermark+0x12d/0x190"). + +This zero-divide happened, e.g., on AMD Tonga Pro under DCE-10, +on a Displayport panel when trying to set a video mode of 2560x1440 +at 165 Hz vrefresh with a dot clock of 635.540 Mhz. + +Refine calculations to avoid the overflows. + +Tested for DCE-10 with R9 380 Tonga + ASUS ROG PG279 panel. + +Reviewed-by: Alex Deucher +Signed-off-by: Mario Kleiner +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 19 +++---------------- + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 19 +++---------------- + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 19 +++---------------- + 3 files changed, 9 insertions(+), 48 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +@@ -1126,23 +1126,10 @@ static u32 dce_v10_0_latency_watermark(s + a.full = dfixed_const(available_bandwidth); + b.full = dfixed_const(wm->num_heads); + a.full = dfixed_div(a, b); ++ tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512); ++ tmp = min(dfixed_trunc(a), tmp); + +- b.full = dfixed_const(mc_latency + 512); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(b, c); +- +- c.full = dfixed_const(dmif_size); +- b.full = dfixed_div(c, b); +- +- tmp = min(dfixed_trunc(a), dfixed_trunc(b)); +- +- b.full = dfixed_const(1000); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(c, b); +- c.full = dfixed_const(wm->bytes_per_pixel); +- b.full = dfixed_mul(b, c); +- +- lb_fill_bw = min(tmp, dfixed_trunc(b)); ++ lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000); + + a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); + b.full = dfixed_const(1000); +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -1114,23 +1114,10 @@ static u32 dce_v11_0_latency_watermark(s + a.full = dfixed_const(available_bandwidth); + b.full = dfixed_const(wm->num_heads); + a.full = dfixed_div(a, b); ++ tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512); ++ tmp = min(dfixed_trunc(a), tmp); + +- b.full = dfixed_const(mc_latency + 512); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(b, c); +- +- c.full = dfixed_const(dmif_size); +- b.full = dfixed_div(c, b); +- +- tmp = min(dfixed_trunc(a), dfixed_trunc(b)); +- +- b.full = dfixed_const(1000); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(c, b); +- c.full = dfixed_const(wm->bytes_per_pixel); +- b.full = dfixed_mul(b, c); +- +- lb_fill_bw = min(tmp, dfixed_trunc(b)); ++ lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000); + + a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); + b.full = dfixed_const(1000); +--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +@@ -1096,23 +1096,10 @@ static u32 dce_v8_0_latency_watermark(st + a.full = dfixed_const(available_bandwidth); + b.full = dfixed_const(wm->num_heads); + a.full = dfixed_div(a, b); ++ tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512); ++ tmp = min(dfixed_trunc(a), tmp); + +- b.full = dfixed_const(mc_latency + 512); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(b, c); +- +- c.full = dfixed_const(dmif_size); +- b.full = dfixed_div(c, b); +- +- tmp = min(dfixed_trunc(a), dfixed_trunc(b)); +- +- b.full = dfixed_const(1000); +- c.full = dfixed_const(wm->disp_clk); +- b.full = dfixed_div(c, b); +- c.full = dfixed_const(wm->bytes_per_pixel); +- b.full = dfixed_mul(b, c); +- +- lb_fill_bw = min(tmp, dfixed_trunc(b)); ++ lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000); + + a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); + b.full = dfixed_const(1000); diff --git a/queue-4.4/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch b/queue-4.4/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch new file mode 100644 index 00000000000..406748ddfe5 --- /dev/null +++ b/queue-4.4/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch @@ -0,0 +1,141 @@ +From d63c277dc672e0c568481af043359420fa9d4736 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Wed, 29 Mar 2017 22:09:11 +0200 +Subject: drm/amdgpu: Make display watermark calculations more accurate + +From: Mario Kleiner + +commit d63c277dc672e0c568481af043359420fa9d4736 upstream. + +Avoid big roundoff errors in scanline/hactive durations for +high pixel clocks, especially for >= 500 Mhz, and thereby +program more accurate display fifo watermarks. + +Implemented here for DCE 6,8,10,11. +Successfully tested on DCE 10 with AMD R9 380 Tonga. + +Reviewed-by: Alex Deucher +Signed-off-by: Mario Kleiner +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 10 +++++----- + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 10 +++++----- + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 10 +++++----- + 3 files changed, 15 insertions(+), 15 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +@@ -1237,14 +1237,14 @@ static void dce_v10_0_program_watermarks + { + struct drm_display_mode *mode = &amdgpu_crtc->base.mode; + struct dce10_wm_params wm_low, wm_high; +- u32 pixel_period; ++ u32 active_time; + u32 line_time = 0; + u32 latency_watermark_a = 0, latency_watermark_b = 0; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; + + if (amdgpu_crtc->base.enabled && num_heads && mode) { +- pixel_period = 1000000 / (u32)mode->clock; +- line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); ++ active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; ++ line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + + /* watermark for high clocks */ + if (adev->pm.dpm_enabled) { +@@ -1259,7 +1259,7 @@ static void dce_v10_0_program_watermarks + + wm_high.disp_clk = mode->clock; + wm_high.src_width = mode->crtc_hdisplay; +- wm_high.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_high.active_time = active_time; + wm_high.blank_time = line_time - wm_high.active_time; + wm_high.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) +@@ -1298,7 +1298,7 @@ static void dce_v10_0_program_watermarks + + wm_low.disp_clk = mode->clock; + wm_low.src_width = mode->crtc_hdisplay; +- wm_low.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_low.active_time = active_time; + wm_low.blank_time = line_time - wm_low.active_time; + wm_low.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) +--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +@@ -1225,14 +1225,14 @@ static void dce_v11_0_program_watermarks + { + struct drm_display_mode *mode = &amdgpu_crtc->base.mode; + struct dce10_wm_params wm_low, wm_high; +- u32 pixel_period; ++ u32 active_time; + u32 line_time = 0; + u32 latency_watermark_a = 0, latency_watermark_b = 0; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; + + if (amdgpu_crtc->base.enabled && num_heads && mode) { +- pixel_period = 1000000 / (u32)mode->clock; +- line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); ++ active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; ++ line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + + /* watermark for high clocks */ + if (adev->pm.dpm_enabled) { +@@ -1247,7 +1247,7 @@ static void dce_v11_0_program_watermarks + + wm_high.disp_clk = mode->clock; + wm_high.src_width = mode->crtc_hdisplay; +- wm_high.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_high.active_time = active_time; + wm_high.blank_time = line_time - wm_high.active_time; + wm_high.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) +@@ -1286,7 +1286,7 @@ static void dce_v11_0_program_watermarks + + wm_low.disp_clk = mode->clock; + wm_low.src_width = mode->crtc_hdisplay; +- wm_low.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_low.active_time = active_time; + wm_low.blank_time = line_time - wm_low.active_time; + wm_low.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) +--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +@@ -1207,14 +1207,14 @@ static void dce_v8_0_program_watermarks( + { + struct drm_display_mode *mode = &amdgpu_crtc->base.mode; + struct dce8_wm_params wm_low, wm_high; +- u32 pixel_period; ++ u32 active_time; + u32 line_time = 0; + u32 latency_watermark_a = 0, latency_watermark_b = 0; + u32 tmp, wm_mask, lb_vblank_lead_lines = 0; + + if (amdgpu_crtc->base.enabled && num_heads && mode) { +- pixel_period = 1000000 / (u32)mode->clock; +- line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535); ++ active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; ++ line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + + /* watermark for high clocks */ + if (adev->pm.dpm_enabled) { +@@ -1229,7 +1229,7 @@ static void dce_v8_0_program_watermarks( + + wm_high.disp_clk = mode->clock; + wm_high.src_width = mode->crtc_hdisplay; +- wm_high.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_high.active_time = active_time; + wm_high.blank_time = line_time - wm_high.active_time; + wm_high.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) +@@ -1268,7 +1268,7 @@ static void dce_v8_0_program_watermarks( + + wm_low.disp_clk = mode->clock; + wm_low.src_width = mode->crtc_hdisplay; +- wm_low.active_time = mode->crtc_hdisplay * pixel_period; ++ wm_low.active_time = active_time; + wm_low.blank_time = line_time - wm_low.active_time; + wm_low.interlaced = false; + if (mode->flags & DRM_MODE_FLAG_INTERLACE) diff --git a/queue-4.4/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch b/queue-4.4/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch new file mode 100644 index 00000000000..50f3534bd66 --- /dev/null +++ b/queue-4.4/drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch @@ -0,0 +1,40 @@ +From ac799acaa4d8db4f7dcd968b15c9596c80a4677f Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +Date: Sat, 18 Mar 2017 16:23:10 -0400 +Subject: drm/nouveau/mmu/nv4a: use nv04 mmu rather than the nv44 one + +From: Ilia Mirkin + +commit ac799acaa4d8db4f7dcd968b15c9596c80a4677f upstream. + +The NV4A (aka NV44A) is an oddity in the family. It only comes in AGP +and PCI varieties, rather than a core PCIE chip with a bridge for +AGP/PCI as necessary. As a result, it appears that the MMU is also +non-functional. For AGP cards, the vast majority of the NV4A lineup, +this worked out since we force AGP cards to use the nv04 mmu. However +for PCI variants, this did not work. + +Switching to the NV04 MMU makes it work like a charm. Thanks to mwk for +the suggestion. This should be a no-op for NV4A AGP boards, as they were +using it already. + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70388 +Signed-off-by: Ilia Mirkin +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -584,7 +584,7 @@ nv44_chipset = { + .i2c = nv04_i2c_new, + .imem = nv40_instmem_new, + .mc = nv44_mc_new, +- .mmu = nv44_mmu_new, ++ .mmu = nv04_mmu_new, + .pci = nv40_pci_new, + .therm = nv40_therm_new, + .timer = nv41_timer_new, diff --git a/queue-4.4/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch b/queue-4.4/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch new file mode 100644 index 00000000000..dac1d3abd5e --- /dev/null +++ b/queue-4.4/drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch @@ -0,0 +1,66 @@ +From e4311ee51d1e2676001b2d8fcefd92bdd79aad85 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 17:33:39 +1000 +Subject: drm/nouveau/therm: remove ineffective workarounds for alarm bugs + +From: Ben Skeggs + +commit e4311ee51d1e2676001b2d8fcefd92bdd79aad85 upstream. + +These were ineffective due to touching the list without the alarm lock, +but should no longer be required. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c | 2 +- + drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c | 2 +- + drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c | 2 +- + drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c +@@ -130,7 +130,7 @@ nvkm_therm_update(struct nvkm_therm *the + poll = false; + } + +- if (list_empty(&therm->alarm.head) && poll) ++ if (poll) + nvkm_timer_alarm(tmr, 1000000000ULL, &therm->alarm); + spin_unlock_irqrestore(&therm->lock, flags); + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fan.c +@@ -83,7 +83,7 @@ nvkm_fan_update(struct nvkm_fan *fan, bo + spin_unlock_irqrestore(&fan->lock, flags); + + /* schedule next fan update, if not at target speed already */ +- if (list_empty(&fan->alarm.head) && target != duty) { ++ if (target != duty) { + u16 bump_period = fan->bios.bump_period; + u16 slow_down_period = fan->bios.slow_down_period; + u64 delay; +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c +@@ -53,7 +53,7 @@ nvkm_fantog_update(struct nvkm_fantog *f + duty = !nvkm_gpio_get(gpio, 0, DCB_GPIO_FAN, 0xff); + nvkm_gpio_set(gpio, 0, DCB_GPIO_FAN, 0xff, duty); + +- if (list_empty(&fan->alarm.head) && percent != (duty * 100)) { ++ if (percent != (duty * 100)) { + u64 next_change = (percent * fan->period_us) / 100; + if (!duty) + next_change = fan->period_us - next_change; +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c +@@ -185,7 +185,7 @@ alarm_timer_callback(struct nvkm_alarm * + spin_unlock_irqrestore(&therm->sensor.alarm_program_lock, flags); + + /* schedule the next poll in one second */ +- if (therm->func->temp_get(therm) >= 0 && list_empty(&alarm->head)) ++ if (therm->func->temp_get(therm) >= 0) + nvkm_timer_alarm(tmr, 1000000000ULL, alarm); + } + diff --git a/queue-4.4/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch b/queue-4.4/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch new file mode 100644 index 00000000000..9de8848baa9 --- /dev/null +++ b/queue-4.4/drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch @@ -0,0 +1,31 @@ +From 3733bd8b407211739e72d051e5f30ad82a52c4bc Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 16:53:42 +1000 +Subject: drm/nouveau/tmr: ack interrupt before processing alarms + +From: Ben Skeggs + +commit 3733bd8b407211739e72d051e5f30ad82a52c4bc upstream. + +Fixes a race where we can miss an alarm that triggers while we're already +processing previous alarms. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/nv04.c +@@ -76,8 +76,8 @@ nv04_timer_intr(struct nvkm_timer *tmr) + u32 stat = nvkm_rd32(device, NV04_PTIMER_INTR_0); + + if (stat & 0x00000001) { +- nvkm_timer_alarm_trigger(tmr); + nvkm_wr32(device, NV04_PTIMER_INTR_0, 0x00000001); ++ nvkm_timer_alarm_trigger(tmr); + stat &= ~0x00000001; + } + diff --git a/queue-4.4/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch b/queue-4.4/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch new file mode 100644 index 00000000000..ba5c6e0300a --- /dev/null +++ b/queue-4.4/drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch @@ -0,0 +1,50 @@ +From 330bdf62fe6a6c5b99a647f7bf7157107c9348b3 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 17:13:29 +1000 +Subject: drm/nouveau/tmr: avoid processing completed alarms when adding a new one + +From: Ben Skeggs + +commit 330bdf62fe6a6c5b99a647f7bf7157107c9348b3 upstream. + +The idea here was to avoid having to "manually" program the HW if there's +a new earliest alarm. This was lazy and bad, as it leads to loads of fun +races between inter-related callers (ie. therm). + +Turns out, it's not so difficult after all. Go figure ;) + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +@@ -80,12 +80,22 @@ nvkm_timer_alarm(struct nvkm_timer *tmr, + if (list->timestamp > alarm->timestamp) + break; + } ++ + list_add_tail(&alarm->head, &list->head); ++ ++ /* Update HW if this is now the earliest alarm. */ ++ list = list_first_entry(&tmr->alarms, typeof(*list), head); ++ if (list == alarm) { ++ tmr->func->alarm_init(tmr, alarm->timestamp); ++ /* This shouldn't happen if callers aren't stupid. ++ * ++ * Worst case scenario is that it'll take roughly ++ * 4 seconds for the next alarm to trigger. ++ */ ++ WARN_ON(alarm->timestamp <= nvkm_timer_read(tmr)); ++ } + } + spin_unlock_irqrestore(&tmr->lock, flags); +- +- /* process pending alarms */ +- nvkm_timer_alarm_trigger(tmr); + } + + void diff --git a/queue-4.4/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch b/queue-4.4/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch new file mode 100644 index 00000000000..462e7cacbf0 --- /dev/null +++ b/queue-4.4/drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch @@ -0,0 +1,49 @@ +From 9fc64667ee48c9a25e7dca1a6bcb6906fec5bcc5 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 17:03:05 +1000 +Subject: drm/nouveau/tmr: fix corruption of the pending list when rescheduling an alarm + +From: Ben Skeggs + +commit 9fc64667ee48c9a25e7dca1a6bcb6906fec5bcc5 upstream. + +At least therm/fantog "attempts" to work around this issue, which could +lead to corruption of the pending alarm list. + +Fix it properly by not updating the timestamp without the lock held, or +trying to add an already pending alarm to the pending alarm list.... + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +@@ -65,14 +65,17 @@ nvkm_timer_alarm(struct nvkm_timer *tmr, + struct nvkm_alarm *list; + unsigned long flags; + +- alarm->timestamp = nvkm_timer_read(tmr) + nsec; +- +- /* append new alarm to list, in soonest-alarm-first order */ ++ /* Remove alarm from pending list. ++ * ++ * This both protects against the corruption of the list, ++ * and implements alarm rescheduling/cancellation. ++ */ + spin_lock_irqsave(&tmr->lock, flags); +- if (!nsec) { +- if (!list_empty(&alarm->head)) +- list_del(&alarm->head); +- } else { ++ list_del_init(&alarm->head); ++ ++ if (nsec) { ++ /* Insert into pending list, ordered earliest to latest. */ ++ alarm->timestamp = nvkm_timer_read(tmr) + nsec; + list_for_each_entry(list, &tmr->alarms, head) { + if (list->timestamp > alarm->timestamp) + break; diff --git a/queue-4.4/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch b/queue-4.4/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch new file mode 100644 index 00000000000..8141f9704da --- /dev/null +++ b/queue-4.4/drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch @@ -0,0 +1,63 @@ +From 1b0f84380b10ee97f7d2dd191294de9017e94d1d Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Thu, 11 May 2017 17:19:48 +1000 +Subject: drm/nouveau/tmr: handle races with hw when updating the next alarm time + +From: Ben Skeggs + +commit 1b0f84380b10ee97f7d2dd191294de9017e94d1d upstream. + +If the time to the next alarm is short enough, we could race with HW and +end up with an ~4 second delay until it triggers. + +Fix this by checking again after we update HW. + +Signed-off-by: Ben Skeggs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c | 26 ++++++++++++++--------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +@@ -36,23 +36,29 @@ nvkm_timer_alarm_trigger(struct nvkm_tim + unsigned long flags; + LIST_HEAD(exec); + +- /* move any due alarms off the pending list */ ++ /* Process pending alarms. */ + spin_lock_irqsave(&tmr->lock, flags); + list_for_each_entry_safe(alarm, atemp, &tmr->alarms, head) { +- if (alarm->timestamp <= nvkm_timer_read(tmr)) +- list_move_tail(&alarm->head, &exec); ++ /* Have we hit the earliest alarm that hasn't gone off? */ ++ if (alarm->timestamp > nvkm_timer_read(tmr)) { ++ /* Schedule it. If we didn't race, we're done. */ ++ tmr->func->alarm_init(tmr, alarm->timestamp); ++ if (alarm->timestamp > nvkm_timer_read(tmr)) ++ break; ++ } ++ ++ /* Move to completed list. We'll drop the lock before ++ * executing the callback so it can reschedule itself. ++ */ ++ list_move_tail(&alarm->head, &exec); + } + +- /* reschedule interrupt for next alarm time */ +- if (!list_empty(&tmr->alarms)) { +- alarm = list_first_entry(&tmr->alarms, typeof(*alarm), head); +- tmr->func->alarm_init(tmr, alarm->timestamp); +- } else { ++ /* Shut down interrupt if no more pending alarms. */ ++ if (list_empty(&tmr->alarms)) + tmr->func->alarm_fini(tmr); +- } + spin_unlock_irqrestore(&tmr->lock, flags); + +- /* execute any pending alarm handlers */ ++ /* Execute completed callbacks. */ + list_for_each_entry_safe(alarm, atemp, &exec, head) { + list_del_init(&alarm->head); + alarm->func(alarm); diff --git a/queue-4.4/iio-dac-ad7303-fix-channel-description.patch b/queue-4.4/iio-dac-ad7303-fix-channel-description.patch new file mode 100644 index 00000000000..0a436dc57cc --- /dev/null +++ b/queue-4.4/iio-dac-ad7303-fix-channel-description.patch @@ -0,0 +1,35 @@ +From ce420fd4251809b4c3119b3b20c8b13bd8eba150 Mon Sep 17 00:00:00 2001 +From: Pavel Roskin +Date: Thu, 13 Apr 2017 14:54:23 -0700 +Subject: iio: dac: ad7303: fix channel description + +From: Pavel Roskin + +commit ce420fd4251809b4c3119b3b20c8b13bd8eba150 upstream. + +realbits, storagebits and shift should be numbers, not ASCII characters. + +Signed-off-by: Pavel Roskin +Reviewed-by: Lars-Peter Clausen +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iio/dac/ad7303.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/iio/dac/ad7303.c ++++ b/drivers/iio/dac/ad7303.c +@@ -184,9 +184,9 @@ static const struct iio_chan_spec_ext_in + .address = (chan), \ + .scan_type = { \ + .sign = 'u', \ +- .realbits = '8', \ +- .storagebits = '8', \ +- .shift = '0', \ ++ .realbits = 8, \ ++ .storagebits = 8, \ ++ .shift = 0, \ + }, \ + .ext_info = ad7303_ext_info, \ + } diff --git a/queue-4.4/of-fdt-add-missing-allocation-failure-check.patch b/queue-4.4/of-fdt-add-missing-allocation-failure-check.patch new file mode 100644 index 00000000000..65918ec54b8 --- /dev/null +++ b/queue-4.4/of-fdt-add-missing-allocation-failure-check.patch @@ -0,0 +1,34 @@ +From 49e67dd17649b60b4d54966e18ec9c80198227f0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 17 May 2017 17:29:09 +0200 +Subject: of: fdt: add missing allocation-failure check + +From: Johan Hovold + +commit 49e67dd17649b60b4d54966e18ec9c80198227f0 upstream. + +The memory allocator passed to __unflatten_device_tree() (e.g. a wrapped +kzalloc) can fail so add the missing sanity check to avoid dereferencing +a NULL pointer. + +Fixes: fe14042358fa ("of/flattree: Refactor unflatten_device_tree and add fdt_unflatten_tree") +Signed-off-by: Johan Hovold +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/fdt.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -416,6 +416,9 @@ static void __unflatten_device_tree(cons + + /* Allocate memory for the expanded device tree */ + mem = dt_alloc(size + 4, __alignof__(struct device_node)); ++ if (!mem) ++ return NULL; ++ + memset(mem, 0, size); + + *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef); diff --git a/queue-4.4/of-fix-sparse-warning-in-of_pci_range_parser_one.patch b/queue-4.4/of-fix-sparse-warning-in-of_pci_range_parser_one.patch new file mode 100644 index 00000000000..1e491c36ba5 --- /dev/null +++ b/queue-4.4/of-fix-sparse-warning-in-of_pci_range_parser_one.patch @@ -0,0 +1,36 @@ +From eb3100365791b06242b8bb5c3c2854ba41dabfbc Mon Sep 17 00:00:00 2001 +From: Rob Herring +Date: Thu, 4 May 2017 12:34:30 -0500 +Subject: of: fix sparse warning in of_pci_range_parser_one + +From: Rob Herring + +commit eb3100365791b06242b8bb5c3c2854ba41dabfbc upstream. + +sparse gives the following warning for 'pci_space': + +../drivers/of/address.c:266:26: warning: incorrect type in assignment (different base types) +../drivers/of/address.c:266:26: expected unsigned int [unsigned] [usertype] pci_space +../drivers/of/address.c:266:26: got restricted __be32 const [usertype] + +It appears that pci_space is only ever accessed on powerpc, so the endian +swap is often not needed. + +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/of/address.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -260,7 +260,7 @@ struct of_pci_range *of_pci_range_parser + if (!parser->range || parser->range + parser->np > parser->end) + return NULL; + +- range->pci_space = parser->range[0]; ++ range->pci_space = be32_to_cpup(parser->range); + range->flags = of_bus_pci_get_flags(parser->range); + range->pci_addr = of_read_number(parser->range + 1, ns); + range->cpu_addr = of_translate_address(parser->node, diff --git a/queue-4.4/ohci-pci-add-qemu-quirk.patch b/queue-4.4/ohci-pci-add-qemu-quirk.patch new file mode 100644 index 00000000000..6180fdf5ce3 --- /dev/null +++ b/queue-4.4/ohci-pci-add-qemu-quirk.patch @@ -0,0 +1,83 @@ +From 21a60f6e65181cad64fd66ccc8080d413721ba27 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 20 Mar 2017 09:11:49 +0100 +Subject: ohci-pci: add qemu quirk + +From: Gerd Hoffmann + +commit 21a60f6e65181cad64fd66ccc8080d413721ba27 upstream. + +On a loaded virtualization host (dozen guests booting at the same time) +it may happen that the ohci controller emulation doesn't manage to do +timely frame processing, with the result that the io watchdog fires and +considers the controller being dead, even though it's only the emulation +being unusual slow due to the load peak. + +So, add a quirk for qemu and don't use the watchdog in case we figure we +are running on emulated ohci. The virtual ohci controller masquerades +as apple ohci controller, but we can identify it by subsystem id. + +Signed-off-by: Gerd Hoffmann +Signed-off-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/ohci-hcd.c | 3 ++- + drivers/usb/host/ohci-pci.c | 16 ++++++++++++++++ + drivers/usb/host/ohci.h | 1 + + 3 files changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -231,7 +231,8 @@ static int ohci_urb_enqueue ( + + /* Start up the I/O watchdog timer, if it's not running */ + if (!timer_pending(&ohci->io_watchdog) && +- list_empty(&ohci->eds_in_use)) { ++ list_empty(&ohci->eds_in_use) && ++ !(ohci->flags & OHCI_QUIRK_QEMU)) { + ohci->prev_frame_no = ohci_frame_no(ohci); + mod_timer(&ohci->io_watchdog, + jiffies + IO_WATCHDOG_DELAY); +--- a/drivers/usb/host/ohci-pci.c ++++ b/drivers/usb/host/ohci-pci.c +@@ -164,6 +164,15 @@ static int ohci_quirk_amd700(struct usb_ + return 0; + } + ++static int ohci_quirk_qemu(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ ++ ohci->flags |= OHCI_QUIRK_QEMU; ++ ohci_dbg(ohci, "enabled qemu quirk\n"); ++ return 0; ++} ++ + /* List of quirks for OHCI */ + static const struct pci_device_id ohci_pci_quirks[] = { + { +@@ -214,6 +223,13 @@ static const struct pci_device_id ohci_p + PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), + .driver_data = (unsigned long)ohci_quirk_amd700, + }, ++ { ++ .vendor = PCI_VENDOR_ID_APPLE, ++ .device = 0x003f, ++ .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET, ++ .subdevice = PCI_SUBDEVICE_ID_QEMU, ++ .driver_data = (unsigned long)ohci_quirk_qemu, ++ }, + + /* FIXME for some of the early AMD 760 southbridges, OHCI + * won't work at all. blacklist them. +--- a/drivers/usb/host/ohci.h ++++ b/drivers/usb/host/ohci.h +@@ -418,6 +418,7 @@ struct ohci_hcd { + #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ + #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ + #define OHCI_QUIRK_GLOBAL_SUSPEND 0x800 /* must suspend ports */ ++#define OHCI_QUIRK_QEMU 0x1000 /* relax timing expectations */ + + // there are also chip quirks/bugs in init logic + diff --git a/queue-4.4/proc-fix-unbalanced-hard-link-numbers.patch b/queue-4.4/proc-fix-unbalanced-hard-link-numbers.patch new file mode 100644 index 00000000000..508ba26a1de --- /dev/null +++ b/queue-4.4/proc-fix-unbalanced-hard-link-numbers.patch @@ -0,0 +1,33 @@ +From d66bb1607e2d8d384e53f3d93db5c18483c8c4f7 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 28 Apr 2017 15:00:15 +0200 +Subject: proc: Fix unbalanced hard link numbers + +From: Takashi Iwai + +commit d66bb1607e2d8d384e53f3d93db5c18483c8c4f7 upstream. + +proc_create_mount_point() forgot to increase the parent's nlink, and +it resulted in unbalanced hard link numbers, e.g. /proc/fs shows one +less than expected. + +Fixes: eb6d38d5427b ("proc: Allow creating permanently empty directories...") +Reported-by: Tristan Ye +Signed-off-by: Takashi Iwai +Signed-off-by: Eric W. Biederman +Signed-off-by: Greg Kroah-Hartman + +--- + fs/proc/generic.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -469,6 +469,7 @@ struct proc_dir_entry *proc_create_mount + ent->data = NULL; + ent->proc_fops = NULL; + ent->proc_iops = NULL; ++ parent->nlink++; + if (proc_register(parent, ent) < 0) { + kfree(ent); + parent->nlink--; diff --git a/queue-4.4/series b/queue-4.4/series index 529bbf0b522..186ad6ce234 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -26,3 +26,17 @@ s390-kdump-add-final-note.patch s390-cputime-fix-incorrect-system-time.patch ath9k_htc-add-support-of-airties-1eda-2315-ar9271-device.patch ath9k_htc-fix-null-deref-at-probe.patch +drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch +drm-amdgpu-make-display-watermark-calculations-more-accurate.patch +drm-nouveau-mmu-nv4a-use-nv04-mmu-rather-than-the-nv44-one.patch +drm-nouveau-therm-remove-ineffective-workarounds-for-alarm-bugs.patch +drm-nouveau-tmr-ack-interrupt-before-processing-alarms.patch +drm-nouveau-tmr-fix-corruption-of-the-pending-list-when-rescheduling-an-alarm.patch +drm-nouveau-tmr-avoid-processing-completed-alarms-when-adding-a-new-one.patch +drm-nouveau-tmr-handle-races-with-hw-when-updating-the-next-alarm-time.patch +cdc-acm-fix-possible-invalid-access-when-processing-notification.patch +ohci-pci-add-qemu-quirk.patch +proc-fix-unbalanced-hard-link-numbers.patch +of-fix-sparse-warning-in-of_pci_range_parser_one.patch +of-fdt-add-missing-allocation-failure-check.patch +iio-dac-ad7303-fix-channel-description.patch