[PATCH 3/3] powerpc: fix reschedule bug in KUAP-unlocked user copy
Guenter Roeck
linux at roeck-us.net
Fri Oct 14 11:18:01 AEDT 2022
On Fri, Oct 14, 2022 at 01:16:47AM +1000, Nicholas Piggin wrote:
> schedule must not be explicitly called while KUAP is unlocked, because
> the AMR register will not be saved across the context switch on 64s
> (preemption is allowed because that is driven by interrupts which do
> save the AMR).
>
> exit_vmx_usercopy() runs inside an unlocked user access region, and it
> calls preempt_enable() which will call schedule() if need_resched() was
> set while non-preemptible. This can cause tasks to run unprotected when
> the should not, and can cause the user copy to be improperly blocked
> when scheduling back to it.
>
> Fix this by avoiding the explicit resched for preempt kernels by
> generating an interrupt to reschedule the context if need_resched() got
> set.
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
Tested-by: Guenter Roeck <linux at roeck-us.net>
> ---
> arch/powerpc/lib/vmx-helper.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c
> index f76a50291fd7..d491da8d1838 100644
> --- a/arch/powerpc/lib/vmx-helper.c
> +++ b/arch/powerpc/lib/vmx-helper.c
> @@ -36,7 +36,17 @@ int exit_vmx_usercopy(void)
> {
> disable_kernel_altivec();
> pagefault_enable();
> - preempt_enable();
> + preempt_enable_no_resched();
> + /*
> + * Must never explicitly call schedule (including preempt_enable())
> + * while in a kuap-unlocked user copy, because the AMR register will
> + * not be saved and restored across context switch. However preempt
> + * kernels need to be preempted as soon as possible if need_resched is
> + * set and we are preemptible. The hack here is to schedule a
> + * decrementer to fire here and reschedule for us if necessary.
> + */
> + if (IS_ENABLED(CONFIG_PREEMPT) && need_resched())
> + set_dec(1);
> return 0;
> }
>
> --
> 2.37.2
>
More information about the Linuxppc-dev
mailing list