diff options
-rw-r--r-- | arch/i386/kernel/time.c | 10 | ||||
-rw-r--r-- | include/asm-i386/ptrace.h | 4 | ||||
-rw-r--r-- | include/asm-i386/segment.h | 19 |
3 files changed, 21 insertions, 12 deletions
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 9603ccaba997..a4f67a6e6821 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c | |||
@@ -131,15 +131,13 @@ unsigned long profile_pc(struct pt_regs *regs) | |||
131 | unsigned long pc = instruction_pointer(regs); | 131 | unsigned long pc = instruction_pointer(regs); |
132 | 132 | ||
133 | #ifdef CONFIG_SMP | 133 | #ifdef CONFIG_SMP |
134 | if (!user_mode_vm(regs) && in_lock_functions(pc)) { | 134 | if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) && |
135 | in_lock_functions(pc)) { | ||
135 | #ifdef CONFIG_FRAME_POINTER | 136 | #ifdef CONFIG_FRAME_POINTER |
136 | return *(unsigned long *)(regs->ebp + 4); | 137 | return *(unsigned long *)(regs->ebp + 4); |
137 | #else | 138 | #else |
138 | unsigned long *sp; | 139 | unsigned long *sp = (unsigned long *)®s->esp; |
139 | if ((regs->xcs & 3) == 0) | 140 | |
140 | sp = (unsigned long *)®s->esp; | ||
141 | else | ||
142 | sp = (unsigned long *)regs->esp; | ||
143 | /* Return address is either directly at stack pointer | 141 | /* Return address is either directly at stack pointer |
144 | or above a saved eflags. Eflags has bits 22-31 zero, | 142 | or above a saved eflags. Eflags has bits 22-31 zero, |
145 | kernel addresses don't. */ | 143 | kernel addresses don't. */ |
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h index 1646996c73da..6002597b9e12 100644 --- a/include/asm-i386/ptrace.h +++ b/include/asm-i386/ptrace.h | |||
@@ -49,6 +49,10 @@ static inline int user_mode_vm(struct pt_regs *regs) | |||
49 | { | 49 | { |
50 | return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; | 50 | return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; |
51 | } | 51 | } |
52 | static inline int v8086_mode(struct pt_regs *regs) | ||
53 | { | ||
54 | return (regs->eflags & VM_MASK); | ||
55 | } | ||
52 | 56 | ||
53 | #define instruction_pointer(regs) ((regs)->eip) | 57 | #define instruction_pointer(regs) ((regs)->eip) |
54 | #define regs_return_value(regs) ((regs)->eax) | 58 | #define regs_return_value(regs) ((regs)->eax) |
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h index 3c796af33776..065f10bfa487 100644 --- a/include/asm-i386/segment.h +++ b/include/asm-i386/segment.h | |||
@@ -83,14 +83,8 @@ | |||
83 | * The GDT has 32 entries | 83 | * The GDT has 32 entries |
84 | */ | 84 | */ |
85 | #define GDT_ENTRIES 32 | 85 | #define GDT_ENTRIES 32 |
86 | |||
87 | #define GDT_SIZE (GDT_ENTRIES * 8) | 86 | #define GDT_SIZE (GDT_ENTRIES * 8) |
88 | 87 | ||
89 | /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ | ||
90 | #define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) | ||
91 | /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ | ||
92 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) | ||
93 | |||
94 | /* Simple and small GDT entries for booting only */ | 88 | /* Simple and small GDT entries for booting only */ |
95 | 89 | ||
96 | #define GDT_ENTRY_BOOT_CS 2 | 90 | #define GDT_ENTRY_BOOT_CS 2 |
@@ -134,4 +128,17 @@ | |||
134 | #ifndef CONFIG_PARAVIRT | 128 | #ifndef CONFIG_PARAVIRT |
135 | #define get_kernel_rpl() 0 | 129 | #define get_kernel_rpl() 0 |
136 | #endif | 130 | #endif |
131 | /* | ||
132 | * Matching rules for certain types of segments. | ||
133 | */ | ||
134 | |||
135 | /* Matches only __KERNEL_CS, ignoring PnP / USER / APM segments */ | ||
136 | #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8) | ||
137 | |||
138 | /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ | ||
139 | #define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) | ||
140 | |||
141 | /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ | ||
142 | #define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) | ||
143 | |||
137 | #endif | 144 | #endif |