aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/kprobes_32.c7
-rw-r--r--arch/x86/kernel/kprobes_64.c7
-rw-r--r--arch/x86/kernel/traps_32.c2
-rw-r--r--arch/x86/kernel/traps_64.c2
-rw-r--r--arch/x86/mm/fault_32.c5
-rw-r--r--arch/x86/mm/fault_64.c5
-rw-r--r--include/asm-x86/irqflags_32.h21
-rw-r--r--include/asm-x86/irqflags_64.h20
-rw-r--r--kernel/lockdep.c2
-rw-r--r--kernel/sched_debug.c5
10 files changed, 61 insertions, 15 deletions
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index 90f778c04b3f..d87a523070d1 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -564,12 +564,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
564 564
565 resume_execution(cur, regs, kcb); 565 resume_execution(cur, regs, kcb);
566 regs->eflags |= kcb->kprobe_saved_eflags; 566 regs->eflags |= kcb->kprobe_saved_eflags;
567#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 567 trace_hardirqs_fixup_flags(regs->eflags);
568 if (raw_irqs_disabled_flags(regs->eflags))
569 trace_hardirqs_off();
570 else
571 trace_hardirqs_on();
572#endif
573 568
574 /*Restore back the original saved kprobes variables and continue. */ 569 /*Restore back the original saved kprobes variables and continue. */
575 if (kcb->kprobe_status == KPROBE_REENTER) { 570 if (kcb->kprobe_status == KPROBE_REENTER) {
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 681b801c5e26..3db3611933d8 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -551,12 +551,7 @@ int __kprobes post_kprobe_handler(struct pt_regs *regs)
551 551
552 resume_execution(cur, regs, kcb); 552 resume_execution(cur, regs, kcb);
553 regs->eflags |= kcb->kprobe_saved_rflags; 553 regs->eflags |= kcb->kprobe_saved_rflags;
554#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 554 trace_hardirqs_fixup_flags(regs->eflags);
555 if (raw_irqs_disabled_flags(regs->eflags))
556 trace_hardirqs_off();
557 else
558 trace_hardirqs_on();
559#endif
560 555
561 /* Restore the original saved kprobes variables and continue. */ 556 /* Restore the original saved kprobes variables and continue. */
562 if (kcb->kprobe_status == KPROBE_REENTER) { 557 if (kcb->kprobe_status == KPROBE_REENTER) {
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index cc9acace7e23..298d13ed3ab3 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -789,6 +789,8 @@ void restart_nmi(void)
789#ifdef CONFIG_KPROBES 789#ifdef CONFIG_KPROBES
790fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) 790fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
791{ 791{
792 trace_hardirqs_fixup();
793
792 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) 794 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
793 == NOTIFY_STOP) 795 == NOTIFY_STOP)
794 return; 796 return;
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index d0c2bc7ab2ec..4a6bd4965f56 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -807,6 +807,8 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
807/* runs on IST stack. */ 807/* runs on IST stack. */
808asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code) 808asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
809{ 809{
810 trace_hardirqs_fixup();
811
810 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) { 812 if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
811 return; 813 return;
812 } 814 }
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index 33563ee8eb0f..a2273d44aa27 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -303,6 +303,11 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
303 int write, si_code; 303 int write, si_code;
304 int fault; 304 int fault;
305 305
306 /*
307 * We can fault from pretty much anywhere, with unknown IRQ state.
308 */
309 trace_hardirqs_fixup();
310
306 /* get the address */ 311 /* get the address */
307 address = read_cr2(); 312 address = read_cr2();
308 313
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 644b4f7ece10..0e26230669ca 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -304,6 +304,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
304 unsigned long flags; 304 unsigned long flags;
305 siginfo_t info; 305 siginfo_t info;
306 306
307 /*
308 * We can fault from pretty much anywhere, with unknown IRQ state.
309 */
310 trace_hardirqs_fixup();
311
307 tsk = current; 312 tsk = current;
308 mm = tsk->mm; 313 mm = tsk->mm;
309 prefetchw(&mm->mmap_sem); 314 prefetchw(&mm->mmap_sem);
diff --git a/include/asm-x86/irqflags_32.h b/include/asm-x86/irqflags_32.h
index d058b04e0083..4c7720089cb5 100644
--- a/include/asm-x86/irqflags_32.h
+++ b/include/asm-x86/irqflags_32.h
@@ -129,6 +129,27 @@ static inline int raw_irqs_disabled(void)
129 129
130 return raw_irqs_disabled_flags(flags); 130 return raw_irqs_disabled_flags(flags);
131} 131}
132
133/*
134 * makes the traced hardirq state match with the machine state
135 *
136 * should be a rarely used function, only in places where its
137 * otherwise impossible to know the irq state, like in traps.
138 */
139static inline void trace_hardirqs_fixup_flags(unsigned long flags)
140{
141 if (raw_irqs_disabled_flags(flags))
142 trace_hardirqs_off();
143 else
144 trace_hardirqs_on();
145}
146
147static inline void trace_hardirqs_fixup(void)
148{
149 unsigned long flags = __raw_local_save_flags();
150
151 trace_hardirqs_fixup_flags(flags);
152}
132#endif /* __ASSEMBLY__ */ 153#endif /* __ASSEMBLY__ */
133 154
134/* 155/*
diff --git a/include/asm-x86/irqflags_64.h b/include/asm-x86/irqflags_64.h
index 5341ea1f815a..bb9163bb29d1 100644
--- a/include/asm-x86/irqflags_64.h
+++ b/include/asm-x86/irqflags_64.h
@@ -112,6 +112,26 @@ static inline int raw_irqs_disabled(void)
112} 112}
113 113
114/* 114/*
115 * makes the traced hardirq state match with the machine state
116 *
117 * should be a rarely used function, only in places where its
118 * otherwise impossible to know the irq state, like in traps.
119 */
120static inline void trace_hardirqs_fixup_flags(unsigned long flags)
121{
122 if (raw_irqs_disabled_flags(flags))
123 trace_hardirqs_off();
124 else
125 trace_hardirqs_on();
126}
127
128static inline void trace_hardirqs_fixup(void)
129{
130 unsigned long flags = __raw_local_save_flags();
131
132 trace_hardirqs_fixup_flags(flags);
133}
134/*
115 * Used in the idle loop; sti takes one instruction cycle 135 * Used in the idle loop; sti takes one instruction cycle
116 * to complete: 136 * to complete:
117 */ 137 */
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 55fe0c7cd95f..ed38bbfc48a3 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2424,7 +2424,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
2424 return 0; 2424 return 0;
2425 2425
2426 /* 2426 /*
2427 * Calculate the chain hash: it's the combined has of all the 2427 * Calculate the chain hash: it's the combined hash of all the
2428 * lock keys along the dependency chain. We save the hash value 2428 * lock keys along the dependency chain. We save the hash value
2429 * at every step so that we can get the current hash easily 2429 * at every step so that we can get the current hash easily
2430 * after unlock. The chain hash is then used to cache dependency 2430 * after unlock. The chain hash is then used to cache dependency
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index e6fb392e5164..415e5c385542 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -80,6 +80,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
80static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) 80static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
81{ 81{
82 struct task_struct *g, *p; 82 struct task_struct *g, *p;
83 unsigned long flags;
83 84
84 SEQ_printf(m, 85 SEQ_printf(m,
85 "\nrunnable tasks:\n" 86 "\nrunnable tasks:\n"
@@ -88,7 +89,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
88 "------------------------------------------------------" 89 "------------------------------------------------------"
89 "----------------------------------------------------\n"); 90 "----------------------------------------------------\n");
90 91
91 read_lock_irq(&tasklist_lock); 92 read_lock_irqsave(&tasklist_lock, flags);
92 93
93 do_each_thread(g, p) { 94 do_each_thread(g, p) {
94 if (!p->se.on_rq || task_cpu(p) != rq_cpu) 95 if (!p->se.on_rq || task_cpu(p) != rq_cpu)
@@ -97,7 +98,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
97 print_task(m, rq, p); 98 print_task(m, rq, p);
98 } while_each_thread(g, p); 99 } while_each_thread(g, p);
99 100
100 read_unlock_irq(&tasklist_lock); 101 read_unlock_irqrestore(&tasklist_lock, flags);
101} 102}
102 103
103void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) 104void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)