lkml.org 
[lkml]   [2007]   [Dec]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch-early-RFC 09/10] LTTng - x86_64 instrumentation
    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
    CC: Thomas Gleixner <tglx@linutronix.de>
    CC: Ingo Molnar <mingo@redhat.com>
    CC: H. Peter Anvin <hpa@zytor.com>
    ---
    arch/x86/ia32/ia32entry.S | 6 +++---
    arch/x86/ia32/ipc32.c | 2 ++
    arch/x86/kernel/apic_64.c | 21 +++++++++++++++++++++
    arch/x86/kernel/cpu/mcheck/mce_intel_64.c | 6 ++++++
    arch/x86/kernel/entry_64.S | 12 ++++++------
    arch/x86/kernel/process_64.c | 11 +++++++++++
    arch/x86/kernel/ptrace_64.c | 5 +++++
    arch/x86/kernel/setup64.c | 1 +
    arch/x86/kernel/smp_64.c | 18 ++++++++++++++++++
    arch/x86/kernel/traps_64.c | 29 +++++++++++++++++++++++++----
    arch/x86/mm/fault_64.c | 7 +++++++
    11 files changed, 105 insertions(+), 13 deletions(-)

    Index: linux-2.6-lttng/arch/x86/ia32/ia32entry.S
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/ia32/ia32entry.S 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/ia32/ia32entry.S 2007-12-05 21:48:46.000000000 -0500
    @@ -125,7 +125,7 @@ ENTRY(ia32_sysenter_target)
    .previous
    GET_THREAD_INFO(%r10)
    orl $TS_COMPAT,threadinfo_status(%r10)
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
    CFI_REMEMBER_STATE
    jnz sysenter_tracesys
    sysenter_do_call:
    @@ -230,7 +230,7 @@ ENTRY(ia32_cstar_target)
    .previous
    GET_THREAD_INFO(%r10)
    orl $TS_COMPAT,threadinfo_status(%r10)
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
    CFI_REMEMBER_STATE
    jnz cstar_tracesys
    cstar_do_call:
    @@ -322,7 +322,7 @@ ENTRY(ia32_syscall)
    SAVE_ARGS 0,0,1
    GET_THREAD_INFO(%r10)
    orl $TS_COMPAT,threadinfo_status(%r10)
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%r10)
    jnz ia32_tracesys
    ia32_do_syscall:
    cmpl $(IA32_NR_syscalls-1),%eax
    Index: linux-2.6-lttng/arch/x86/ia32/ipc32.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/ia32/ipc32.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/ia32/ipc32.c 2007-12-05 21:48:46.000000000 -0500
    @@ -18,6 +18,8 @@ sys32_ipc(u32 call, int first, int secon
    version = call >> 16; /* hack for backward compatibility */
    call &= 0xffff;

    + trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
    +
    switch (call) {
    case SEMOP:
    /* struct sembuf is the same on 32 and 64bit :)) */
    Index: linux-2.6-lttng/arch/x86/kernel/entry_64.S
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/entry_64.S 2007-12-05 21:48:05.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/entry_64.S 2007-12-05 21:48:46.000000000 -0500
    @@ -161,7 +161,7 @@ ENTRY(ret_from_fork)
    CFI_ADJUST_CFA_OFFSET -4
    call schedule_tail
    GET_THREAD_INFO(%rcx)
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE),threadinfo_flags(%rcx)
    jnz rff_trace
    rff_action:
    RESTORE_REST
    @@ -229,7 +229,7 @@ ENTRY(system_call)
    movq %rcx,RIP-ARGOFFSET(%rsp)
    CFI_REL_OFFSET rip,RIP-ARGOFFSET
    GET_THREAD_INFO(%rcx)
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx)
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),threadinfo_flags(%rcx)
    jnz tracesys
    cmpq $__NR_syscall_max,%rax
    ja badsys
    @@ -268,7 +268,7 @@ sysret_check:
    /* Handle reschedules */
    /* edx: work, edi: workmask */
    sysret_careful:
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),%edx
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SECCOMP),%edx
    jnz ret_from_sys_call_trace
    bt $TIF_NEED_RESCHED,%edx
    jnc sysret_signal
    @@ -377,7 +377,7 @@ int_very_careful:
    sti
    SAVE_REST
    /* Check for syscall exit trace */
    - testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edx
    + testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SINGLESTEP),%edx
    jz int_signal
    pushq %rdi
    CFI_ADJUST_CFA_OFFSET 8
    @@ -385,7 +385,7 @@ int_very_careful:
    call syscall_trace_leave
    popq %rdi
    CFI_ADJUST_CFA_OFFSET -8
    - andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi
    + andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_KERNEL_TRACE|_TIF_SINGLESTEP),%edi
    jmp int_restore_rest

    int_signal:
    @@ -957,7 +957,7 @@ bad_gs:
    * asm input arguments:
    * rdi: fn, rsi: arg, rdx: flags
    */
    -ENTRY(kernel_thread)
    +ENTRY(kernel_thread_asm)
    CFI_STARTPROC
    FAKE_STACK_FRAME $child_rip
    SAVE_ALL
    Index: linux-2.6-lttng/arch/x86/kernel/process_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/process_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/process_64.c 2007-12-05 21:48:46.000000000 -0500
    @@ -54,6 +54,9 @@

    asmlinkage extern void ret_from_fork(void);

    +asmlinkage long kernel_thread_asm(int (*fn)(void *), void * arg,
    + unsigned long flags);
    +
    unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;

    unsigned long boot_option_idle_override = 0;
    @@ -903,3 +906,11 @@ unsigned long arch_align_stack(unsigned
    sp -= get_random_int() % 8192;
    return sp & ~0xf;
    }
    +
    +asmlinkage long kernel_thread(int (*fn)(void *), void * arg,
    + unsigned long flags)
    +{
    + long pid = kernel_thread_asm(fn, arg, flags);
    + trace_mark(kernel_arch_kthread_create, "pid %ld fn %p", pid, fn);
    + return pid;
    +}
    Index: linux-2.6-lttng/arch/x86/kernel/ptrace_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/ptrace_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/ptrace_64.c 2007-12-05 21:48:46.000000000 -0500
    @@ -587,6 +587,9 @@ static void syscall_trace(struct pt_regs

    asmlinkage void syscall_trace_enter(struct pt_regs *regs)
    {
    + trace_mark(kernel_arch_syscall_entry, "syscall_id %d ip #p%ld",
    + (int)regs->orig_rax, instruction_pointer(regs));
    +
    /* do the secure computing check first */
    secure_computing(regs->orig_rax);

    @@ -611,6 +614,8 @@ asmlinkage void syscall_trace_enter(stru

    asmlinkage void syscall_trace_leave(struct pt_regs *regs)
    {
    + trace_mark(kernel_arch_syscall_exit, "ret %ld", regs->rax);
    +
    if (unlikely(current->audit_context))
    audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);

    Index: linux-2.6-lttng/arch/x86/kernel/traps_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/traps_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/traps_64.c 2007-12-05 21:49:48.000000000 -0500
    @@ -573,6 +573,9 @@ static void __kprobes do_trap(int trapnr
    {
    struct task_struct *tsk = current;

    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", trapnr,
    + instruction_pointer(regs));
    +
    if (user_mode(regs)) {
    /*
    * We want error_code and trap_no set for userspace
    @@ -598,6 +601,7 @@ static void __kprobes do_trap(int trapnr
    force_sig_info(signr, info, tsk);
    else
    force_sig(signr, tsk);
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    return;
    }

    @@ -613,8 +617,10 @@ static void __kprobes do_trap(int trapnr
    tsk->thread.trap_no = trapnr;
    die(str, regs, error_code);
    }
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    return;
    }
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    }

    #define DO_ERROR(trapnr, signr, str, name) \
    @@ -699,7 +705,10 @@ asmlinkage void __kprobes do_general_pro
    tsk->comm, tsk->pid,
    regs->rip, regs->rsp, error_code);

    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", 13,
    + instruction_pointer(regs));
    force_sig(SIGSEGV, tsk);
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    return;
    }

    @@ -779,6 +788,9 @@ asmlinkage __kprobes void default_do_nmi
    unsigned char reason = 0;
    int cpu;

    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
    + 2, instruction_pointer(regs));
    +
    cpu = smp_processor_id();

    /* Only the BSP gets external NMIs from the system. */
    @@ -788,20 +800,20 @@ asmlinkage __kprobes void default_do_nmi
    if (!(reason & 0xc0)) {
    if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
    == NOTIFY_STOP)
    - return;
    + goto end;
    /*
    * Ok, so this is none of the documented NMI sources,
    * so it must be the NMI watchdog.
    */
    if (nmi_watchdog_tick(regs,reason))
    - return;
    + goto end;
    if (!do_nmi_callback(regs,cpu))
    unknown_nmi_error(reason, regs);

    - return;
    + goto end;
    }
    if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
    - return;
    + goto end;

    /* AK: following checks seem to be broken on modern chipsets. FIXME */

    @@ -809,6 +821,8 @@ asmlinkage __kprobes void default_do_nmi
    mem_parity_error(reason, regs);
    if (reason & 0x40)
    io_check_error(reason, regs);
    +end:
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    }

    /* runs on IST stack. */
    @@ -902,7 +916,10 @@ asmlinkage void __kprobes do_debug(struc
    info.si_errno = 0;
    info.si_code = TRAP_BRKPT;
    info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
    + 1, instruction_pointer(regs));
    force_sig_info(SIGTRAP, &info, tsk);
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);

    clear_dr7:
    set_debugreg(0UL, 7);
    @@ -1060,6 +1077,10 @@ asmlinkage void do_simd_coprocessor_erro

    asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs)
    {
    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
    + 16, instruction_pointer(regs));
    +
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    }

    asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
    Index: linux-2.6-lttng/arch/x86/mm/fault_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/mm/fault_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/mm/fault_64.c 2007-12-05 21:48:52.000000000 -0500
    @@ -441,7 +441,10 @@ good_area:
    * make sure we exit gracefully rather than endlessly redo
    * the fault.
    */
    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
    + 14, instruction_pointer(regs));
    fault = handle_mm_fault(mm, vma, address, write);
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    if (unlikely(fault & VM_FAULT_ERROR)) {
    if (fault & VM_FAULT_OOM)
    goto out_of_memory;
    @@ -472,6 +475,9 @@ bad_area_nosemaphore:
    */
    local_irq_enable();

    + trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
    + 14, instruction_pointer(regs));
    +
    if (is_prefetch(regs, address, error_code))
    return;

    @@ -503,6 +509,7 @@ bad_area_nosemaphore:
    /* info.si_code has been set above */
    info.si_addr = (void __user *)address;
    force_sig_info(SIGSEGV, &info, tsk);
    + trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
    return;
    }

    Index: linux-2.6-lttng/arch/x86/kernel/setup64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/setup64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/setup64.c 2007-12-05 21:48:46.000000000 -0500
    @@ -189,6 +189,7 @@ unsigned long kernel_eflags;
    * debugging, no special alignment required.
    */
    DEFINE_PER_CPU(struct orig_ist, orig_ist);
    +EXPORT_PER_CPU_SYMBOL_GPL(orig_ist);

    /*
    * cpu_init() initializes state that is per-CPU. Some data is already
    Index: linux-2.6-lttng/arch/x86/kernel/apic_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/apic_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/apic_64.c 2007-12-05 21:48:58.000000000 -0500
    @@ -1085,7 +1085,14 @@ void smp_apic_timer_interrupt(struct pt_
    */
    exit_idle();
    irq_enter();
    +
    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + LOCAL_TIMER_VECTOR, (regs)?(!user_mode(regs)):(1));
    +
    smp_local_timer_interrupt();
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    +
    irq_exit();
    set_irq_regs(old_regs);
    }
    @@ -1145,6 +1152,10 @@ asmlinkage void smp_spurious_interrupt(v
    unsigned int v;
    exit_idle();
    irq_enter();
    +
    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + SPURIOUS_APIC_VECTOR, -1);
    +
    /*
    * Check if this really is a spurious interrupt and ACK it
    * if it is a vectored one. Just in case...
    @@ -1155,6 +1166,9 @@ asmlinkage void smp_spurious_interrupt(v
    ack_APIC_irq();

    add_pda(irq_spurious_count, 1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    +
    irq_exit();
    }

    @@ -1168,6 +1182,10 @@ asmlinkage void smp_error_interrupt(void

    exit_idle();
    irq_enter();
    +
    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + ERROR_APIC_VECTOR, -1);
    +
    /* First tickle the hardware, only then report what went on. -- REW */
    v = apic_read(APIC_ESR);
    apic_write(APIC_ESR, 0);
    @@ -1187,6 +1205,9 @@ asmlinkage void smp_error_interrupt(void
    */
    printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
    smp_processor_id(), v , v1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    +
    irq_exit();
    }

    Index: linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/cpu/mcheck/mce_intel_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/cpu/mcheck/mce_intel_64.c 2007-12-05 21:48:58.000000000 -0500
    @@ -22,11 +22,17 @@ asmlinkage void smp_thermal_interrupt(vo
    exit_idle();
    irq_enter();

    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + THERMAL_APIC_VECTOR, -1);
    +
    rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
    if (therm_throt_process(msr_val & 1))
    mce_log_therm_throt_event(smp_processor_id(), msr_val);

    add_pda(irq_thermal_count, 1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    +
    irq_exit();
    }

    Index: linux-2.6-lttng/arch/x86/kernel/smp_64.c
    ===================================================================
    --- linux-2.6-lttng.orig/arch/x86/kernel/smp_64.c 2007-12-05 21:05:48.000000000 -0500
    +++ linux-2.6-lttng/arch/x86/kernel/smp_64.c 2007-12-05 21:48:58.000000000 -0500
    @@ -151,6 +151,9 @@ asmlinkage void smp_invalidate_interrupt
    * BUG();
    */

    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + sender, (regs)?(!user_mode(regs)):(1));
    +
    if (f->flush_mm == read_pda(active_mm)) {
    if (read_pda(mmu_state) == TLBSTATE_OK) {
    if (f->flush_va == FLUSH_ALL)
    @@ -164,6 +167,8 @@ out:
    ack_APIC_irq();
    cpu_clear(cpu, f->flush_cpumask);
    add_pda(irq_tlb_count, 1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    }

    static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
    @@ -501,7 +506,13 @@ void smp_send_stop(void)
    asmlinkage void smp_reschedule_interrupt(void)
    {
    ack_APIC_irq();
    +
    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + RESCHEDULE_VECTOR, -1);
    +
    add_pda(irq_resched_count, 1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    }

    asmlinkage void smp_call_function_interrupt(void)
    @@ -522,8 +533,15 @@ asmlinkage void smp_call_function_interr
    */
    exit_idle();
    irq_enter();
    +
    + trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u",
    + CALL_FUNCTION_VECTOR, -1);
    +
    (*func)(info);
    add_pda(irq_call_count, 1);
    +
    + trace_mark(kernel_irq_exit, MARK_NOARGS);
    +
    irq_exit();
    if (wait) {
    mb();
    --
    Mathieu Desnoyers
    Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
    OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68


    \
     
     \ /
      Last update: 2007-12-06 04:05    [W:0.044 / U:29.384 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site