[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 1 Jan 2020 10:47:04 +0100
From: "Jason A. Donenfeld" <Jason@...c4.com>
To: Paul Burton <paulburton@...nel.org>
Cc: Arnd Bergmann <arnd@...db.de>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"open list:BROADCOM NVRAM DRIVER" <linux-mips@...r.kernel.org>,
Vincenzo Frascino <vincenzo.frascino@....com>,
Christian Brauner <christian.brauner@...onical.com>
Subject: Re: [PATCH] mips: vdso: conditionalize 32-bit time functions on COMPAT_32BIT_TIME
On Wed, Jan 1, 2020 at 5:08 AM Paul Burton <paulburton@...nel.org> wrote:
>
> Hi Jason,
>
> On Tue, Dec 31, 2019 at 05:14:41PM +0100, Jason A. Donenfeld wrote:
> > Here's a "one click" reproducer:
> > https://data.zx2c4.com/mips-musl-libc-weird-crash-time32-compat.tar.xz
> >
> > Untar that and hit `make -j$(nproc)`, and you'll get a freshly built
> > and crashing kernel+userland.
>
> Thanks for the test case. It seems like the VDSO code isn't saving &
> restoring $gp/$28, even though it's meant to be callee-saved in both the
> n32 & n64 ABIs. With some digging I found that the below seems to
> resolve the issue. Could you check whether it works for you?
>
> I'm still not quite sure *why* this happens; perhaps GCC just decides it
> doesn't need to save & restore $gp/$28 when it spots that it's being
> "used" for __current_thread_info (even though that's never actually
> referenced in the VDSO)?
>
> Just moving the declaration of __current_thread_info inside the
> current_thread_info() function seems to do the trick too, and is
> probably a bit neater.
>
> Thanks,
> Paul
>
> ---
> diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
> index 4993db40482c..ac33959bbb1f 100644
> --- a/arch/mips/include/asm/thread_info.h
> +++ b/arch/mips/include/asm/thread_info.h
> @@ -50,7 +50,11 @@ struct thread_info {
> }
>
> /* How to get the thread information struct from C. */
> +#ifdef __VDSO__
> +register struct thread_info *__current_thread_info __asm__("$0");
> +#else
> register struct thread_info *__current_thread_info __asm__("$28");
> +#endif
>
> static inline struct thread_info *current_thread_info(void)
> {
Holy guacamole, nice catch. That's interesting behavior indeed...
I'll leave it to you to submit for 5.5?
Powered by blists - more mailing lists