diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 13:44:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 13:44:35 -0400 |
commit | 269af9a1a08d368b46d72e74126564d04c354f7e (patch) | |
tree | f0f2a8dd54075edebbb728602822e2b7378588d0 /arch/x86/include | |
parent | 8ca038dc10eec80f280d9d483f1835ac2763a787 (diff) | |
parent | 8b5ad472991796b2347464922c72de2ca5a028f3 (diff) |
Merge branch 'x86-extable-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull exception table generation updates from Ingo Molnar:
"The biggest change here is to allow the build-time sorting of the
exception table, to speed up booting. This is achieved by the
architecture enabling BUILDTIME_EXTABLE_SORT. This option is enabled
for x86 and MIPS currently.
On x86 a number of fixes and changes were needed to allow build-time
sorting of the exception table, in particular a relocation invariant
exception table format was needed. This required the abstracting out
of exception table protocol and the removal of 20 years of accumulated
assumptions about the x86 exception table format.
While at it, this tree also cleans up various other aspects of
exception handling, such as early(er) exception handling for
rdmsr_safe() et al.
All in one, as the result of these changes the x86 exception code is
now pretty nice and modern. As an added bonus any regressions in this
code will be early and violent crashes, so if you see any of those,
you'll know whom to blame!"
Fix up trivial conflicts in arch/{mips,x86}/Kconfig files due to nearby
modifications of other core architecture options.
* 'x86-extable-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (35 commits)
Revert "x86, extable: Disable presorted exception table for now"
scripts/sortextable: Handle relative entries, and other cleanups
x86, extable: Switch to relative exception table entries
x86, extable: Disable presorted exception table for now
x86, extable: Add _ASM_EXTABLE_EX() macro
x86, extable: Remove open-coded exception table entries in arch/x86/ia32/ia32entry.S
x86, extable: Remove open-coded exception table entries in arch/x86/include/asm/xsave.h
x86, extable: Remove open-coded exception table entries in arch/x86/include/asm/kvm_host.h
x86, extable: Remove the now-unused __ASM_EX_SEC macros
x86, extable: Remove open-coded exception table entries in arch/x86/xen/xen-asm_32.S
x86, extable: Remove open-coded exception table entries in arch/x86/um/checksum_32.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/usercopy_32.c
x86, extable: Remove open-coded exception table entries in arch/x86/lib/putuser.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/getuser.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/csum-copy_64.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/copy_user_nocache_64.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/copy_user_64.S
x86, extable: Remove open-coded exception table entries in arch/x86/lib/checksum_32.S
x86, extable: Remove open-coded exception table entries in arch/x86/kernel/test_rodata.c
x86, extable: Remove open-coded exception table entries in arch/x86/kernel/entry_64.S
...
Diffstat (limited to 'arch/x86/include')
-rw-r--r-- | arch/x86/include/asm/asm.h | 38 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/msr.h | 9 | ||||
-rw-r--r-- | arch/x86/include/asm/nops.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/segment.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/uaccess.h | 25 | ||||
-rw-r--r-- | arch/x86/include/asm/xsave.h | 10 |
8 files changed, 55 insertions, 46 deletions
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 9412d6558c88..1c2d247f65ce 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h | |||
@@ -4,11 +4,9 @@ | |||
4 | #ifdef __ASSEMBLY__ | 4 | #ifdef __ASSEMBLY__ |
5 | # define __ASM_FORM(x) x | 5 | # define __ASM_FORM(x) x |
6 | # define __ASM_FORM_COMMA(x) x, | 6 | # define __ASM_FORM_COMMA(x) x, |
7 | # define __ASM_EX_SEC .section __ex_table, "a" | ||
8 | #else | 7 | #else |
9 | # define __ASM_FORM(x) " " #x " " | 8 | # define __ASM_FORM(x) " " #x " " |
10 | # define __ASM_FORM_COMMA(x) " " #x "," | 9 | # define __ASM_FORM_COMMA(x) " " #x "," |
11 | # define __ASM_EX_SEC " .section __ex_table,\"a\"\n" | ||
12 | #endif | 10 | #endif |
13 | 11 | ||
14 | #ifdef CONFIG_X86_32 | 12 | #ifdef CONFIG_X86_32 |
@@ -42,17 +40,33 @@ | |||
42 | 40 | ||
43 | /* Exception table entry */ | 41 | /* Exception table entry */ |
44 | #ifdef __ASSEMBLY__ | 42 | #ifdef __ASSEMBLY__ |
45 | # define _ASM_EXTABLE(from,to) \ | 43 | # define _ASM_EXTABLE(from,to) \ |
46 | __ASM_EX_SEC ; \ | 44 | .pushsection "__ex_table","a" ; \ |
47 | _ASM_ALIGN ; \ | 45 | .balign 8 ; \ |
48 | _ASM_PTR from , to ; \ | 46 | .long (from) - . ; \ |
49 | .previous | 47 | .long (to) - . ; \ |
48 | .popsection | ||
49 | |||
50 | # define _ASM_EXTABLE_EX(from,to) \ | ||
51 | .pushsection "__ex_table","a" ; \ | ||
52 | .balign 8 ; \ | ||
53 | .long (from) - . ; \ | ||
54 | .long (to) - . + 0x7ffffff0 ; \ | ||
55 | .popsection | ||
50 | #else | 56 | #else |
51 | # define _ASM_EXTABLE(from,to) \ | 57 | # define _ASM_EXTABLE(from,to) \ |
52 | __ASM_EX_SEC \ | 58 | " .pushsection \"__ex_table\",\"a\"\n" \ |
53 | _ASM_ALIGN "\n" \ | 59 | " .balign 8\n" \ |
54 | _ASM_PTR #from "," #to "\n" \ | 60 | " .long (" #from ") - .\n" \ |
55 | " .previous\n" | 61 | " .long (" #to ") - .\n" \ |
62 | " .popsection\n" | ||
63 | |||
64 | # define _ASM_EXTABLE_EX(from,to) \ | ||
65 | " .pushsection \"__ex_table\",\"a\"\n" \ | ||
66 | " .balign 8\n" \ | ||
67 | " .long (" #from ") - .\n" \ | ||
68 | " .long (" #to ") - . + 0x7ffffff0\n" \ | ||
69 | " .popsection\n" | ||
56 | #endif | 70 | #endif |
57 | 71 | ||
58 | #endif /* _ASM_X86_ASM_H */ | 72 | #endif /* _ASM_X86_ASM_H */ |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index e216ba066e79..e5b97be12d2a 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <asm/desc.h> | 27 | #include <asm/desc.h> |
28 | #include <asm/mtrr.h> | 28 | #include <asm/mtrr.h> |
29 | #include <asm/msr-index.h> | 29 | #include <asm/msr-index.h> |
30 | #include <asm/asm.h> | ||
30 | 31 | ||
31 | #define KVM_MAX_VCPUS 254 | 32 | #define KVM_MAX_VCPUS 254 |
32 | #define KVM_SOFT_MAX_VCPUS 160 | 33 | #define KVM_SOFT_MAX_VCPUS 160 |
@@ -921,9 +922,7 @@ extern bool kvm_rebooting; | |||
921 | __ASM_SIZE(push) " $666b \n\t" \ | 922 | __ASM_SIZE(push) " $666b \n\t" \ |
922 | "call kvm_spurious_fault \n\t" \ | 923 | "call kvm_spurious_fault \n\t" \ |
923 | ".popsection \n\t" \ | 924 | ".popsection \n\t" \ |
924 | ".pushsection __ex_table, \"a\" \n\t" \ | 925 | _ASM_EXTABLE(666b, 667b) |
925 | _ASM_PTR " 666b, 667b \n\t" \ | ||
926 | ".popsection" | ||
927 | 926 | ||
928 | #define __kvm_handle_fault_on_reboot(insn) \ | 927 | #define __kvm_handle_fault_on_reboot(insn) \ |
929 | ____kvm_handle_fault_on_reboot(insn, "") | 928 | ____kvm_handle_fault_on_reboot(insn, "") |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 95203d40ffdd..084ef95274cd 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -169,14 +169,7 @@ static inline int wrmsr_safe(unsigned msr, unsigned low, unsigned high) | |||
169 | return native_write_msr_safe(msr, low, high); | 169 | return native_write_msr_safe(msr, low, high); |
170 | } | 170 | } |
171 | 171 | ||
172 | /* | 172 | /* rdmsr with exception handling */ |
173 | * rdmsr with exception handling. | ||
174 | * | ||
175 | * Please note that the exception handling works only after we've | ||
176 | * switched to the "smart" #GP handler in trap_init() which knows about | ||
177 | * exception tables - using this macro earlier than that causes machine | ||
178 | * hangs on boxes which do not implement the @msr in the first argument. | ||
179 | */ | ||
180 | #define rdmsr_safe(msr, p1, p2) \ | 173 | #define rdmsr_safe(msr, p1, p2) \ |
181 | ({ \ | 174 | ({ \ |
182 | int __err; \ | 175 | int __err; \ |
diff --git a/arch/x86/include/asm/nops.h b/arch/x86/include/asm/nops.h index 405b4032a60b..aff2b3356101 100644 --- a/arch/x86/include/asm/nops.h +++ b/arch/x86/include/asm/nops.h | |||
@@ -87,7 +87,11 @@ | |||
87 | #define P6_NOP8 0x0f,0x1f,0x84,0x00,0,0,0,0 | 87 | #define P6_NOP8 0x0f,0x1f,0x84,0x00,0,0,0,0 |
88 | #define P6_NOP5_ATOMIC P6_NOP5 | 88 | #define P6_NOP5_ATOMIC P6_NOP5 |
89 | 89 | ||
90 | #ifdef __ASSEMBLY__ | ||
91 | #define _ASM_MK_NOP(x) .byte x | ||
92 | #else | ||
90 | #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" | 93 | #define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n" |
94 | #endif | ||
91 | 95 | ||
92 | #if defined(CONFIG_MK7) | 96 | #if defined(CONFIG_MK7) |
93 | #define ASM_NOP1 _ASM_MK_NOP(K7_NOP1) | 97 | #define ASM_NOP1 _ASM_MK_NOP(K7_NOP1) |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index aa0f91308367..6cbbabf52707 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -1023,10 +1023,8 @@ extern void default_banner(void); | |||
1023 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs) \ | 1023 | call PARA_INDIRECT(pv_cpu_ops+PV_CPU_swapgs) \ |
1024 | ) | 1024 | ) |
1025 | 1025 | ||
1026 | #define GET_CR2_INTO_RCX \ | 1026 | #define GET_CR2_INTO_RAX \ |
1027 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2); \ | 1027 | call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) |
1028 | movq %rax, %rcx; \ | ||
1029 | xorq %rax, %rax; | ||
1030 | 1028 | ||
1031 | #define PARAVIRT_ADJUST_EXCEPTION_FRAME \ | 1029 | #define PARAVIRT_ADJUST_EXCEPTION_FRAME \ |
1032 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ | 1030 | PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ |
diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 165466233ab0..c48a95035a77 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h | |||
@@ -205,13 +205,15 @@ | |||
205 | 205 | ||
206 | #define IDT_ENTRIES 256 | 206 | #define IDT_ENTRIES 256 |
207 | #define NUM_EXCEPTION_VECTORS 32 | 207 | #define NUM_EXCEPTION_VECTORS 32 |
208 | /* Bitmask of exception vectors which push an error code on the stack */ | ||
209 | #define EXCEPTION_ERRCODE_MASK 0x00027d00 | ||
208 | #define GDT_SIZE (GDT_ENTRIES * 8) | 210 | #define GDT_SIZE (GDT_ENTRIES * 8) |
209 | #define GDT_ENTRY_TLS_ENTRIES 3 | 211 | #define GDT_ENTRY_TLS_ENTRIES 3 |
210 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) | 212 | #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) |
211 | 213 | ||
212 | #ifdef __KERNEL__ | 214 | #ifdef __KERNEL__ |
213 | #ifndef __ASSEMBLY__ | 215 | #ifndef __ASSEMBLY__ |
214 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][10]; | 216 | extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; |
215 | 217 | ||
216 | /* | 218 | /* |
217 | * Load a segment. Fall back on loading the zero | 219 | * Load a segment. Fall back on loading the zero |
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index e0544597cfe7..851fe0dc13bc 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h | |||
@@ -79,11 +79,12 @@ | |||
79 | #define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) | 79 | #define access_ok(type, addr, size) (likely(__range_not_ok(addr, size) == 0)) |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * The exception table consists of pairs of addresses: the first is the | 82 | * The exception table consists of pairs of addresses relative to the |
83 | * address of an instruction that is allowed to fault, and the second is | 83 | * exception table enty itself: the first is the address of an |
84 | * the address at which the program should continue. No registers are | 84 | * instruction that is allowed to fault, and the second is the address |
85 | * modified, so it is entirely up to the continuation code to figure out | 85 | * at which the program should continue. No registers are modified, |
86 | * what to do. | 86 | * so it is entirely up to the continuation code to figure out what to |
87 | * do. | ||
87 | * | 88 | * |
88 | * All the routines below use bits of fixup code that are out of line | 89 | * All the routines below use bits of fixup code that are out of line |
89 | * with the main instruction path. This means when everything is well, | 90 | * with the main instruction path. This means when everything is well, |
@@ -92,10 +93,14 @@ | |||
92 | */ | 93 | */ |
93 | 94 | ||
94 | struct exception_table_entry { | 95 | struct exception_table_entry { |
95 | unsigned long insn, fixup; | 96 | int insn, fixup; |
96 | }; | 97 | }; |
98 | /* This is not the generic standard exception_table_entry format */ | ||
99 | #define ARCH_HAS_SORT_EXTABLE | ||
100 | #define ARCH_HAS_SEARCH_EXTABLE | ||
97 | 101 | ||
98 | extern int fixup_exception(struct pt_regs *regs); | 102 | extern int fixup_exception(struct pt_regs *regs); |
103 | extern int early_fixup_exception(unsigned long *ip); | ||
99 | 104 | ||
100 | /* | 105 | /* |
101 | * These are the main single-value transfer routines. They automatically | 106 | * These are the main single-value transfer routines. They automatically |
@@ -202,8 +207,8 @@ extern int __get_user_bad(void); | |||
202 | asm volatile("1: movl %%eax,0(%1)\n" \ | 207 | asm volatile("1: movl %%eax,0(%1)\n" \ |
203 | "2: movl %%edx,4(%1)\n" \ | 208 | "2: movl %%edx,4(%1)\n" \ |
204 | "3:\n" \ | 209 | "3:\n" \ |
205 | _ASM_EXTABLE(1b, 2b - 1b) \ | 210 | _ASM_EXTABLE_EX(1b, 2b) \ |
206 | _ASM_EXTABLE(2b, 3b - 2b) \ | 211 | _ASM_EXTABLE_EX(2b, 3b) \ |
207 | : : "A" (x), "r" (addr)) | 212 | : : "A" (x), "r" (addr)) |
208 | 213 | ||
209 | #define __put_user_x8(x, ptr, __ret_pu) \ | 214 | #define __put_user_x8(x, ptr, __ret_pu) \ |
@@ -408,7 +413,7 @@ do { \ | |||
408 | #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ | 413 | #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ |
409 | asm volatile("1: mov"itype" %1,%"rtype"0\n" \ | 414 | asm volatile("1: mov"itype" %1,%"rtype"0\n" \ |
410 | "2:\n" \ | 415 | "2:\n" \ |
411 | _ASM_EXTABLE(1b, 2b - 1b) \ | 416 | _ASM_EXTABLE_EX(1b, 2b) \ |
412 | : ltype(x) : "m" (__m(addr))) | 417 | : ltype(x) : "m" (__m(addr))) |
413 | 418 | ||
414 | #define __put_user_nocheck(x, ptr, size) \ | 419 | #define __put_user_nocheck(x, ptr, size) \ |
@@ -450,7 +455,7 @@ struct __large_struct { unsigned long buf[100]; }; | |||
450 | #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ | 455 | #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ |
451 | asm volatile("1: mov"itype" %"rtype"0,%1\n" \ | 456 | asm volatile("1: mov"itype" %"rtype"0,%1\n" \ |
452 | "2:\n" \ | 457 | "2:\n" \ |
453 | _ASM_EXTABLE(1b, 2b - 1b) \ | 458 | _ASM_EXTABLE_EX(1b, 2b) \ |
454 | : : ltype(x), "m" (__m(addr))) | 459 | : : ltype(x), "m" (__m(addr))) |
455 | 460 | ||
456 | /* | 461 | /* |
diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h index c6ce2452f10c..8a1b6f9b594a 100644 --- a/arch/x86/include/asm/xsave.h +++ b/arch/x86/include/asm/xsave.h | |||
@@ -80,10 +80,7 @@ static inline int xsave_user(struct xsave_struct __user *buf) | |||
80 | "3: movl $-1,%[err]\n" | 80 | "3: movl $-1,%[err]\n" |
81 | " jmp 2b\n" | 81 | " jmp 2b\n" |
82 | ".previous\n" | 82 | ".previous\n" |
83 | ".section __ex_table,\"a\"\n" | 83 | _ASM_EXTABLE(1b,3b) |
84 | _ASM_ALIGN "\n" | ||
85 | _ASM_PTR "1b,3b\n" | ||
86 | ".previous" | ||
87 | : [err] "=r" (err) | 84 | : [err] "=r" (err) |
88 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) | 85 | : "D" (buf), "a" (-1), "d" (-1), "0" (0) |
89 | : "memory"); | 86 | : "memory"); |
@@ -106,10 +103,7 @@ static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask) | |||
106 | "3: movl $-1,%[err]\n" | 103 | "3: movl $-1,%[err]\n" |
107 | " jmp 2b\n" | 104 | " jmp 2b\n" |
108 | ".previous\n" | 105 | ".previous\n" |
109 | ".section __ex_table,\"a\"\n" | 106 | _ASM_EXTABLE(1b,3b) |
110 | _ASM_ALIGN "\n" | ||
111 | _ASM_PTR "1b,3b\n" | ||
112 | ".previous" | ||
113 | : [err] "=r" (err) | 107 | : [err] "=r" (err) |
114 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) | 108 | : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0) |
115 | : "memory"); /* memory required? */ | 109 | : "memory"); /* memory required? */ |