aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2005-07-29 15:02:09 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-29 15:17:27 -0400
commit36c4fd23cc06f81d68ee968c4c1bf1cebb3dcea5 (patch)
tree53bbd9c8fef8b84e26e0ae0471eb6c912e7ba553 /arch
parente7b47ccaf655cbaf336745a9b65cf7b22a536fca (diff)
[PATCH] x86_64 machine_kexec: Cleanup inline assembly.
In an uncensored copy of code from i386 to x86_64 I wound up with inline assembly with the wrong constraints. Use input constraints instead of output constraints. So I know the assembler will do the right thing specify the size of the operand lidtq and lgdtq instead of just lidt and lgdt. Make load_segments use an input constraint, and delete the macro fun. Without having to reload %cs like I do on i386 this code is noticeably simpler. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/kernel/machine_kexec.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
index 60d1eff41567..717f7db4b532 100644
--- a/arch/x86_64/kernel/machine_kexec.c
+++ b/arch/x86_64/kernel/machine_kexec.c
@@ -122,45 +122,43 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
122 122
123static void set_idt(void *newidt, u16 limit) 123static void set_idt(void *newidt, u16 limit)
124{ 124{
125 unsigned char curidt[10]; 125 struct desc_ptr curidt;
126 126
127 /* x86-64 supports unaliged loads & stores */ 127 /* x86-64 supports unaliged loads & stores */
128 (*(u16 *)(curidt)) = limit; 128 curidt.size = limit;
129 (*(u64 *)(curidt +2)) = (unsigned long)(newidt); 129 curidt.address = (unsigned long)newidt;
130 130
131 __asm__ __volatile__ ( 131 __asm__ __volatile__ (
132 "lidt %0\n" 132 "lidtq %0\n"
133 : "=m" (curidt) 133 : : "m" (curidt)
134 ); 134 );
135}; 135};
136 136
137 137
138static void set_gdt(void *newgdt, u16 limit) 138static void set_gdt(void *newgdt, u16 limit)
139{ 139{
140 unsigned char curgdt[10]; 140 struct desc_ptr curgdt;
141 141
142 /* x86-64 supports unaligned loads & stores */ 142 /* x86-64 supports unaligned loads & stores */
143 (*(u16 *)(curgdt)) = limit; 143 curgdt.size = limit;
144 (*(u64 *)(curgdt +2)) = (unsigned long)(newgdt); 144 curgdt.address = (unsigned long)newgdt;
145 145
146 __asm__ __volatile__ ( 146 __asm__ __volatile__ (
147 "lgdt %0\n" 147 "lgdtq %0\n"
148 : "=m" (curgdt) 148 : : "m" (curgdt)
149 ); 149 );
150}; 150};
151 151
152static void load_segments(void) 152static void load_segments(void)
153{ 153{
154 __asm__ __volatile__ ( 154 __asm__ __volatile__ (
155 "\tmovl $"STR(__KERNEL_DS)",%eax\n" 155 "\tmovl %0,%%ds\n"
156 "\tmovl %eax,%ds\n" 156 "\tmovl %0,%%es\n"
157 "\tmovl %eax,%es\n" 157 "\tmovl %0,%%ss\n"
158 "\tmovl %eax,%ss\n" 158 "\tmovl %0,%%fs\n"
159 "\tmovl %eax,%fs\n" 159 "\tmovl %0,%%gs\n"
160 "\tmovl %eax,%gs\n" 160 : : "a" (__KERNEL_DS)
161 ); 161 );
162#undef STR
163#undef __STR
164} 162}
165 163
166typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, 164typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,