diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 18:49:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-10 18:49:10 -0400 |
commit | aa98936e4f423dc2706771368598b04870059d14 (patch) | |
tree | 5b503225ee28f4b9648354db54eb29f4c097c140 /arch | |
parent | 082b63ae45e7d14e15995dedd782ec7344596fb2 (diff) | |
parent | 0c23590f00f85467b318ad0c20c36796a5bd4c60 (diff) |
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86, 64-bit: ifdef out struct thread_struct::ip
x86, 32-bit: ifdef out struct thread_struct::fs
x86: clean up alternative.h
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/alternative.h | 59 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 2 |
3 files changed, 28 insertions, 38 deletions
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index f6aa18eadf71..1a37bcdc8606 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/stringify.h> | ||
6 | #include <asm/asm.h> | 7 | #include <asm/asm.h> |
7 | 8 | ||
8 | /* | 9 | /* |
@@ -74,6 +75,22 @@ static inline void alternatives_smp_switch(int smp) {} | |||
74 | 75 | ||
75 | const unsigned char *const *find_nop_table(void); | 76 | const unsigned char *const *find_nop_table(void); |
76 | 77 | ||
78 | /* alternative assembly primitive: */ | ||
79 | #define ALTERNATIVE(oldinstr, newinstr, feature) \ | ||
80 | \ | ||
81 | "661:\n\t" oldinstr "\n662:\n" \ | ||
82 | ".section .altinstructions,\"a\"\n" \ | ||
83 | _ASM_ALIGN "\n" \ | ||
84 | _ASM_PTR "661b\n" /* label */ \ | ||
85 | _ASM_PTR "663f\n" /* new instruction */ \ | ||
86 | " .byte " __stringify(feature) "\n" /* feature bit */ \ | ||
87 | " .byte 662b-661b\n" /* sourcelen */ \ | ||
88 | " .byte 664f-663f\n" /* replacementlen */ \ | ||
89 | ".previous\n" \ | ||
90 | ".section .altinstr_replacement, \"ax\"\n" \ | ||
91 | "663:\n\t" newinstr "\n664:\n" /* replacement */ \ | ||
92 | ".previous" | ||
93 | |||
77 | /* | 94 | /* |
78 | * Alternative instructions for different CPU types or capabilities. | 95 | * Alternative instructions for different CPU types or capabilities. |
79 | * | 96 | * |
@@ -87,18 +104,7 @@ const unsigned char *const *find_nop_table(void); | |||
87 | * without volatile and memory clobber. | 104 | * without volatile and memory clobber. |
88 | */ | 105 | */ |
89 | #define alternative(oldinstr, newinstr, feature) \ | 106 | #define alternative(oldinstr, newinstr, feature) \ |
90 | asm volatile ("661:\n\t" oldinstr "\n662:\n" \ | 107 | asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory") |
91 | ".section .altinstructions,\"a\"\n" \ | ||
92 | _ASM_ALIGN "\n" \ | ||
93 | _ASM_PTR "661b\n" /* label */ \ | ||
94 | _ASM_PTR "663f\n" /* new instruction */ \ | ||
95 | " .byte %c0\n" /* feature bit */ \ | ||
96 | " .byte 662b-661b\n" /* sourcelen */ \ | ||
97 | " .byte 664f-663f\n" /* replacementlen */ \ | ||
98 | ".previous\n" \ | ||
99 | ".section .altinstr_replacement,\"ax\"\n" \ | ||
100 | "663:\n\t" newinstr "\n664:\n" /* replacement */ \ | ||
101 | ".previous" :: "i" (feature) : "memory") | ||
102 | 108 | ||
103 | /* | 109 | /* |
104 | * Alternative inline assembly with input. | 110 | * Alternative inline assembly with input. |
@@ -109,35 +115,16 @@ const unsigned char *const *find_nop_table(void); | |||
109 | * Best is to use constraints that are fixed size (like (%1) ... "r") | 115 | * Best is to use constraints that are fixed size (like (%1) ... "r") |
110 | * If you use variable sized constraints like "m" or "g" in the | 116 | * If you use variable sized constraints like "m" or "g" in the |
111 | * replacement make sure to pad to the worst case length. | 117 | * replacement make sure to pad to the worst case length. |
118 | * Leaving an unused argument 0 to keep API compatibility. | ||
112 | */ | 119 | */ |
113 | #define alternative_input(oldinstr, newinstr, feature, input...) \ | 120 | #define alternative_input(oldinstr, newinstr, feature, input...) \ |
114 | asm volatile ("661:\n\t" oldinstr "\n662:\n" \ | 121 | asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \ |
115 | ".section .altinstructions,\"a\"\n" \ | 122 | : : "i" (0), ## input) |
116 | _ASM_ALIGN "\n" \ | ||
117 | _ASM_PTR "661b\n" /* label */ \ | ||
118 | _ASM_PTR "663f\n" /* new instruction */ \ | ||
119 | " .byte %c0\n" /* feature bit */ \ | ||
120 | " .byte 662b-661b\n" /* sourcelen */ \ | ||
121 | " .byte 664f-663f\n" /* replacementlen */ \ | ||
122 | ".previous\n" \ | ||
123 | ".section .altinstr_replacement,\"ax\"\n" \ | ||
124 | "663:\n\t" newinstr "\n664:\n" /* replacement */ \ | ||
125 | ".previous" :: "i" (feature), ##input) | ||
126 | 123 | ||
127 | /* Like alternative_input, but with a single output argument */ | 124 | /* Like alternative_input, but with a single output argument */ |
128 | #define alternative_io(oldinstr, newinstr, feature, output, input...) \ | 125 | #define alternative_io(oldinstr, newinstr, feature, output, input...) \ |
129 | asm volatile ("661:\n\t" oldinstr "\n662:\n" \ | 126 | asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \ |
130 | ".section .altinstructions,\"a\"\n" \ | 127 | : output : "i" (0), ## input) |
131 | _ASM_ALIGN "\n" \ | ||
132 | _ASM_PTR "661b\n" /* label */ \ | ||
133 | _ASM_PTR "663f\n" /* new instruction */ \ | ||
134 | " .byte %c[feat]\n" /* feature bit */ \ | ||
135 | " .byte 662b-661b\n" /* sourcelen */ \ | ||
136 | " .byte 664f-663f\n" /* replacementlen */ \ | ||
137 | ".previous\n" \ | ||
138 | ".section .altinstr_replacement,\"ax\"\n" \ | ||
139 | "663:\n\t" newinstr "\n664:\n" /* replacement */ \ | ||
140 | ".previous" : output : [feat] "i" (feature), ##input) | ||
141 | 128 | ||
142 | /* | 129 | /* |
143 | * use this macro(s) if you need more than one output parameter | 130 | * use this macro(s) if you need more than one output parameter |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 6469866a7410..b0431a4f066f 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -428,8 +428,12 @@ struct thread_struct { | |||
428 | unsigned short fsindex; | 428 | unsigned short fsindex; |
429 | unsigned short gsindex; | 429 | unsigned short gsindex; |
430 | #endif | 430 | #endif |
431 | #ifdef CONFIG_X86_32 | ||
431 | unsigned long ip; | 432 | unsigned long ip; |
433 | #endif | ||
434 | #ifdef CONFIG_X86_64 | ||
432 | unsigned long fs; | 435 | unsigned long fs; |
436 | #endif | ||
433 | unsigned long gs; | 437 | unsigned long gs; |
434 | /* Hardware debugging registers: */ | 438 | /* Hardware debugging registers: */ |
435 | unsigned long debugreg0; | 439 | unsigned long debugreg0; |
@@ -876,7 +880,6 @@ static inline void spin_lock_prefetch(const void *x) | |||
876 | .vm86_info = NULL, \ | 880 | .vm86_info = NULL, \ |
877 | .sysenter_cs = __KERNEL_CS, \ | 881 | .sysenter_cs = __KERNEL_CS, \ |
878 | .io_bitmap_ptr = NULL, \ | 882 | .io_bitmap_ptr = NULL, \ |
879 | .fs = __KERNEL_PERCPU, \ | ||
880 | } | 883 | } |
881 | 884 | ||
882 | /* | 885 | /* |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index b1f4dffb919e..8d82a77a3f3b 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -142,7 +142,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | |||
142 | gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); | 142 | gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8); |
143 | gdb_regs32[GDB_CS] = __KERNEL_CS; | 143 | gdb_regs32[GDB_CS] = __KERNEL_CS; |
144 | gdb_regs32[GDB_SS] = __KERNEL_DS; | 144 | gdb_regs32[GDB_SS] = __KERNEL_DS; |
145 | gdb_regs[GDB_PC] = p->thread.ip; | 145 | gdb_regs[GDB_PC] = 0; |
146 | gdb_regs[GDB_R8] = 0; | 146 | gdb_regs[GDB_R8] = 0; |
147 | gdb_regs[GDB_R9] = 0; | 147 | gdb_regs[GDB_R9] = 0; |
148 | gdb_regs[GDB_R10] = 0; | 148 | gdb_regs[GDB_R10] = 0; |