From: Greg Kroah-Hartman Date: Mon, 6 Jan 2020 12:21:29 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.14.163~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d323c33e2ec964ccb9f65f7e33d3b838410d231b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: alsa-ice1724-fix-sleep-in-atomic-in-infrasonic-quartet-support-code.patch mips-avoid-vdso-abi-breakage-due-to-global-register-variable.patch --- diff --git a/queue-4.9/alsa-ice1724-fix-sleep-in-atomic-in-infrasonic-quartet-support-code.patch b/queue-4.9/alsa-ice1724-fix-sleep-in-atomic-in-infrasonic-quartet-support-code.patch new file mode 100644 index 00000000000..8d2b2caafa0 --- /dev/null +++ b/queue-4.9/alsa-ice1724-fix-sleep-in-atomic-in-infrasonic-quartet-support-code.patch @@ -0,0 +1,64 @@ +From 0aec96f5897ac16ad9945f531b4bef9a2edd2ebd Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 18 Dec 2019 20:26:06 +0100 +Subject: ALSA: ice1724: Fix sleep-in-atomic in Infrasonic Quartet support code + +From: Takashi Iwai + +commit 0aec96f5897ac16ad9945f531b4bef9a2edd2ebd upstream. + +Jia-Ju Bai reported a possible sleep-in-atomic scenario in the ice1724 +driver with Infrasonic Quartet support code: namely, ice->set_rate +callback gets called inside ice->reg_lock spinlock, while the callback +in quartet.c holds ice->gpio_mutex. + +This patch fixes the invalid call: it simply moves the calls of +ice->set_rate and ice->set_mclk callbacks outside the spinlock. + +Reported-by: Jia-Ju Bai +Cc: +Link: https://lore.kernel.org/r/5d43135e-73b9-a46a-2155-9e91d0dcdf83@gmail.com +Link: https://lore.kernel.org/r/20191218192606.12866-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/ice1712/ice1724.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/sound/pci/ice1712/ice1724.c ++++ b/sound/pci/ice1712/ice1724.c +@@ -661,6 +661,7 @@ static int snd_vt1724_set_pro_rate(struc + unsigned long flags; + unsigned char mclk_change; + unsigned int i, old_rate; ++ bool call_set_rate = false; + + if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) + return -EINVAL; +@@ -684,7 +685,7 @@ static int snd_vt1724_set_pro_rate(struc + * setting clock rate for internal clock mode */ + old_rate = ice->get_rate(ice); + if (force || (old_rate != rate)) +- ice->set_rate(ice, rate); ++ call_set_rate = true; + else if (rate == ice->cur_rate) { + spin_unlock_irqrestore(&ice->reg_lock, flags); + return 0; +@@ -692,12 +693,14 @@ static int snd_vt1724_set_pro_rate(struc + } + + ice->cur_rate = rate; ++ spin_unlock_irqrestore(&ice->reg_lock, flags); ++ ++ if (call_set_rate) ++ ice->set_rate(ice, rate); + + /* setting master clock */ + mclk_change = ice->set_mclk(ice, rate); + +- spin_unlock_irqrestore(&ice->reg_lock, flags); +- + if (mclk_change && ice->gpio.i2s_mclk_changed) + ice->gpio.i2s_mclk_changed(ice); + if (ice->gpio.set_pro_rate) diff --git a/queue-4.9/mips-avoid-vdso-abi-breakage-due-to-global-register-variable.patch b/queue-4.9/mips-avoid-vdso-abi-breakage-due-to-global-register-variable.patch new file mode 100644 index 00000000000..ae97cbd61be --- /dev/null +++ b/queue-4.9/mips-avoid-vdso-abi-breakage-due-to-global-register-variable.patch @@ -0,0 +1,97 @@ +From bbcc5672b0063b0e9d65dc8787a4f09c3b5bb5cc Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Wed, 1 Jan 2020 20:50:38 -0800 +Subject: MIPS: Avoid VDSO ABI breakage due to global register variable + +From: Paul Burton + +commit bbcc5672b0063b0e9d65dc8787a4f09c3b5bb5cc upstream. + +Declaring __current_thread_info as a global register variable has the +effect of preventing GCC from saving & restoring its value in cases +where the ABI would typically do so. + +To quote GCC documentation: + +> If the register is a call-saved register, call ABI is affected: the +> register will not be restored in function epilogue sequences after the +> variable has been assigned. Therefore, functions cannot safely return +> to callers that assume standard ABI. + +When our position independent VDSO is built for the n32 or n64 ABIs all +functions it exposes should be preserving the value of $gp/$28 for their +caller, but in the presence of the __current_thread_info global register +variable GCC stops doing so & simply clobbers $gp/$28 when calculating +the address of the GOT. + +In cases where the VDSO returns success this problem will typically be +masked by the caller in libc returning & restoring $gp/$28 itself, but +that is by no means guaranteed. In cases where the VDSO returns an error +libc will typically contain a fallback path which will now fail +(typically with a bad memory access) if it attempts anything which +relies upon the value of $gp/$28 - eg. accessing anything via the GOT. + +One fix for this would be to move the declaration of +__current_thread_info inside the current_thread_info() function, +demoting it from global register variable to local register variable & +avoiding inadvertently creating a non-standard calling ABI for the VDSO. +Unfortunately this causes issues for clang, which doesn't support local +register variables as pointed out by commit fe92da0f355e ("MIPS: Changed +current_thread_info() to an equivalent supported by both clang and GCC") +which introduced the global register variable before we had a VDSO to +worry about. + +Instead, fix this by continuing to use the global register variable for +the kernel proper but declare __current_thread_info as a simple extern +variable when building the VDSO. It should never be referenced, and will +cause a link error if it is. This resolves the calling convention issue +for the VDSO without having any impact upon the build of the kernel +itself for either clang or gcc. + +Signed-off-by: Paul Burton +Fixes: ebb5e78cc634 ("MIPS: Initial implementation of a VDSO") +Reported-by: Jason A. Donenfeld +Reviewed-by: Jason A. Donenfeld +Tested-by: Jason A. Donenfeld +Cc: Arnd Bergmann +Cc: Christian Brauner +Cc: Vincenzo Frascino +Cc: # v4.4+ +Cc: linux-mips@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/asm/thread_info.h | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/mips/include/asm/thread_info.h ++++ b/arch/mips/include/asm/thread_info.h +@@ -52,8 +52,26 @@ struct thread_info { + #define init_thread_info (init_thread_union.thread_info) + #define init_stack (init_thread_union.stack) + +-/* How to get the thread information struct from C. */ ++/* ++ * A pointer to the struct thread_info for the currently executing thread is ++ * held in register $28/$gp. ++ * ++ * We declare __current_thread_info as a global register variable rather than a ++ * local register variable within current_thread_info() because clang doesn't ++ * support explicit local register variables. ++ * ++ * When building the VDSO we take care not to declare the global register ++ * variable because this causes GCC to not preserve the value of $28/$gp in ++ * functions that change its value (which is common in the PIC VDSO when ++ * accessing the GOT). Since the VDSO shouldn't be accessing ++ * __current_thread_info anyway we declare it extern in order to cause a link ++ * failure if it's referenced. ++ */ ++#ifdef __VDSO__ ++extern struct thread_info *__current_thread_info; ++#else + register struct thread_info *__current_thread_info __asm__("$28"); ++#endif + + static inline struct thread_info *current_thread_info(void) + { diff --git a/queue-4.9/series b/queue-4.9/series index 4b1fb6e4033..318bdcd7e03 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -16,3 +16,5 @@ xfs-fix-mount-failure-crash-on-invalid-iclog-memory-.patch taskstats-fix-data-race.patch drm-limit-to-int_max-in-create_blob-ioctl.patch revert-perf-report-add-warning-when-libunwind-not-co.patch +alsa-ice1724-fix-sleep-in-atomic-in-infrasonic-quartet-support-code.patch +mips-avoid-vdso-abi-breakage-due-to-global-register-variable.patch