lkml.org 
[lkml]   [2012]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH tip/core/rcu 09/26] x86: Exception hooks for userspace RCU extended QS
    On Thu, Aug 30, 2012 at 02:05:26PM -0700, Paul E. McKenney wrote:
    > From: Frederic Weisbecker <fweisbec@gmail.com>
    >
    > Add necessary hooks to x86 exception for userspace
    > RCU extended quiescent state support.
    >
    > This includes traps, page fault, debug exceptions, etc...
    >
    > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
    > Cc: Alessio Igor Bogani <abogani@kernel.org>
    > Cc: Andrew Morton <akpm@linux-foundation.org>
    > Cc: Avi Kivity <avi@redhat.com>
    > Cc: Chris Metcalf <cmetcalf@tilera.com>
    > Cc: Christoph Lameter <cl@linux.com>
    > Cc: Geoff Levand <geoff@infradead.org>
    > Cc: Gilad Ben Yossef <gilad@benyossef.com>
    > Cc: Hakan Akkan <hakanakkan@gmail.com>
    > Cc: H. Peter Anvin <hpa@zytor.com>
    > Cc: Ingo Molnar <mingo@kernel.org>
    > Cc: Josh Triplett <josh@joshtriplett.org>
    > Cc: Kevin Hilman <khilman@ti.com>
    > Cc: Max Krasnyansky <maxk@qualcomm.com>
    > Cc: Peter Zijlstra <peterz@infradead.org>
    > Cc: Stephen Hemminger <shemminger@vyatta.com>
    > Cc: Steven Rostedt <rostedt@goodmis.org>
    > Cc: Sven-Thorsten Dietrich <thebigcorporation@gmail.com>
    > Cc: Thomas Gleixner <tglx@linutronix.de>
    > Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

    Reviewed-by: Josh Triplett <josh@joshtriplett.org>

    > arch/x86/include/asm/rcu.h | 20 ++++++++++++++++++++
    > arch/x86/kernel/traps.c | 30 ++++++++++++++++++++++--------
    > arch/x86/mm/fault.c | 13 +++++++++++--
    > 3 files changed, 53 insertions(+), 10 deletions(-)
    > create mode 100644 arch/x86/include/asm/rcu.h
    >
    > diff --git a/arch/x86/include/asm/rcu.h b/arch/x86/include/asm/rcu.h
    > new file mode 100644
    > index 0000000..439815b
    > --- /dev/null
    > +++ b/arch/x86/include/asm/rcu.h
    > @@ -0,0 +1,20 @@
    > +#ifndef _ASM_X86_RCU_H
    > +#define _ASM_X86_RCU_H
    > +
    > +#include <linux/rcupdate.h>
    > +#include <asm/ptrace.h>
    > +
    > +static inline void exception_enter(struct pt_regs *regs)
    > +{
    > + rcu_user_exit();
    > +}
    > +
    > +static inline void exception_exit(struct pt_regs *regs)
    > +{
    > +#ifdef CONFIG_RCU_USER_QS
    > + if (user_mode(regs))
    > + rcu_user_enter();
    > +#endif
    > +}
    > +
    > +#endif
    > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
    > index b481341..ab82cbd 100644
    > --- a/arch/x86/kernel/traps.c
    > +++ b/arch/x86/kernel/traps.c
    > @@ -55,6 +55,7 @@
    > #include <asm/i387.h>
    > #include <asm/fpu-internal.h>
    > #include <asm/mce.h>
    > +#include <asm/rcu.h>
    >
    > #include <asm/mach_traps.h>
    >
    > @@ -180,11 +181,15 @@ vm86_trap:
    > #define DO_ERROR(trapnr, signr, str, name) \
    > dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
    > { \
    > - if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
    > - == NOTIFY_STOP) \
    > + exception_enter(regs); \
    > + if (notify_die(DIE_TRAP, str, regs, error_code, \
    > + trapnr, signr) == NOTIFY_STOP) { \
    > + exception_exit(regs); \
    > return; \
    > + } \
    > conditional_sti(regs); \
    > do_trap(trapnr, signr, str, regs, error_code, NULL); \
    > + exception_exit(regs); \
    > }
    >
    > #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
    > @@ -195,11 +200,15 @@ dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
    > info.si_errno = 0; \
    > info.si_code = sicode; \
    > info.si_addr = (void __user *)siaddr; \
    > - if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \
    > - == NOTIFY_STOP) \
    > + exception_enter(regs); \
    > + if (notify_die(DIE_TRAP, str, regs, error_code, \
    > + trapnr, signr) == NOTIFY_STOP) { \
    > + exception_exit(regs); \
    > return; \
    > + } \
    > conditional_sti(regs); \
    > do_trap(trapnr, signr, str, regs, error_code, &info); \
    > + exception_exit(regs); \
    > }
    >
    > DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV,
    > @@ -312,6 +321,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
    > ftrace_int3_handler(regs))
    > return;
    > #endif
    > + exception_enter(regs);
    > #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
    > if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
    > SIGTRAP) == NOTIFY_STOP)
    > @@ -331,6 +341,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co
    > do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
    > preempt_conditional_cli(regs);
    > debug_stack_usage_dec();
    > + exception_exit(regs);
    > }
    >
    > #ifdef CONFIG_X86_64
    > @@ -391,6 +402,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
    > unsigned long dr6;
    > int si_code;
    >
    > + exception_enter(regs);
    > +
    > get_debugreg(dr6, 6);
    >
    > /* Filter out all the reserved bits which are preset to 1 */
    > @@ -406,7 +419,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
    >
    > /* Catch kmemcheck conditions first of all! */
    > if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
    > - return;
    > + goto exit;
    >
    > /* DR6 may or may not be cleared by the CPU */
    > set_debugreg(0, 6);
    > @@ -421,7 +434,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
    >
    > if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
    > SIGTRAP) == NOTIFY_STOP)
    > - return;
    > + goto exit;
    >
    > /*
    > * Let others (NMI) know that the debug stack is in use
    > @@ -437,7 +450,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
    > X86_TRAP_DB);
    > preempt_conditional_cli(regs);
    > debug_stack_usage_dec();
    > - return;
    > + goto exit;
    > }
    >
    > /*
    > @@ -458,7 +471,8 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
    > preempt_conditional_cli(regs);
    > debug_stack_usage_dec();
    >
    > - return;
    > +exit:
    > + exception_exit(regs);
    > }
    >
    > /*
    > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
    > index 76dcd9d..7dde46d 100644
    > --- a/arch/x86/mm/fault.c
    > +++ b/arch/x86/mm/fault.c
    > @@ -18,6 +18,7 @@
    > #include <asm/pgalloc.h> /* pgd_*(), ... */
    > #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
    > #include <asm/fixmap.h> /* VSYSCALL_START */
    > +#include <asm/rcu.h> /* exception_enter(), ... */
    >
    > /*
    > * Page fault error code bits:
    > @@ -1000,8 +1001,8 @@ static int fault_in_kernel_space(unsigned long address)
    > * and the problem, and then passes it off to one of the appropriate
    > * routines.
    > */
    > -dotraplinkage void __kprobes
    > -do_page_fault(struct pt_regs *regs, unsigned long error_code)
    > +static void __kprobes
    > +__do_page_fault(struct pt_regs *regs, unsigned long error_code)
    > {
    > struct vm_area_struct *vma;
    > struct task_struct *tsk;
    > @@ -1209,3 +1210,11 @@ good_area:
    >
    > up_read(&mm->mmap_sem);
    > }
    > +
    > +dotraplinkage void __kprobes
    > +do_page_fault(struct pt_regs *regs, unsigned long error_code)
    > +{
    > + exception_enter(regs);
    > + __do_page_fault(regs, error_code);
    > + exception_exit(regs);
    > +}
    > --
    > 1.7.8
    >


    \
     
     \ /
      Last update: 2012-09-01 02:41    [W:4.363 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site