All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <fweisbec@gmail.com>
To: Ingo Molnar <mingo@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>,
	Andy Lutomirski <luto@kernel.org>,
	"Paul E. McKenney" <paulmck@us.ibm.com>, X86 ML <x86@kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Rik van Riel <riel@redhat.com>, Oleg Nesterov <oleg@redhat.com>,
	Denys Vlasenko <vda.linux@googlemail.com>,
	Borislav Petkov <bp@alien8.de>, Kees Cook <keescook@chromium.org>,
	Brian Gerst <brgerst@gmail.com>
Subject: Re: [RFC/INCOMPLETE 01/13] context_tracking: Add context_tracking_assert_state
Date: Thu, 18 Jun 2015 18:26:37 +0200	[thread overview]
Message-ID: <20150618162636.GB841@lerouge> (raw)
In-Reply-To: <20150618161729.GB5799@gmail.com>

On Thu, Jun 18, 2015 at 06:17:29PM +0200, Ingo Molnar wrote:
> 
> * Andy Lutomirski <luto@amacapital.net> wrote:
> 
> > On Thu, Jun 18, 2015 at 4:07 AM, Andy Lutomirski <luto@amacapital.net> wrote:
> > > On Thu, Jun 18, 2015 at 2:57 AM, Ingo Molnar <mingo@kernel.org> wrote:
> > >>
> > >> * Andy Lutomirski <luto@amacapital.net> wrote:
> > >>
> > >>> On Wed, Jun 17, 2015 at 2:41 AM, Ingo Molnar <mingo@kernel.org> wrote:
> > >>> >
> > >>> > * Andy Lutomirski <luto@kernel.org> wrote:
> > >>> >
> > >>> >> This will let us sprinkle sanity checks around the kernel without
> > >>> >> making too much of a mess.
> > >>> >>
> > >>> >> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> > >>> >> ---
> > >>> >>  include/linux/context_tracking.h | 8 ++++++++
> > >>> >>  1 file changed, 8 insertions(+)
> > >>> >>
> > >>> >> diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
> > >>> >> index 2821838256b4..0fbea4b152e1 100644
> > >>> >> --- a/include/linux/context_tracking.h
> > >>> >> +++ b/include/linux/context_tracking.h
> > >>> >> @@ -57,6 +57,13 @@ static inline void context_tracking_task_switch(struct task_struct *prev,
> > >>> >>       if (context_tracking_is_enabled())
> > >>> >>               __context_tracking_task_switch(prev, next);
> > >>> >>  }
> > >>> >> +
> > >>> >> +static inline void context_tracking_assert_state(enum ctx_state state)
> > >>> >> +{
> > >>> >> +     rcu_lockdep_assert(!context_tracking_is_enabled() ||
> > >>> >> +                        this_cpu_read(context_tracking.state) == state,
> > >>> >> +                        "context tracking state was wrong");
> > >>> >> +}
> > >>> >
> > >>> > Please don't introduce assert() style debug check interfaces!
> > >>> >
> > >>> > (And RCU should be fixed too I suspect.)
> > >>> >
> > >>> > They are absolutely horrible on the brain when mixed with WARN_ON() interfaces,
> > >>> > which are the dominant runtime check interface in the kernel.
> > >>> >
> > >>> > Instead make it something like:
> > >>> >
> > >>> >   #define ct_state() (this_cpu_read(context_tracking.state))
> > >>> >
> > >>> >   #define CT_WARN_ON(cond) \
> > >>> >         WARN_ON(context_tracking_is_enabled() && (cond))
> > >>> >
> > >>> > and then the debug checks can be written as:
> > >>> >
> > >>> >         CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
> > >>> >
> > >>> > This is IMHO _far_ more readable than:
> > >>> >
> > >>> >         context_tracking_assert_state(CONTEXT_KERNEL);
> > >>> >
> > >>> > ok?
> > >>> >
> > >>> > (Assuming people will accept 'ct/CT' as an abbreviation for context tracking.)
> > >>>
> > >>> Hmm, ok I guess.  The part I don't like is having ct_state() at all on
> > >>> non-context-tracking kernels -- it seems like it's asking for trouble.
> > >>
> > >> Well:
> > >>
> > >>  - if # CONFIG_CONTEXT_TRACKING is not se, then CT_WARN_ON() does nothing.
> > >>
> > >>  - if CONFIG_CONTEXT_TRACKING=y, but !context_tracking_is_enabled(), then
> > >>    CT_WARN_ON() will evaluate 'cond', but won't calculate it.
> > >>
> > >>  - only if CONFIG_CONTEXT_TRACKING=y && context_tracking_is_enabled() should we
> > >>    get as far as ct_state() evaluation.
> > >>
> > >> so I'm not sure I see the problem you are seeing.
> > >>
> > >>> We could make CT_WARN_ON not even evaluate its argument if
> > >>> !CONFIG_CONTEXT_TRACKING, but then we still have ct_state() returning garbage if
> > >>> !context_tracking_is_enabled().
> > >>
> > >> My understanding is that if !context_tracking_is_enabled() then the compiler
> > >> should not even try to evaluate the rest. This is why doing a NULL pointer check
> > >> like this is safe:
> > >
> > > I'm fine with everything you just covered.  My only objection is that,
> > > if ct_state() exists, then someone might call it outside CT_WARN_ON,
> > > in which case it will break on non-context-tracking setups.
> > 
> > The more I think about it, the more I dislike ct_state().  We have
> > in_atomic(), which is already problematic because the return value
> > isn't reliable.  ct_state(), if callable on non context-tracking
> > kernels, will also be unreliable.  I prefer things like
> > lockdep_assert_held because they can't be misused.
> > 
> > It would be far too easy for someone to read:
> > 
> > CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
> > 
> > and add:
> > 
> > if (ct_state() == CONTEXT_KERNEL)
> >   do_something();
> > 
> > and that would be bad.
> 
> But ct_state() could be made reliable: if !context_tracking_is_enabled() then it 
> should return -1 or so.
> 
> I.e. we could make it something like:
> 
>         enum ctx_state {
>                 CONTEXT_DISABLED	= -1,
>                 CONTEXT_KERNEL		=  0,
>                 CONTEXT_USER		=  1,
>                 CONTEXT_GUEST		=  2,
>         } state;
> 
> static inline enum ctx_state ct_state(void)
> {
> 	if (context_tracking_is_enabled())
> 		return this_cpu_read(context_tracking.state))
> 
> 	return CONTEXT_DISABLED;
> }
> 
> and then CT_WARN_ON() DTRT.

That sounds good. With good layout of these things, the compiler should still be
able to nop related code when context tracking is disabled.

> 
> Thanks,
> 
> 	Ingo

  reply	other threads:[~2015-06-18 16:26 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-16 20:16 [RFC/INCOMPLETE 00/13] x86: Rewrite exit-to-userspace code Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 01/13] context_tracking: Add context_tracking_assert_state Andy Lutomirski
2015-06-17  9:41   ` Ingo Molnar
2015-06-17 14:15     ` Andy Lutomirski
2015-06-18  9:57       ` Ingo Molnar
2015-06-18 11:07         ` Andy Lutomirski
2015-06-18 15:52           ` Andy Lutomirski
2015-06-18 16:17             ` Ingo Molnar
2015-06-18 16:26               ` Frederic Weisbecker [this message]
2015-06-18 19:26                 ` Andy Lutomirski
2015-06-17 15:27     ` Paul E. McKenney
2015-06-18  9:59       ` Ingo Molnar
2015-06-18 22:54         ` Paul E. McKenney
2015-06-19  2:19           ` Paul E. McKenney
2015-06-30 11:04           ` Ingo Molnar
2015-06-30 16:16             ` Paul E. McKenney
2015-06-16 20:16 ` [RFC/INCOMPLETE 02/13] notifiers: Assert that RCU is watching in notify_die Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 03/13] x86: Move C entry and exit code to arch/x86/entry/common.c Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 04/13] x86/traps: Assert that we're in CONTEXT_KERNEL in exception entries Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 05/13] x86/entry: Add enter_from_user_mode and use it in syscalls Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 06/13] x86/entry: Add new, comprehensible entry and exit hooks Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 07/13] x86/entry/64: Really create an error-entry-from-usermode code path Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 08/13] x86/entry/64: Migrate 64-bit syscalls to new exit hooks Andy Lutomirski
2015-06-17 10:00   ` Ingo Molnar
2015-06-17 10:02     ` Ingo Molnar
2015-06-17 14:12       ` Andy Lutomirski
2015-06-18 10:17         ` Ingo Molnar
2015-06-18 10:19           ` Ingo Molnar
2015-06-16 20:16 ` [RFC/INCOMPLETE 09/13] x86/entry/compat: Migrate compat " Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 10/13] x86/asm/entry/64: Save all regs on interrupt entry Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 11/13] x86/asm/entry/64: Simplify irq stack pt_regs handling Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 12/13] x86/asm/entry/64: Migrate error and interrupt exit work to C Andy Lutomirski
2015-06-16 20:16 ` [RFC/INCOMPLETE 13/13] x86/entry: Remove SCHEDULE_USER and asm/context-tracking.h Andy Lutomirski
2015-06-17  9:48 ` [RFC/INCOMPLETE 00/13] x86: Rewrite exit-to-userspace code Ingo Molnar
2015-06-17 10:13   ` Richard Weinberger
2015-06-17 11:04     ` Ingo Molnar
2015-06-17 14:19     ` Andy Lutomirski
2015-06-17 15:16   ` Andy Lutomirski
2015-06-18 10:14     ` Ingo Molnar
2015-06-17 10:32 ` Ingo Molnar
2015-06-17 11:14   ` Ingo Molnar
2015-06-17 14:23   ` Andy Lutomirski
2015-06-18 10:11     ` Ingo Molnar
2015-06-18 11:06       ` Andy Lutomirski
2015-06-18 16:24         ` Ingo Molnar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150618162636.GB841@lerouge \
    --to=fweisbec@gmail.com \
    --cc=bp@alien8.de \
    --cc=brgerst@gmail.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    --cc=paulmck@us.ibm.com \
    --cc=riel@redhat.com \
    --cc=vda.linux@googlemail.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.