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
This commit is contained in:
commit
aa98936e4f
@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
/*
|
||||
@ -74,6 +75,22 @@ static inline void alternatives_smp_switch(int smp) {}
|
||||
|
||||
const unsigned char *const *find_nop_table(void);
|
||||
|
||||
/* alternative assembly primitive: */
|
||||
#define ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||
\
|
||||
"661:\n\t" oldinstr "\n662:\n" \
|
||||
".section .altinstructions,\"a\"\n" \
|
||||
_ASM_ALIGN "\n" \
|
||||
_ASM_PTR "661b\n" /* label */ \
|
||||
_ASM_PTR "663f\n" /* new instruction */ \
|
||||
" .byte " __stringify(feature) "\n" /* feature bit */ \
|
||||
" .byte 662b-661b\n" /* sourcelen */ \
|
||||
" .byte 664f-663f\n" /* replacementlen */ \
|
||||
".previous\n" \
|
||||
".section .altinstr_replacement, \"ax\"\n" \
|
||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
||||
".previous"
|
||||
|
||||
/*
|
||||
* Alternative instructions for different CPU types or capabilities.
|
||||
*
|
||||
@ -87,18 +104,7 @@ const unsigned char *const *find_nop_table(void);
|
||||
* without volatile and memory clobber.
|
||||
*/
|
||||
#define alternative(oldinstr, newinstr, feature) \
|
||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
||||
".section .altinstructions,\"a\"\n" \
|
||||
_ASM_ALIGN "\n" \
|
||||
_ASM_PTR "661b\n" /* label */ \
|
||||
_ASM_PTR "663f\n" /* new instruction */ \
|
||||
" .byte %c0\n" /* feature bit */ \
|
||||
" .byte 662b-661b\n" /* sourcelen */ \
|
||||
" .byte 664f-663f\n" /* replacementlen */ \
|
||||
".previous\n" \
|
||||
".section .altinstr_replacement,\"ax\"\n" \
|
||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
||||
".previous" :: "i" (feature) : "memory")
|
||||
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) : : : "memory")
|
||||
|
||||
/*
|
||||
* Alternative inline assembly with input.
|
||||
@ -109,35 +115,16 @@ const unsigned char *const *find_nop_table(void);
|
||||
* Best is to use constraints that are fixed size (like (%1) ... "r")
|
||||
* If you use variable sized constraints like "m" or "g" in the
|
||||
* replacement make sure to pad to the worst case length.
|
||||
* Leaving an unused argument 0 to keep API compatibility.
|
||||
*/
|
||||
#define alternative_input(oldinstr, newinstr, feature, input...) \
|
||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
||||
".section .altinstructions,\"a\"\n" \
|
||||
_ASM_ALIGN "\n" \
|
||||
_ASM_PTR "661b\n" /* label */ \
|
||||
_ASM_PTR "663f\n" /* new instruction */ \
|
||||
" .byte %c0\n" /* feature bit */ \
|
||||
" .byte 662b-661b\n" /* sourcelen */ \
|
||||
" .byte 664f-663f\n" /* replacementlen */ \
|
||||
".previous\n" \
|
||||
".section .altinstr_replacement,\"ax\"\n" \
|
||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
||||
".previous" :: "i" (feature), ##input)
|
||||
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||
: : "i" (0), ## input)
|
||||
|
||||
/* Like alternative_input, but with a single output argument */
|
||||
#define alternative_io(oldinstr, newinstr, feature, output, input...) \
|
||||
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
|
||||
".section .altinstructions,\"a\"\n" \
|
||||
_ASM_ALIGN "\n" \
|
||||
_ASM_PTR "661b\n" /* label */ \
|
||||
_ASM_PTR "663f\n" /* new instruction */ \
|
||||
" .byte %c[feat]\n" /* feature bit */ \
|
||||
" .byte 662b-661b\n" /* sourcelen */ \
|
||||
" .byte 664f-663f\n" /* replacementlen */ \
|
||||
".previous\n" \
|
||||
".section .altinstr_replacement,\"ax\"\n" \
|
||||
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
|
||||
".previous" : output : [feat] "i" (feature), ##input)
|
||||
asm volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
|
||||
: output : "i" (0), ## input)
|
||||
|
||||
/*
|
||||
* use this macro(s) if you need more than one output parameter
|
||||
|
@ -428,8 +428,12 @@ struct thread_struct {
|
||||
unsigned short fsindex;
|
||||
unsigned short gsindex;
|
||||
#endif
|
||||
#ifdef CONFIG_X86_32
|
||||
unsigned long ip;
|
||||
#endif
|
||||
#ifdef CONFIG_X86_64
|
||||
unsigned long fs;
|
||||
#endif
|
||||
unsigned long gs;
|
||||
/* Hardware debugging registers: */
|
||||
unsigned long debugreg0;
|
||||
@ -876,7 +880,6 @@ static inline void spin_lock_prefetch(const void *x)
|
||||
.vm86_info = NULL, \
|
||||
.sysenter_cs = __KERNEL_CS, \
|
||||
.io_bitmap_ptr = NULL, \
|
||||
.fs = __KERNEL_PERCPU, \
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -142,7 +142,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
gdb_regs32[GDB_PS] = *(unsigned long *)(p->thread.sp + 8);
|
||||
gdb_regs32[GDB_CS] = __KERNEL_CS;
|
||||
gdb_regs32[GDB_SS] = __KERNEL_DS;
|
||||
gdb_regs[GDB_PC] = p->thread.ip;
|
||||
gdb_regs[GDB_PC] = 0;
|
||||
gdb_regs[GDB_R8] = 0;
|
||||
gdb_regs[GDB_R9] = 0;
|
||||
gdb_regs[GDB_R10] = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user