aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel
diff options
context:
space:
mode:
authorZachary Amsden <zach@vmware.com>2005-09-03 18:56:36 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:11 -0400
commit4bb0d3ec3e5b1e9e2399cdc641b3b6521ac9cdaa (patch)
tree5e8d7646f5c6a2cec990b6d591f230d496b20664 /arch/i386/kernel
parent2a0694d15d55d0deed928786a6393d5e45e37d76 (diff)
[PATCH] i386: inline asm cleanup
i386 Inline asm cleanup. Use cr/dr accessor functions. Also, a potential bugfix. Also, some CR accessors really should be volatile. Reads from CR0 (numeric state may change in an exception handler), writes to CR4 (flipping CR4.TSD) and reads from CR2 (page fault) prevent instruction re-ordering. I did not add memory clobber to CR3 / CR4 / CR0 updates, as it was not there to begin with, and in no case should kernel memory be clobbered, except when doing a TLB flush, which already has memory clobber. I noticed that page invalidation does not have a memory clobber. I can't find a bug as a result, but there is definitely a potential for a bug here: #define __flush_tlb_single(addr) \ __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr)) Signed-off-by: Zachary Amsden <zach@vmware.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel')
-rw-r--r--arch/i386/kernel/cpu/common.c12
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c12
-rw-r--r--arch/i386/kernel/cpu/cyrix.c6
-rw-r--r--arch/i386/kernel/efi.c4
-rw-r--r--arch/i386/kernel/machine_kexec.c8
-rw-r--r--arch/i386/kernel/process.c16
-rw-r--r--arch/i386/kernel/smp.c2
7 files changed, 20 insertions, 40 deletions
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 4553ffd94b1f..361f2e7ccb12 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -642,12 +642,12 @@ void __devinit cpu_init(void)
642 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); 642 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
643 643
644 /* Clear all 6 debug registers: */ 644 /* Clear all 6 debug registers: */
645 645 set_debugreg(0, 0);
646#define CD(register) set_debugreg(0, register) 646 set_debugreg(0, 1);
647 647 set_debugreg(0, 2);
648 CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7); 648 set_debugreg(0, 3);
649 649 set_debugreg(0, 6);
650#undef CD 650 set_debugreg(0, 7);
651 651
652 /* 652 /*
653 * Force FPU initialization: 653 * Force FPU initialization:
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 04e3563da4fe..bf02b5026e62 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -64,8 +64,6 @@ static int dont_scale_voltage;
64#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) 64#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
65 65
66 66
67#define __hlt() __asm__ __volatile__("hlt": : :"memory")
68
69/* Clock ratios multiplied by 10 */ 67/* Clock ratios multiplied by 10 */
70static int clock_ratio[32]; 68static int clock_ratio[32];
71static int eblcr_table[32]; 69static int eblcr_table[32];
@@ -168,11 +166,9 @@ static void do_powersaver(union msr_longhaul *longhaul,
168 outb(0xFE,0x21); /* TMR0 only */ 166 outb(0xFE,0x21); /* TMR0 only */
169 outb(0xFF,0x80); /* delay */ 167 outb(0xFF,0x80); /* delay */
170 168
171 local_irq_enable(); 169 safe_halt();
172
173 __hlt();
174 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); 170 wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
175 __hlt(); 171 halt();
176 172
177 local_irq_disable(); 173 local_irq_disable();
178 174
@@ -251,9 +247,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
251 bcr2.bits.CLOCKMUL = clock_ratio_index; 247 bcr2.bits.CLOCKMUL = clock_ratio_index;
252 local_irq_disable(); 248 local_irq_disable();
253 wrmsrl (MSR_VIA_BCR2, bcr2.val); 249 wrmsrl (MSR_VIA_BCR2, bcr2.val);
254 local_irq_enable(); 250 safe_halt();
255
256 __hlt();
257 251
258 /* Disable software clock multiplier */ 252 /* Disable software clock multiplier */
259 rdmsrl (MSR_VIA_BCR2, bcr2.val); 253 rdmsrl (MSR_VIA_BCR2, bcr2.val);
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index ba4b01138c8f..ff87cc22b323 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -132,11 +132,7 @@ static void __init set_cx86_memwb(void)
132 setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); 132 setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04);
133 /* set 'Not Write-through' */ 133 /* set 'Not Write-through' */
134 cr0 = 0x20000000; 134 cr0 = 0x20000000;
135 __asm__("movl %%cr0,%%eax\n\t" 135 write_cr0(read_cr0() | cr0);
136 "orl %0,%%eax\n\t"
137 "movl %%eax,%%cr0\n"
138 : : "r" (cr0)
139 :"ax");
140 /* CCR2 bit 2: lock NW bit and set WT1 */ 136 /* CCR2 bit 2: lock NW bit and set WT1 */
141 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); 137 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 );
142} 138}
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index 850648ae8305..921fdb15fc9b 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -79,7 +79,7 @@ static void efi_call_phys_prelog(void)
79 * directory. If I have PSE, I just need to duplicate one entry in 79 * directory. If I have PSE, I just need to duplicate one entry in
80 * page directory. 80 * page directory.
81 */ 81 */
82 __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); 82 cr4 = read_cr4();
83 83
84 if (cr4 & X86_CR4_PSE) { 84 if (cr4 & X86_CR4_PSE) {
85 efi_bak_pg_dir_pointer[0].pgd = 85 efi_bak_pg_dir_pointer[0].pgd =
@@ -115,7 +115,7 @@ static void efi_call_phys_epilog(void)
115 cpu_gdt_descr[0].address = 115 cpu_gdt_descr[0].address =
116 (unsigned long) __va(cpu_gdt_descr[0].address); 116 (unsigned long) __va(cpu_gdt_descr[0].address);
117 __asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr)); 117 __asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr));
118 __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); 118 cr4 = read_cr4();
119 119
120 if (cr4 & X86_CR4_PSE) { 120 if (cr4 & X86_CR4_PSE) {
121 swapper_pg_dir[pgd_index(0)].pgd = 121 swapper_pg_dir[pgd_index(0)].pgd =
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
index cb699a2aa1f8..f19f6d34bcbf 100644
--- a/arch/i386/kernel/machine_kexec.c
+++ b/arch/i386/kernel/machine_kexec.c
@@ -17,13 +17,7 @@
17#include <asm/apic.h> 17#include <asm/apic.h>
18#include <asm/cpufeature.h> 18#include <asm/cpufeature.h>
19#include <asm/desc.h> 19#include <asm/desc.h>
20 20#include <asm/system.h>
21static inline unsigned long read_cr3(void)
22{
23 unsigned long cr3;
24 asm volatile("movl %%cr3,%0": "=r"(cr3));
25 return cr3;
26}
27 21
28#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 22#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
29 23
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index e3f362e8af5b..761d4ed47ef3 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -313,16 +313,12 @@ void show_regs(struct pt_regs * regs)
313 printk(" DS: %04x ES: %04x\n", 313 printk(" DS: %04x ES: %04x\n",
314 0xffff & regs->xds,0xffff & regs->xes); 314 0xffff & regs->xds,0xffff & regs->xes);
315 315
316 __asm__("movl %%cr0, %0": "=r" (cr0)); 316 cr0 = read_cr0();
317 __asm__("movl %%cr2, %0": "=r" (cr2)); 317 cr2 = read_cr2();
318 __asm__("movl %%cr3, %0": "=r" (cr3)); 318 cr3 = read_cr3();
319 /* This could fault if %cr4 does not exist */ 319 if (current_cpu_data.x86 > 4) {
320 __asm__("1: movl %%cr4, %0 \n" 320 cr4 = read_cr4();
321 "2: \n" 321 }
322 ".section __ex_table,\"a\" \n"
323 ".long 1b,2b \n"
324 ".previous \n"
325 : "=r" (cr4): "0" (0));
326 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); 322 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
327 show_trace(NULL, &regs->esp); 323 show_trace(NULL, &regs->esp);
328} 324}
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index cec4bde67161..48b55db3680f 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -576,7 +576,7 @@ static void stop_this_cpu (void * dummy)
576 local_irq_disable(); 576 local_irq_disable();
577 disable_local_APIC(); 577 disable_local_APIC();
578 if (cpu_data[smp_processor_id()].hlt_works_ok) 578 if (cpu_data[smp_processor_id()].hlt_works_ok)
579 for(;;) __asm__("hlt"); 579 for(;;) halt();
580 for (;;); 580 for (;;);
581} 581}
582 582