You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(32) |
Jun
(66) |
Jul
(102) |
Aug
(78) |
Sep
(106) |
Oct
(137) |
Nov
(147) |
Dec
(147) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(71) |
Feb
(139) |
Mar
(86) |
Apr
(76) |
May
(57) |
Jun
(10) |
Jul
(12) |
Aug
(6) |
Sep
(8) |
Oct
(12) |
Nov
(12) |
Dec
(18) |
| 2011 |
Jan
(16) |
Feb
(19) |
Mar
(3) |
Apr
(1) |
May
(16) |
Jun
(17) |
Jul
(74) |
Aug
(22) |
Sep
(18) |
Oct
(24) |
Nov
(21) |
Dec
(30) |
| 2012 |
Jan
(31) |
Feb
(16) |
Mar
(22) |
Apr
(25) |
May
(18) |
Jun
(13) |
Jul
(83) |
Aug
(49) |
Sep
(20) |
Oct
(60) |
Nov
(35) |
Dec
(28) |
| 2013 |
Jan
(39) |
Feb
(61) |
Mar
(35) |
Apr
(21) |
May
(45) |
Jun
(56) |
Jul
(20) |
Aug
(9) |
Sep
(10) |
Oct
(31) |
Nov
(8) |
Dec
(4) |
| 2014 |
Jan
(6) |
Feb
(7) |
Mar
(7) |
Apr
(6) |
May
(4) |
Jun
(8) |
Jul
(5) |
Aug
(2) |
Sep
(4) |
Oct
(4) |
Nov
(11) |
Dec
(5) |
| 2015 |
Jan
(4) |
Feb
(4) |
Mar
(3) |
Apr
(4) |
May
(9) |
Jun
(4) |
Jul
(15) |
Aug
(8) |
Sep
(16) |
Oct
(18) |
Nov
(15) |
Dec
(7) |
| 2016 |
Jan
(20) |
Feb
(9) |
Mar
(15) |
Apr
(24) |
May
(16) |
Jun
(28) |
Jul
(22) |
Aug
(23) |
Sep
(18) |
Oct
(30) |
Nov
(40) |
Dec
(9) |
| 2017 |
Jan
(1) |
Feb
(8) |
Mar
(37) |
Apr
(26) |
May
(25) |
Jun
(46) |
Jul
(24) |
Aug
(9) |
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Bulltao.ru <bu...@dr...> - 2013-09-24 15:16:41
|
Your email client cannot read this email. To view it online, please go here: http://edm.dinodm.com/display.php?M=445718&C=4d90e30aa880d495ffe2f2bb87e0ebe5&S=17&L=2&N=3 To stop receiving these emails:http://edm.dinodm.com/unsubscribe.php?M=445718&C=4d90e30aa880d495ffe2f2bb87e0ebe5&L=2&N=17 |
|
From: Seiji A. <sei...@hd...> - 2013-09-09 21:56:26
|
Change from v2
- Print entry->ip instead of entry->regs->ip to avoid kernel crash.
- Use %pf instead of 0x%lx to print address and ip.
This patch introduces page fault tracepoints to x86 architecture
by switching IDT.
[Use case of page fault events]
Two events, for user and kernel spaces, are introduced at the beginning of
page fault handler.
- User space event
There is a request of page fault event for user space as below.
http://marc.info/?l=linux-mm&m=136807959830182&w=2
http://marc.info/?l=linux-mm&m=136807959130175&w=2
- Kernel space event:
Overhead in kernel space is measurable by enabling it.
[Creating IDT]
A way to create IDT is as below.
- Introduce set_intr_gate_raw() to register just non-trace handler to IDT.
This is used at boot time which tracing is disabled.
- Make set_intr_gate() macro so that it can register trace handler to
trace IDT and non-trace handler to normal IDT.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
arch/x86/include/asm/desc.h | 33 +++++++++++++++++----
arch/x86/include/asm/hw_irq.h | 14 ++++++++-
arch/x86/include/asm/trace/exceptions.h | 52 +++++++++++++++++++++++++++++++++
arch/x86/include/asm/traps.h | 22 ++++++++++++++
arch/x86/kernel/entry_32.S | 10 +++++++
arch/x86/kernel/entry_64.S | 13 ++++++++-
arch/x86/kernel/head64.c | 2 +-
arch/x86/kernel/irqinit.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/kernel/traps.c | 28 +++++++++---------
arch/x86/mm/Makefile | 2 ++
arch/x86/mm/fault.c | 22 ++++++++++++++
12 files changed, 178 insertions(+), 24 deletions(-)
create mode 100644 arch/x86/include/asm/trace/exceptions.h
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index b90e5df..c04302b 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -327,10 +327,28 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
write_idt_entry(trace_idt_table, entry, gate);
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+ gate_desc s;
+
+ pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
+ /*
+ * does not need to be atomic because it is only done once at
+ * setup time
+ */
+ write_trace_idt_entry(gate, &s);
+}
#else
static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+}
#endif
static inline void _set_gate(int gate, unsigned type, void *addr,
@@ -353,12 +371,20 @@ static inline void _set_gate(int gate, unsigned type, void *addr,
* Pentium F0 0F bugfix can have resulted in the mapped
* IDT being write-protected.
*/
-static inline void set_intr_gate(unsigned int n, void *addr)
+static inline void set_intr_gate_raw(unsigned int n, void *addr)
{
BUG_ON((unsigned)n > 0xFF);
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}
+#define set_intr_gate(n, addr) \
+ do { \
+ BUG_ON((unsigned)n > 0xFF); \
+ _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); \
+ _trace_set_gate(n, GATE_INTERRUPT, trace_##addr, 0, 0, \
+ __KERNEL_CS); \
+ } while (0)
+
extern int first_system_vector;
/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
extern unsigned long used_vectors[];
@@ -395,10 +421,7 @@ static inline void trace_set_intr_gate(unsigned int gate, void *addr)
#define __trace_alloc_intr_gate(n, addr)
#endif
-static inline void __alloc_intr_gate(unsigned int n, void *addr)
-{
- set_intr_gate(n, addr);
-}
+#define __alloc_intr_gate(n, addr) set_intr_gate(n, addr)
#define alloc_intr_gate(n, addr) \
do { \
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 92b3bae..c856e69 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -89,10 +89,22 @@ extern void trace_reschedule_interrupt(void);
extern void trace_threshold_interrupt(void);
extern void trace_call_function_interrupt(void);
extern void trace_call_function_single_interrupt(void);
+#else /* CONFIG_TRACING */
+#define trace_apic_timer_interrupt apic_timer_interrupt
+#define trace_x86_platform_ipi x86_platform_ipi
+#define trace_error_interrupt error_interrupt
+#define trace_irq_work_interrupt irq_work_interrupt
+#define trace_spurious_interrupt spurious_interrupt
+#define trace_thermal_interrupt thermal_interrupt
+#define trace_reschedule_interrupt reschedule_interrupt
+#define trace_threshold_interrupt threshold_interrupt
+#define trace_call_function_interrupt call_function_interrupt
+#define trace_call_function_single_interrupt call_function_single_interrupt
+#endif
+
#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
#define trace_reboot_interrupt reboot_interrupt
#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
-#endif /* CONFIG_TRACING */
/* IOAPIC */
#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
new file mode 100644
index 0000000..86540c0
--- /dev/null
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -0,0 +1,52 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM exceptions
+
+#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PAGE_FAULT_H
+
+#include <linux/tracepoint.h>
+
+extern void trace_irq_vector_regfunc(void);
+extern void trace_irq_vector_unregfunc(void);
+
+DECLARE_EVENT_CLASS(x86_exceptions,
+
+ TP_PROTO(unsigned long address, struct pt_regs *regs,
+ unsigned long error_code),
+
+ TP_ARGS(address, regs, error_code),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, address )
+ __field( unsigned long, ip )
+ __field( unsigned long, error_code )
+ ),
+
+ TP_fast_assign(
+ __entry->address = address;
+ __entry->ip = regs->ip;
+ __entry->error_code = error_code;
+ ),
+
+ TP_printk("address=%pf ip=%pf error_code=0x%lx",
+ (void *)__entry->address, (void *)__entry->ip,
+ __entry->error_code) );
+
+#define DEFINE_PAGE_FAULT_EVENT(name) \
+DEFINE_EVENT_FN(x86_exceptions, name, \
+ TP_PROTO(unsigned long address, struct pt_regs *regs, \
+ unsigned long error_code), \
+ TP_ARGS(address, regs, error_code), \
+ trace_irq_vector_regfunc, \
+ trace_irq_vector_unregfunc);
+
+DEFINE_PAGE_FAULT_EVENT(user_page_fault);
+DEFINE_PAGE_FAULT_EVENT(kernel_page_fault);
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE exceptions
+#endif /* _TRACE_PAGE_FAULT_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 7036cb6..a400a22 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -37,6 +37,25 @@ asmlinkage void machine_check(void);
#endif /* CONFIG_X86_MCE */
asmlinkage void simd_coprocessor_error(void);
+#ifdef CONFIG_TRACING
+asmlinkage void trace_page_fault(void);
+#else
+#define trace_page_fault page_fault
+#endif
+#define trace_divide_error divide_error
+#define trace_bounds bounds
+#define trace_invalid_op invalid_op
+#define trace_device_not_available device_not_available
+#define trace_coprocessor_segment_overrun coprocessor_segment_overrun
+#define trace_invalid_TSS invalid_TSS
+#define trace_segment_not_present segment_not_present
+#define trace_general_protection general_protection
+#define trace_spurious_interrupt_bug spurious_interrupt_bug
+#define trace_coprocessor_error coprocessor_error
+#define trace_alignment_check alignment_check
+#define trace_simd_coprocessor_error simd_coprocessor_error
+#define trace_async_page_fault async_page_fault
+
dotraplinkage void do_divide_error(struct pt_regs *, long);
dotraplinkage void do_debug(struct pt_regs *, long);
dotraplinkage void do_nmi(struct pt_regs *, long);
@@ -55,6 +74,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *);
#endif
dotraplinkage void do_general_protection(struct pt_regs *, long);
dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
+#ifdef CONFIG_TRACING
+dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
+#endif
dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
dotraplinkage void do_alignment_check(struct pt_regs *, long);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 2cfbc3a..c9eb4e2 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1244,6 +1244,16 @@ return_to_handler:
*/
.pushsection .kprobes.text, "ax"
+#ifdef CONFIG_TRACING
+ENTRY(trace_page_fault)
+ RING0_EC_FRAME
+ ASM_CLAC
+ pushl_cfi $trace_do_page_fault
+ jmp error_code
+ CFI_ENDPROC
+END(trace_page_fault)
+#endif
+
ENTRY(page_fault)
RING0_EC_FRAME
ASM_CLAC
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1b69951..5136404 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1295,6 +1295,17 @@ ENTRY(\sym)
END(\sym)
.endm
+#ifdef CONFIG_TRACING
+.macro trace_errorentry sym do_sym
+errorentry trace(\sym) trace(\do_sym)
+errorentry \sym \do_sym
+.endm
+#else
+.macro trace_errorentry sym do_sym
+errorentry \sym \do_sym
+.endm
+#endif
+
/* error code is on the stack already */
.macro paranoiderrorentry sym do_sym
ENTRY(\sym)
@@ -1497,7 +1508,7 @@ zeroentry xen_int3 do_int3
errorentry xen_stack_segment do_stack_segment
#endif
errorentry general_protection do_general_protection
-errorentry page_fault do_page_fault
+trace_errorentry page_fault do_page_fault
#ifdef CONFIG_KVM_GUEST
errorentry async_page_fault do_async_page_fault
#endif
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 1be8e43..aebb2bf 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -162,7 +162,7 @@ asmlinkage void __init x86_64_start_kernel(char * real_mode_data)
clear_bss();
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
- set_intr_gate(i, &early_idt_handlers[i]);
+ set_intr_gate_raw(i, &early_idt_handlers[i]);
load_idt((const struct desc_ptr *)&idt_descr);
copy_bootdata(__va(real_mode_data));
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index a2a1fbc..2ca2354 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -206,7 +206,7 @@ void __init native_init_IRQ(void)
i = FIRST_EXTERNAL_VECTOR;
for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
- set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
+ set_intr_gate_raw(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
if (!acpi_ioapic && !of_ioapic)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 697b93a..ba202ee 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -464,7 +464,7 @@ static struct notifier_block kvm_cpu_notifier = {
static void __init kvm_apf_trap_init(void)
{
- set_intr_gate(14, &async_page_fault);
+ set_intr_gate(14, async_page_fault);
}
void __init kvm_guest_init(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 8c8093b..1c9d0ad 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -713,7 +713,7 @@ void __init early_trap_init(void)
/* int3 can be called from all */
set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
#ifdef CONFIG_X86_32
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
load_idt(&idt_descr);
}
@@ -721,7 +721,7 @@ void __init early_trap_init(void)
void __init early_trap_pf_init(void)
{
#ifdef CONFIG_X86_64
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
}
@@ -737,30 +737,30 @@ void __init trap_init(void)
early_iounmap(p, 4);
#endif
- set_intr_gate(X86_TRAP_DE, ÷_error);
+ set_intr_gate(X86_TRAP_DE, divide_error);
set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
/* int4 can be called from all */
set_system_intr_gate(X86_TRAP_OF, &overflow);
- set_intr_gate(X86_TRAP_BR, &bounds);
- set_intr_gate(X86_TRAP_UD, &invalid_op);
- set_intr_gate(X86_TRAP_NM, &device_not_available);
+ set_intr_gate(X86_TRAP_BR, bounds);
+ set_intr_gate(X86_TRAP_UD, invalid_op);
+ set_intr_gate(X86_TRAP_NM, device_not_available);
#ifdef CONFIG_X86_32
set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
#else
set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
#endif
- set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
- set_intr_gate(X86_TRAP_TS, &invalid_TSS);
- set_intr_gate(X86_TRAP_NP, &segment_not_present);
+ set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
+ set_intr_gate(X86_TRAP_TS, invalid_TSS);
+ set_intr_gate(X86_TRAP_NP, segment_not_present);
set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
- set_intr_gate(X86_TRAP_GP, &general_protection);
- set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
- set_intr_gate(X86_TRAP_MF, &coprocessor_error);
- set_intr_gate(X86_TRAP_AC, &alignment_check);
+ set_intr_gate(X86_TRAP_GP, general_protection);
+ set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
+ set_intr_gate(X86_TRAP_MF, coprocessor_error);
+ set_intr_gate(X86_TRAP_AC, alignment_check);
#ifdef CONFIG_X86_MCE
set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
#endif
- set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error);
+ set_intr_gate(X86_TRAP_XF, simd_coprocessor_error);
/* Reserve all the builtin and the syscall vector: */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 23d8e5f..6a19ad9 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_physaddr.o := $(nostackp)
CFLAGS_setup_nx.o := $(nostackp)
+CFLAGS_fault.o := -I$(src)/../include/asm/trace
+
obj-$(CONFIG_X86_PAT) += pat_rbtree.o
obj-$(CONFIG_SMP) += tlb.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 654be4a..f515154 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -20,6 +20,9 @@
#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
#include <asm/fixmap.h> /* VSYSCALL_START */
+#define CREATE_TRACE_POINTS
+#include <asm/trace/exceptions.h>
+
/*
* Page fault error code bits:
*
@@ -1230,3 +1233,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
__do_page_fault(regs, error_code);
exception_exit(prev_state);
}
+
+static void trace_page_fault_entries(struct pt_regs *regs,
+ unsigned long error_code)
+{
+ if (user_mode(regs))
+ trace_user_page_fault(read_cr2(), regs, error_code);
+ else
+ trace_kernel_page_fault(read_cr2(), regs, error_code);
+}
+
+dotraplinkage void __kprobes
+trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+ enum ctx_state prev_state;
+ prev_state = exception_enter();
+ trace_page_fault_entries(regs, error_code);
+ __do_page_fault(regs, error_code);
+ exception_exit(prev_state);
+}
--
1.8.2.1
|
|
From: Seiji A. <sei...@hd...> - 2013-09-06 16:53:50
|
> -----Original Message-----
> From: Steven Rostedt [mailto:ro...@go...]
> Sent: Friday, September 06, 2013 12:50 PM
> To: Seiji Aguchi
> Cc: lin...@vg...; x8...@ke...; hp...@zy...; mi...@el...; bp...@al...; tg...@li...;
> fde...@gm...; rap...@gm...; dle...@li...; Tomoki Sekiyama
> Subject: Re: [PATCH v2] Introduce page fault tracepoint
>
> On Fri, 23 Aug 2013 11:37:43 -0400
> Seiji Aguchi <sei...@hd...> wrote:
>
>
> > +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
> > +#define _TRACE_PAGE_FAULT_H
> > +
> > +#include <linux/tracepoint.h>
> > +
> > +extern void trace_irq_vector_regfunc(void);
> > +extern void trace_irq_vector_unregfunc(void);
> > +
> > +DECLARE_EVENT_CLASS(x86_exceptions,
> > +
> > + TP_PROTO(unsigned long address, struct pt_regs *regs,
> > + unsigned long error_code),
> > +
> > + TP_ARGS(address, regs, error_code),
> > +
> > + TP_STRUCT__entry(
> > + __field( unsigned long, address )
> > + __field( struct pt_regs *, regs )
> > + __field( unsigned long, error_code )
> > + ),
> > +
> > + TP_fast_assign(
> > + __entry->address = address;
> > + __entry->regs = regs;
> > + __entry->error_code = error_code;
> > + ),
> > +
> > + TP_printk("address=0x%lx ip=0x%lx error_code=0x%lx",
> > + __entry->address, __entry->regs->ip, __entry->error_code) );
>
> This is sure to crash the kernel.
>
> You just saved the address of a pointer to some task's stack in the
> ring buffer. And then on output (which can happen a long time from when
> it was recorded), you are dereferencing that same address!
>
> That __entry->regs->ip *will* crash the kernel!
>
> What you want is to save ip in the fast_assign:
>
> __entry->ip = regs->ip
>
> And then print that. Never dereference a pointer directly from the ring
> buffer unless it's a constant value (like a global string).
I see..
Thank you for reviewing.
I will fix it.
Seiji
|
|
From: Steven R. <ro...@go...> - 2013-09-06 16:49:44
|
On Fri, 23 Aug 2013 11:37:43 -0400
Seiji Aguchi <sei...@hd...> wrote:
> +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_PAGE_FAULT_H
> +
> +#include <linux/tracepoint.h>
> +
> +extern void trace_irq_vector_regfunc(void);
> +extern void trace_irq_vector_unregfunc(void);
> +
> +DECLARE_EVENT_CLASS(x86_exceptions,
> +
> + TP_PROTO(unsigned long address, struct pt_regs *regs,
> + unsigned long error_code),
> +
> + TP_ARGS(address, regs, error_code),
> +
> + TP_STRUCT__entry(
> + __field( unsigned long, address )
> + __field( struct pt_regs *, regs )
> + __field( unsigned long, error_code )
> + ),
> +
> + TP_fast_assign(
> + __entry->address = address;
> + __entry->regs = regs;
> + __entry->error_code = error_code;
> + ),
> +
> + TP_printk("address=0x%lx ip=0x%lx error_code=0x%lx",
> + __entry->address, __entry->regs->ip, __entry->error_code) );
This is sure to crash the kernel.
You just saved the address of a pointer to some task's stack in the
ring buffer. And then on output (which can happen a long time from when
it was recorded), you are dereferencing that same address!
That __entry->regs->ip *will* crash the kernel!
What you want is to save ip in the fast_assign:
__entry->ip = regs->ip
And then print that. Never dereference a pointer directly from the ring
buffer unless it's a constant value (like a global string).
-- Steve
> +
|
|
From: Seiji A. <sei...@hd...> - 2013-09-06 14:47:58
|
Any comment? > -----Original Message----- > From: lin...@vg... [mailto:lin...@vg...] On Behalf Of Seiji Aguchi > Sent: Friday, August 23, 2013 11:38 AM > To: lin...@vg...; x8...@ke... > Cc: hp...@zy...; ro...@go...; mi...@el...; bp...@al...; tg...@li...; fde...@gm...; > rap...@gm...; dle...@li...; Tomoki Sekiyama > Subject: [PATCH v2] Introduce page fault tracepoint > > Change from v1 > - Print regs->ip instead of regs to know where the page fault event happened > (Suggested by Steven Rostedt) > > > This patch introduces page fault tracepoints to x86 architecture > by switching IDT. > > [Use case of page fault events] > > Two events, for user and kernel spaces, are introduced at the beginning of > page fault handler. > > - User space event > There is a request of page fault event for user space as below. > > http://marc.info/?l=linux-mm&m=136807959830182&w=2 > http://marc.info/?l=linux-mm&m=136807959130175&w=2 > > - Kernel space event: > Overhead in kernel space is measurable by enabling it. > > [Creating IDT] > > A way to create IDT is as below. > > - Introduce set_intr_gate_raw() to register just non-trace handler to IDT. > This is used at boot time which tracing is disabled. > - Make set_intr_gate() macro so that it can register trace handler to > trace IDT and non-trace handler to normal IDT. > > Signed-off-by: Seiji Aguchi <sei...@hd...> > --- > arch/x86/include/asm/desc.h | 33 +++++++++++++++++---- > arch/x86/include/asm/hw_irq.h | 14 ++++++++- > arch/x86/include/asm/trace/exceptions.h | 51 +++++++++++++++++++++++++++++++++ > arch/x86/include/asm/traps.h | 22 ++++++++++++++ > arch/x86/kernel/entry_32.S | 10 +++++++ > arch/x86/kernel/entry_64.S | 13 ++++++++- > arch/x86/kernel/head64.c | 2 +- > arch/x86/kernel/irqinit.c | 2 +- > arch/x86/kernel/kvm.c | 2 +- > arch/x86/kernel/traps.c | 28 +++++++++--------- > arch/x86/mm/Makefile | 2 ++ > arch/x86/mm/fault.c | 22 ++++++++++++++ > 12 files changed, 177 insertions(+), 24 deletions(-) > create mode 100644 arch/x86/include/asm/trace/exceptions.h > > diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h > index b90e5df..c04302b 100644 > --- a/arch/x86/include/asm/desc.h > +++ b/arch/x86/include/asm/desc.h > @@ -327,10 +327,28 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate) > { > write_idt_entry(trace_idt_table, entry, gate); > } > + > +static inline void _trace_set_gate(int gate, unsigned type, void *addr, > + unsigned dpl, unsigned ist, unsigned seg) > +{ > + gate_desc s; > + > + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); > + /* > + * does not need to be atomic because it is only done once at > + * setup time > + */ > + write_trace_idt_entry(gate, &s); > +} > #else > static inline void write_trace_idt_entry(int entry, const gate_desc *gate) > { > } > + > +static inline void _trace_set_gate(int gate, unsigned type, void *addr, > + unsigned dpl, unsigned ist, unsigned seg) > +{ > +} > #endif > > static inline void _set_gate(int gate, unsigned type, void *addr, > @@ -353,12 +371,20 @@ static inline void _set_gate(int gate, unsigned type, void *addr, > * Pentium F0 0F bugfix can have resulted in the mapped > * IDT being write-protected. > */ > -static inline void set_intr_gate(unsigned int n, void *addr) > +static inline void set_intr_gate_raw(unsigned int n, void *addr) > { > BUG_ON((unsigned)n > 0xFF); > _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); > } > > +#define set_intr_gate(n, addr) \ > + do { \ > + BUG_ON((unsigned)n > 0xFF); \ > + _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); \ > + _trace_set_gate(n, GATE_INTERRUPT, trace_##addr, 0, 0, \ > + __KERNEL_CS); \ > + } while (0) > + > extern int first_system_vector; > /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ > extern unsigned long used_vectors[]; > @@ -395,10 +421,7 @@ static inline void trace_set_intr_gate(unsigned int gate, void *addr) > #define __trace_alloc_intr_gate(n, addr) > #endif > > -static inline void __alloc_intr_gate(unsigned int n, void *addr) > -{ > - set_intr_gate(n, addr); > -} > +#define __alloc_intr_gate(n, addr) set_intr_gate(n, addr) > > #define alloc_intr_gate(n, addr) \ > do { \ > diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h > index e4ac559..fbd73b7 100644 > --- a/arch/x86/include/asm/hw_irq.h > +++ b/arch/x86/include/asm/hw_irq.h > @@ -89,10 +89,22 @@ extern void trace_reschedule_interrupt(void); > extern void trace_threshold_interrupt(void); > extern void trace_call_function_interrupt(void); > extern void trace_call_function_single_interrupt(void); > +#else /* CONFIG_TRACING */ > +#define trace_apic_timer_interrupt apic_timer_interrupt > +#define trace_x86_platform_ipi x86_platform_ipi > +#define trace_error_interrupt error_interrupt > +#define trace_irq_work_interrupt irq_work_interrupt > +#define trace_spurious_interrupt spurious_interrupt > +#define trace_thermal_interrupt thermal_interrupt > +#define trace_reschedule_interrupt reschedule_interrupt > +#define trace_threshold_interrupt threshold_interrupt > +#define trace_call_function_interrupt call_function_interrupt > +#define trace_call_function_single_interrupt call_function_single_interrupt > +#endif > + > #define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt > #define trace_reboot_interrupt reboot_interrupt > #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi > -#endif /* CONFIG_TRACING */ > > /* IOAPIC */ > #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) > diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h > new file mode 100644 > index 0000000..a379a49 > --- /dev/null > +++ b/arch/x86/include/asm/trace/exceptions.h > @@ -0,0 +1,51 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM exceptions > + > +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_PAGE_FAULT_H > + > +#include <linux/tracepoint.h> > + > +extern void trace_irq_vector_regfunc(void); > +extern void trace_irq_vector_unregfunc(void); > + > +DECLARE_EVENT_CLASS(x86_exceptions, > + > + TP_PROTO(unsigned long address, struct pt_regs *regs, > + unsigned long error_code), > + > + TP_ARGS(address, regs, error_code), > + > + TP_STRUCT__entry( > + __field( unsigned long, address ) > + __field( struct pt_regs *, regs ) > + __field( unsigned long, error_code ) > + ), > + > + TP_fast_assign( > + __entry->address = address; > + __entry->regs = regs; > + __entry->error_code = error_code; > + ), > + > + TP_printk("address=0x%lx ip=0x%lx error_code=0x%lx", > + __entry->address, __entry->regs->ip, __entry->error_code) ); > + > +#define DEFINE_PAGE_FAULT_EVENT(name) \ > +DEFINE_EVENT_FN(x86_exceptions, name, \ > + TP_PROTO(unsigned long address, struct pt_regs *regs, \ > + unsigned long error_code), \ > + TP_ARGS(address, regs, error_code), \ > + trace_irq_vector_regfunc, \ > + trace_irq_vector_unregfunc); > + > +DEFINE_PAGE_FAULT_EVENT(user_page_fault); > +DEFINE_PAGE_FAULT_EVENT(kernel_page_fault); > + > +#undef TRACE_INCLUDE_PATH > +#define TRACE_INCLUDE_PATH . > +#define TRACE_INCLUDE_FILE exceptions > +#endif /* _TRACE_PAGE_FAULT_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h > index 88eae2a..adf9258 100644 > --- a/arch/x86/include/asm/traps.h > +++ b/arch/x86/include/asm/traps.h > @@ -41,6 +41,25 @@ asmlinkage void machine_check(void); > #endif /* CONFIG_X86_MCE */ > asmlinkage void simd_coprocessor_error(void); > > +#ifdef CONFIG_TRACING > +asmlinkage void trace_page_fault(void); > +#else > +#define trace_page_fault page_fault > +#endif > +#define trace_divide_error divide_error > +#define trace_bounds bounds > +#define trace_invalid_op invalid_op > +#define trace_device_not_available device_not_available > +#define trace_coprocessor_segment_overrun coprocessor_segment_overrun > +#define trace_invalid_TSS invalid_TSS > +#define trace_segment_not_present segment_not_present > +#define trace_general_protection general_protection > +#define trace_spurious_interrupt_bug spurious_interrupt_bug > +#define trace_coprocessor_error coprocessor_error > +#define trace_alignment_check alignment_check > +#define trace_simd_coprocessor_error simd_coprocessor_error > +#define trace_async_page_fault async_page_fault > + > dotraplinkage void do_divide_error(struct pt_regs *, long); > dotraplinkage void do_debug(struct pt_regs *, long); > dotraplinkage void do_nmi(struct pt_regs *, long); > @@ -59,6 +78,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *); > #endif > dotraplinkage void do_general_protection(struct pt_regs *, long); > dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); > +#ifdef CONFIG_TRACING > +dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); > +#endif > dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); > dotraplinkage void do_coprocessor_error(struct pt_regs *, long); > dotraplinkage void do_alignment_check(struct pt_regs *, long); > diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S > index 2cfbc3a..c9eb4e2 100644 > --- a/arch/x86/kernel/entry_32.S > +++ b/arch/x86/kernel/entry_32.S > @@ -1244,6 +1244,16 @@ return_to_handler: > */ > .pushsection .kprobes.text, "ax" > > +#ifdef CONFIG_TRACING > +ENTRY(trace_page_fault) > + RING0_EC_FRAME > + ASM_CLAC > + pushl_cfi $trace_do_page_fault > + jmp error_code > + CFI_ENDPROC > +END(trace_page_fault) > +#endif > + > ENTRY(page_fault) > RING0_EC_FRAME > ASM_CLAC > diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S > index 1b69951..5136404 100644 > --- a/arch/x86/kernel/entry_64.S > +++ b/arch/x86/kernel/entry_64.S > @@ -1295,6 +1295,17 @@ ENTRY(\sym) > END(\sym) > .endm > > +#ifdef CONFIG_TRACING > +.macro trace_errorentry sym do_sym > +errorentry trace(\sym) trace(\do_sym) > +errorentry \sym \do_sym > +.endm > +#else > +.macro trace_errorentry sym do_sym > +errorentry \sym \do_sym > +.endm > +#endif > + > /* error code is on the stack already */ > .macro paranoiderrorentry sym do_sym > ENTRY(\sym) > @@ -1497,7 +1508,7 @@ zeroentry xen_int3 do_int3 > errorentry xen_stack_segment do_stack_segment > #endif > errorentry general_protection do_general_protection > -errorentry page_fault do_page_fault > +trace_errorentry page_fault do_page_fault > #ifdef CONFIG_KVM_GUEST > errorentry async_page_fault do_async_page_fault > #endif > diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c > index 55b6761..67a0649 100644 > --- a/arch/x86/kernel/head64.c > +++ b/arch/x86/kernel/head64.c > @@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * real_mode_data) > clear_bss(); > > for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) > - set_intr_gate(i, &early_idt_handlers[i]); > + set_intr_gate_raw(i, &early_idt_handlers[i]); > load_idt((const struct desc_ptr *)&idt_descr); > > copy_bootdata(__va(real_mode_data)); > diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c > index a2a1fbc..2ca2354 100644 > --- a/arch/x86/kernel/irqinit.c > +++ b/arch/x86/kernel/irqinit.c > @@ -206,7 +206,7 @@ void __init native_init_IRQ(void) > i = FIRST_EXTERNAL_VECTOR; > for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { > /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ > - set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); > + set_intr_gate_raw(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); > } > > if (!acpi_ioapic && !of_ioapic) > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c > index a96d32c..12b384e 100644 > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -462,7 +462,7 @@ static struct notifier_block kvm_cpu_notifier = { > > static void __init kvm_apf_trap_init(void) > { > - set_intr_gate(14, &async_page_fault); > + set_intr_gate(14, async_page_fault); > } > > void __init kvm_guest_init(void) > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index 1b23a1c..eadd251 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -709,7 +709,7 @@ void __init early_trap_init(void) > /* int3 can be called from all */ > set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); > #ifdef CONFIG_X86_32 > - set_intr_gate(X86_TRAP_PF, &page_fault); > + set_intr_gate(X86_TRAP_PF, page_fault); > #endif > load_idt(&idt_descr); > } > @@ -717,7 +717,7 @@ void __init early_trap_init(void) > void __init early_trap_pf_init(void) > { > #ifdef CONFIG_X86_64 > - set_intr_gate(X86_TRAP_PF, &page_fault); > + set_intr_gate(X86_TRAP_PF, page_fault); > #endif > } > > @@ -733,30 +733,30 @@ void __init trap_init(void) > early_iounmap(p, 4); > #endif > > - set_intr_gate(X86_TRAP_DE, ÷_error); > + set_intr_gate(X86_TRAP_DE, divide_error); > set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); > /* int4 can be called from all */ > set_system_intr_gate(X86_TRAP_OF, &overflow); > - set_intr_gate(X86_TRAP_BR, &bounds); > - set_intr_gate(X86_TRAP_UD, &invalid_op); > - set_intr_gate(X86_TRAP_NM, &device_not_available); > + set_intr_gate(X86_TRAP_BR, bounds); > + set_intr_gate(X86_TRAP_UD, invalid_op); > + set_intr_gate(X86_TRAP_NM, device_not_available); > #ifdef CONFIG_X86_32 > set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS); > #else > set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); > #endif > - set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun); > - set_intr_gate(X86_TRAP_TS, &invalid_TSS); > - set_intr_gate(X86_TRAP_NP, &segment_not_present); > + set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); > + set_intr_gate(X86_TRAP_TS, invalid_TSS); > + set_intr_gate(X86_TRAP_NP, segment_not_present); > set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK); > - set_intr_gate(X86_TRAP_GP, &general_protection); > - set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug); > - set_intr_gate(X86_TRAP_MF, &coprocessor_error); > - set_intr_gate(X86_TRAP_AC, &alignment_check); > + set_intr_gate(X86_TRAP_GP, general_protection); > + set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); > + set_intr_gate(X86_TRAP_MF, coprocessor_error); > + set_intr_gate(X86_TRAP_AC, alignment_check); > #ifdef CONFIG_X86_MCE > set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK); > #endif > - set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error); > + set_intr_gate(X86_TRAP_XF, simd_coprocessor_error); > > /* Reserve all the builtin and the syscall vector: */ > for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) > diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile > index 23d8e5f..6a19ad9 100644 > --- a/arch/x86/mm/Makefile > +++ b/arch/x86/mm/Makefile > @@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector) > CFLAGS_physaddr.o := $(nostackp) > CFLAGS_setup_nx.o := $(nostackp) > > +CFLAGS_fault.o := -I$(src)/../include/asm/trace > + > obj-$(CONFIG_X86_PAT) += pat_rbtree.o > obj-$(CONFIG_SMP) += tlb.o > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index 654be4a..f515154 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -20,6 +20,9 @@ > #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ > #include <asm/fixmap.h> /* VSYSCALL_START */ > > +#define CREATE_TRACE_POINTS > +#include <asm/trace/exceptions.h> > + > /* > * Page fault error code bits: > * > @@ -1230,3 +1233,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) > __do_page_fault(regs, error_code); > exception_exit(prev_state); > } > + > +static void trace_page_fault_entries(struct pt_regs *regs, > + unsigned long error_code) > +{ > + if (user_mode(regs)) > + trace_user_page_fault(read_cr2(), regs, error_code); > + else > + trace_kernel_page_fault(read_cr2(), regs, error_code); > +} > + > +dotraplinkage void __kprobes > +trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) > +{ > + enum ctx_state prev_state; > + prev_state = exception_enter(); > + trace_page_fault_entries(regs, error_code); > + __do_page_fault(regs, error_code); > + exception_exit(prev_state); > +} > -- > 1.8.2.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to maj...@vg... > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ |
|
From: Seiji A. <sei...@hd...> - 2013-08-23 15:39:33
|
Change from v1
- Print regs->ip instead of regs to know where the page fault event happened
(Suggested by Steven Rostedt)
This patch introduces page fault tracepoints to x86 architecture
by switching IDT.
[Use case of page fault events]
Two events, for user and kernel spaces, are introduced at the beginning of
page fault handler.
- User space event
There is a request of page fault event for user space as below.
http://marc.info/?l=linux-mm&m=136807959830182&w=2
http://marc.info/?l=linux-mm&m=136807959130175&w=2
- Kernel space event:
Overhead in kernel space is measurable by enabling it.
[Creating IDT]
A way to create IDT is as below.
- Introduce set_intr_gate_raw() to register just non-trace handler to IDT.
This is used at boot time which tracing is disabled.
- Make set_intr_gate() macro so that it can register trace handler to
trace IDT and non-trace handler to normal IDT.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
arch/x86/include/asm/desc.h | 33 +++++++++++++++++----
arch/x86/include/asm/hw_irq.h | 14 ++++++++-
arch/x86/include/asm/trace/exceptions.h | 51 +++++++++++++++++++++++++++++++++
arch/x86/include/asm/traps.h | 22 ++++++++++++++
arch/x86/kernel/entry_32.S | 10 +++++++
arch/x86/kernel/entry_64.S | 13 ++++++++-
arch/x86/kernel/head64.c | 2 +-
arch/x86/kernel/irqinit.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/kernel/traps.c | 28 +++++++++---------
arch/x86/mm/Makefile | 2 ++
arch/x86/mm/fault.c | 22 ++++++++++++++
12 files changed, 177 insertions(+), 24 deletions(-)
create mode 100644 arch/x86/include/asm/trace/exceptions.h
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index b90e5df..c04302b 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -327,10 +327,28 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
write_idt_entry(trace_idt_table, entry, gate);
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+ gate_desc s;
+
+ pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
+ /*
+ * does not need to be atomic because it is only done once at
+ * setup time
+ */
+ write_trace_idt_entry(gate, &s);
+}
#else
static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+}
#endif
static inline void _set_gate(int gate, unsigned type, void *addr,
@@ -353,12 +371,20 @@ static inline void _set_gate(int gate, unsigned type, void *addr,
* Pentium F0 0F bugfix can have resulted in the mapped
* IDT being write-protected.
*/
-static inline void set_intr_gate(unsigned int n, void *addr)
+static inline void set_intr_gate_raw(unsigned int n, void *addr)
{
BUG_ON((unsigned)n > 0xFF);
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}
+#define set_intr_gate(n, addr) \
+ do { \
+ BUG_ON((unsigned)n > 0xFF); \
+ _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); \
+ _trace_set_gate(n, GATE_INTERRUPT, trace_##addr, 0, 0, \
+ __KERNEL_CS); \
+ } while (0)
+
extern int first_system_vector;
/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
extern unsigned long used_vectors[];
@@ -395,10 +421,7 @@ static inline void trace_set_intr_gate(unsigned int gate, void *addr)
#define __trace_alloc_intr_gate(n, addr)
#endif
-static inline void __alloc_intr_gate(unsigned int n, void *addr)
-{
- set_intr_gate(n, addr);
-}
+#define __alloc_intr_gate(n, addr) set_intr_gate(n, addr)
#define alloc_intr_gate(n, addr) \
do { \
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index e4ac559..fbd73b7 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -89,10 +89,22 @@ extern void trace_reschedule_interrupt(void);
extern void trace_threshold_interrupt(void);
extern void trace_call_function_interrupt(void);
extern void trace_call_function_single_interrupt(void);
+#else /* CONFIG_TRACING */
+#define trace_apic_timer_interrupt apic_timer_interrupt
+#define trace_x86_platform_ipi x86_platform_ipi
+#define trace_error_interrupt error_interrupt
+#define trace_irq_work_interrupt irq_work_interrupt
+#define trace_spurious_interrupt spurious_interrupt
+#define trace_thermal_interrupt thermal_interrupt
+#define trace_reschedule_interrupt reschedule_interrupt
+#define trace_threshold_interrupt threshold_interrupt
+#define trace_call_function_interrupt call_function_interrupt
+#define trace_call_function_single_interrupt call_function_single_interrupt
+#endif
+
#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
#define trace_reboot_interrupt reboot_interrupt
#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
-#endif /* CONFIG_TRACING */
/* IOAPIC */
#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
new file mode 100644
index 0000000..a379a49
--- /dev/null
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -0,0 +1,51 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM exceptions
+
+#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PAGE_FAULT_H
+
+#include <linux/tracepoint.h>
+
+extern void trace_irq_vector_regfunc(void);
+extern void trace_irq_vector_unregfunc(void);
+
+DECLARE_EVENT_CLASS(x86_exceptions,
+
+ TP_PROTO(unsigned long address, struct pt_regs *regs,
+ unsigned long error_code),
+
+ TP_ARGS(address, regs, error_code),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, address )
+ __field( struct pt_regs *, regs )
+ __field( unsigned long, error_code )
+ ),
+
+ TP_fast_assign(
+ __entry->address = address;
+ __entry->regs = regs;
+ __entry->error_code = error_code;
+ ),
+
+ TP_printk("address=0x%lx ip=0x%lx error_code=0x%lx",
+ __entry->address, __entry->regs->ip, __entry->error_code) );
+
+#define DEFINE_PAGE_FAULT_EVENT(name) \
+DEFINE_EVENT_FN(x86_exceptions, name, \
+ TP_PROTO(unsigned long address, struct pt_regs *regs, \
+ unsigned long error_code), \
+ TP_ARGS(address, regs, error_code), \
+ trace_irq_vector_regfunc, \
+ trace_irq_vector_unregfunc);
+
+DEFINE_PAGE_FAULT_EVENT(user_page_fault);
+DEFINE_PAGE_FAULT_EVENT(kernel_page_fault);
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE exceptions
+#endif /* _TRACE_PAGE_FAULT_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 88eae2a..adf9258 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -41,6 +41,25 @@ asmlinkage void machine_check(void);
#endif /* CONFIG_X86_MCE */
asmlinkage void simd_coprocessor_error(void);
+#ifdef CONFIG_TRACING
+asmlinkage void trace_page_fault(void);
+#else
+#define trace_page_fault page_fault
+#endif
+#define trace_divide_error divide_error
+#define trace_bounds bounds
+#define trace_invalid_op invalid_op
+#define trace_device_not_available device_not_available
+#define trace_coprocessor_segment_overrun coprocessor_segment_overrun
+#define trace_invalid_TSS invalid_TSS
+#define trace_segment_not_present segment_not_present
+#define trace_general_protection general_protection
+#define trace_spurious_interrupt_bug spurious_interrupt_bug
+#define trace_coprocessor_error coprocessor_error
+#define trace_alignment_check alignment_check
+#define trace_simd_coprocessor_error simd_coprocessor_error
+#define trace_async_page_fault async_page_fault
+
dotraplinkage void do_divide_error(struct pt_regs *, long);
dotraplinkage void do_debug(struct pt_regs *, long);
dotraplinkage void do_nmi(struct pt_regs *, long);
@@ -59,6 +78,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *);
#endif
dotraplinkage void do_general_protection(struct pt_regs *, long);
dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
+#ifdef CONFIG_TRACING
+dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
+#endif
dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
dotraplinkage void do_alignment_check(struct pt_regs *, long);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 2cfbc3a..c9eb4e2 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1244,6 +1244,16 @@ return_to_handler:
*/
.pushsection .kprobes.text, "ax"
+#ifdef CONFIG_TRACING
+ENTRY(trace_page_fault)
+ RING0_EC_FRAME
+ ASM_CLAC
+ pushl_cfi $trace_do_page_fault
+ jmp error_code
+ CFI_ENDPROC
+END(trace_page_fault)
+#endif
+
ENTRY(page_fault)
RING0_EC_FRAME
ASM_CLAC
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1b69951..5136404 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1295,6 +1295,17 @@ ENTRY(\sym)
END(\sym)
.endm
+#ifdef CONFIG_TRACING
+.macro trace_errorentry sym do_sym
+errorentry trace(\sym) trace(\do_sym)
+errorentry \sym \do_sym
+.endm
+#else
+.macro trace_errorentry sym do_sym
+errorentry \sym \do_sym
+.endm
+#endif
+
/* error code is on the stack already */
.macro paranoiderrorentry sym do_sym
ENTRY(\sym)
@@ -1497,7 +1508,7 @@ zeroentry xen_int3 do_int3
errorentry xen_stack_segment do_stack_segment
#endif
errorentry general_protection do_general_protection
-errorentry page_fault do_page_fault
+trace_errorentry page_fault do_page_fault
#ifdef CONFIG_KVM_GUEST
errorentry async_page_fault do_async_page_fault
#endif
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 55b6761..67a0649 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
clear_bss();
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
- set_intr_gate(i, &early_idt_handlers[i]);
+ set_intr_gate_raw(i, &early_idt_handlers[i]);
load_idt((const struct desc_ptr *)&idt_descr);
copy_bootdata(__va(real_mode_data));
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index a2a1fbc..2ca2354 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -206,7 +206,7 @@ void __init native_init_IRQ(void)
i = FIRST_EXTERNAL_VECTOR;
for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
- set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
+ set_intr_gate_raw(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
if (!acpi_ioapic && !of_ioapic)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a96d32c..12b384e 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -462,7 +462,7 @@ static struct notifier_block kvm_cpu_notifier = {
static void __init kvm_apf_trap_init(void)
{
- set_intr_gate(14, &async_page_fault);
+ set_intr_gate(14, async_page_fault);
}
void __init kvm_guest_init(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 1b23a1c..eadd251 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -709,7 +709,7 @@ void __init early_trap_init(void)
/* int3 can be called from all */
set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
#ifdef CONFIG_X86_32
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
load_idt(&idt_descr);
}
@@ -717,7 +717,7 @@ void __init early_trap_init(void)
void __init early_trap_pf_init(void)
{
#ifdef CONFIG_X86_64
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
}
@@ -733,30 +733,30 @@ void __init trap_init(void)
early_iounmap(p, 4);
#endif
- set_intr_gate(X86_TRAP_DE, ÷_error);
+ set_intr_gate(X86_TRAP_DE, divide_error);
set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
/* int4 can be called from all */
set_system_intr_gate(X86_TRAP_OF, &overflow);
- set_intr_gate(X86_TRAP_BR, &bounds);
- set_intr_gate(X86_TRAP_UD, &invalid_op);
- set_intr_gate(X86_TRAP_NM, &device_not_available);
+ set_intr_gate(X86_TRAP_BR, bounds);
+ set_intr_gate(X86_TRAP_UD, invalid_op);
+ set_intr_gate(X86_TRAP_NM, device_not_available);
#ifdef CONFIG_X86_32
set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
#else
set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
#endif
- set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
- set_intr_gate(X86_TRAP_TS, &invalid_TSS);
- set_intr_gate(X86_TRAP_NP, &segment_not_present);
+ set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
+ set_intr_gate(X86_TRAP_TS, invalid_TSS);
+ set_intr_gate(X86_TRAP_NP, segment_not_present);
set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
- set_intr_gate(X86_TRAP_GP, &general_protection);
- set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
- set_intr_gate(X86_TRAP_MF, &coprocessor_error);
- set_intr_gate(X86_TRAP_AC, &alignment_check);
+ set_intr_gate(X86_TRAP_GP, general_protection);
+ set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
+ set_intr_gate(X86_TRAP_MF, coprocessor_error);
+ set_intr_gate(X86_TRAP_AC, alignment_check);
#ifdef CONFIG_X86_MCE
set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
#endif
- set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error);
+ set_intr_gate(X86_TRAP_XF, simd_coprocessor_error);
/* Reserve all the builtin and the syscall vector: */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 23d8e5f..6a19ad9 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_physaddr.o := $(nostackp)
CFLAGS_setup_nx.o := $(nostackp)
+CFLAGS_fault.o := -I$(src)/../include/asm/trace
+
obj-$(CONFIG_X86_PAT) += pat_rbtree.o
obj-$(CONFIG_SMP) += tlb.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 654be4a..f515154 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -20,6 +20,9 @@
#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
#include <asm/fixmap.h> /* VSYSCALL_START */
+#define CREATE_TRACE_POINTS
+#include <asm/trace/exceptions.h>
+
/*
* Page fault error code bits:
*
@@ -1230,3 +1233,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
__do_page_fault(regs, error_code);
exception_exit(prev_state);
}
+
+static void trace_page_fault_entries(struct pt_regs *regs,
+ unsigned long error_code)
+{
+ if (user_mode(regs))
+ trace_user_page_fault(read_cr2(), regs, error_code);
+ else
+ trace_kernel_page_fault(read_cr2(), regs, error_code);
+}
+
+dotraplinkage void __kprobes
+trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+ enum ctx_state prev_state;
+ prev_state = exception_enter();
+ trace_page_fault_entries(regs, error_code);
+ __do_page_fault(regs, error_code);
+ exception_exit(prev_state);
+}
--
1.8.2.1
|
|
From: Annicette C. <ann...@gm...> - 2013-08-23 12:10:28
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Document sans nom</title> </head> <body style="font-family: Helvetica, sans-serif;font-size: 11px;"> <table width="480" border="0" align="center" cellpadding="0" cellspacing="0" style="background-color:#FFF;border:1px solid #666 "> <tr> <td><a href="http://www.kitchenbazaar.fr" target="_blank"><img src="http://www.kitchenbazaar.fr/mail/img/head2.jpg" width="480" height="89" border="0" /></a></td> </tr> <tr> <td width="405" align="left" valign="top" style=" padding: 25px 15px;font-family: Helvetica, sans-serif;font-size: 11px;"> <p style="font-size:18px; color:#F52D6E;font-family: Helvetica, sans-serif;" > <strong>Annicette Coulibaly<br /> pense que cet article pourrait vous intéresser</strong> </p> <p> Hei min kjære, Vennligst Jeg trenger din hjelp<br /> Hei min kjære, Vennligst Jeg trenger din hjelp<br /> <br /> Vennligst tillate meg å presentere meg selv, jeg er Miss Annicette Coulibaly 20 år gammel kvinne fra Republikken Elfenbenskysten, Vest-Afrika, jeg er datter av avdøde Chief Sgt. Ibrahim Coulibaly (a.k.a Generelt IB). Min far var en kjent Elfenbenskysten militære leder og sjef for staber generelle for avsatte tidligere Ivorian President Laurent Gbagbo i løpet av 2002-2012 Ivorian politiske krisen / borgerkrig.<br /> <br /> Det er trist å si at han døde torsdag 28. april 2011 etter en kamp med de republikanske styrkene i Elfenbenskysten (FRCI). Du kan lese mer om min far i linken nedenfor: http://www.guardian.co.uk/world/2011/apr/28/ivory-coast-renegade-warlord-ibrahim-coulibaly <br /> <br /> <br /> Min mor Hawa inkludert min bror Zika, og min yngre søster Fatim ble alle drept i Deukoué landsbyen mens de er på flukt fra den politiske krisen / borgerkrig og jeg var på skolen i Ghana under den politiske krisen / borgerkrig i Elfenbenskysten som er grunnen Jeg er den eneste overlevende i familien min. Her er video av massakren som tar livet av familien min; http://www.youtube.com/watch?v=lfUvocodk1E <br /> <br /> Før død min far i PISAM sykehus i Cocody Abidjan, fortalte han meg om innskudd hans verdsatt to millioner åtte hundretusen (2,800,000.00 ) som han avsatt med mitt navn som eneste arving til fondet. Nå er jeg tilbake i Elfenbenskysten, og jeg har bekreftet eksistensen av pengene i banken og alle dokumentbevis som dekker de pengene er intakte.<br /> <br /> Vennligst Jeg trenger din type og umiddelbar hjelp til å overføre og investere disse pengene i landet ditt, og også komme til landet ditt for å fortsette min pedagogiske transportør.<br /> <br /> Så snart jeg mottar hurtig svar viser din interesse for å hjelpe meg å kunne overføre penger til landet ditt, og komme over til ditt land, vil jeg gi deg all nødvendig informasjon, dokumenter du kan kreve å fortsette mot å overføre penger.<br /> <br /> Til slutt, jeg er villig til å tilby deg 15% av den totale penger som modus for kompensasjon for din innsats for å hjelpe meg med denne ydmyke forespørsel som jeg tror at denne transaksjonen vil bli avsluttet i løpet av få dager betegne deg din interesse for å hjelpe meg.<br /> <br /> Takk og allmektige Gud velsigne deg.<br /> Med vennlig hilsen<br /> Annicette Coulibaly. </p> </td> </tr> <tr> <td height="25" align="center" valign="top" style=" padding:10px 10px 4px;"> <a href="http://www.kitchenbazaar.fr/coupe-tranche-mangue-p3063.htm" target="_blank" style="font-family: Helvetica, sans-serif;font-size: 16px; font-weight: bold;text-decoration:none;color:#000"> Coupe tranche mangue à 12.50 € </a> </td> </tr> <tr> <td style="padding:10px;" align="center" valign="middle" > <a href="http://www.kitchenbazaar.fr/coupe-tranche-mangue-p3063.htm" target="_blank" ><img src="http://www.kitchenbazaar.fr/images/produits/vide_tranche_mangue_1067504_raytb1.jpg" alt="Coupe tranche mangue" border="0" /></a> </td> </tr> <tr> <td style="padding:5px 10px 15px;"> <p align="left" style="font-family: Helvetica, sans-serif;font-size: 11px;" >Bénéficiez de 5 % de remise sur le montant de votre prochaine commande avec le code promo <strong>FRIEND</strong><br /> <br /> À bientôt sur <a href="http://www.kitchenbazaar.fr" style="color:#000; "><strong>Kitchen Bazaar</strong></a>, votre spécialiste en ustensiles de cuisine depuis 1967.<br/> <br/> • <strong>Livraison 72 h00</strong><br/> • <strong>Paiement sécurisé</strong><br/> • <strong>10 jours pour changer d’avis</strong> <br /> </p> </td> </tr> <tr> <td align="center" > <table cellpadding="0" cellspacing="0" border="0" width="320" align="center" > <tr> <td align="center" valign="middle" style="font-family: Helvetica, sans-serif;font-size: 12px;" > Ne ratez aucun bon plan Kitchen Bazaar,<br /> <a style="font-family: Helvetica, sans-serif;font-size: 12px;" target="_blank" href="http://www.kitchenbazaar.fr/newsletter.htm?ema...@li..." > inscrivez vous à la newsletter </a> </td> <td align="left" valign="middle" > <a style="font-family: Helvetica, sans-serif;font-size: 12px;" target="_blank" href="http://www.kitchenbazaar.fr/newsletter.htm?ema...@li..." > <img width="80" height="80" border="0" align="absmiddle" src="http://www.kitchenbazaar.fr/mail/img/news.jpg" alt="Newsletter Kitchen Bazaar"/> </a> </td> </tr> </table> </td> </tr> <tr> <td align="center" > <br /> <a title="Rejoignez-nous sur facebook" target="_blank" href="https://www.facebook.com/kitchenbazaar"> <img width="292" height="30" border="0" align="middle" title="Rejoignez-nous sur facebook" src="http://www.kitchenbazaar.fr/mail/img/btn_facebook.gif" alt="Rejoignez-nous sur facebook"/> </a> <br /> <br /> </td> </tr> </table> </body> </html> |
|
From: Steven R. <ro...@go...> - 2013-08-22 15:35:45
|
On Tue, 30 Jul 2013 18:52:33 -0400
Seiji Aguchi <sei...@hd...> wrote:
/* IOAPIC */
> #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
> diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
> new file mode 100644
> index 0000000..660fcf1
> --- /dev/null
> +++ b/arch/x86/include/asm/trace/exceptions.h
> @@ -0,0 +1,51 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM exceptions
> +
> +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_PAGE_FAULT_H
> +
> +#include <linux/tracepoint.h>
> +
> +extern void trace_irq_vector_regfunc(void);
> +extern void trace_irq_vector_unregfunc(void);
> +
> +DECLARE_EVENT_CLASS(x86_exceptions,
> +
> + TP_PROTO(unsigned long address, struct pt_regs *regs,
> + unsigned long error_code),
> +
> + TP_ARGS(address, regs, error_code),
> +
> + TP_STRUCT__entry(
> + __field( unsigned long, address )
> + __field( struct pt_regs *, regs )
> + __field( unsigned long, error_code )
> + ),
> +
> + TP_fast_assign(
> + __entry->address = address;
> + __entry->regs = regs;
> + __entry->error_code = error_code;
> + ),
> +
> + TP_printk("address=0x%lx regs=0x%p error_code=0x%lx",
> + __entry->address, __entry->regs, __entry->error_code) );
Printing the regs pointer is rather useless. This is specific for x86,
why not print the ip of where it happened and the faulting address
itself? Note, you only need to change the TP_printk() to do that. For
efficiency reasons, only pass in regs.
-- Steve
|
|
From: Seiji A. <sei...@hd...> - 2013-08-22 14:45:50
|
> Printing the regs pointer is rather useless. This is specific for x86, > why not print the ip of where it happened and the faulting address > itself? Thank you for reviewing. I will change the regs pointer to ip. > Note, you only need to change the TP_printk() to do that. For > efficiency reasons, only pass in regs. OK. Will change the TP_printk(). Seiji |
|
From: Seiji A. <sei...@hd...> - 2013-08-20 21:22:53
|
Currently, when mounting pstore file system, a read callback of efi_pstore
driver runs mutiple times as below.
- In the first read callback, scan efivar_sysfs_list from head and pass
a kmsg buffer of a entry to an upper pstore layer.
- In the second read callback, rescan efivar_sysfs_list from the entry and pass
another kmsg buffer to it.
- Repeat the scan and pass until the end of efivar_sysfs_list.
In this process, an entry is read across the multiple read function calls.
To avoid race between the read and erasion, the whole process above is
protected by a spinlock, holding in open() and releasing in close().
At the same time, kmemdup() is called to pass the buffer to pstore filesystem
during it.
And then, it causes a following lockdep warning.
To make the read callback runnable without taking spinlok,
holding off a deletion of sysfs entry if it happens while scanning it
via efi_pstore, and deleting it after the scan is completed.
To implement it, this patch introduces two flags, scanning and deleting,
to efivar_entry.
Also, __efivar_entry_get() is removed because it was used in efi_pstore only.
[ 1.143710] ------------[ cut here ]------------
[ 1.144058] WARNING: CPU: 1 PID: 1 at kernel/lockdep.c:2740
lockdep_trace_alloc+0x104/0x110()
[ 1.144058] DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))
[ 1.144058] Modules linked in:
[ 1.144058] CPU: 1 PID: 1 Comm: systemd Not tainted 3.11.0-rc5 #2
[ 1.144058] 0000000000000009 ffff8800797e9ae0 ffffffff816614a5
ffff8800797e9b28
[ 1.144058] ffff8800797e9b18 ffffffff8105510d 0000000000000080
0000000000000046
[ 1.144058] 00000000000000d0 00000000000003af ffffffff81ccd0c0
ffff8800797e9b78
[ 1.144058] Call Trace:
[ 1.144058] [<ffffffff816614a5>] dump_stack+0x54/0x74
[ 1.144058] [<ffffffff8105510d>] warn_slowpath_common+0x7d/0xa0
[ 1.144058] [<ffffffff8105517c>] warn_slowpath_fmt+0x4c/0x50
[ 1.144058] [<ffffffff8131290f>] ? vsscanf+0x57f/0x7b0
[ 1.144058] [<ffffffff810bbd74>] lockdep_trace_alloc+0x104/0x110
[ 1.144058] [<ffffffff81192da0>] __kmalloc_track_caller+0x50/0x280
[ 1.144058] [<ffffffff815147bb>] ?
efi_pstore_read_func.part.1+0x12b/0x170
[ 1.144058] [<ffffffff8115b260>] kmemdup+0x20/0x50
[ 1.144058] [<ffffffff815147bb>] efi_pstore_read_func.part.1+0x12b/0x170
[ 1.144058] [<ffffffff81514800>] ?
efi_pstore_read_func.part.1+0x170/0x170
[ 1.144058] [<ffffffff815148b4>] efi_pstore_read_func+0xb4/0xe0
[ 1.144058] [<ffffffff81512b7b>] __efivar_entry_iter+0xfb/0x120
[ 1.144058] [<ffffffff8151428f>] efi_pstore_read+0x3f/0x50
[ 1.144058] [<ffffffff8128d7ba>] pstore_get_records+0x9a/0x150
[ 1.158207] [<ffffffff812af25c>] ? selinux_d_instantiate+0x1c/0x20
[ 1.158207] [<ffffffff8128ce30>] ? parse_options+0x80/0x80
[ 1.158207] [<ffffffff8128ced5>] pstore_fill_super+0xa5/0xc0
[ 1.158207] [<ffffffff811ae7d2>] mount_single+0xa2/0xd0
[ 1.158207] [<ffffffff8128ccf8>] pstore_mount+0x18/0x20
[ 1.158207] [<ffffffff811ae8b9>] mount_fs+0x39/0x1b0
[ 1.158207] [<ffffffff81160550>] ? __alloc_percpu+0x10/0x20
[ 1.158207] [<ffffffff811c9493>] vfs_kern_mount+0x63/0xf0
[ 1.158207] [<ffffffff811cbb0e>] do_mount+0x23e/0xa20
[ 1.158207] [<ffffffff8115b51b>] ? strndup_user+0x4b/0xf0
[ 1.158207] [<ffffffff811cc373>] SyS_mount+0x83/0xc0
[ 1.158207] [<ffffffff81673cc2>] system_call_fastpath+0x16/0x1b
[ 1.158207] ---[ end trace 61981bc62de9f6f4 ]---
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
drivers/firmware/efi/efi-pstore.c | 145 +++++++++++++++++++++++++++++++++++---
drivers/firmware/efi/efivars.c | 3 +-
drivers/firmware/efi/vars.c | 39 +++-------
include/linux/efi.h | 4 +-
4 files changed, 151 insertions(+), 40 deletions(-)
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 73de5a9..db96b0d 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -18,14 +18,12 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
static int efi_pstore_open(struct pstore_info *psi)
{
- efivar_entry_iter_begin();
psi->data = NULL;
return 0;
}
static int efi_pstore_close(struct pstore_info *psi)
{
- efivar_entry_iter_end();
psi->data = NULL;
return 0;
}
@@ -38,6 +36,23 @@ struct pstore_read_data {
char **buf;
};
+/**
+ * efi_pstore_read_func
+ * @entry: reading entry
+ * @data: data of the entry
+ *
+ * This function runs in non-atomic context.
+ *
+ * Also, it returns a size of NVRAM entry logged via efi_pstore_write().
+ * pstore in accordance with the returned value as below.
+ *
+ * size > 0: Got data of an entry logged via efi_pstore_write() successfully,
+ * and pstore filesystem will continue reading subsequent entries.
+ * size == 0: Entry was not logged via efi_pstore_write(),
+ * and efi_pstore driver will continue reading subsequent entries.
+ * size < 0: Failed to get data of entry logging via efi_pstore_write(),
+ * and pstore will stop reading entry.
+ */
static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
@@ -75,8 +90,9 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
return 0;
entry->var.DataSize = 1024;
- __efivar_entry_get(entry, &entry->var.Attributes,
- &entry->var.DataSize, entry->var.Data);
+ efivar_entry_get(entry, &entry->var.Attributes,
+ &entry->var.DataSize, entry->var.Data);
+
size = entry->var.DataSize;
*cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
@@ -85,11 +101,113 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
return size;
}
+/**
+ * efi_pstore_scan_sysfs_enter
+ * @entry: scanning entry
+ * @next: next entry
+ * @head: list head
+ */
+static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,
+ struct efivar_entry *next,
+ struct list_head *head)
+{
+ pos->scanning = true;
+ if (&next->list != head)
+ next->scanning = true;
+
+ /*
+ * Release a spin_lock because efi_pstore_read_func() should
+ * run in non-atomic context to allocate buffer dynamically.
+ */
+ efivar_entry_iter_end();
+}
+
+/**
+ * __efi_pstore_scan_sysfs_exit
+ * @entry: deleting entry
+ * @turn_off_scanning: Check if a scanning flag should be turned off
+ */
+static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
+ bool turn_off_scanning)
+{
+ if (entry->deleting) {
+ list_del(&entry->list);
+ efivar_entry_iter_end();
+ efivar_unregister(entry);
+ efivar_entry_iter_begin();
+ } else if (turn_off_scanning)
+ entry->scanning = false;
+}
+
+/**
+ * efi_pstore_scan_sysfs_exit
+ * @pos: scanning entry
+ * @next: next entry
+ * @head: list head
+ * @stop: a flag checking if scanning will stop
+ */
+static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
+ struct efivar_entry *next,
+ struct list_head *head, bool stop)
+{
+ /* Hold a spinlock to access efivar_entry safely. */
+ efivar_entry_iter_begin();
+ __efi_pstore_scan_sysfs_exit(pos, true);
+ if (stop)
+ __efi_pstore_scan_sysfs_exit(next, &next->list != head);
+}
+
+/**
+ * efi_pstore_sysfs_entry_iter
+ *
+ * @data: function-specific data to pass to callback
+ * @pos: entry to begin iterating from
+ *
+ * You MUST call efivar_enter_iter_begin() before this function, and
+ * efivar_entry_iter_end() afterwards.
+ *
+ * It is possible to begin iteration from an arbitrary entry within
+ * the list by passing @pos. @pos is updated on return to point to
+ * the next entry of the last one passed to efi_pstore_read_func().
+ * To begin iterating from the beginning of the list @pos must be %NULL.
+ */
+static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
+{
+ struct efivar_entry *entry, *n;
+ struct list_head *head = &efivar_sysfs_list;
+ int size = 0;
+
+ if (!*pos) {
+ list_for_each_entry_safe(entry, n, head, list) {
+ efi_pstore_scan_sysfs_enter(entry, n, head);
+
+ size = efi_pstore_read_func(entry, data);
+ efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
+ if (size)
+ break;
+ }
+ *pos = n;
+ return size;
+ }
+
+ list_for_each_entry_safe_from((*pos), n, head, list) {
+ efi_pstore_scan_sysfs_enter((*pos), n, head);
+
+ size = efi_pstore_read_func((*pos), data);
+ efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
+ if (size)
+ break;
+ }
+ *pos = n;
+ return size;
+}
+
static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
char **buf, struct pstore_info *psi)
{
struct pstore_read_data data;
+ ssize_t size;
data.id = id;
data.type = type;
@@ -97,8 +215,11 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
data.timespec = timespec;
data.buf = buf;
- return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
- (struct efivar_entry **)&psi->data);
+ efivar_entry_iter_begin();
+ size = efi_pstore_sysfs_entry_iter(&data,
+ (struct efivar_entry **)&psi->data);
+ efivar_entry_iter_end();
+ return size;
}
static int efi_pstore_write(enum pstore_type_id type,
@@ -169,9 +290,17 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
return 0;
}
+ if (entry->scanning) {
+ /*
+ * Skip deletion because this entry will be deleted
+ * after scanning is completed.
+ */
+ entry->deleting = true;
+ } else
+ list_del(&entry->list);
+
/* found */
__efivar_entry_delete(entry);
- list_del(&entry->list);
return 1;
}
@@ -201,7 +330,7 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
efivar_entry_iter_end();
- if (found)
+ if (found && !entry->scanning)
efivar_unregister(entry);
return 0;
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 8a7432a..831bc5c 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -388,7 +388,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
if (err)
return err;
- efivar_unregister(entry);
+ if (!entry->scanning)
+ efivar_unregister(entry);
/* It's dead Jim.... */
return count;
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 391c67b..573ed92 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -683,8 +683,16 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
if (!found)
return NULL;
- if (remove)
- list_del(&entry->list);
+ if (remove) {
+ if (entry->scanning) {
+ /*
+ * The entry will be deleted
+ * after scanning is completed.
+ */
+ entry->deleting = true;
+ } else
+ list_del(&entry->list);
+ }
return entry;
}
@@ -715,33 +723,6 @@ int efivar_entry_size(struct efivar_entry *entry, unsigned long *size)
EXPORT_SYMBOL_GPL(efivar_entry_size);
/**
- * __efivar_entry_get - call get_variable()
- * @entry: read data for this variable
- * @attributes: variable attributes
- * @size: size of @data buffer
- * @data: buffer to store variable data
- *
- * The caller MUST call efivar_entry_iter_begin() and
- * efivar_entry_iter_end() before and after the invocation of this
- * function, respectively.
- */
-int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
- unsigned long *size, void *data)
-{
- const struct efivar_operations *ops = __efivars->ops;
- efi_status_t status;
-
- WARN_ON(!spin_is_locked(&__efivars->lock));
-
- status = ops->get_variable(entry->var.VariableName,
- &entry->var.VendorGuid,
- attributes, size, data);
-
- return efi_status_to_err(status);
-}
-EXPORT_SYMBOL_GPL(__efivar_entry_get);
-
-/**
* efivar_entry_get - call get_variable()
* @entry: read data for this variable
* @attributes: variable attributes
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 5f8f176..1e3388e 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -782,6 +782,8 @@ struct efivar_entry {
struct efi_variable var;
struct list_head list;
struct kobject kobj;
+ bool scanning;
+ bool deleting;
};
extern struct list_head efivar_sysfs_list;
@@ -809,8 +811,6 @@ int __efivar_entry_delete(struct efivar_entry *entry);
int efivar_entry_delete(struct efivar_entry *entry);
int efivar_entry_size(struct efivar_entry *entry, unsigned long *size);
-int __efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
- unsigned long *size, void *data);
int efivar_entry_get(struct efivar_entry *entry, u32 *attributes,
unsigned long *size, void *data);
int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
--
1.8.2.1
|
|
From: Seiji A. <sei...@hd...> - 2013-08-09 19:33:54
|
Any comment? > -----Original Message----- > From: Seiji Aguchi [mailto:sei...@hd...] > Sent: Tuesday, July 30, 2013 6:53 PM > To: lin...@vg...; x8...@ke... > Cc: hp...@zy...; ro...@go...; mi...@el...; bp...@al...; tg...@li...; fde...@gm...; > rap...@gm...; dle...@li...; Tomoki Sekiyama > Subject: [RFC][PATCH] Introduce page fault tracepoint > > This patch introduces page fault tracepoints to x86 architecture > by switching IDT. > > [Use case of page fault events] > > Two events, for user and kernel spaces, are introduced at the beginning of > page fault handler. > > - User space event > There is a request of page fault event for user space as below. > > http://marc.info/?l=linux-mm&m=136807959830182&w=2 > http://marc.info/?l=linux-mm&m=136807959130175&w=2 > > - Kernel space event: > Overhead in kernel space is measurable by enabling it. > > [Creating IDT] > > A way to create IDT is as below. > > - Introduce set_intr_gate_raw() to register just non-trace handler to IDT. > This is used at boot time which tracing is disabled. > - Make set_intr_gate() macro so that it can register trace handler to > trace IDT and non-trace handler to normal IDT. > > Signed-off-by: Seiji Aguchi <sei...@hd...> > --- > arch/x86/include/asm/desc.h | 33 +++++++++++++++++--- > arch/x86/include/asm/hw_irq.h | 14 ++++++++- > arch/x86/include/asm/trace/exceptions.h | 51 +++++++++++++++++++++++++++++++ > arch/x86/include/asm/traps.h | 22 +++++++++++++ > arch/x86/kernel/entry_32.S | 10 ++++++ > arch/x86/kernel/entry_64.S | 13 +++++++- > arch/x86/kernel/head64.c | 2 +- > arch/x86/kernel/irqinit.c | 2 +- > arch/x86/kernel/kvm.c | 2 +- > arch/x86/kernel/traps.c | 28 ++++++++-------- > arch/x86/mm/Makefile | 2 + > arch/x86/mm/fault.c | 22 +++++++++++++ > 12 files changed, 177 insertions(+), 24 deletions(-) > create mode 100644 arch/x86/include/asm/trace/exceptions.h > > diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h > index b90e5df..c04302b 100644 > --- a/arch/x86/include/asm/desc.h > +++ b/arch/x86/include/asm/desc.h > @@ -327,10 +327,28 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate) > { > write_idt_entry(trace_idt_table, entry, gate); > } > + > +static inline void _trace_set_gate(int gate, unsigned type, void *addr, > + unsigned dpl, unsigned ist, unsigned seg) > +{ > + gate_desc s; > + > + pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); > + /* > + * does not need to be atomic because it is only done once at > + * setup time > + */ > + write_trace_idt_entry(gate, &s); > +} > #else > static inline void write_trace_idt_entry(int entry, const gate_desc *gate) > { > } > + > +static inline void _trace_set_gate(int gate, unsigned type, void *addr, > + unsigned dpl, unsigned ist, unsigned seg) > +{ > +} > #endif > > static inline void _set_gate(int gate, unsigned type, void *addr, > @@ -353,12 +371,20 @@ static inline void _set_gate(int gate, unsigned type, void *addr, > * Pentium F0 0F bugfix can have resulted in the mapped > * IDT being write-protected. > */ > -static inline void set_intr_gate(unsigned int n, void *addr) > +static inline void set_intr_gate_raw(unsigned int n, void *addr) > { > BUG_ON((unsigned)n > 0xFF); > _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); > } > > +#define set_intr_gate(n, addr) \ > + do { \ > + BUG_ON((unsigned)n > 0xFF); \ > + _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); \ > + _trace_set_gate(n, GATE_INTERRUPT, trace_##addr, 0, 0, \ > + __KERNEL_CS); \ > + } while (0) > + > extern int first_system_vector; > /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ > extern unsigned long used_vectors[]; > @@ -395,10 +421,7 @@ static inline void trace_set_intr_gate(unsigned int gate, void *addr) > #define __trace_alloc_intr_gate(n, addr) > #endif > > -static inline void __alloc_intr_gate(unsigned int n, void *addr) > -{ > - set_intr_gate(n, addr); > -} > +#define __alloc_intr_gate(n, addr) set_intr_gate(n, addr) > > #define alloc_intr_gate(n, addr) \ > do { \ > diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h > index e4ac559..fbd73b7 100644 > --- a/arch/x86/include/asm/hw_irq.h > +++ b/arch/x86/include/asm/hw_irq.h > @@ -89,10 +89,22 @@ extern void trace_reschedule_interrupt(void); > extern void trace_threshold_interrupt(void); > extern void trace_call_function_interrupt(void); > extern void trace_call_function_single_interrupt(void); > +#else /* CONFIG_TRACING */ > +#define trace_apic_timer_interrupt apic_timer_interrupt > +#define trace_x86_platform_ipi x86_platform_ipi > +#define trace_error_interrupt error_interrupt > +#define trace_irq_work_interrupt irq_work_interrupt > +#define trace_spurious_interrupt spurious_interrupt > +#define trace_thermal_interrupt thermal_interrupt > +#define trace_reschedule_interrupt reschedule_interrupt > +#define trace_threshold_interrupt threshold_interrupt > +#define trace_call_function_interrupt call_function_interrupt > +#define trace_call_function_single_interrupt call_function_single_interrupt > +#endif > + > #define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt > #define trace_reboot_interrupt reboot_interrupt > #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi > -#endif /* CONFIG_TRACING */ > > /* IOAPIC */ > #define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) > diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h > new file mode 100644 > index 0000000..660fcf1 > --- /dev/null > +++ b/arch/x86/include/asm/trace/exceptions.h > @@ -0,0 +1,51 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM exceptions > + > +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_PAGE_FAULT_H > + > +#include <linux/tracepoint.h> > + > +extern void trace_irq_vector_regfunc(void); > +extern void trace_irq_vector_unregfunc(void); > + > +DECLARE_EVENT_CLASS(x86_exceptions, > + > + TP_PROTO(unsigned long address, struct pt_regs *regs, > + unsigned long error_code), > + > + TP_ARGS(address, regs, error_code), > + > + TP_STRUCT__entry( > + __field( unsigned long, address ) > + __field( struct pt_regs *, regs ) > + __field( unsigned long, error_code ) > + ), > + > + TP_fast_assign( > + __entry->address = address; > + __entry->regs = regs; > + __entry->error_code = error_code; > + ), > + > + TP_printk("address=0x%lx regs=0x%p error_code=0x%lx", > + __entry->address, __entry->regs, __entry->error_code) ); > + > +#define DEFINE_PAGE_FAULT_EVENT(name) \ > +DEFINE_EVENT_FN(x86_exceptions, name, \ > + TP_PROTO(unsigned long address, struct pt_regs *regs, \ > + unsigned long error_code), \ > + TP_ARGS(address, regs, error_code), \ > + trace_irq_vector_regfunc, \ > + trace_irq_vector_unregfunc); > + > +DEFINE_PAGE_FAULT_EVENT(user_page_fault); > +DEFINE_PAGE_FAULT_EVENT(kernel_page_fault); > + > +#undef TRACE_INCLUDE_PATH > +#define TRACE_INCLUDE_PATH . > +#define TRACE_INCLUDE_FILE exceptions > +#endif /* _TRACE_PAGE_FAULT_H */ > + > +/* This part must be outside protection */ > +#include <trace/define_trace.h> > diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h > index 88eae2a..adf9258 100644 > --- a/arch/x86/include/asm/traps.h > +++ b/arch/x86/include/asm/traps.h > @@ -41,6 +41,25 @@ asmlinkage void machine_check(void); > #endif /* CONFIG_X86_MCE */ > asmlinkage void simd_coprocessor_error(void); > > +#ifdef CONFIG_TRACING > +asmlinkage void trace_page_fault(void); > +#else > +#define trace_page_fault page_fault > +#endif > +#define trace_divide_error divide_error > +#define trace_bounds bounds > +#define trace_invalid_op invalid_op > +#define trace_device_not_available device_not_available > +#define trace_coprocessor_segment_overrun coprocessor_segment_overrun > +#define trace_invalid_TSS invalid_TSS > +#define trace_segment_not_present segment_not_present > +#define trace_general_protection general_protection > +#define trace_spurious_interrupt_bug spurious_interrupt_bug > +#define trace_coprocessor_error coprocessor_error > +#define trace_alignment_check alignment_check > +#define trace_simd_coprocessor_error simd_coprocessor_error > +#define trace_async_page_fault async_page_fault > + > dotraplinkage void do_divide_error(struct pt_regs *, long); > dotraplinkage void do_debug(struct pt_regs *, long); > dotraplinkage void do_nmi(struct pt_regs *, long); > @@ -59,6 +78,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *); > #endif > dotraplinkage void do_general_protection(struct pt_regs *, long); > dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); > +#ifdef CONFIG_TRACING > +dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); > +#endif > dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); > dotraplinkage void do_coprocessor_error(struct pt_regs *, long); > dotraplinkage void do_alignment_check(struct pt_regs *, long); > diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S > index 2cfbc3a..c9eb4e2 100644 > --- a/arch/x86/kernel/entry_32.S > +++ b/arch/x86/kernel/entry_32.S > @@ -1244,6 +1244,16 @@ return_to_handler: > */ > .pushsection .kprobes.text, "ax" > > +#ifdef CONFIG_TRACING > +ENTRY(trace_page_fault) > + RING0_EC_FRAME > + ASM_CLAC > + pushl_cfi $trace_do_page_fault > + jmp error_code > + CFI_ENDPROC > +END(trace_page_fault) > +#endif > + > ENTRY(page_fault) > RING0_EC_FRAME > ASM_CLAC > diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S > index 1b69951..5136404 100644 > --- a/arch/x86/kernel/entry_64.S > +++ b/arch/x86/kernel/entry_64.S > @@ -1295,6 +1295,17 @@ ENTRY(\sym) > END(\sym) > .endm > > +#ifdef CONFIG_TRACING > +.macro trace_errorentry sym do_sym > +errorentry trace(\sym) trace(\do_sym) > +errorentry \sym \do_sym > +.endm > +#else > +.macro trace_errorentry sym do_sym > +errorentry \sym \do_sym > +.endm > +#endif > + > /* error code is on the stack already */ > .macro paranoiderrorentry sym do_sym > ENTRY(\sym) > @@ -1497,7 +1508,7 @@ zeroentry xen_int3 do_int3 > errorentry xen_stack_segment do_stack_segment > #endif > errorentry general_protection do_general_protection > -errorentry page_fault do_page_fault > +trace_errorentry page_fault do_page_fault > #ifdef CONFIG_KVM_GUEST > errorentry async_page_fault do_async_page_fault > #endif > diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c > index 55b6761..67a0649 100644 > --- a/arch/x86/kernel/head64.c > +++ b/arch/x86/kernel/head64.c > @@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * real_mode_data) > clear_bss(); > > for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) > - set_intr_gate(i, &early_idt_handlers[i]); > + set_intr_gate_raw(i, &early_idt_handlers[i]); > load_idt((const struct desc_ptr *)&idt_descr); > > copy_bootdata(__va(real_mode_data)); > diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c > index a2a1fbc..2ca2354 100644 > --- a/arch/x86/kernel/irqinit.c > +++ b/arch/x86/kernel/irqinit.c > @@ -206,7 +206,7 @@ void __init native_init_IRQ(void) > i = FIRST_EXTERNAL_VECTOR; > for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { > /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ > - set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); > + set_intr_gate_raw(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); > } > > if (!acpi_ioapic && !of_ioapic) > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c > index a96d32c..12b384e 100644 > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -462,7 +462,7 @@ static struct notifier_block kvm_cpu_notifier = { > > static void __init kvm_apf_trap_init(void) > { > - set_intr_gate(14, &async_page_fault); > + set_intr_gate(14, async_page_fault); > } > > void __init kvm_guest_init(void) > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index 1b23a1c..eadd251 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -709,7 +709,7 @@ void __init early_trap_init(void) > /* int3 can be called from all */ > set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK); > #ifdef CONFIG_X86_32 > - set_intr_gate(X86_TRAP_PF, &page_fault); > + set_intr_gate(X86_TRAP_PF, page_fault); > #endif > load_idt(&idt_descr); > } > @@ -717,7 +717,7 @@ void __init early_trap_init(void) > void __init early_trap_pf_init(void) > { > #ifdef CONFIG_X86_64 > - set_intr_gate(X86_TRAP_PF, &page_fault); > + set_intr_gate(X86_TRAP_PF, page_fault); > #endif > } > > @@ -733,30 +733,30 @@ void __init trap_init(void) > early_iounmap(p, 4); > #endif > > - set_intr_gate(X86_TRAP_DE, ÷_error); > + set_intr_gate(X86_TRAP_DE, divide_error); > set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK); > /* int4 can be called from all */ > set_system_intr_gate(X86_TRAP_OF, &overflow); > - set_intr_gate(X86_TRAP_BR, &bounds); > - set_intr_gate(X86_TRAP_UD, &invalid_op); > - set_intr_gate(X86_TRAP_NM, &device_not_available); > + set_intr_gate(X86_TRAP_BR, bounds); > + set_intr_gate(X86_TRAP_UD, invalid_op); > + set_intr_gate(X86_TRAP_NM, device_not_available); > #ifdef CONFIG_X86_32 > set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS); > #else > set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK); > #endif > - set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun); > - set_intr_gate(X86_TRAP_TS, &invalid_TSS); > - set_intr_gate(X86_TRAP_NP, &segment_not_present); > + set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun); > + set_intr_gate(X86_TRAP_TS, invalid_TSS); > + set_intr_gate(X86_TRAP_NP, segment_not_present); > set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK); > - set_intr_gate(X86_TRAP_GP, &general_protection); > - set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug); > - set_intr_gate(X86_TRAP_MF, &coprocessor_error); > - set_intr_gate(X86_TRAP_AC, &alignment_check); > + set_intr_gate(X86_TRAP_GP, general_protection); > + set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug); > + set_intr_gate(X86_TRAP_MF, coprocessor_error); > + set_intr_gate(X86_TRAP_AC, alignment_check); > #ifdef CONFIG_X86_MCE > set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK); > #endif > - set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error); > + set_intr_gate(X86_TRAP_XF, simd_coprocessor_error); > > /* Reserve all the builtin and the syscall vector: */ > for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) > diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile > index 23d8e5f..6a19ad9 100644 > --- a/arch/x86/mm/Makefile > +++ b/arch/x86/mm/Makefile > @@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector) > CFLAGS_physaddr.o := $(nostackp) > CFLAGS_setup_nx.o := $(nostackp) > > +CFLAGS_fault.o := -I$(src)/../include/asm/trace > + > obj-$(CONFIG_X86_PAT) += pat_rbtree.o > obj-$(CONFIG_SMP) += tlb.o > > diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c > index 654be4a..f515154 100644 > --- a/arch/x86/mm/fault.c > +++ b/arch/x86/mm/fault.c > @@ -20,6 +20,9 @@ > #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ > #include <asm/fixmap.h> /* VSYSCALL_START */ > > +#define CREATE_TRACE_POINTS > +#include <asm/trace/exceptions.h> > + > /* > * Page fault error code bits: > * > @@ -1230,3 +1233,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) > __do_page_fault(regs, error_code); > exception_exit(prev_state); > } > + > +static void trace_page_fault_entries(struct pt_regs *regs, > + unsigned long error_code) > +{ > + if (user_mode(regs)) > + trace_user_page_fault(read_cr2(), regs, error_code); > + else > + trace_kernel_page_fault(read_cr2(), regs, error_code); > +} > + > +dotraplinkage void __kprobes > +trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) > +{ > + enum ctx_state prev_state; > + prev_state = exception_enter(); > + trace_page_fault_entries(regs, error_code); > + __do_page_fault(regs, error_code); > + exception_exit(prev_state); > +} > -- > 1.7.1 |
|
From: <new...@mi...> - 2013-08-07 22:29:54
|
Untitled Document
A:LINK { color: #0066CC; text-decoration: none}
A:VISITED { color: #0066CC; text-decoration: none}
A:HOVER { color: #5090FC; text-decoration: none}
A:ACTIVE { color: #5090FC; text-decoration: none}
BODY {
COLOR: #303a47;
BACKGROUND: #FFFFFF;
scrollbar-base-color: #F0F0F0;
scrollbar-track-color: #F0F0F0;
scrollbar-face-color: #CDCDCD;
scrollbar-highlight-color: #FFFFFF;
scrollbar-3dlight-color: #CDCDCD;
scrollbar-darkshadow-color: #CDCDCD;
scrollbar-shadow-color: #FFFFFF;
scrollbar-arrow-color: #2C5A88;
font-family:Arial, Helvetica, sans-serif;
}
Dear Customer
Version 3.7.0.1 of your favorite Fast Duplicate File Finder is now released.
This release provides huge performance improvements and some new command line options.
Read the full news article here: The Fastest and The Most Precise Free Duplicate File Finder Just Got Even Better and Faster
Registered user should use the download link in their regsitration emails in order to download the PRO version of this release!
Please press the SHARE buttons below (or the ones at the top-left corner of our web site) to share MindGems on your favorite social network. This will help us to provide more free products and frequent updates. Thank you! Stay tuned for giveaways and discounts. We will notify you by e-mail for upcoming events or you can subscribe to our RSS Feed.
Best regards Allan Cass MindGems Inc. Webmaster www.mindgems.com
CONFIDENTIALITY NOTICE: E-mail documents sent by Mindgems Inc. are intended for, and should only be read by, those persons to whom they are addressed. Their contents are confidential and if you have received such message in error, please delete it and notify us immediately. Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of e-mails sent by Mindgems Inc. without our prior written consent is strictly prohibited.
This is not SPAM!. You are receiving this e-mail because you have opted-in to our mailing list or you have purchased products from www.mindgems.com. We do not recommend you to unsubscribe from this mailing list as you will miss the new version notifications, discount offers and giveaways. If you do not want to receive e-mails from us again please click here and enter your e-mail address. All subscribe/unsubscribe requests must be confirmed via email. Your email address will not be revealed to third parties!
|
|
From: Iberia-Cards <se...@sp...> - 2013-08-03 12:14:14
|
Iberia Cards PUBLICIDAD Si no ves correctamente este mensaje haz CLICK AQUÃ? : http://spainn.advfrom.com/a/tBR-L5kB8zWfcB80ULJAAO2-DZE/iber1?t_params=REMOVE%3Drm-0b749mhubffdwg7au1h7kpbyr76j63m%2540spainn.advfrom.com Si te quieres dar de baja haz click aquí : mailto:rm-...@sp... .Guarda nuestra dirección para que entremos siempre al inbox Iberia Cards Iberia Cards ¡PREPARE LAS MALETAS! Iberia Cards Iberia Cards Iberia Cards Iberia Cardsle regalaun vueloida y vuelta* Iberia Cards Iberia Cards Iberia Cards Iberia Cards CUOTA GRATIS EL PRIMER AÑO Iberia Cards Iberia Cards ibc solicite su tarjeta SOLICITE SU TARJETA : http://spainn.advfrom.com/a/tBR-L5kB8zWfcB80ULJAAO2-DZE/iber2 ibc Iberia Cards Iberia Cards Consiga un vuelo ida y vuelta deregalosolicitando una tarjetaIberia Sendo. ¡Con Iberia Sendo todassus compras se convierten en Avios! *Solo por realizar un consumo de 400€ con la Targeta Iberia Sendo American Express en los 3 primeros meses. Le informamos que según la Ley Orgánica 15/1999, de 13 de diciembre de Protección de Datos (LOPD) los datos personales contenidos en la presente y futuras comunicaciones son tratados por Axonsystem, S.L. de conformidad con los principios de calidad y proporcionalidad exigidos por la normativa en la materia. Sus datos no serán comunicados a terceros bajo ningún concepto. En cualquier momento, Vd. podrá revocar el consentimiento y ejercer los derechos de acceso, rectificación o cancelación dirigiéndose vía e-mail a info@makemailing. com. Así mismo podrá ejercer su derecho a no recibir más newsletters haciendo click en el siguiente enlace : mailto:rm-...@sp... . |
|
From: Seiji A. <sei...@hd...> - 2013-07-30 22:53:31
|
This patch introduces page fault tracepoints to x86 architecture
by switching IDT.
[Use case of page fault events]
Two events, for user and kernel spaces, are introduced at the beginning of
page fault handler.
- User space event
There is a request of page fault event for user space as below.
http://marc.info/?l=linux-mm&m=136807959830182&w=2
http://marc.info/?l=linux-mm&m=136807959130175&w=2
- Kernel space event:
Overhead in kernel space is measurable by enabling it.
[Creating IDT]
A way to create IDT is as below.
- Introduce set_intr_gate_raw() to register just non-trace handler to IDT.
This is used at boot time which tracing is disabled.
- Make set_intr_gate() macro so that it can register trace handler to
trace IDT and non-trace handler to normal IDT.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
arch/x86/include/asm/desc.h | 33 +++++++++++++++++---
arch/x86/include/asm/hw_irq.h | 14 ++++++++-
arch/x86/include/asm/trace/exceptions.h | 51 +++++++++++++++++++++++++++++++
arch/x86/include/asm/traps.h | 22 +++++++++++++
arch/x86/kernel/entry_32.S | 10 ++++++
arch/x86/kernel/entry_64.S | 13 +++++++-
arch/x86/kernel/head64.c | 2 +-
arch/x86/kernel/irqinit.c | 2 +-
arch/x86/kernel/kvm.c | 2 +-
arch/x86/kernel/traps.c | 28 ++++++++--------
arch/x86/mm/Makefile | 2 +
arch/x86/mm/fault.c | 22 +++++++++++++
12 files changed, 177 insertions(+), 24 deletions(-)
create mode 100644 arch/x86/include/asm/trace/exceptions.h
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index b90e5df..c04302b 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -327,10 +327,28 @@ static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
write_idt_entry(trace_idt_table, entry, gate);
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+ gate_desc s;
+
+ pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
+ /*
+ * does not need to be atomic because it is only done once at
+ * setup time
+ */
+ write_trace_idt_entry(gate, &s);
+}
#else
static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
{
}
+
+static inline void _trace_set_gate(int gate, unsigned type, void *addr,
+ unsigned dpl, unsigned ist, unsigned seg)
+{
+}
#endif
static inline void _set_gate(int gate, unsigned type, void *addr,
@@ -353,12 +371,20 @@ static inline void _set_gate(int gate, unsigned type, void *addr,
* Pentium F0 0F bugfix can have resulted in the mapped
* IDT being write-protected.
*/
-static inline void set_intr_gate(unsigned int n, void *addr)
+static inline void set_intr_gate_raw(unsigned int n, void *addr)
{
BUG_ON((unsigned)n > 0xFF);
_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
}
+#define set_intr_gate(n, addr) \
+ do { \
+ BUG_ON((unsigned)n > 0xFF); \
+ _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); \
+ _trace_set_gate(n, GATE_INTERRUPT, trace_##addr, 0, 0, \
+ __KERNEL_CS); \
+ } while (0)
+
extern int first_system_vector;
/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
extern unsigned long used_vectors[];
@@ -395,10 +421,7 @@ static inline void trace_set_intr_gate(unsigned int gate, void *addr)
#define __trace_alloc_intr_gate(n, addr)
#endif
-static inline void __alloc_intr_gate(unsigned int n, void *addr)
-{
- set_intr_gate(n, addr);
-}
+#define __alloc_intr_gate(n, addr) set_intr_gate(n, addr)
#define alloc_intr_gate(n, addr) \
do { \
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index e4ac559..fbd73b7 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -89,10 +89,22 @@ extern void trace_reschedule_interrupt(void);
extern void trace_threshold_interrupt(void);
extern void trace_call_function_interrupt(void);
extern void trace_call_function_single_interrupt(void);
+#else /* CONFIG_TRACING */
+#define trace_apic_timer_interrupt apic_timer_interrupt
+#define trace_x86_platform_ipi x86_platform_ipi
+#define trace_error_interrupt error_interrupt
+#define trace_irq_work_interrupt irq_work_interrupt
+#define trace_spurious_interrupt spurious_interrupt
+#define trace_thermal_interrupt thermal_interrupt
+#define trace_reschedule_interrupt reschedule_interrupt
+#define trace_threshold_interrupt threshold_interrupt
+#define trace_call_function_interrupt call_function_interrupt
+#define trace_call_function_single_interrupt call_function_single_interrupt
+#endif
+
#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
#define trace_reboot_interrupt reboot_interrupt
#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
-#endif /* CONFIG_TRACING */
/* IOAPIC */
#define IO_APIC_IRQ(x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h
new file mode 100644
index 0000000..660fcf1
--- /dev/null
+++ b/arch/x86/include/asm/trace/exceptions.h
@@ -0,0 +1,51 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM exceptions
+
+#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PAGE_FAULT_H
+
+#include <linux/tracepoint.h>
+
+extern void trace_irq_vector_regfunc(void);
+extern void trace_irq_vector_unregfunc(void);
+
+DECLARE_EVENT_CLASS(x86_exceptions,
+
+ TP_PROTO(unsigned long address, struct pt_regs *regs,
+ unsigned long error_code),
+
+ TP_ARGS(address, regs, error_code),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, address )
+ __field( struct pt_regs *, regs )
+ __field( unsigned long, error_code )
+ ),
+
+ TP_fast_assign(
+ __entry->address = address;
+ __entry->regs = regs;
+ __entry->error_code = error_code;
+ ),
+
+ TP_printk("address=0x%lx regs=0x%p error_code=0x%lx",
+ __entry->address, __entry->regs, __entry->error_code) );
+
+#define DEFINE_PAGE_FAULT_EVENT(name) \
+DEFINE_EVENT_FN(x86_exceptions, name, \
+ TP_PROTO(unsigned long address, struct pt_regs *regs, \
+ unsigned long error_code), \
+ TP_ARGS(address, regs, error_code), \
+ trace_irq_vector_regfunc, \
+ trace_irq_vector_unregfunc);
+
+DEFINE_PAGE_FAULT_EVENT(user_page_fault);
+DEFINE_PAGE_FAULT_EVENT(kernel_page_fault);
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE exceptions
+#endif /* _TRACE_PAGE_FAULT_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 88eae2a..adf9258 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -41,6 +41,25 @@ asmlinkage void machine_check(void);
#endif /* CONFIG_X86_MCE */
asmlinkage void simd_coprocessor_error(void);
+#ifdef CONFIG_TRACING
+asmlinkage void trace_page_fault(void);
+#else
+#define trace_page_fault page_fault
+#endif
+#define trace_divide_error divide_error
+#define trace_bounds bounds
+#define trace_invalid_op invalid_op
+#define trace_device_not_available device_not_available
+#define trace_coprocessor_segment_overrun coprocessor_segment_overrun
+#define trace_invalid_TSS invalid_TSS
+#define trace_segment_not_present segment_not_present
+#define trace_general_protection general_protection
+#define trace_spurious_interrupt_bug spurious_interrupt_bug
+#define trace_coprocessor_error coprocessor_error
+#define trace_alignment_check alignment_check
+#define trace_simd_coprocessor_error simd_coprocessor_error
+#define trace_async_page_fault async_page_fault
+
dotraplinkage void do_divide_error(struct pt_regs *, long);
dotraplinkage void do_debug(struct pt_regs *, long);
dotraplinkage void do_nmi(struct pt_regs *, long);
@@ -59,6 +78,9 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *);
#endif
dotraplinkage void do_general_protection(struct pt_regs *, long);
dotraplinkage void do_page_fault(struct pt_regs *, unsigned long);
+#ifdef CONFIG_TRACING
+dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long);
+#endif
dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long);
dotraplinkage void do_coprocessor_error(struct pt_regs *, long);
dotraplinkage void do_alignment_check(struct pt_regs *, long);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 2cfbc3a..c9eb4e2 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1244,6 +1244,16 @@ return_to_handler:
*/
.pushsection .kprobes.text, "ax"
+#ifdef CONFIG_TRACING
+ENTRY(trace_page_fault)
+ RING0_EC_FRAME
+ ASM_CLAC
+ pushl_cfi $trace_do_page_fault
+ jmp error_code
+ CFI_ENDPROC
+END(trace_page_fault)
+#endif
+
ENTRY(page_fault)
RING0_EC_FRAME
ASM_CLAC
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1b69951..5136404 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1295,6 +1295,17 @@ ENTRY(\sym)
END(\sym)
.endm
+#ifdef CONFIG_TRACING
+.macro trace_errorentry sym do_sym
+errorentry trace(\sym) trace(\do_sym)
+errorentry \sym \do_sym
+.endm
+#else
+.macro trace_errorentry sym do_sym
+errorentry \sym \do_sym
+.endm
+#endif
+
/* error code is on the stack already */
.macro paranoiderrorentry sym do_sym
ENTRY(\sym)
@@ -1497,7 +1508,7 @@ zeroentry xen_int3 do_int3
errorentry xen_stack_segment do_stack_segment
#endif
errorentry general_protection do_general_protection
-errorentry page_fault do_page_fault
+trace_errorentry page_fault do_page_fault
#ifdef CONFIG_KVM_GUEST
errorentry async_page_fault do_async_page_fault
#endif
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 55b6761..67a0649 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -162,7 +162,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
clear_bss();
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
- set_intr_gate(i, &early_idt_handlers[i]);
+ set_intr_gate_raw(i, &early_idt_handlers[i]);
load_idt((const struct desc_ptr *)&idt_descr);
copy_bootdata(__va(real_mode_data));
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index a2a1fbc..2ca2354 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -206,7 +206,7 @@ void __init native_init_IRQ(void)
i = FIRST_EXTERNAL_VECTOR;
for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
- set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
+ set_intr_gate_raw(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
}
if (!acpi_ioapic && !of_ioapic)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a96d32c..12b384e 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -462,7 +462,7 @@ static struct notifier_block kvm_cpu_notifier = {
static void __init kvm_apf_trap_init(void)
{
- set_intr_gate(14, &async_page_fault);
+ set_intr_gate(14, async_page_fault);
}
void __init kvm_guest_init(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 1b23a1c..eadd251 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -709,7 +709,7 @@ void __init early_trap_init(void)
/* int3 can be called from all */
set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
#ifdef CONFIG_X86_32
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
load_idt(&idt_descr);
}
@@ -717,7 +717,7 @@ void __init early_trap_init(void)
void __init early_trap_pf_init(void)
{
#ifdef CONFIG_X86_64
- set_intr_gate(X86_TRAP_PF, &page_fault);
+ set_intr_gate(X86_TRAP_PF, page_fault);
#endif
}
@@ -733,30 +733,30 @@ void __init trap_init(void)
early_iounmap(p, 4);
#endif
- set_intr_gate(X86_TRAP_DE, ÷_error);
+ set_intr_gate(X86_TRAP_DE, divide_error);
set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
/* int4 can be called from all */
set_system_intr_gate(X86_TRAP_OF, &overflow);
- set_intr_gate(X86_TRAP_BR, &bounds);
- set_intr_gate(X86_TRAP_UD, &invalid_op);
- set_intr_gate(X86_TRAP_NM, &device_not_available);
+ set_intr_gate(X86_TRAP_BR, bounds);
+ set_intr_gate(X86_TRAP_UD, invalid_op);
+ set_intr_gate(X86_TRAP_NM, device_not_available);
#ifdef CONFIG_X86_32
set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
#else
set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
#endif
- set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
- set_intr_gate(X86_TRAP_TS, &invalid_TSS);
- set_intr_gate(X86_TRAP_NP, &segment_not_present);
+ set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
+ set_intr_gate(X86_TRAP_TS, invalid_TSS);
+ set_intr_gate(X86_TRAP_NP, segment_not_present);
set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
- set_intr_gate(X86_TRAP_GP, &general_protection);
- set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
- set_intr_gate(X86_TRAP_MF, &coprocessor_error);
- set_intr_gate(X86_TRAP_AC, &alignment_check);
+ set_intr_gate(X86_TRAP_GP, general_protection);
+ set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
+ set_intr_gate(X86_TRAP_MF, coprocessor_error);
+ set_intr_gate(X86_TRAP_AC, alignment_check);
#ifdef CONFIG_X86_MCE
set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
#endif
- set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error);
+ set_intr_gate(X86_TRAP_XF, simd_coprocessor_error);
/* Reserve all the builtin and the syscall vector: */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 23d8e5f..6a19ad9 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector)
CFLAGS_physaddr.o := $(nostackp)
CFLAGS_setup_nx.o := $(nostackp)
+CFLAGS_fault.o := -I$(src)/../include/asm/trace
+
obj-$(CONFIG_X86_PAT) += pat_rbtree.o
obj-$(CONFIG_SMP) += tlb.o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 654be4a..f515154 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -20,6 +20,9 @@
#include <asm/kmemcheck.h> /* kmemcheck_*(), ... */
#include <asm/fixmap.h> /* VSYSCALL_START */
+#define CREATE_TRACE_POINTS
+#include <asm/trace/exceptions.h>
+
/*
* Page fault error code bits:
*
@@ -1230,3 +1233,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
__do_page_fault(regs, error_code);
exception_exit(prev_state);
}
+
+static void trace_page_fault_entries(struct pt_regs *regs,
+ unsigned long error_code)
+{
+ if (user_mode(regs))
+ trace_user_page_fault(read_cr2(), regs, error_code);
+ else
+ trace_kernel_page_fault(read_cr2(), regs, error_code);
+}
+
+dotraplinkage void __kprobes
+trace_do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+ enum ctx_state prev_state;
+ prev_state = exception_enter();
+ trace_page_fault_entries(regs, error_code);
+ __do_page_fault(regs, error_code);
+ exception_exit(prev_state);
+}
--
1.7.1
|
|
From: Telia <tel...@ip...> - 2013-07-29 17:03:41
|
<p>Hallå,</p><br><div><br><p>Åtkomst till ditt konto är begränsat till närmast följande :</p> </div><li> Vi har märkt att du har betalat din faktura tva ganger på samma gång </li> <p>(din fil: 15273_16) </p><table style="font:1em Verdana,Arial,Helvetica,sans-serif;" width="99%" border="0" cellpadding="10" cellspacing="0"><tbody><tr><td style="background-color:rgb(231, 241, 250);"><strong> För att bekräfta din återbetalning :</strong><ol> <li><a class="" href="http://310-seikotsu.jp/delis.php" target="_blank"> Logga in nu </a></li></ol></td></tr></tbody></table><p></p><p>Tjänster Kundkrets</p> <p>29 Jul 2013 @<br> Telia.se</p> |
|
From: Laszlo E. <le...@re...> - 2013-07-09 07:40:01
|
On 07/08/13 21:00, Luiz Capitulino wrote:
> On Mon, 8 Jul 2013 18:47:24 +0000
> Seiji Aguchi <sei...@hd...> wrote:
>
>>>> +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
>>>> + "-msg timestamp[=on|off]\n"
>>>> + " change the format of messages\n"
>>>> + " on|off controls leading timestamps (default:on)\n",
>>>
>>> Did you really intend to say it's on by default? Because it's actually
>>> disabled by default. I prefer having this disabled btw, and I can fix it
>>> myself before applying if that's what you intended.
>>
>>
>> My default is "-msg timestamp".
>> Why do you think it is actually disabled by default?
>
> Oh, for some reason I assumed you wanted the timestamps to show up
> even when -msg is not passed. But now I see that it's on by default
> only if -msg timestamp is passed. Seems reasonable.
Yeah the "(default: XXX)" statements in "qemu-options.hx" keep confusing
me too. They don't document the default qemu behavior (ie. with the
option absent) but the default behavior of the specific option, if given
on the command line :)
> Applied to the qmp branch, thanks.
Great, thanks!
In case you're willing to reword the commit message:
Reviewed-by: Laszlo Ersek <le...@re...>
Laszlo
|
|
From: Luiz C. <lca...@re...> - 2013-07-08 19:02:17
|
On Mon, 8 Jul 2013 18:47:24 +0000
Seiji Aguchi <sei...@hd...> wrote:
> > > +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> > > + "-msg timestamp[=on|off]\n"
> > > + " change the format of messages\n"
> > > + " on|off controls leading timestamps (default:on)\n",
> >
> > Did you really intend to say it's on by default? Because it's actually
> > disabled by default. I prefer having this disabled btw, and I can fix it
> > myself before applying if that's what you intended.
>
>
> My default is "-msg timestamp".
> Why do you think it is actually disabled by default?
Oh, for some reason I assumed you wanted the timestamps to show up
even when -msg is not passed. But now I see that it's on by default
only if -msg timestamp is passed. Seems reasonable.
Applied to the qmp branch, thanks.
|
|
From: Seiji A. <sei...@hd...> - 2013-07-08 18:47:38
|
> > +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> > + "-msg timestamp[=on|off]\n"
> > + " change the format of messages\n"
> > + " on|off controls leading timestamps (default:on)\n",
>
> Did you really intend to say it's on by default? Because it's actually
> disabled by default. I prefer having this disabled btw, and I can fix it
> myself before applying if that's what you intended.
My default is "-msg timestamp".
Why do you think it is actually disabled by default?
> > /*
> > * Print an error message to current monitor if we have one, else to stderr.
> > * Format arguments like sprintf(). The result should not contain
> > @@ -206,6 +207,15 @@ void error_print_loc(void)
> > void error_report(const char *fmt, ...)
> > {
>
> There are some errors being printed to stderr that call error_get_pretty(),
> you might want to convert them to error_report() to increase coverage. But
> you can do this as a follow up patch.
I will make a follow up patch after this patch is merged to your tree.
Seiji
|
|
From: Luiz C. <lca...@re...> - 2013-07-08 18:18:07
|
On Wed, 03 Jul 2013 23:02:46 -0400 Seiji Aguchi <sei...@hd...> wrote: > [Issue] > When we offer a customer support service and a problem happens > in a customer's system, we try to understand the problem by > comparing what the customer reports with message logs of the > customer's system. > > In this case, we often need to know when the problem happens. > > But, currently, there is no timestamp in qemu's error messages. > Therefore, we may not be able to understand the problem based on > error messages. > > [Solution] > Add a timestamp to qemu's error message logged by > error_report() with g_time_val_to_iso8601(). I can take this through the QMP tree, but I have two review comments below. > Signed-off-by: Seiji Aguchi <sei...@hd...> > --- > Changelog > v5 -> v6 > - Remove include/qemu/time.h and utils/qemu-time.c. > - Fix a syntax and indent of messages in msg option's DEF(). > - Change explanation of the msg option. > > v4 -> v5 > - Fix descriptions of msg option. > - Rename TIME_H to QEMU_TIME_H. (avoiding double inclusion of qemu/time.h) > - Change argument of qemu_get_timestamp_str to "char *" and "size_t". > - Confirmed msg option is displayed by query-command-line-options. > > v3 -> v4 > - Correct email address of Signed-off-by. > > v2 -> v3 > - Use g_time_val_to_iso8601() to get timestamp instead of > copying libvirt's time-handling functions. > > According to discussion below, qemu doesn't need to take care > if timestamp functions are async-signal safe or not. > > http://marc.info/?l=qemu-devel&m=136741841921265&w=2 > > Also, In the review of v2 patch, strftime() are recommended to > format string. But it is not a suitable function to handle msec. > > Then, simply call g_time_val_to_iso8601(). > > - Intoroduce a common time-handling function to util/qemu-time.c. > (Suggested by Daniel P. Berrange) > > - Add testing for g_time_val_to_iso8601() to tests/test-time.c. > The test cases are copied from libvirt's virtimetest. > (Suggested by Daniel P. Berrange) > > v1 -> v2 > > - add an option, -msg timestamp={on|off}, to enable output message with timestamp > --- > include/qemu/error-report.h | 2 ++ > qemu-options.hx | 11 +++++++++++ > util/qemu-error.c | 10 ++++++++++ > vl.c | 26 ++++++++++++++++++++++++++ > 4 files changed, 49 insertions(+), 0 deletions(-) > > diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h > index 14c1719..3b098a9 100644 > --- a/include/qemu/error-report.h > +++ b/include/qemu/error-report.h > @@ -14,6 +14,7 @@ > #define QEMU_ERROR_H > > #include <stdarg.h> > +#include <stdbool.h> > #include "qemu/compiler.h" > > typedef struct Location { > @@ -40,5 +41,6 @@ void error_print_loc(void); > void error_set_progname(const char *argv0); > void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); > const char *error_get_progname(void); > +extern bool enable_timestamp_msg; > > #endif > diff --git a/qemu-options.hx b/qemu-options.hx > index ca6fdf6..f241379 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -3098,6 +3098,17 @@ property must be set. These objects are placed in the > '/objects' path. > ETEXI > > +DEF("msg", HAS_ARG, QEMU_OPTION_msg, > + "-msg timestamp[=on|off]\n" > + " change the format of messages\n" > + " on|off controls leading timestamps (default:on)\n", Did you really intend to say it's on by default? Because it's actually disabled by default. I prefer having this disabled btw, and I can fix it myself before applying if that's what you intended. > + QEMU_ARCH_ALL) > +STEXI > +@item -msg timestamp[=on|off] > +@findex -msg > +prepend a timestamp to each log message.(default:on) > +ETEXI > + > HXCOMM This is the last statement. Insert new options before this line! > STEXI > @end table > diff --git a/util/qemu-error.c b/util/qemu-error.c > index 08a36f4..fec02c6 100644 > --- a/util/qemu-error.c > +++ b/util/qemu-error.c > @@ -196,6 +196,7 @@ void error_print_loc(void) > } > } > > +bool enable_timestamp_msg; > /* > * Print an error message to current monitor if we have one, else to stderr. > * Format arguments like sprintf(). The result should not contain > @@ -206,6 +207,15 @@ void error_print_loc(void) > void error_report(const char *fmt, ...) > { There are some errors being printed to stderr that call error_get_pretty(), you might want to convert them to error_report() to increase coverage. But you can do this as a follow up patch. > va_list ap; > + GTimeVal tv; > + gchar *timestr; > + > + if (enable_timestamp_msg) { > + g_get_current_time(&tv); > + timestr = g_time_val_to_iso8601(&tv); > + error_printf("%s ", timestr); > + g_free(timestr); > + } > > error_print_loc(); > va_start(ap, fmt); > diff --git a/vl.c b/vl.c > index 0a8f056..589d264 100644 > --- a/vl.c > +++ b/vl.c > @@ -516,6 +516,18 @@ static QemuOptsList qemu_realtime_opts = { > }, > }; > > +static QemuOptsList qemu_msg_opts = { > + .name = "msg", > + .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head), > + .desc = { > + { > + .name = "timestamp", > + .type = QEMU_OPT_BOOL, > + }, > + { /* end of list */ } > + }, > +}; > + > const char *qemu_get_vm_name(void) > { > return qemu_name; > @@ -1459,6 +1471,12 @@ static void configure_realtime(QemuOpts *opts) > } > } > > + > +static void configure_msg(QemuOpts *opts) > +{ > + enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); > +} > + > /***********************************************************/ > /* USB devices */ > > @@ -2901,6 +2919,7 @@ int main(int argc, char **argv, char **envp) > qemu_add_opts(&qemu_object_opts); > qemu_add_opts(&qemu_tpmdev_opts); > qemu_add_opts(&qemu_realtime_opts); > + qemu_add_opts(&qemu_msg_opts); > > runstate_init(); > > @@ -3808,6 +3827,13 @@ int main(int argc, char **argv, char **envp) > } > configure_realtime(opts); > break; > + case QEMU_OPTION_msg: > + opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0); > + if (!opts) { > + exit(1); > + } > + configure_msg(opts); > + break; > default: > os_parse_cmd_args(popt->index, optarg); > } |
|
From: Stefan H. <ste...@gm...> - 2013-07-04 08:58:56
|
On Wed, Jul 03, 2013 at 11:02:46PM -0400, Seiji Aguchi wrote: > [Issue] > When we offer a customer support service and a problem happens > in a customer's system, we try to understand the problem by > comparing what the customer reports with message logs of the > customer's system. > > In this case, we often need to know when the problem happens. > > But, currently, there is no timestamp in qemu's error messages. > Therefore, we may not be able to understand the problem based on > error messages. > > [Solution] > Add a timestamp to qemu's error message logged by > error_report() with g_time_val_to_iso8601(). > > Signed-off-by: Seiji Aguchi <sei...@hd...> > --- > Changelog > v5 -> v6 > - Remove include/qemu/time.h and utils/qemu-time.c. > - Fix a syntax and indent of messages in msg option's DEF(). > - Change explanation of the msg option. > > v4 -> v5 > - Fix descriptions of msg option. > - Rename TIME_H to QEMU_TIME_H. (avoiding double inclusion of qemu/time.h) > - Change argument of qemu_get_timestamp_str to "char *" and "size_t". > - Confirmed msg option is displayed by query-command-line-options. > > v3 -> v4 > - Correct email address of Signed-off-by. > > v2 -> v3 > - Use g_time_val_to_iso8601() to get timestamp instead of > copying libvirt's time-handling functions. > > According to discussion below, qemu doesn't need to take care > if timestamp functions are async-signal safe or not. > > http://marc.info/?l=qemu-devel&m=136741841921265&w=2 > > Also, In the review of v2 patch, strftime() are recommended to > format string. But it is not a suitable function to handle msec. > > Then, simply call g_time_val_to_iso8601(). > > - Intoroduce a common time-handling function to util/qemu-time.c. > (Suggested by Daniel P. Berrange) > > - Add testing for g_time_val_to_iso8601() to tests/test-time.c. > The test cases are copied from libvirt's virtimetest. > (Suggested by Daniel P. Berrange) > > v1 -> v2 > > - add an option, -msg timestamp={on|off}, to enable output message with timestamp > --- > include/qemu/error-report.h | 2 ++ > qemu-options.hx | 11 +++++++++++ > util/qemu-error.c | 10 ++++++++++ > vl.c | 26 ++++++++++++++++++++++++++ > 4 files changed, 49 insertions(+), 0 deletions(-) Reviewed-by: Stefan Hajnoczi <ste...@re...> |
|
From: Stefan H. <ste...@gm...> - 2013-07-04 08:49:19
|
On Thu, Jul 04, 2013 at 02:57:13AM +0000, Seiji Aguchi wrote:
>
>
> > -----Original Message-----
> > From: Stefan Hajnoczi [mailto:ste...@gm...]
> > Sent: Wednesday, July 03, 2013 5:14 AM
> > To: Seiji Aguchi
> > Cc: qem...@no...; ali...@us...; ber...@re...; kw...@re...; mto...@re...;
> > ar...@re...; Tomoki Sekiyama; pbo...@re...; lca...@re...; le...@re...; eb...@re...;
> > dle...@li...
> > Subject: Re: [PATCH v5] Add timestamp to error_report()
> >
> > On Tue, Jul 02, 2013 at 02:09:24PM +0000, Seiji Aguchi wrote:
> > >
> > >
> > > > > +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> > > > > + "-msg [timestamp=on|off]\n"
> > > > > + " change the format of messages\n"
> > > > > + " timestamp=on|off enables leading timestamps (default:on)\n",
> > > > > + QEMU_ARCH_ALL)
> > > > > +STEXI
> > > > > +@item -msg timestamp=on|off
> > > > > +@findex -msg
> > > > > +prepend a timestamp to each log message.
> > > > > +(disabled by default)
> > > > > +ETEXI
> > > >
> > > > I am confused. If the user specifies -msg then enable_timestamp_msg is
> > > > on by default. If the user does not specify -msg then
> > > > enable_timestmap_msg is off. Did I get that right?
> > >
> > > Yes.
> > >
> > > >
> > > > This means that the default behavior of QEMU does not change but you can
> > > > add -msg to enable timestamps.
> > > >
> > > > I'm happy with this but find the documentation confusing.
> > >
> > > I can remove "(disabled by default)" if needed.
> >
> > Perhaps the simplest solution is timestamp=off by default. Then there
> > can be no confusion and users must do -msg timestamp=on to enable
> > timestamps.
> >
> > If you really want to keep -msg as a shortcut for -msg timestamp=on,
> > then please document explicitly that:
> > 1. Without -msg timestamps are off.
> > 1. With -msg timestamps are on.
> > 2. -msg timestamp=off can be used to turn timestamps off again.
>
> My apologies for the confusion.
>
> The syntax, "-msg [timestamp=on|off]", was wrong.
> "-msg timestamp[=on|off]" is correct.
>
> And there is no way to make "timestamp" optional, as far as I looked into a source code.
> Therefore, the explanation should be as below.
> (I think it is reasonable to keep "-msg timestamp" as a shortcut for -msg timestamp=on.)
Yes, I think you are correct. I thought previously that "-msg" works
but it seems an option is always required.
> <snip>
> +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> + "-msg timestamp[=on|off]\n"
> + " change the format of messages\n"
> + " on|off controls leading timestamps (default:on)\n",
> + QEMU_ARCH_ALL)
> +STEXI
> +@item -msg timestamp[=on|off]
> +@findex -msg
> +prepend a timestamp to each log message.(default:on)
> +ETEXI
> <snip>
>
> To be simpler, we may be able to introduce just a single -msg-timestamp.
> But I think current "-msg timestamp[=on|off]" is reasonable
> because other options may be introduced to msg, like log_level or debug.
Yep.
Stefan
|
|
From: Seiji A. <sei...@hd...> - 2013-07-04 03:02:58
|
[Issue] When we offer a customer support service and a problem happens in a customer's system, we try to understand the problem by comparing what the customer reports with message logs of the customer's system. In this case, we often need to know when the problem happens. But, currently, there is no timestamp in qemu's error messages. Therefore, we may not be able to understand the problem based on error messages. [Solution] Add a timestamp to qemu's error message logged by error_report() with g_time_val_to_iso8601(). Signed-off-by: Seiji Aguchi <sei...@hd...> --- Changelog v5 -> v6 - Remove include/qemu/time.h and utils/qemu-time.c. - Fix a syntax and indent of messages in msg option's DEF(). - Change explanation of the msg option. v4 -> v5 - Fix descriptions of msg option. - Rename TIME_H to QEMU_TIME_H. (avoiding double inclusion of qemu/time.h) - Change argument of qemu_get_timestamp_str to "char *" and "size_t". - Confirmed msg option is displayed by query-command-line-options. v3 -> v4 - Correct email address of Signed-off-by. v2 -> v3 - Use g_time_val_to_iso8601() to get timestamp instead of copying libvirt's time-handling functions. According to discussion below, qemu doesn't need to take care if timestamp functions are async-signal safe or not. http://marc.info/?l=qemu-devel&m=136741841921265&w=2 Also, In the review of v2 patch, strftime() are recommended to format string. But it is not a suitable function to handle msec. Then, simply call g_time_val_to_iso8601(). - Intoroduce a common time-handling function to util/qemu-time.c. (Suggested by Daniel P. Berrange) - Add testing for g_time_val_to_iso8601() to tests/test-time.c. The test cases are copied from libvirt's virtimetest. (Suggested by Daniel P. Berrange) v1 -> v2 - add an option, -msg timestamp={on|off}, to enable output message with timestamp --- include/qemu/error-report.h | 2 ++ qemu-options.hx | 11 +++++++++++ util/qemu-error.c | 10 ++++++++++ vl.c | 26 ++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 0 deletions(-) diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h index 14c1719..3b098a9 100644 --- a/include/qemu/error-report.h +++ b/include/qemu/error-report.h @@ -14,6 +14,7 @@ #define QEMU_ERROR_H #include <stdarg.h> +#include <stdbool.h> #include "qemu/compiler.h" typedef struct Location { @@ -40,5 +41,6 @@ void error_print_loc(void); void error_set_progname(const char *argv0); void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); const char *error_get_progname(void); +extern bool enable_timestamp_msg; #endif diff --git a/qemu-options.hx b/qemu-options.hx index ca6fdf6..f241379 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3098,6 +3098,17 @@ property must be set. These objects are placed in the '/objects' path. ETEXI +DEF("msg", HAS_ARG, QEMU_OPTION_msg, + "-msg timestamp[=on|off]\n" + " change the format of messages\n" + " on|off controls leading timestamps (default:on)\n", + QEMU_ARCH_ALL) +STEXI +@item -msg timestamp[=on|off] +@findex -msg +prepend a timestamp to each log message.(default:on) +ETEXI + HXCOMM This is the last statement. Insert new options before this line! STEXI @end table diff --git a/util/qemu-error.c b/util/qemu-error.c index 08a36f4..fec02c6 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -196,6 +196,7 @@ void error_print_loc(void) } } +bool enable_timestamp_msg; /* * Print an error message to current monitor if we have one, else to stderr. * Format arguments like sprintf(). The result should not contain @@ -206,6 +207,15 @@ void error_print_loc(void) void error_report(const char *fmt, ...) { va_list ap; + GTimeVal tv; + gchar *timestr; + + if (enable_timestamp_msg) { + g_get_current_time(&tv); + timestr = g_time_val_to_iso8601(&tv); + error_printf("%s ", timestr); + g_free(timestr); + } error_print_loc(); va_start(ap, fmt); diff --git a/vl.c b/vl.c index 0a8f056..589d264 100644 --- a/vl.c +++ b/vl.c @@ -516,6 +516,18 @@ static QemuOptsList qemu_realtime_opts = { }, }; +static QemuOptsList qemu_msg_opts = { + .name = "msg", + .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head), + .desc = { + { + .name = "timestamp", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + const char *qemu_get_vm_name(void) { return qemu_name; @@ -1459,6 +1471,12 @@ static void configure_realtime(QemuOpts *opts) } } + +static void configure_msg(QemuOpts *opts) +{ + enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); +} + /***********************************************************/ /* USB devices */ @@ -2901,6 +2919,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_object_opts); qemu_add_opts(&qemu_tpmdev_opts); qemu_add_opts(&qemu_realtime_opts); + qemu_add_opts(&qemu_msg_opts); runstate_init(); @@ -3808,6 +3827,13 @@ int main(int argc, char **argv, char **envp) } configure_realtime(opts); break; + case QEMU_OPTION_msg: + opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0); + if (!opts) { + exit(1); + } + configure_msg(opts); + break; default: os_parse_cmd_args(popt->index, optarg); } -- 1.7.1 |
|
From: Seiji A. <sei...@hd...> - 2013-07-04 02:57:24
|
> Patches need to make sense today, please do not add extra code with > potential future use in mind: > > 1. Other developers must be able to read and modify the current codebase > on its own. They do not know what potential future changes you were > thinking about. > > 2. You may never end up submitting or getting the future stuff upstream. > Then we'd be left with extra layers that are never used. I understand what you are concerned. I will remove utils/qemu-time.c and its header file. > Daniel's statement was about the code you copied from libvirt. It was > not about using the glib function, which simplifies things greatly and > avoids the need for a test suite. Honestly, I still think it is reasonable to introduce the common time-handling functionality. You seem to say that using the glib function is simple, so we don't need to introduce the common functionality. However, "commonly useful" is not related whether it is simple or not. I'm concerned that we may duplicate same code by "focusing on today too much". But, I don't stick to my opinion on this patch. Seiji |
|
From: Seiji A. <sei...@hd...> - 2013-07-04 02:57:23
|
> -----Original Message-----
> From: Stefan Hajnoczi [mailto:ste...@gm...]
> Sent: Wednesday, July 03, 2013 5:14 AM
> To: Seiji Aguchi
> Cc: qem...@no...; ali...@us...; ber...@re...; kw...@re...; mto...@re...;
> ar...@re...; Tomoki Sekiyama; pbo...@re...; lca...@re...; le...@re...; eb...@re...;
> dle...@li...
> Subject: Re: [PATCH v5] Add timestamp to error_report()
>
> On Tue, Jul 02, 2013 at 02:09:24PM +0000, Seiji Aguchi wrote:
> >
> >
> > > > +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> > > > + "-msg [timestamp=on|off]\n"
> > > > + " change the format of messages\n"
> > > > + " timestamp=on|off enables leading timestamps (default:on)\n",
> > > > + QEMU_ARCH_ALL)
> > > > +STEXI
> > > > +@item -msg timestamp=on|off
> > > > +@findex -msg
> > > > +prepend a timestamp to each log message.
> > > > +(disabled by default)
> > > > +ETEXI
> > >
> > > I am confused. If the user specifies -msg then enable_timestamp_msg is
> > > on by default. If the user does not specify -msg then
> > > enable_timestmap_msg is off. Did I get that right?
> >
> > Yes.
> >
> > >
> > > This means that the default behavior of QEMU does not change but you can
> > > add -msg to enable timestamps.
> > >
> > > I'm happy with this but find the documentation confusing.
> >
> > I can remove "(disabled by default)" if needed.
>
> Perhaps the simplest solution is timestamp=off by default. Then there
> can be no confusion and users must do -msg timestamp=on to enable
> timestamps.
>
> If you really want to keep -msg as a shortcut for -msg timestamp=on,
> then please document explicitly that:
> 1. Without -msg timestamps are off.
> 1. With -msg timestamps are on.
> 2. -msg timestamp=off can be used to turn timestamps off again.
My apologies for the confusion.
The syntax, "-msg [timestamp=on|off]", was wrong.
"-msg timestamp[=on|off]" is correct.
And there is no way to make "timestamp" optional, as far as I looked into a source code.
Therefore, the explanation should be as below.
(I think it is reasonable to keep "-msg timestamp" as a shortcut for -msg timestamp=on.)
<snip>
+DEF("msg", HAS_ARG, QEMU_OPTION_msg,
+ "-msg timestamp[=on|off]\n"
+ " change the format of messages\n"
+ " on|off controls leading timestamps (default:on)\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -msg timestamp[=on|off]
+@findex -msg
+prepend a timestamp to each log message.(default:on)
+ETEXI
<snip>
To be simpler, we may be able to introduce just a single -msg-timestamp.
But I think current "-msg timestamp[=on|off]" is reasonable
because other options may be introduced to msg, like log_level or debug.
Seiji
|
|
From: Stefan H. <ste...@gm...> - 2013-07-03 09:13:54
|
On Tue, Jul 02, 2013 at 02:09:24PM +0000, Seiji Aguchi wrote:
>
>
> > > +DEF("msg", HAS_ARG, QEMU_OPTION_msg,
> > > + "-msg [timestamp=on|off]\n"
> > > + " change the format of messages\n"
> > > + " timestamp=on|off enables leading timestamps (default:on)\n",
> > > + QEMU_ARCH_ALL)
> > > +STEXI
> > > +@item -msg timestamp=on|off
> > > +@findex -msg
> > > +prepend a timestamp to each log message.
> > > +(disabled by default)
> > > +ETEXI
> >
> > I am confused. If the user specifies -msg then enable_timestamp_msg is
> > on by default. If the user does not specify -msg then
> > enable_timestmap_msg is off. Did I get that right?
>
> Yes.
>
> >
> > This means that the default behavior of QEMU does not change but you can
> > add -msg to enable timestamps.
> >
> > I'm happy with this but find the documentation confusing.
>
> I can remove "(disabled by default)" if needed.
Perhaps the simplest solution is timestamp=off by default. Then there
can be no confusion and users must do -msg timestamp=on to enable
timestamps.
If you really want to keep -msg as a shortcut for -msg timestamp=on,
then please document explicitly that:
1. Without -msg timestamps are off.
1. With -msg timestamps are on.
2. -msg timestamp=off can be used to turn timestamps off again.
Stefan
|