From: Sebastian Parschauer s.parschauer@gmx.de
[ Upstream commit 627a49975bdc3220f360a8237603a6344ee6a588 ]
The PixArt OEM mice are known for disconnecting every minute in runlevel 1 or 3 if they are not always polled. One Lenovo PixArt mouse is already fixed. Got two references for 17ef:602e and three references for 17ef:6019 misbehaving like this. Got one direct bug report for 17ef:6093 from Wyatt Ward (wyatt8740). So add HID_QUIRK_ALWAYS_POLL for all of them.
Link: https://github.com/sriemer/fix-linux-mouse issue 22 Signed-off-by: Sebastian Parschauer s.parschauer@gmx.de Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-quirks.c | 3 +++ 2 files changed, 6 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 73e4590ea9c94..5e418d5f5439d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -730,6 +730,9 @@ #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
#define USB_VENDOR_ID_LG 0x1fd2 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index a49fa2b047cba..59491798d6c2a 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -105,6 +105,9 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
From: Peilin Ye yepeilin.cs@gmail.com
[ Upstream commit 25a097f5204675550afb879ee18238ca917cba7a ]
`uref->usage_index` is not always being properly checked, causing hiddev_ioctl_usage() to go out of bounds under some cases. Fix it.
Reported-by: syzbot+34ee1b45d88571c2fa8b@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?id=f2aebe90b8c56806b050a20b36f51ed6acabe80... Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Peilin Ye yepeilin.cs@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/usbhid/hiddev.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 35b1fa6d962ec..4711fb191a072 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -519,12 +519,16 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
switch (cmd) { case HIDIOCGUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; uref->value = field->value[uref->usage_index]; if (copy_to_user(user_arg, uref, sizeof(*uref))) goto fault; goto goodreturn;
case HIDIOCSUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; field->value[uref->usage_index] = uref->value; goto goodreturn;
From: Kalyan Thota kalyan_t@codeaurora.org
[ Upstream commit 4c978caf08aa155bdeadd9e2d4b026d4ce97ebd0 ]
Plane validation uses an API drm_calc_scale which will return src/dst value as a scale ratio.
when viewing the range on a scale the values should fall in as
Upscale ratio < Unity scale < Downscale ratio for src/dst formula
Fix the min and max scale ratios to suit the API accordingly.
Signed-off-by: Kalyan Thota kalyan_t@codeaurora.org Tested-by: Kristian H. Kristensen hoegsberg@google.com Reviewed-by: Kristian H. Kristensen hoegsberg@google.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 58d5acbcfc5c2..b984bafd27e25 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -853,9 +853,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
- min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxdwnscale); + min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale); ret = drm_atomic_helper_check_plane_state(state, crtc_state, min_scale, - pdpu->pipe_sblk->maxupscale << 16, + pdpu->pipe_sblk->maxdwnscale << 16, true, true); if (ret) { DPU_ERROR_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
From: Samuel Thibault samuel.thibault@ens-lyon.org
[ Upstream commit 2b86d9b8ec6efb86fc5ea44f2d49b1df17f699a1 ]
This was missed while introducing the tty-based serial access.
The only remaining use of wait_for_xmitr with tty-based access is in spk_synth_is_alive_restart to check whether the synth can be restarted. With tty-based this is up to the tty layer to cope with the buffering etc. so we can just say yes.
Signed-off-by: Samuel Thibault samuel.thibault@ens-lyon.org Link: https://lore.kernel.org/r/20200804160637.x3iycau5izywbgzl@function Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/speakup/serialio.c | 8 +++++--- drivers/staging/speakup/spk_priv.h | 1 - drivers/staging/speakup/spk_ttyio.c | 7 +++++++ drivers/staging/speakup/spk_types.h | 1 + drivers/staging/speakup/synth.c | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index 177a2988641c1..403b01d66367e 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c @@ -32,6 +32,7 @@ static void spk_serial_tiocmset(unsigned int set, unsigned int clear); static unsigned char spk_serial_in(void); static unsigned char spk_serial_in_nowait(void); static void spk_serial_flush_buffer(void); +static int spk_serial_wait_for_xmitr(struct spk_synth *in_synth);
struct spk_io_ops spk_serial_io_ops = { .synth_out = spk_serial_out, @@ -40,6 +41,7 @@ struct spk_io_ops spk_serial_io_ops = { .synth_in = spk_serial_in, .synth_in_nowait = spk_serial_in_nowait, .flush_buffer = spk_serial_flush_buffer, + .wait_for_xmitr = spk_serial_wait_for_xmitr, }; EXPORT_SYMBOL_GPL(spk_serial_io_ops);
@@ -211,7 +213,7 @@ void spk_stop_serial_interrupt(void) } EXPORT_SYMBOL_GPL(spk_stop_serial_interrupt);
-int spk_wait_for_xmitr(struct spk_synth *in_synth) +static int spk_serial_wait_for_xmitr(struct spk_synth *in_synth) { int tmout = SPK_XMITR_TIMEOUT;
@@ -280,7 +282,7 @@ static void spk_serial_flush_buffer(void)
static int spk_serial_out(struct spk_synth *in_synth, const char ch) { - if (in_synth->alive && spk_wait_for_xmitr(in_synth)) { + if (in_synth->alive && spk_serial_wait_for_xmitr(in_synth)) { outb_p(ch, speakup_info.port_tts); return 1; } @@ -295,7 +297,7 @@ const char *spk_serial_synth_immediate(struct spk_synth *synth, while ((ch = *buff)) { if (ch == '\n') ch = synth->procspeech; - if (spk_wait_for_xmitr(synth)) + if (spk_serial_wait_for_xmitr(synth)) outb(ch, speakup_info.port_tts); else return buff; diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h index ac6a74883af47..e9e3460634da2 100644 --- a/drivers/staging/speakup/spk_priv.h +++ b/drivers/staging/speakup/spk_priv.h @@ -36,7 +36,6 @@
const struct old_serial_port *spk_serial_init(int index); void spk_stop_serial_interrupt(void); -int spk_wait_for_xmitr(struct spk_synth *in_synth); void spk_serial_release(void); void spk_ttyio_release(void); void spk_ttyio_register_ldisc(void); diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index 5a9eff08cb960..b79361b6dc3a6 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -116,6 +116,7 @@ static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear); static unsigned char spk_ttyio_in(void); static unsigned char spk_ttyio_in_nowait(void); static void spk_ttyio_flush_buffer(void); +static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth);
struct spk_io_ops spk_ttyio_ops = { .synth_out = spk_ttyio_out, @@ -125,6 +126,7 @@ struct spk_io_ops spk_ttyio_ops = { .synth_in = spk_ttyio_in, .synth_in_nowait = spk_ttyio_in_nowait, .flush_buffer = spk_ttyio_flush_buffer, + .wait_for_xmitr = spk_ttyio_wait_for_xmitr, }; EXPORT_SYMBOL_GPL(spk_ttyio_ops);
@@ -286,6 +288,11 @@ static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear) mutex_unlock(&speakup_tty_mutex); }
+static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth) +{ + return 1; +} + static unsigned char ttyio_in(int timeout) { struct spk_ldisc_data *ldisc_data = speakup_tty->disc_data; diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h index a2fc72c298944..f2d3bd72c2c19 100644 --- a/drivers/staging/speakup/spk_types.h +++ b/drivers/staging/speakup/spk_types.h @@ -157,6 +157,7 @@ struct spk_io_ops { unsigned char (*synth_in)(void); unsigned char (*synth_in_nowait)(void); void (*flush_buffer)(void); + int (*wait_for_xmitr)(struct spk_synth *synth); };
struct spk_synth { diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index 3568bfb89912c..ac47dbac72075 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c @@ -159,7 +159,7 @@ int spk_synth_is_alive_restart(struct spk_synth *synth) { if (synth->alive) return 1; - if (spk_wait_for_xmitr(synth) > 0) { + if (synth->io_ops->wait_for_xmitr(synth) > 0) { /* restart */ synth->alive = 1; synth_printf("%s", synth->init);
From: John Stultz john.stultz@linaro.org
[ Upstream commit 975efc66d4e654207c17f939eb737ac591ac38fe ]
When booting with heavily modularized config, the serial console may not be able to load until after init when modules that satisfy needed dependencies have time to load.
Unfortunately, as qcom_geni_console_setup is marked as __init, the function may have been freed before we get to run it, causing boot time crashes such as:
[ 6.469057] Unable to handle kernel paging request at virtual address ffffffe645d4e6cc [ 6.481623] Mem abort info: [ 6.484466] ESR = 0x86000007 [ 6.487557] EC = 0x21: IABT (current EL), IL = 32 bits [ 6.492929] SET = 0, FnV = 0g [ 6.496016] EA = 0, S1PTW = 0 [ 6.499202] swapper pgtable: 4k pages, 39-bit VAs, pgdp=000000008151e000 [ 6.501286] ufshcd-qcom 1d84000.ufshc: ufshcd_print_pwr_info:[RX, TX]: gear=[3, 3], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2 [ 6.505977] [ffffffe645d4e6cc] pgd=000000017df9f003, p4d=000000017df9f003, pud=000000017df9f003, pmd=000000017df9c003, pte=0000000000000000 [ 6.505990] Internal error: Oops: 86000007 [#1] PREEMPT SMP [ 6.505995] Modules linked in: zl10353 zl10039 zl10036 zd1301_demod xc5000 xc4000 ves1x93 ves1820 tuner_xc2028 tuner_simple tuner_types tua9001 tua6100 1 [ 6.506152] isl6405 [ 6.518104] ufshcd-qcom 1d84000.ufshc: ufshcd_find_max_sup_active_icc_level: Regulator capability was not set, actvIccLevel=0 [ 6.530549] horus3a helene fc2580 fc0013 fc0012 fc0011 ec100 e4000 dvb_pll ds3000 drxk drxd drx39xyj dib9000 dib8000 dib7000p dib7000m dib3000mc dibx003 [ 6.624271] CPU: 7 PID: 148 Comm: kworker/7:2 Tainted: G W 5.8.0-mainline-12021-g6defd37ba1cd #3455 [ 6.624273] Hardware name: Thundercomm Dragonboard 845c (DT) [ 6.624290] Workqueue: events deferred_probe_work_func [ 6.624296] pstate: 40c00005 (nZcv daif +PAN +UAO BTYPE=--) [ 6.624307] pc : qcom_geni_console_setup+0x0/0x110 [ 6.624316] lr : try_enable_new_console+0xa0/0x140 [ 6.624318] sp : ffffffc010843a30 [ 6.624320] x29: ffffffc010843a30 x28: ffffffe645c3e7d0 [ 6.624325] x27: ffffff80f8022180 x26: ffffffc010843b28 [ 6.637937] x25: 0000000000000000 x24: ffffffe6462a2000 [ 6.637941] x23: ffffffe646398000 x22: 0000000000000000 [ 6.637945] x21: 0000000000000000 x20: ffffffe6462a5ce8 [ 6.637952] x19: ffffffe646398e38 x18: ffffffffffffffff [ 6.680296] x17: 0000000000000000 x16: ffffffe64492b900 [ 6.680300] x15: ffffffe6461e9d08 x14: 69202930203d2064 [ 6.680305] x13: 7561625f65736162 x12: 202c363331203d20 [ 6.696434] x11: 0000000000000030 x10: 0101010101010101 [ 6.696438] x9 : 4d4d20746120304d x8 : 7f7f7f7f7f7f7f7f [ 6.707249] x7 : feff4c524c787373 x6 : 0000000000008080 [ 6.707253] x5 : 0000000000000000 x4 : 8080000000000000 [ 6.707257] x3 : 0000000000000000 x2 : ffffffe645d4e6cc [ 6.744223] qcom_geni_serial 898000.serial: dev_pm_opp_set_rate: failed to find OPP for freq 102400000 (-34) [ 6.744966] x1 : fffffffefe74e174 x0 : ffffffe6462a5ce8 [ 6.753580] qcom_geni_serial 898000.serial: dev_pm_opp_set_rate: failed to find OPP for freq 102400000 (-34) [ 6.761634] Call trace: [ 6.761639] qcom_geni_console_setup+0x0/0x110 [ 6.761645] register_console+0x29c/0x2f8 [ 6.767981] Bluetooth: hci0: Frame reassembly failed (-84) [ 6.775252] uart_add_one_port+0x438/0x500 [ 6.775258] qcom_geni_serial_probe+0x2c4/0x4a8 [ 6.775266] platform_drv_probe+0x58/0xa8 [ 6.855359] really_probe+0xec/0x398 [ 6.855362] driver_probe_device+0x5c/0xb8 [ 6.855367] __device_attach_driver+0x98/0xb8 [ 7.184945] bus_for_each_drv+0x74/0xd8 [ 7.188825] __device_attach+0xec/0x148 [ 7.192705] device_initial_probe+0x24/0x30 [ 7.196937] bus_probe_device+0x9c/0xa8 [ 7.200816] deferred_probe_work_func+0x7c/0xb8 [ 7.205398] process_one_work+0x20c/0x4b0 [ 7.209456] worker_thread+0x48/0x460 [ 7.213157] kthread+0x14c/0x158 [ 7.216432] ret_from_fork+0x10/0x18 [ 7.220049] Code: bad PC value [ 7.223139] ---[ end trace 73f3b21e251d5a70 ]---
Thus this patch removes the __init avoiding crash in such configs.
Cc: Andy Gross agross@kernel.org Cc: Jiri Slaby jirislaby@kernel.org Cc: Saravana Kannan saravanak@google.com Cc: Todd Kjos tkjos@google.com Cc: Amit Pundir amit.pundir@linaro.org Cc: linux-arm-msm@vger.kernel.org Cc: linux-serial@vger.kernel.org Suggested-by: Saravana Kannan saravanak@google.com Signed-off-by: John Stultz john.stultz@linaro.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20200811025044.70626-1-john.stultz@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index f98a79172ad23..0b184256034fb 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1063,7 +1063,7 @@ static unsigned int qcom_geni_serial_tx_empty(struct uart_port *uport) }
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE -static int __init qcom_geni_console_setup(struct console *co, char *options) +static int qcom_geni_console_setup(struct console *co, char *options) { struct uart_port *uport; struct qcom_geni_serial_port *port;
From: Krishna Manikandan mkrishn@codeaurora.org
[ Upstream commit 9d5cbf5fe46e350715389d89d0c350d83289a102 ]
Define shutdown callback for display drm driver, so as to disable all the CRTCS when shutdown notification is received by the driver.
This change will turn off the timing engine so that no display transactions are requested while mmu translations are getting disabled during reboot sequence.
Signed-off-by: Krishna Manikandan mkrishn@codeaurora.org
Changes in v2: - Remove NULL check from msm_pdev_shutdown (Stephen Boyd) - Change commit text to reflect when this issue was uncovered (Sai Prakash Ranjan)
Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b73fbb65e14b2..4558d66761b3c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1321,6 +1321,13 @@ static int msm_pdev_remove(struct platform_device *pdev) return 0; }
+static void msm_pdev_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + drm_atomic_helper_shutdown(drm); +} + static const struct of_device_id dt_match[] = { { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 }, { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, @@ -1332,6 +1339,7 @@ MODULE_DEVICE_TABLE(of, dt_match); static struct platform_driver msm_platform_driver = { .probe = msm_pdev_probe, .remove = msm_pdev_remove, + .shutdown = msm_pdev_shutdown, .driver = { .name = "msm", .of_match_table = dt_match,
From: Tom Rix trix@redhat.com
[ Upstream commit cecf7560f00a8419396a2ed0f6e5d245ccb4feac ]
clang static analysis reports this representative problem
applesmc.c:758:10: warning: 1st function call argument is an uninitialized value left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
buffer is filled by the earlier call
ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, ...
This problem is reported because a goto skips the status check. Other similar problems use data from applesmc_read_key before checking the status. So move the checks to before the use.
Signed-off-by: Tom Rix trix@redhat.com Reviewed-by: Henrik Rydberg rydberg@bitmath.org Link: https://lore.kernel.org/r/20200820131932.10590-1-trix@redhat.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/applesmc.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 183ff3d251299..006bc07bcd301 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -748,15 +748,18 @@ static ssize_t applesmc_light_show(struct device *dev, }
ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + if (ret) + goto out; /* newer macbooks report a single 10-bit bigendian value */ if (data_length == 10) { left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2; goto out; } left = buffer[2]; + + ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); if (ret) goto out; - ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); right = buffer[2];
out: @@ -805,12 +808,11 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, to_index(attr));
ret = applesmc_read_key(newkey, buffer, 2); - speed = ((buffer[0] << 8 | buffer[1]) >> 2); - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); + + speed = ((buffer[0] << 8 | buffer[1]) >> 2); + return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); }
static ssize_t applesmc_store_fan_speed(struct device *dev, @@ -846,12 +848,11 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, u8 buffer[2];
ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); + + manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); }
static ssize_t applesmc_store_fan_manual(struct device *dev, @@ -867,10 +868,11 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, return -EINVAL;
ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - val = (buffer[0] << 8 | buffer[1]); if (ret) goto out;
+ val = (buffer[0] << 8 | buffer[1]); + if (input) val = val | (0x01 << to_index(attr)); else @@ -946,13 +948,12 @@ static ssize_t applesmc_key_count_show(struct device *dev, u32 count;
ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); - count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + - ((u32)buffer[2]<<8) + buffer[3]; - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); + + count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + + ((u32)buffer[2]<<8) + buffer[3]; + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); }
static ssize_t applesmc_key_at_index_read_show(struct device *dev,
From: Amit Engel amit.engel@dell.com
[ Upstream commit 0d3b6a8d213a30387b5104b2fb25376d18636f23 ]
Based on nvme spec, when keep alive timeout is set to zero the keep-alive timer should be disabled.
Signed-off-by: Amit Engel amit.engel@dell.com Signed-off-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/core.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 57a4062cbb59e..7d7176369edf7 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -369,6 +369,9 @@ static void nvmet_keep_alive_timer(struct work_struct *work)
static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl) { + if (unlikely(ctrl->kato == 0)) + return; + pr_debug("ctrl %d start keep-alive timer for %d secs\n", ctrl->cntlid, ctrl->kato);
@@ -378,6 +381,9 @@ static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl)
static void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl) { + if (unlikely(ctrl->kato == 0)) + return; + pr_debug("ctrl %d stop keep-alive\n", ctrl->cntlid);
cancel_delayed_work_sync(&ctrl->ka_work);
From: Rob Clark robdclark@chromium.org
[ Upstream commit 43906812eaab06423f56af5cca9a9fcdbb4ac454 ]
This has roughly the same effect as drm_atomic_helper_wait_for_vblanks(), basically just ensuring that vblank accounting is enabled so that we get valid timestamp/seqn on pageflip events.
Signed-off-by: Rob Clark robdclark@chromium.org Tested-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_atomic.c | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 5ccfad794c6a5..561bfa48841c3 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -27,6 +27,34 @@ int msm_atomic_prepare_fb(struct drm_plane *plane, return msm_framebuffer_prepare(new_state->fb, kms->aspace); }
+/* + * Helpers to control vblanks while we flush.. basically just to ensure + * that vblank accounting is switched on, so we get valid seqn/timestamp + * on pageflip events (if requested) + */ + +static void vblank_get(struct msm_kms *kms, unsigned crtc_mask) +{ + struct drm_crtc *crtc; + + for_each_crtc_mask(kms->dev, crtc, crtc_mask) { + if (!crtc->state->active) + continue; + drm_crtc_vblank_get(crtc); + } +} + +static void vblank_put(struct msm_kms *kms, unsigned crtc_mask) +{ + struct drm_crtc *crtc; + + for_each_crtc_mask(kms->dev, crtc, crtc_mask) { + if (!crtc->state->active) + continue; + drm_crtc_vblank_put(crtc); + } +} + static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) { unsigned crtc_mask = BIT(crtc_idx); @@ -44,6 +72,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
kms->funcs->enable_commit(kms);
+ vblank_get(kms, crtc_mask); + /* * Flush hardware updates: */ @@ -58,6 +88,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask);
+ vblank_put(kms, crtc_mask); + mutex_lock(&kms->commit_lock); kms->funcs->complete_commit(kms, crtc_mask); mutex_unlock(&kms->commit_lock); @@ -221,6 +253,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) */ kms->pending_crtc_mask &= ~crtc_mask;
+ vblank_get(kms, crtc_mask); + /* * Flush hardware updates: */ @@ -235,6 +269,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask);
+ vblank_put(kms, crtc_mask); + mutex_lock(&kms->commit_lock); kms->funcs->complete_commit(kms, crtc_mask); mutex_unlock(&kms->commit_lock);
From: Ofir Bitton obitton@habana.ai
[ Upstream commit bce382a8bb080ed5f2f3a06754526dc58b91cca2 ]
We must validate FW size in order not to corrupt memory in case a malicious FW file will be present in system.
Signed-off-by: Ofir Bitton obitton@habana.ai Signed-off-by: Oded Gabbay oded.gabbay@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/habanalabs/firmware_if.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/misc/habanalabs/firmware_if.c b/drivers/misc/habanalabs/firmware_if.c index ea2ca67fbfbfa..153858475abc1 100644 --- a/drivers/misc/habanalabs/firmware_if.c +++ b/drivers/misc/habanalabs/firmware_if.c @@ -11,6 +11,7 @@ #include <linux/genalloc.h> #include <linux/io-64-nonatomic-lo-hi.h>
+#define FW_FILE_MAX_SIZE 0x1400000 /* maximum size of 20MB */ /** * hl_fw_push_fw_to_device() - Push FW code to device. * @hdev: pointer to hl_device structure. @@ -43,6 +44,14 @@ int hl_fw_push_fw_to_device(struct hl_device *hdev, const char *fw_name,
dev_dbg(hdev->dev, "%s firmware size == %zu\n", fw_name, fw_size);
+ if (fw_size > FW_FILE_MAX_SIZE) { + dev_err(hdev->dev, + "FW file size %zu exceeds maximum of %u bytes\n", + fw_size, FW_FILE_MAX_SIZE); + rc = -EINVAL; + goto out; + } + fw_data = (const u64 *) fw->data;
memcpy_toio(dst, fw_data, fw_size);
From: Ofir Bitton obitton@habana.ai
[ Upstream commit 0839152f8c1efc1cc2d515d1ff1e253ca9402ad3 ]
vmalloc can return different return code than NULL and a valid pointer. We must validate it in order to dereference a non valid pointer.
Signed-off-by: Ofir Bitton obitton@habana.ai Signed-off-by: Oded Gabbay oded.gabbay@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/habanalabs/memory.c | 9 +++++++-- drivers/misc/habanalabs/mmu.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/habanalabs/memory.c b/drivers/misc/habanalabs/memory.c index 22566b75ca50c..acfccf32be6b9 100644 --- a/drivers/misc/habanalabs/memory.c +++ b/drivers/misc/habanalabs/memory.c @@ -67,6 +67,11 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, num_pgs = (args->alloc.mem_size + (page_size - 1)) >> page_shift; total_size = num_pgs << page_shift;
+ if (!total_size) { + dev_err(hdev->dev, "Cannot allocate 0 bytes\n"); + return -EINVAL; + } + contiguous = args->flags & HL_MEM_CONTIGUOUS;
if (contiguous) { @@ -94,7 +99,7 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, phys_pg_pack->contiguous = contiguous;
phys_pg_pack->pages = kvmalloc_array(num_pgs, sizeof(u64), GFP_KERNEL); - if (!phys_pg_pack->pages) { + if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) { rc = -ENOMEM; goto pages_arr_err; } @@ -689,7 +694,7 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
phys_pg_pack->pages = kvmalloc_array(total_npages, sizeof(u64), GFP_KERNEL); - if (!phys_pg_pack->pages) { + if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) { rc = -ENOMEM; goto page_pack_arr_mem_err; } diff --git a/drivers/misc/habanalabs/mmu.c b/drivers/misc/habanalabs/mmu.c index 176c315836f12..d66e16de4cda3 100644 --- a/drivers/misc/habanalabs/mmu.c +++ b/drivers/misc/habanalabs/mmu.c @@ -422,7 +422,7 @@ int hl_mmu_init(struct hl_device *hdev) hdev->mmu_shadow_hop0 = kvmalloc_array(prop->max_asid, prop->mmu_hop_table_size, GFP_KERNEL | __GFP_ZERO); - if (!hdev->mmu_shadow_hop0) { + if (ZERO_OR_NULL_PTR(hdev->mmu_shadow_hop0)) { rc = -ENOMEM; goto err_pool_add; }
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit f5749d6181fa7df5ae741788e5d96f593d3a60b6 ]
New Qualcomm firmware has changed a way it reports back the 'started' event. Support new register values.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 9ea748667fab0..40431a09dc97c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -199,12 +199,22 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu) { int ret; u32 val; + u32 mask, reset_val; + + val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8); + if (val <= 0x20010004) { + mask = 0xffffffff; + reset_val = 0xbabeface; + } else { + mask = 0x1ff; + reset_val = 0x100; + }
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1); gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val, - val == 0xbabeface, 100, 10000); + (val & mask) == reset_val, 100, 10000);
if (ret) DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
From: Jeff Layton jlayton@kernel.org
[ Upstream commit 496ceaf12432b3d136dcdec48424312e71359ea7 ]
Leases don't currently work correctly on kcephfs, as they are not broken when caps are revoked. They could eventually be implemented similarly to how we did them in libcephfs, but for now don't allow them.
[ idryomov: no need for simple_nosetlease() in ceph_dir_fops and ceph_snapdir_fops ]
Signed-off-by: Jeff Layton jlayton@kernel.org Reviewed-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ceph/file.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index ce54a1b12819b..dc97a7fd81315 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -2197,6 +2197,7 @@ const struct file_operations ceph_file_fops = { .mmap = ceph_mmap, .fsync = ceph_fsync, .lock = ceph_lock, + .setlease = simple_nosetlease, .flock = ceph_flock, .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write,
From: Tomi Valkeinen tomi.valkeinen@ti.com
[ Upstream commit 7fd5b25499bcec157dd4de9a713425efcf4571cd ]
After commit 92cc68e35863c1c61c449efa2b2daef6e9926048 ("drm/vblank: Use spin_(un)lock_irq() in drm_crtc_vblank_on()") omapdrm locking is broken:
WARNING: inconsistent lock state 5.8.0-rc2-00483-g92cc68e35863 #13 Tainted: G W -------------------------------- inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. swapper/0/0 [HC1[1]:SC0[0]:HE0:SE1] takes: ea98222c (&dev->event_lock#2){?.+.}-{2:2}, at: drm_handle_vblank+0x4c/0x520 [drm] {HARDIRQ-ON-W} state was registered at: trace_hardirqs_on+0x9c/0x1ec _raw_spin_unlock_irq+0x20/0x58 omap_crtc_atomic_enable+0x54/0xa0 [omapdrm] drm_atomic_helper_commit_modeset_enables+0x218/0x270 [drm_kms_helper] omap_atomic_commit_tail+0x48/0xc4 [omapdrm] commit_tail+0x9c/0x190 [drm_kms_helper] drm_atomic_helper_commit+0x154/0x188 [drm_kms_helper] drm_client_modeset_commit_atomic+0x228/0x268 [drm] drm_client_modeset_commit_locked+0x60/0x1d0 [drm] drm_client_modeset_commit+0x24/0x40 [drm] drm_fb_helper_restore_fbdev_mode_unlocked+0x54/0xa8 [drm_kms_helper] drm_fb_helper_set_par+0x2c/0x5c [drm_kms_helper] drm_fb_helper_hotplug_event.part.0+0xa0/0xbc [drm_kms_helper] drm_kms_helper_hotplug_event+0x24/0x30 [drm_kms_helper] output_poll_execute+0x1a8/0x1c0 [drm_kms_helper] process_one_work+0x268/0x800 worker_thread+0x30/0x4e0 kthread+0x164/0x190 ret_from_fork+0x14/0x20
The reason for this is that omapdrm calls drm_crtc_vblank_on() while holding event_lock taken with spin_lock_irq().
It is not clear why drm_crtc_vblank_on() and drm_crtc_vblank_get() are called while holding event_lock. I don't see any problem with moving those calls outside the lock, which is what this patch does.
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Link: https://patchwork.freedesktop.org/patch/msgid/20200819103021.440288-1-tomi.v... Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/omap_crtc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 3c5ddbf30e974..f5e18802e7bc6 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -451,11 +451,12 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc, if (omap_state->manually_updated) return;
- spin_lock_irq(&crtc->dev->event_lock); drm_crtc_vblank_on(crtc); + ret = drm_crtc_vblank_get(crtc); WARN_ON(ret != 0);
+ spin_lock_irq(&crtc->dev->event_lock); omap_crtc_arm_event(crtc); spin_unlock_irq(&crtc->dev->event_lock); }
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 49d9c5936314e44d314c605c39cce0fd947f9c3a ]
Match the pattern elsewhere in this file.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Steven Rostedt (VMware) rostedt@goodmis.org Reviewed-by: Thomas Gleixner tglx@linutronix.de Acked-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Tested-by: Marco Elver elver@google.com Link: https://lkml.kernel.org/r/20200821085348.251340558@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 29d2d7a21bd7b..73f08cda21e0e 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -148,7 +148,8 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv, */ stop_critical_timings(); drv->states[index].enter_s2idle(dev, drv, index); - WARN_ON(!irqs_disabled()); + if (WARN_ON_ONCE(!irqs_disabled())) + local_irq_disable(); /* * timekeeping_resume() that will be called by tick_unfreeze() for the * first CPU executing it calls functions containing RCU read-side
From: Hou Pu houpu@bytedance.com
[ Upstream commit acb19e17c5134dd78668c429ecba5b481f038e6a ]
If we configured io timeout of nbd0 to 100s. Later after we finished using it, we configured nbd0 again and set the io timeout to 0. We expect it would timeout after 30 seconds and keep retry. But in fact we could not change the timeout when we set it to 0. the timeout is still the original 100s.
So change the timeout to default 30s when we set it to zero. It also behaves same as commit 2da22da57348 ("nbd: fix zero cmd timeout handling v2").
It becomes more important if we were reconfigure a nbd device and the io timeout it set to zero. Because it could take 30s to detect the new socket and thus io could be completed more quickly compared to 100s.
Signed-off-by: Hou Pu houpu@bytedance.com Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7b61d53ba050e..7c577cabb9c3b 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1349,6 +1349,8 @@ static void nbd_set_cmd_timeout(struct nbd_device *nbd, u64 timeout) nbd->tag_set.timeout = timeout * HZ; if (timeout) blk_queue_rq_timeout(nbd->disk->queue, timeout * HZ); + else + blk_queue_rq_timeout(nbd->disk->queue, 30 * HZ); }
/* Must be called with config_lock held */
From: Sven Schnelle svens@linux.ibm.com
[ Upstream commit 1196f12a2c960951d02262af25af0bb1775ebcc2 ]
Since commit a21ee6055c30 ("lockdep: Change hardirq{s_enabled,_context} to per-cpu variables") the lockdep code itself uses percpu variables. This leads to recursions because the percpu macros are calling preempt_enable() which might call trace_preempt_on().
Signed-off-by: Sven Schnelle svens@linux.ibm.com Reviewed-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/percpu.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h index 50b4ce8cddfdc..918f0ba4f4d20 100644 --- a/arch/s390/include/asm/percpu.h +++ b/arch/s390/include/asm/percpu.h @@ -29,7 +29,7 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ old__, new__, prev__; \ pcp_op_T__ *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ prev__ = *ptr__; \ do { \ @@ -37,7 +37,7 @@ new__ = old__ op (val); \ prev__ = cmpxchg(ptr__, old__, new__); \ } while (prev__ != old__); \ - preempt_enable(); \ + preempt_enable_notrace(); \ new__; \ })
@@ -68,7 +68,7 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ if (__builtin_constant_p(val__) && \ ((szcast)val__ > -129) && ((szcast)val__ < 128)) { \ @@ -84,7 +84,7 @@ : [val__] "d" (val__) \ : "cc"); \ } \ - preempt_enable(); \ + preempt_enable_notrace(); \ }
#define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int) @@ -95,14 +95,14 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ asm volatile( \ op " %[old__],%[val__],%[ptr__]\n" \ : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ : [val__] "d" (val__) \ : "cc"); \ - preempt_enable(); \ + preempt_enable_notrace(); \ old__ + val__; \ })
@@ -114,14 +114,14 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ asm volatile( \ op " %[old__],%[val__],%[ptr__]\n" \ : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ : [val__] "d" (val__) \ : "cc"); \ - preempt_enable(); \ + preempt_enable_notrace(); \ }
#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, "lan") @@ -136,10 +136,10 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ ret__; \ pcp_op_T__ *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ ret__ = cmpxchg(ptr__, oval, nval); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ })
@@ -152,10 +152,10 @@ ({ \ typeof(pcp) *ptr__; \ typeof(pcp) ret__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ ret__ = xchg(ptr__, nval); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ })
@@ -171,11 +171,11 @@ typeof(pcp1) *p1__; \ typeof(pcp2) *p2__; \ int ret__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ p1__ = raw_cpu_ptr(&(pcp1)); \ p2__ = raw_cpu_ptr(&(pcp2)); \ ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ })
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
[ Upstream commit 168f09cdadbd547c2b202246ef9a8183da725f13 ]
[Why] These aren't stable on some platform configurations when driving multiple displays, especially on higher resolution.
In particular the delay in asserting p-state and validating from x86 outweights any power or performance benefit from the hardware composition.
Under some configurations this will manifest itself as extreme stutter or unresponsiveness especially when combined with cursor movement.
[How] Disable these for now. Exposing overlays to userspace doesn't guarantee that they'll be able to use them in any and all configurations and it's part of the DRM contract to have userspace gracefully handle validation failures when they occur.
Valdiation occurs as part of DC and this in particular affects RV, so disable this in dcn10_global_validation.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Hersen Wu hersenxs.wu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 1599bb9711111..e860ae05feda1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1151,6 +1151,7 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont bool video_large = false; bool desktop_large = false; bool dcc_disabled = false; + bool mpo_enabled = false;
for (i = 0; i < context->stream_count; i++) { if (context->stream_status[i].plane_count == 0) @@ -1159,6 +1160,9 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont if (context->stream_status[i].plane_count > 2) return DC_FAIL_UNSUPPORTED_1;
+ if (context->stream_status[i].plane_count > 1) + mpo_enabled = true; + for (j = 0; j < context->stream_status[i].plane_count; j++) { struct dc_plane_state *plane = context->stream_status[i].plane_states[j]; @@ -1182,6 +1186,10 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont } }
+ /* Disable MPO in multi-display configurations. */ + if (context->stream_count > 1 && mpo_enabled) + return DC_FAIL_UNSUPPORTED_1; + /* * Workaround: On DCN10 there is UMC issue that causes underflow when * playing 4k video on 4k desktop with video downscaled and single channel
From: Furquan Shaikh furquan@google.com
[ Upstream commit 5896585512e5156482335e902f7c7393b940da51 ]
In `amdgpu_dm_update_backlight_caps()`, there is a local `amdgpu_dm_backlight_caps` object that is filled in by `amdgpu_acpi_get_backlight_caps()`. However, this object is uninitialized before the call and hence the subsequent check for aux_support can fail since it is not initialized by `amdgpu_acpi_get_backlight_caps()` as well. This change initializes this local `amdgpu_dm_backlight_caps` object to 0.
Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Furquan Shaikh furquan@google.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2c0eb7140ca0e..526e4161df454 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2064,6 +2064,8 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm) #if defined(CONFIG_ACPI) struct amdgpu_dm_backlight_caps caps;
+ memset(&caps, 0, sizeof(caps)); + if (dm->backlight_caps.caps_valid) return;
From: Wayne Lin Wayne.Lin@amd.com
[ Upstream commit ef67d792a2fc578319399f605fbec2f99ecc06ea ]
[Why] In dm_dp_aux_transfer() now, we forget to handle AUX_WR fail cases. We suppose every write wil get done successfully and hence some AUX commands might not sent out indeed.
[How] Check if AUX_WR success. If not, retry it.
Signed-off-by: Wayne Lin Wayne.Lin@amd.com Reviewed-by: Hersen Wu hersenxs.wu@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git 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 index 28a6c7b2ef4bb..2f858507ca702 100644 --- 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 @@ -101,7 +101,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, &operation_result);
- if (payload.write) + if (payload.write && result >= 0) result = msg->size;
if (result < 0)
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit b67a468a4ccef593cd8df6a02ba3d167b77f0c81 ]
When amdgpu_display_modeset_create_props() fails, state and state->context should be freed to prevent memleak. It's the same when amdgpu_dm_audio_init() fails.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 526e4161df454..2da040c1876dd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2043,12 +2043,18 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) &dm_atomic_state_funcs);
r = amdgpu_display_modeset_create_props(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + }
r = amdgpu_dm_audio_init(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + }
return 0; }
From: Simon Leiner simon@leiner.me
[ Upstream commit d742db70033c745e410523e00522ee0cfe2aa416 ]
On some architectures (like ARM), virt_to_gfn cannot be used for vmalloc'd memory because of its reliance on virt_to_phys. This patch introduces a check for vmalloc'd addresses and obtains the PFN using vmalloc_to_pfn in that case.
Signed-off-by: Simon Leiner simon@leiner.me Reviewed-by: Stefano Stabellini sstabellini@kernel.org Link: https://lore.kernel.org/r/20200825093153.35500-1-simon@leiner.me Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/xenbus/xenbus_client.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index a38292ef79f6d..f38bdaea0ef11 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -363,8 +363,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, int i, j;
for (i = 0; i < nr_pages; i++) { - err = gnttab_grant_foreign_access(dev->otherend_id, - virt_to_gfn(vaddr), 0); + unsigned long gfn; + + if (is_vmalloc_addr(vaddr)) + gfn = pfn_to_gfn(vmalloc_to_pfn(vaddr)); + else + gfn = virt_to_gfn(vaddr); + + err = gnttab_grant_foreign_access(dev->otherend_id, gfn, 0); if (err < 0) { xenbus_dev_fatal(dev, err, "granting access to ring page");
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit 0a4c56c80f90797e9b9f8426c6aae4c0cf1c9785 ]
Commit ef91bb196b0d ("kernel.h: Silence sparse warning in lower_32_bits") caused new warnings to show in the fsldma driver, but that commit was not to blame: it only exposed some very incorrect code that tried to take the low 32 bits of an address.
That made no sense for multiple reasons, the most notable one being that that code was intentionally limited to only 32-bit ppc builds, so "only low 32 bits of an address" was completely nonsensical. There were no high bits to mask off to begin with.
But even more importantly fropm a correctness standpoint, turning the address into an integer then caused the subsequent address arithmetic to be completely wrong too, and the "+1" actually incremented the address by one, rather than by four.
Which again was incorrect, since the code was reading two 32-bit values and trying to make a 64-bit end result of it all. Surprisingly, the iowrite64() did not suffer from the same odd and incorrect model.
This code has never worked, but it's questionable whether anybody cared: of the two users that actually read the 64-bit value (by way of some C preprocessor hackery and eventually the 'get_cdar()' inline function), one of them explicitly ignored the value, and the other one might just happen to work despite the incorrect value being read.
This patch at least makes it not fail the build any more, and makes the logic superficially sane. Whether it makes any difference to the code _working_ or not shall remain a mystery.
Compile-tested-by: Guenter Roeck linux@roeck-us.net Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/fsldma.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index 56f18ae992332..308bed0a560ac 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h @@ -205,10 +205,10 @@ struct fsldma_chan { #else static u64 fsl_ioread64(const u64 __iomem *addr) { - u32 fsl_addr = lower_32_bits(addr); - u64 fsl_addr_hi = (u64)in_le32((u32 *)(fsl_addr + 1)) << 32; + u32 val_lo = in_le32((u32 __iomem *)addr); + u32 val_hi = in_le32((u32 __iomem *)addr + 1);
- return fsl_addr_hi | in_le32((u32 *)fsl_addr); + return ((u64)val_hi << 32) + val_lo; }
static void fsl_iowrite64(u64 val, u64 __iomem *addr) @@ -219,10 +219,10 @@ static void fsl_iowrite64(u64 val, u64 __iomem *addr)
static u64 fsl_ioread64be(const u64 __iomem *addr) { - u32 fsl_addr = lower_32_bits(addr); - u64 fsl_addr_hi = (u64)in_be32((u32 *)fsl_addr) << 32; + u32 val_hi = in_be32((u32 __iomem *)addr); + u32 val_lo = in_be32((u32 __iomem *)addr + 1);
- return fsl_addr_hi | in_be32((u32 *)(fsl_addr + 1)); + return ((u64)val_hi << 32) + val_lo; }
static void fsl_iowrite64be(u64 val, u64 __iomem *addr)
linux-stable-mirror@lists.linaro.org