All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
@ 2016-05-10 20:56 Mateusz Guzik
  2016-05-10 20:58 ` Andy Lutomirski
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Mateusz Guzik @ 2016-05-10 20:56 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: linux-kernel, Thomas Gleixner, H. Peter Anvin

This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"

Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
---
 arch/x86/kernel/process_64.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4285f6a..6b16c36 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -541,6 +541,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 			load_gs_index(0);
 			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
 		}
+		put_cpu();
 		break;
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
  2016-05-10 20:56 [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS Mateusz Guzik
@ 2016-05-10 20:58 ` Andy Lutomirski
  2016-05-11 20:35   ` Mateusz Guzik
  2016-05-12 15:11 ` Andy Lutomirski
  2016-05-13 11:51 ` [tip:x86/asm] x86/arch_prctl/64: Restore accidentally removed put_cpu() " tip-bot for Mateusz Guzik
  2 siblings, 1 reply; 7+ messages in thread
From: Andy Lutomirski @ 2016-05-10 20:58 UTC (permalink / raw)
  To: Mateusz Guzik
  Cc: Andy Lutomirski, linux-kernel, Thomas Gleixner, H. Peter Anvin

On Tue, May 10, 2016 at 1:56 PM, Mateusz Guzik <mguzik@redhat.com> wrote:
> This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"

Indeed.  How did that survive lockdep?

Acked-by: Andy Lutomirski <luto@kernel.org>

>
> Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
> ---
>  arch/x86/kernel/process_64.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> index 4285f6a..6b16c36 100644
> --- a/arch/x86/kernel/process_64.c
> +++ b/arch/x86/kernel/process_64.c
> @@ -541,6 +541,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
>                         load_gs_index(0);
>                         ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
>                 }
> +               put_cpu();
>                 break;
>         case ARCH_SET_FS:
>                 /* Not strictly needed for fs, but do it for symmetry
> --
> 1.8.3.1
>



-- 
Andy Lutomirski
AMA Capital Management, LLC

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
  2016-05-10 20:58 ` Andy Lutomirski
@ 2016-05-11 20:35   ` Mateusz Guzik
  2016-05-12  0:00     ` Andy Lutomirski
  0 siblings, 1 reply; 7+ messages in thread
From: Mateusz Guzik @ 2016-05-11 20:35 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, linux-kernel, Thomas Gleixner, H. Peter Anvin

On Tue, May 10, 2016 at 01:58:24PM -0700, Andy Lutomirski wrote:
> On Tue, May 10, 2016 at 1:56 PM, Mateusz Guzik <mguzik@redhat.com> wrote:
> > This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"
> 
> Indeed.  How did that survive lockdep?
> 

lockdep_sys_exit only checks actual locks.

In the common path after return from particular syscall interrupts get
blindly disabled (as opposed to checking first that they are enabled).
preemption count is not checked in the fast path at all and is checked
elsewhere as a side effect of calls to e.g. schedule().

How about a hack along these lines (note I don't claim this is
committable as it is, but it should work):

diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index ec138e5..5887bc7 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -303,6 +303,24 @@ static void syscall_slow_exit_work(struct pt_regs *regs, u32 cached_flags)
 		tracehook_report_syscall_exit(regs, step);
 }
 
+#ifdef CONFIG_PROVE_LOCKING
+/*
+ * Called after syscall handlers return.
+ */
+__visible void syscall_assert_exit(struct pt_regs *regs)
+{
+	if (in_atomic() || irqs_disabled()) {
+		printk(KERN_ERR "invalid state on exit from syscall %ld: "
+			"in_atomic(): %d, irqs_disabled(): %d, pid: %d, "
+			"name: %s\n", regs->orig_ax, in_atomic(),
+			irqs_disabled(), current->pid, current->comm);
+	}
+
+	if (irqs_disabled())
+		local_irq_enable();
+}
+#endif
+
 /*
  * Called with IRQs on and fully valid regs.  Returns with IRQs off in a
  * state such that we can immediately switch to user mode.
@@ -314,9 +332,7 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)
 
 	CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
 
-	if (IS_ENABLED(CONFIG_PROVE_LOCKING) &&
-	    WARN(irqs_disabled(), "syscall %ld left IRQs disabled", regs->orig_ax))
-		local_irq_enable();
+	syscall_assert_exit(regs);
 
 	/*
 	 * First do one-time work.  If these work items are enabled, we
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 9ee0da1..6c5cc23 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -210,6 +210,12 @@ entry_SYSCALL_64_fastpath:
 	movq	%rax, RAX(%rsp)
 1:
 
+#ifdef CONFIG_PROVE_LOCKING
+	/*
+	 * We want to validate bunch of stuff, which will clobber registers.
+	 */
+	jmp	2f
+#endif
 	/*
 	 * If we get here, then we know that pt_regs is clean for SYSRET64.
 	 * If we see that no exit work is required (which we are required
@@ -236,6 +242,7 @@ entry_SYSCALL_64_fastpath:
 	 */
 	TRACE_IRQS_ON
 	ENABLE_INTERRUPTS(CLBR_NONE)
+2:
 	SAVE_EXTRA_REGS
 	movq	%rsp, %rdi
 	call	syscall_return_slowpath	/* returns with IRQs disabled */

-- 
Mateusz Guzik

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
  2016-05-11 20:35   ` Mateusz Guzik
@ 2016-05-12  0:00     ` Andy Lutomirski
  0 siblings, 0 replies; 7+ messages in thread
From: Andy Lutomirski @ 2016-05-12  0:00 UTC (permalink / raw)
  To: Mateusz Guzik; +Cc: linux-kernel, H. Peter Anvin, Thomas Gleixner

On May 11, 2016 1:35 PM, "Mateusz Guzik" <mguzik@redhat.com> wrote:
>
> On Tue, May 10, 2016 at 01:58:24PM -0700, Andy Lutomirski wrote:
> > On Tue, May 10, 2016 at 1:56 PM, Mateusz Guzik <mguzik@redhat.com> wrote:
> > > This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"
> >
> > Indeed.  How did that survive lockdep?
> >
>
> lockdep_sys_exit only checks actual locks.
>
> In the common path after return from particular syscall interrupts get
> blindly disabled (as opposed to checking first that they are enabled).
> preemption count is not checked in the fast path at all and is checked
> elsewhere as a side effect of calls to e.g. schedule().
>
> How about a hack along these lines (note I don't claim this is
> committable as it is, but it should work):
>
> diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
> index ec138e5..5887bc7 100644
> --- a/arch/x86/entry/common.c
> +++ b/arch/x86/entry/common.c
> @@ -303,6 +303,24 @@ static void syscall_slow_exit_work(struct pt_regs *regs, u32 cached_flags)
>                 tracehook_report_syscall_exit(regs, step);
>  }
>
> +#ifdef CONFIG_PROVE_LOCKING
> +/*
> + * Called after syscall handlers return.
> + */
> +__visible void syscall_assert_exit(struct pt_regs *regs)
> +{
> +       if (in_atomic() || irqs_disabled()) {
> +               printk(KERN_ERR "invalid state on exit from syscall %ld: "
> +                       "in_atomic(): %d, irqs_disabled(): %d, pid: %d, "
> +                       "name: %s\n", regs->orig_ax, in_atomic(),
> +                       irqs_disabled(), current->pid, current->comm);
> +       }
> +
> +       if (irqs_disabled())
> +               local_irq_enable();
> +}
> +#endif
> +
>  /*
>   * Called with IRQs on and fully valid regs.  Returns with IRQs off in a
>   * state such that we can immediately switch to user mode.
> @@ -314,9 +332,7 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)
>
>         CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
>
> -       if (IS_ENABLED(CONFIG_PROVE_LOCKING) &&
> -           WARN(irqs_disabled(), "syscall %ld left IRQs disabled", regs->orig_ax))
> -               local_irq_enable();
> +       syscall_assert_exit(regs);
>
>         /*
>          * First do one-time work.  If these work items are enabled, we
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index 9ee0da1..6c5cc23 100644
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -210,6 +210,12 @@ entry_SYSCALL_64_fastpath:
>         movq    %rax, RAX(%rsp)
>  1:
>
> +#ifdef CONFIG_PROVE_LOCKING
> +       /*
> +        * We want to validate bunch of stuff, which will clobber registers.
> +        */
> +       jmp     2f
> +#endif
>         /*
>          * If we get here, then we know that pt_regs is clean for SYSRET64.
>          * If we see that no exit work is required (which we are required
> @@ -236,6 +242,7 @@ entry_SYSCALL_64_fastpath:
>          */
>         TRACE_IRQS_ON
>         ENABLE_INTERRUPTS(CLBR_NONE)
> +2:
>         SAVE_EXTRA_REGS
>         movq    %rsp, %rdi
>         call    syscall_return_slowpath /* returns with IRQs disabled */

It would be nice to do this in a cross-arch way.  Maybe we could
extend lockdep_sys_exit?  Ingo, do you think that would be reasonable?

--Andy

>
> --
> Mateusz Guzik

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
  2016-05-10 20:56 [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS Mateusz Guzik
  2016-05-10 20:58 ` Andy Lutomirski
@ 2016-05-12 15:11 ` Andy Lutomirski
  2016-05-13 11:50   ` Ingo Molnar
  2016-05-13 11:51 ` [tip:x86/asm] x86/arch_prctl/64: Restore accidentally removed put_cpu() " tip-bot for Mateusz Guzik
  2 siblings, 1 reply; 7+ messages in thread
From: Andy Lutomirski @ 2016-05-12 15:11 UTC (permalink / raw)
  To: X86 ML, Borislav Petkov
  Cc: Andy Lutomirski, linux-kernel, Thomas Gleixner, H. Peter Anvin,
	Sasha Levin, Mateusz Guzik

On Tue, May 10, 2016 at 1:56 PM, Mateusz Guzik <mguzik@redhat.com> wrote:
> This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"
>
> Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
> ---
>  arch/x86/kernel/process_64.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> index 4285f6a..6b16c36 100644
> --- a/arch/x86/kernel/process_64.c
> +++ b/arch/x86/kernel/process_64.c
> @@ -541,6 +541,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
>                         load_gs_index(0);
>                         ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
>                 }
> +               put_cpu();
>                 break;
>         case ARCH_SET_FS:
>                 /* Not strictly needed for fs, but do it for symmetry
> --
> 1.8.3.1
>

Ingo, can you apply this before the merge window opens?

I just noticed that you weren't cc'd, so I'll repeat my ack:

Acked-by: Andy Lutomirski <luto@kernel.org>

And I'll ask, since IIRC you wrote it: would it make sense to augment
lockdep_sys_exit to see if preemption got left disabled?

Thanks,
Andy

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS
  2016-05-12 15:11 ` Andy Lutomirski
@ 2016-05-13 11:50   ` Ingo Molnar
  0 siblings, 0 replies; 7+ messages in thread
From: Ingo Molnar @ 2016-05-13 11:50 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: X86 ML, Borislav Petkov, linux-kernel, Thomas Gleixner,
	H. Peter Anvin, Sasha Levin, Mateusz Guzik


* Andy Lutomirski <luto@kernel.org> wrote:

> On Tue, May 10, 2016 at 1:56 PM, Mateusz Guzik <mguzik@redhat.com> wrote:
> > This fixes 731e33e39a5b95ad770 "Remove FSBASE/GSBASE < 4G optimization"
> >
> > Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
> > ---
> >  arch/x86/kernel/process_64.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
> > index 4285f6a..6b16c36 100644
> > --- a/arch/x86/kernel/process_64.c
> > +++ b/arch/x86/kernel/process_64.c
> > @@ -541,6 +541,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
> >                         load_gs_index(0);
> >                         ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
> >                 }
> > +               put_cpu();
> >                 break;
> >         case ARCH_SET_FS:
> >                 /* Not strictly needed for fs, but do it for symmetry
> > --
> > 1.8.3.1
> >
> 
> Ingo, can you apply this before the merge window opens?

Yeah, done, applied it to tip:x86/asm.

> I just noticed that you weren't cc'd, so I'll repeat my ack:
> 
> Acked-by: Andy Lutomirski <luto@kernel.org>
> 
> And I'll ask, since IIRC you wrote it: would it make sense to augment
> lockdep_sys_exit to see if preemption got left disabled?

Yeah, absolutely. I'm quite sure early lockdep versions did such a check.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [tip:x86/asm] x86/arch_prctl/64: Restore accidentally removed put_cpu() in ARCH_SET_GS
  2016-05-10 20:56 [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS Mateusz Guzik
  2016-05-10 20:58 ` Andy Lutomirski
  2016-05-12 15:11 ` Andy Lutomirski
@ 2016-05-13 11:51 ` tip-bot for Mateusz Guzik
  2 siblings, 0 replies; 7+ messages in thread
From: tip-bot for Mateusz Guzik @ 2016-05-13 11:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, tglx, linux-kernel, alexander.shishkin, mguzik, bp,
	vincent.weaver, mingo, peterz, acme, torvalds, luto, dvlasenk,
	luto, jolsa, brgerst, eranian

Commit-ID:  4afd0565552c87f23834db9121dd9cf6955d0b43
Gitweb:     http://git.kernel.org/tip/4afd0565552c87f23834db9121dd9cf6955d0b43
Author:     Mateusz Guzik <mguzik@redhat.com>
AuthorDate: Tue, 10 May 2016 22:56:43 +0200
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 13 May 2016 13:50:15 +0200

x86/arch_prctl/64: Restore accidentally removed put_cpu() in ARCH_SET_GS

This fixes an oversight in:

	731e33e39a5b95 ("Remove FSBASE/GSBASE < 4G optimization")

Signed-off-by: Mateusz Guzik <mguzik@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: http://lkml.kernel.org/r/1462913803-29634-1-git-send-email-mguzik@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/kernel/process_64.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 4285f6a..6b16c36 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -541,6 +541,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
 			load_gs_index(0);
 			ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr);
 		}
+		put_cpu();
 		break;
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-05-13 11:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-10 20:56 [PATCH] x86/arch_prctl/64: restore accidentally removed put_cpu in ARCH_SET_GS Mateusz Guzik
2016-05-10 20:58 ` Andy Lutomirski
2016-05-11 20:35   ` Mateusz Guzik
2016-05-12  0:00     ` Andy Lutomirski
2016-05-12 15:11 ` Andy Lutomirski
2016-05-13 11:50   ` Ingo Molnar
2016-05-13 11:51 ` [tip:x86/asm] x86/arch_prctl/64: Restore accidentally removed put_cpu() " tip-bot for Mateusz Guzik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.