diff options
author | Stas Sergeev <stsp@aknet.ru> | 2006-12-06 20:14:01 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:01 -0500 |
commit | be44d2aabce2d62f72d5751d1871b6212bf7a1c7 (patch) | |
tree | 3f190dd5b5747ee83b50c4596b4801ce6c6b551c /include | |
parent | bb81a09e55eaf7e5f798468ab971469b6f66a259 (diff) |
[PATCH] i386: espfix cleanup
Clean up the espfix code:
- Introduced PER_CPU() macro to be used from asm
- Introduced GET_DESC_BASE() macro to be used from asm
- Rewrote the fixup code in asm, as calling a C code with the altered %ss
appeared to be unsafe
- No longer altering the stack from a .fixup section
- 16bit per-cpu stack is no longer used, instead the stack segment base
is patched the way so that the high word of the kernel and user %esp
are the same.
- Added the limit-patching for the espfix segment. (Chuck Ebbert)
[jeremy@goop.org: use the x86 scaling addressing mode rather than shifting]
Signed-off-by: Stas Sergeev <stsp@aknet.ru>
Signed-off-by: Andi Kleen <ak@suse.de>
Acked-by: Zachary Amsden <zach@vmware.com>
Acked-by: Chuck Ebbert <76306.1226@compuserve.com>
Acked-by: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-i386/desc.h | 27 | ||||
-rw-r--r-- | include/asm-i386/percpu.h | 25 |
2 files changed, 48 insertions, 4 deletions
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index a0398f780ca1..6cf2ac2bfde7 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #include <asm/ldt.h> | 4 | #include <asm/ldt.h> |
5 | #include <asm/segment.h> | 5 | #include <asm/segment.h> |
6 | 6 | ||
7 | #define CPU_16BIT_STACK_SIZE 1024 | ||
8 | |||
9 | #ifndef __ASSEMBLY__ | 7 | #ifndef __ASSEMBLY__ |
10 | 8 | ||
11 | #include <linux/preempt.h> | 9 | #include <linux/preempt.h> |
@@ -16,8 +14,6 @@ | |||
16 | 14 | ||
17 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; | 15 | extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; |
18 | 16 | ||
19 | DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); | ||
20 | |||
21 | struct Xgt_desc_struct { | 17 | struct Xgt_desc_struct { |
22 | unsigned short size; | 18 | unsigned short size; |
23 | unsigned long address __attribute__((packed)); | 19 | unsigned long address __attribute__((packed)); |
@@ -181,6 +177,29 @@ static inline unsigned long get_desc_base(unsigned long *desc) | |||
181 | return base; | 177 | return base; |
182 | } | 178 | } |
183 | 179 | ||
180 | #else /* __ASSEMBLY__ */ | ||
181 | |||
182 | /* | ||
183 | * GET_DESC_BASE reads the descriptor base of the specified segment. | ||
184 | * | ||
185 | * Args: | ||
186 | * idx - descriptor index | ||
187 | * gdt - GDT pointer | ||
188 | * base - 32bit register to which the base will be written | ||
189 | * lo_w - lo word of the "base" register | ||
190 | * lo_b - lo byte of the "base" register | ||
191 | * hi_b - hi byte of the low word of the "base" register | ||
192 | * | ||
193 | * Example: | ||
194 | * GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) | ||
195 | * Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. | ||
196 | */ | ||
197 | #define GET_DESC_BASE(idx, gdt, base, lo_w, lo_b, hi_b) \ | ||
198 | movb idx*8+4(gdt), lo_b; \ | ||
199 | movb idx*8+7(gdt), hi_b; \ | ||
200 | shll $16, base; \ | ||
201 | movw idx*8+2(gdt), lo_w; | ||
202 | |||
184 | #endif /* !__ASSEMBLY__ */ | 203 | #endif /* !__ASSEMBLY__ */ |
185 | 204 | ||
186 | #endif | 205 | #endif |
diff --git a/include/asm-i386/percpu.h b/include/asm-i386/percpu.h index 5764afa4b6a4..510ae1d3486c 100644 --- a/include/asm-i386/percpu.h +++ b/include/asm-i386/percpu.h | |||
@@ -1,6 +1,31 @@ | |||
1 | #ifndef __ARCH_I386_PERCPU__ | 1 | #ifndef __ARCH_I386_PERCPU__ |
2 | #define __ARCH_I386_PERCPU__ | 2 | #define __ARCH_I386_PERCPU__ |
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | ||
4 | #include <asm-generic/percpu.h> | 5 | #include <asm-generic/percpu.h> |
6 | #else | ||
7 | |||
8 | /* | ||
9 | * PER_CPU finds an address of a per-cpu variable. | ||
10 | * | ||
11 | * Args: | ||
12 | * var - variable name | ||
13 | * cpu - 32bit register containing the current CPU number | ||
14 | * | ||
15 | * The resulting address is stored in the "cpu" argument. | ||
16 | * | ||
17 | * Example: | ||
18 | * PER_CPU(cpu_gdt_descr, %ebx) | ||
19 | */ | ||
20 | #ifdef CONFIG_SMP | ||
21 | #define PER_CPU(var, cpu) \ | ||
22 | movl __per_cpu_offset(,cpu,4), cpu; \ | ||
23 | addl $per_cpu__/**/var, cpu; | ||
24 | #else /* ! SMP */ | ||
25 | #define PER_CPU(var, cpu) \ | ||
26 | movl $per_cpu__/**/var, cpu; | ||
27 | #endif /* SMP */ | ||
28 | |||
29 | #endif /* !__ASSEMBLY__ */ | ||
5 | 30 | ||
6 | #endif /* __ARCH_I386_PERCPU__ */ | 31 | #endif /* __ARCH_I386_PERCPU__ */ |