aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/time_32.c13
-rw-r--r--arch/x86/kernel/time_64.c8
2 files changed, 11 insertions, 10 deletions
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
index fd876cc77487..fda0c34da757 100644
--- a/arch/x86/kernel/time_32.c
+++ b/arch/x86/kernel/time_32.c
@@ -34,23 +34,22 @@ unsigned long profile_pc(struct pt_regs *regs)
34{ 34{
35 unsigned long pc = instruction_pointer(regs); 35 unsigned long pc = instruction_pointer(regs);
36 36
37#ifdef CONFIG_SMP
38 if (!user_mode_vm(regs) && in_lock_functions(pc)) { 37 if (!user_mode_vm(regs) && in_lock_functions(pc)) {
39#ifdef CONFIG_FRAME_POINTER 38#ifdef CONFIG_FRAME_POINTER
40 return *(unsigned long *)(regs->bp + sizeof(long)); 39 return *(unsigned long *)(regs->bp + sizeof(long));
41#else 40#else
42 unsigned long *sp = (unsigned long *)&regs->sp; 41 unsigned long *sp = (unsigned long *)regs->sp;
43 42 /*
44 /* Return address is either directly at stack pointer 43 * Return address is either directly at stack pointer
45 or above a saved flags. Eflags has bits 22-31 zero, 44 * or above a saved flags. Eflags has bits 22-31 zero,
46 kernel addresses don't. */ 45 * kernel addresses don't.
46 */
47 if (sp[0] >> 22) 47 if (sp[0] >> 22)
48 return sp[0]; 48 return sp[0];
49 if (sp[1] >> 22) 49 if (sp[1] >> 22)
50 return sp[1]; 50 return sp[1];
51#endif 51#endif
52 } 52 }
53#endif
54 return pc; 53 return pc;
55} 54}
56EXPORT_SYMBOL(profile_pc); 55EXPORT_SYMBOL(profile_pc);
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index e59a40ebff14..fda0c34da757 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -34,14 +34,16 @@ unsigned long profile_pc(struct pt_regs *regs)
34{ 34{
35 unsigned long pc = instruction_pointer(regs); 35 unsigned long pc = instruction_pointer(regs);
36 36
37 /* Assume the lock function has either no stack frame or a copy
38 of flags from PUSHF
39 Eflags always has bits 22 and up cleared unlike kernel addresses. */
40 if (!user_mode_vm(regs) && in_lock_functions(pc)) { 37 if (!user_mode_vm(regs) && in_lock_functions(pc)) {
41#ifdef CONFIG_FRAME_POINTER 38#ifdef CONFIG_FRAME_POINTER
42 return *(unsigned long *)(regs->bp + sizeof(long)); 39 return *(unsigned long *)(regs->bp + sizeof(long));
43#else 40#else
44 unsigned long *sp = (unsigned long *)regs->sp; 41 unsigned long *sp = (unsigned long *)regs->sp;
42 /*
43 * Return address is either directly at stack pointer
44 * or above a saved flags. Eflags has bits 22-31 zero,
45 * kernel addresses don't.
46 */
45 if (sp[0] >> 22) 47 if (sp[0] >> 22)
46 return sp[0]; 48 return sp[0];
47 if (sp[1] >> 22) 49 if (sp[1] >> 22)