aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2006-12-06 20:14:07 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:07 -0500
commitd3561b7fa0fb0fc583bab0eeda32bec9e4c4056d (patch)
tree39d835965878622d052ef3b3c7b759d83b6bc327
parentdb91b882aabd0b3b55a87cbfb344f2798bb740b4 (diff)
[PATCH] paravirt: header and stubs for paravirtualisation
Create a paravirt.h header for all the critical operations which need to be replaced with hypervisor calls, and include that instead of defining native operations, when CONFIG_PARAVIRT. This patch does the dumbest possible replacement of paravirtualized instructions: calls through a "paravirt_ops" structure. Currently these are function implementations of native hardware: hypervisors will override the ops structure with their own variants. All the pv-ops functions are declared "fastcall" so that a specific register-based ABI is used, to make inlining assember easier. And: +From: Andy Whitcroft <apw@shadowen.org> The paravirt ops introduce a 'weak' attribute onto memory_setup(). Code ordering leads to the following warnings on x86: arch/i386/kernel/setup.c:651: warning: weak declaration of `memory_setup' after first use results in unspecified behavior Move memory_setup() to avoid this. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Jeremy Fitzhardinge <jeremy@goop.org> Cc: Zachary Amsden <zach@vmware.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Andy Whitcroft <apw@shadowen.org>
-rw-r--r--arch/i386/Kconfig11
-rw-r--r--arch/i386/boot/compressed/misc.c1
-rw-r--r--arch/i386/kernel/Makefile1
-rw-r--r--arch/i386/kernel/asm-offsets.c10
-rw-r--r--arch/i386/kernel/entry.S34
-rw-r--r--arch/i386/kernel/i8259.c5
-rw-r--r--arch/i386/kernel/paravirt.c404
-rw-r--r--arch/i386/kernel/setup.c8
-rw-r--r--arch/i386/kernel/smpboot.c5
-rw-r--r--arch/i386/kernel/time.c15
-rw-r--r--arch/i386/power/cpu.c8
-rw-r--r--drivers/net/de600.c1
-rw-r--r--include/asm-i386/delay.h8
-rw-r--r--include/asm-i386/desc.h9
-rw-r--r--include/asm-i386/io.h8
-rw-r--r--include/asm-i386/irq.h3
-rw-r--r--include/asm-i386/irqflags.h42
-rw-r--r--include/asm-i386/mach-default/setup_arch.h2
-rw-r--r--include/asm-i386/msr.h5
-rw-r--r--include/asm-i386/paravirt.h281
-rw-r--r--include/asm-i386/processor.h15
-rw-r--r--include/asm-i386/segment.h2
-rw-r--r--include/asm-i386/setup.h1
-rw-r--r--include/asm-i386/spinlock.h4
-rw-r--r--include/asm-i386/suspend.h8
-rw-r--r--include/asm-i386/system.h16
-rw-r--r--include/asm-i386/time.h41
27 files changed, 890 insertions, 58 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 1f0f7b60995e..bb1fa061c6cf 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -182,6 +182,17 @@ config X86_ES7000
182 182
183endchoice 183endchoice
184 184
185config PARAVIRT
186 bool "Paravirtualization support (EXPERIMENTAL)"
187 depends on EXPERIMENTAL
188 help
189 Paravirtualization is a way of running multiple instances of
190 Linux on the same machine, under a hypervisor. This option
191 changes the kernel so it can modify itself when it is run
192 under a hypervisor, improving performance significantly.
193 However, when run without a hypervisor the kernel is
194 theoretically slower. If in doubt, say N.
195
185config ACPI_SRAT 196config ACPI_SRAT
186 bool 197 bool
187 default y 198 default y
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index dc1538931555..c6798c75c67d 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -9,6 +9,7 @@
9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 9 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
10 */ 10 */
11 11
12#undef CONFIG_PARAVIRT
12#include <linux/linkage.h> 13#include <linux/linkage.h>
13#include <linux/vmalloc.h> 14#include <linux/vmalloc.h>
14#include <linux/screen_info.h> 15#include <linux/screen_info.h>
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index f614854bd71f..406612136049 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_VM86) += vm86.o
39obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 39obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
40obj-$(CONFIG_HPET_TIMER) += hpet.o 40obj-$(CONFIG_HPET_TIMER) += hpet.o
41obj-$(CONFIG_K8_NB) += k8.o 41obj-$(CONFIG_K8_NB) += k8.o
42obj-$(CONFIG_PARAVIRT) += paravirt.o
42 43
43EXTRA_AFLAGS := -traditional 44EXTRA_AFLAGS := -traditional
44 45
diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c
index 0666eb0ed7bc..1b2f3cd33270 100644
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/i386/kernel/asm-offsets.c
@@ -101,4 +101,14 @@ void foo(void)
101 BLANK(); 101 BLANK();
102 OFFSET(PDA_cpu, i386_pda, cpu_number); 102 OFFSET(PDA_cpu, i386_pda, cpu_number);
103 OFFSET(PDA_pcurrent, i386_pda, pcurrent); 103 OFFSET(PDA_pcurrent, i386_pda, pcurrent);
104
105#ifdef CONFIG_PARAVIRT
106 BLANK();
107 OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled);
108 OFFSET(PARAVIRT_irq_disable, paravirt_ops, irq_disable);
109 OFFSET(PARAVIRT_irq_enable, paravirt_ops, irq_enable);
110 OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
111 OFFSET(PARAVIRT_iret, paravirt_ops, iret);
112 OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
113#endif
104} 114}
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 0220bc8cbb43..d274612e05cd 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -62,13 +62,6 @@ DF_MASK = 0x00000400
62NT_MASK = 0x00004000 62NT_MASK = 0x00004000
63VM_MASK = 0x00020000 63VM_MASK = 0x00020000
64 64
65/* These are replaces for paravirtualization */
66#define DISABLE_INTERRUPTS cli
67#define ENABLE_INTERRUPTS sti
68#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
69#define INTERRUPT_RETURN iret
70#define GET_CR0_INTO_EAX movl %cr0, %eax
71
72#ifdef CONFIG_PREEMPT 65#ifdef CONFIG_PREEMPT
73#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF 66#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF
74#else 67#else
@@ -416,6 +409,20 @@ ldt_ss:
416 jnz restore_nocheck 409 jnz restore_nocheck
417 testl $0x00400000, %eax # returning to 32bit stack? 410 testl $0x00400000, %eax # returning to 32bit stack?
418 jnz restore_nocheck # allright, normal return 411 jnz restore_nocheck # allright, normal return
412
413#ifdef CONFIG_PARAVIRT
414 /*
415 * The kernel can't run on a non-flat stack if paravirt mode
416 * is active. Rather than try to fixup the high bits of
417 * ESP, bypass this code entirely. This may break DOSemu
418 * and/or Wine support in a paravirt VM, although the option
419 * is still available to implement the setting of the high
420 * 16-bits in the INTERRUPT_RETURN paravirt-op.
421 */
422 cmpl $0, paravirt_ops+PARAVIRT_enabled
423 jne restore_nocheck
424#endif
425
419 /* If returning to userspace with 16bit stack, 426 /* If returning to userspace with 16bit stack,
420 * try to fix the higher word of ESP, as the CPU 427 * try to fix the higher word of ESP, as the CPU
421 * won't restore it. 428 * won't restore it.
@@ -833,6 +840,19 @@ nmi_espfix_stack:
833.previous 840.previous
834KPROBE_END(nmi) 841KPROBE_END(nmi)
835 842
843#ifdef CONFIG_PARAVIRT
844ENTRY(native_iret)
8451: iret
846.section __ex_table,"a"
847 .align 4
848 .long 1b,iret_exc
849.previous
850
851ENTRY(native_irq_enable_sysexit)
852 sti
853 sysexit
854#endif
855
836KPROBE_ENTRY(int3) 856KPROBE_ENTRY(int3)
837 RING0_INT_FRAME 857 RING0_INT_FRAME
838 pushl $-1 # mark this as an int 858 pushl $-1 # mark this as an int
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 62996cd17084..c8d45821c788 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -381,7 +381,10 @@ void __init init_ISA_irqs (void)
381 } 381 }
382} 382}
383 383
384void __init init_IRQ(void) 384/* Overridden in paravirt.c */
385void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
386
387void __init native_init_IRQ(void)
385{ 388{
386 int i; 389 int i;
387 390
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c
new file mode 100644
index 000000000000..478192cd4b90
--- /dev/null
+++ b/arch/i386/kernel/paravirt.c
@@ -0,0 +1,404 @@
1/* Paravirtualization interfaces
2 Copyright (C) 2006 Rusty Russell IBM Corporation
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18#include <linux/errno.h>
19#include <linux/module.h>
20#include <linux/efi.h>
21#include <linux/bcd.h>
22
23#include <asm/bug.h>
24#include <asm/paravirt.h>
25#include <asm/desc.h>
26#include <asm/setup.h>
27#include <asm/arch_hooks.h>
28#include <asm/time.h>
29#include <asm/irq.h>
30#include <asm/delay.h>
31
32/* nop stub */
33static void native_nop(void)
34{
35}
36
37static void __init default_banner(void)
38{
39 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
40 paravirt_ops.name);
41}
42
43char *memory_setup(void)
44{
45 return paravirt_ops.memory_setup();
46}
47
48static fastcall unsigned long native_get_debugreg(int regno)
49{
50 unsigned long val = 0; /* Damn you, gcc! */
51
52 switch (regno) {
53 case 0:
54 asm("movl %%db0, %0" :"=r" (val)); break;
55 case 1:
56 asm("movl %%db1, %0" :"=r" (val)); break;
57 case 2:
58 asm("movl %%db2, %0" :"=r" (val)); break;
59 case 3:
60 asm("movl %%db3, %0" :"=r" (val)); break;
61 case 6:
62 asm("movl %%db6, %0" :"=r" (val)); break;
63 case 7:
64 asm("movl %%db7, %0" :"=r" (val)); break;
65 default:
66 BUG();
67 }
68 return val;
69}
70
71static fastcall void native_set_debugreg(int regno, unsigned long value)
72{
73 switch (regno) {
74 case 0:
75 asm("movl %0,%%db0" : /* no output */ :"r" (value));
76 break;
77 case 1:
78 asm("movl %0,%%db1" : /* no output */ :"r" (value));
79 break;
80 case 2:
81 asm("movl %0,%%db2" : /* no output */ :"r" (value));
82 break;
83 case 3:
84 asm("movl %0,%%db3" : /* no output */ :"r" (value));
85 break;
86 case 6:
87 asm("movl %0,%%db6" : /* no output */ :"r" (value));
88 break;
89 case 7:
90 asm("movl %0,%%db7" : /* no output */ :"r" (value));
91 break;
92 default:
93 BUG();
94 }
95}
96
97void init_IRQ(void)
98{
99 paravirt_ops.init_IRQ();
100}
101
102static fastcall void native_clts(void)
103{
104 asm volatile ("clts");
105}
106
107static fastcall unsigned long native_read_cr0(void)
108{
109 unsigned long val;
110 asm volatile("movl %%cr0,%0\n\t" :"=r" (val));
111 return val;
112}
113
114static fastcall void native_write_cr0(unsigned long val)
115{
116 asm volatile("movl %0,%%cr0": :"r" (val));
117}
118
119static fastcall unsigned long native_read_cr2(void)
120{
121 unsigned long val;
122 asm volatile("movl %%cr2,%0\n\t" :"=r" (val));
123 return val;
124}
125
126static fastcall void native_write_cr2(unsigned long val)
127{
128 asm volatile("movl %0,%%cr2": :"r" (val));
129}
130
131static fastcall unsigned long native_read_cr3(void)
132{
133 unsigned long val;
134 asm volatile("movl %%cr3,%0\n\t" :"=r" (val));
135 return val;
136}
137
138static fastcall void native_write_cr3(unsigned long val)
139{
140 asm volatile("movl %0,%%cr3": :"r" (val));
141}
142
143static fastcall unsigned long native_read_cr4(void)
144{
145 unsigned long val;
146 asm volatile("movl %%cr4,%0\n\t" :"=r" (val));
147 return val;
148}
149
150static fastcall unsigned long native_read_cr4_safe(void)
151{
152 unsigned long val;
153 /* This could fault if %cr4 does not exist */
154 asm("1: movl %%cr4, %0 \n"
155 "2: \n"
156 ".section __ex_table,\"a\" \n"
157 ".long 1b,2b \n"
158 ".previous \n"
159 : "=r" (val): "0" (0));
160 return val;
161}
162
163static fastcall void native_write_cr4(unsigned long val)
164{
165 asm volatile("movl %0,%%cr4": :"r" (val));
166}
167
168static fastcall unsigned long native_save_fl(void)
169{
170 unsigned long f;
171 asm volatile("pushfl ; popl %0":"=g" (f): /* no input */);
172 return f;
173}
174
175static fastcall void native_restore_fl(unsigned long f)
176{
177 asm volatile("pushl %0 ; popfl": /* no output */
178 :"g" (f)
179 :"memory", "cc");
180}
181
182static fastcall void native_irq_disable(void)
183{
184 asm volatile("cli": : :"memory");
185}
186
187static fastcall void native_irq_enable(void)
188{
189 asm volatile("sti": : :"memory");
190}
191
192static fastcall void native_safe_halt(void)
193{
194 asm volatile("sti; hlt": : :"memory");
195}
196
197static fastcall void native_halt(void)
198{
199 asm volatile("hlt": : :"memory");
200}
201
202static fastcall void native_wbinvd(void)
203{
204 asm volatile("wbinvd": : :"memory");
205}
206
207static fastcall unsigned long long native_read_msr(unsigned int msr, int *err)
208{
209 unsigned long long val;
210
211 asm volatile("2: rdmsr ; xorl %0,%0\n"
212 "1:\n\t"
213 ".section .fixup,\"ax\"\n\t"
214 "3: movl %3,%0 ; jmp 1b\n\t"
215 ".previous\n\t"
216 ".section __ex_table,\"a\"\n"
217 " .align 4\n\t"
218 " .long 2b,3b\n\t"
219 ".previous"
220 : "=r" (*err), "=A" (val)
221 : "c" (msr), "i" (-EFAULT));
222
223 return val;
224}
225
226static fastcall int native_write_msr(unsigned int msr, unsigned long long val)
227{
228 int err;
229 asm volatile("2: wrmsr ; xorl %0,%0\n"
230 "1:\n\t"
231 ".section .fixup,\"ax\"\n\t"
232 "3: movl %4,%0 ; jmp 1b\n\t"
233 ".previous\n\t"
234 ".section __ex_table,\"a\"\n"
235 " .align 4\n\t"
236 " .long 2b,3b\n\t"
237 ".previous"
238 : "=a" (err)
239 : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)),
240 "i" (-EFAULT));
241 return err;
242}
243
244static fastcall unsigned long long native_read_tsc(void)
245{
246 unsigned long long val;
247 asm volatile("rdtsc" : "=A" (val));
248 return val;
249}
250
251static fastcall unsigned long long native_read_pmc(void)
252{
253 unsigned long long val;
254 asm volatile("rdpmc" : "=A" (val));
255 return val;
256}
257
258static fastcall void native_load_tr_desc(void)
259{
260 asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
261}
262
263static fastcall void native_load_gdt(const struct Xgt_desc_struct *dtr)
264{
265 asm volatile("lgdt %0"::"m" (*dtr));
266}
267
268static fastcall void native_load_idt(const struct Xgt_desc_struct *dtr)
269{
270 asm volatile("lidt %0"::"m" (*dtr));
271}
272
273static fastcall void native_store_gdt(struct Xgt_desc_struct *dtr)
274{
275 asm ("sgdt %0":"=m" (*dtr));
276}
277
278static fastcall void native_store_idt(struct Xgt_desc_struct *dtr)
279{
280 asm ("sidt %0":"=m" (*dtr));
281}
282
283static fastcall unsigned long native_store_tr(void)
284{
285 unsigned long tr;
286 asm ("str %0":"=r" (tr));
287 return tr;
288}
289
290static fastcall void native_load_tls(struct thread_struct *t, unsigned int cpu)
291{
292#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
293 C(0); C(1); C(2);
294#undef C
295}
296
297static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high)
298{
299 u32 *lp = (u32 *)((char *)dt + entry*8);
300 lp[0] = entry_low;
301 lp[1] = entry_high;
302}
303
304static fastcall void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high)
305{
306 native_write_dt_entry(dt, entrynum, low, high);
307}
308
309static fastcall void native_write_gdt_entry(void *dt, int entrynum, u32 low, u32 high)
310{
311 native_write_dt_entry(dt, entrynum, low, high);
312}
313
314static fastcall void native_write_idt_entry(void *dt, int entrynum, u32 low, u32 high)
315{
316 native_write_dt_entry(dt, entrynum, low, high);
317}
318
319static fastcall void native_load_esp0(struct tss_struct *tss,
320 struct thread_struct *thread)
321{
322 tss->esp0 = thread->esp0;
323
324 /* This can only happen when SEP is enabled, no need to test "SEP"arately */
325 if (unlikely(tss->ss1 != thread->sysenter_cs)) {
326 tss->ss1 = thread->sysenter_cs;
327 wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0);
328 }
329}
330
331static fastcall void native_io_delay(void)
332{
333 asm volatile("outb %al,$0x80");
334}
335
336/* These are in entry.S */
337extern fastcall void native_iret(void);
338extern fastcall void native_irq_enable_sysexit(void);
339
340static int __init print_banner(void)
341{
342 paravirt_ops.banner();
343 return 0;
344}
345core_initcall(print_banner);
346
347struct paravirt_ops paravirt_ops = {
348 .name = "bare hardware",
349 .paravirt_enabled = 0,
350 .kernel_rpl = 0,
351
352 .banner = default_banner,
353 .arch_setup = native_nop,
354 .memory_setup = machine_specific_memory_setup,
355 .get_wallclock = native_get_wallclock,
356 .set_wallclock = native_set_wallclock,
357 .time_init = time_init_hook,
358 .init_IRQ = native_init_IRQ,
359
360 .cpuid = native_cpuid,
361 .get_debugreg = native_get_debugreg,
362 .set_debugreg = native_set_debugreg,
363 .clts = native_clts,
364 .read_cr0 = native_read_cr0,
365 .write_cr0 = native_write_cr0,
366 .read_cr2 = native_read_cr2,
367 .write_cr2 = native_write_cr2,
368 .read_cr3 = native_read_cr3,
369 .write_cr3 = native_write_cr3,
370 .read_cr4 = native_read_cr4,
371 .read_cr4_safe = native_read_cr4_safe,
372 .write_cr4 = native_write_cr4,
373 .save_fl = native_save_fl,
374 .restore_fl = native_restore_fl,
375 .irq_disable = native_irq_disable,
376 .irq_enable = native_irq_enable,
377 .safe_halt = native_safe_halt,
378 .halt = native_halt,
379 .wbinvd = native_wbinvd,
380 .read_msr = native_read_msr,
381 .write_msr = native_write_msr,
382 .read_tsc = native_read_tsc,
383 .read_pmc = native_read_pmc,
384 .load_tr_desc = native_load_tr_desc,
385 .set_ldt = native_set_ldt,
386 .load_gdt = native_load_gdt,
387 .load_idt = native_load_idt,
388 .store_gdt = native_store_gdt,
389 .store_idt = native_store_idt,
390 .store_tr = native_store_tr,
391 .load_tls = native_load_tls,
392 .write_ldt_entry = native_write_ldt_entry,
393 .write_gdt_entry = native_write_gdt_entry,
394 .write_idt_entry = native_write_idt_entry,
395 .load_esp0 = native_load_esp0,
396
397 .set_iopl_mask = native_set_iopl_mask,
398 .io_delay = native_io_delay,
399 .const_udelay = __const_udelay,
400
401 .irq_enable_sysexit = native_irq_enable_sysexit,
402 .iret = native_iret,
403};
404EXPORT_SYMBOL(paravirt_ops);
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index e5bb87aa5a45..695d53fd14de 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -495,6 +495,12 @@ static void set_mca_bus(int x)
495static void set_mca_bus(int x) { } 495static void set_mca_bus(int x) { }
496#endif 496#endif
497 497
498/* Overridden in paravirt.c if CONFIG_PARAVIRT */
499char * __attribute__((weak)) memory_setup(void)
500{
501 return machine_specific_memory_setup();
502}
503
498/* 504/*
499 * Determine if we were loaded by an EFI loader. If so, then we have also been 505 * Determine if we were loaded by an EFI loader. If so, then we have also been
500 * passed the efi memmap, systab, etc., so we should use these data structures 506 * passed the efi memmap, systab, etc., so we should use these data structures
@@ -547,7 +553,7 @@ void __init setup_arch(char **cmdline_p)
547 efi_init(); 553 efi_init();
548 else { 554 else {
549 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 555 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
550 print_memory_map(machine_specific_memory_setup()); 556 print_memory_map(memory_setup());
551 } 557 }
552 558
553 copy_edd(); 559 copy_edd();
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 095636620fa2..cd7de9c9654b 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -33,6 +33,11 @@
33 * Dave Jones : Report invalid combinations of Athlon CPUs. 33 * Dave Jones : Report invalid combinations of Athlon CPUs.
34* Rusty Russell : Hacked into shape for new "hotplug" boot process. */ 34* Rusty Russell : Hacked into shape for new "hotplug" boot process. */
35 35
36
37/* SMP boot always wants to use real time delay to allow sufficient time for
38 * the APs to come online */
39#define USE_REAL_TIME_DELAY
40
36#include <linux/module.h> 41#include <linux/module.h>
37#include <linux/init.h> 42#include <linux/init.h>
38#include <linux/kernel.h> 43#include <linux/kernel.h>
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 78af572fd17c..c505b16c0990 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -56,6 +56,7 @@
56#include <asm/uaccess.h> 56#include <asm/uaccess.h>
57#include <asm/processor.h> 57#include <asm/processor.h>
58#include <asm/timer.h> 58#include <asm/timer.h>
59#include <asm/time.h>
59 60
60#include "mach_time.h" 61#include "mach_time.h"
61 62
@@ -116,10 +117,7 @@ static int set_rtc_mmss(unsigned long nowtime)
116 /* gets recalled with irq locally disabled */ 117 /* gets recalled with irq locally disabled */
117 /* XXX - does irqsave resolve this? -johnstul */ 118 /* XXX - does irqsave resolve this? -johnstul */
118 spin_lock_irqsave(&rtc_lock, flags); 119 spin_lock_irqsave(&rtc_lock, flags);
119 if (efi_enabled) 120 retval = set_wallclock(nowtime);
120 retval = efi_set_rtc_mmss(nowtime);
121 else
122 retval = mach_set_rtc_mmss(nowtime);
123 spin_unlock_irqrestore(&rtc_lock, flags); 121 spin_unlock_irqrestore(&rtc_lock, flags);
124 122
125 return retval; 123 return retval;
@@ -223,10 +221,7 @@ unsigned long get_cmos_time(void)
223 221
224 spin_lock_irqsave(&rtc_lock, flags); 222 spin_lock_irqsave(&rtc_lock, flags);
225 223
226 if (efi_enabled) 224 retval = get_wallclock();
227 retval = efi_get_time();
228 else
229 retval = mach_get_cmos_time();
230 225
231 spin_unlock_irqrestore(&rtc_lock, flags); 226 spin_unlock_irqrestore(&rtc_lock, flags);
232 227
@@ -370,7 +365,7 @@ static void __init hpet_time_init(void)
370 printk("Using HPET for base-timer\n"); 365 printk("Using HPET for base-timer\n");
371 } 366 }
372 367
373 time_init_hook(); 368 do_time_init();
374} 369}
375#endif 370#endif
376 371
@@ -392,5 +387,5 @@ void __init time_init(void)
392 387
393 do_settimeofday(&ts); 388 do_settimeofday(&ts);
394 389
395 time_init_hook(); 390 do_time_init();
396} 391}
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
index 5a1abeff033b..2c15500f8713 100644
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -26,8 +26,8 @@ void __save_processor_state(struct saved_context *ctxt)
26 /* 26 /*
27 * descriptor tables 27 * descriptor tables
28 */ 28 */
29 store_gdt(&ctxt->gdt_limit); 29 store_gdt(&ctxt->gdt);
30 store_idt(&ctxt->idt_limit); 30 store_idt(&ctxt->idt);
31 store_tr(ctxt->tr); 31 store_tr(ctxt->tr);
32 32
33 /* 33 /*
@@ -99,8 +99,8 @@ void __restore_processor_state(struct saved_context *ctxt)
99 * now restore the descriptor tables to their proper values 99 * now restore the descriptor tables to their proper values
100 * ltr is done i fix_processor_context(). 100 * ltr is done i fix_processor_context().
101 */ 101 */
102 load_gdt(&ctxt->gdt_limit); 102 load_gdt(&ctxt->gdt);
103 load_idt(&ctxt->idt_limit); 103 load_idt(&ctxt->idt);
104 104
105 /* 105 /*
106 * segment registers 106 * segment registers
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
index 690bb40b353d..8396e411f1ce 100644
--- a/drivers/net/de600.c
+++ b/drivers/net/de600.c
@@ -43,7 +43,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $, Bjorn Ekwall (bj
43 * modify the following "#define": (see <asm/io.h> for more info) 43 * modify the following "#define": (see <asm/io.h> for more info)
44#define REALLY_SLOW_IO 44#define REALLY_SLOW_IO
45 */ 45 */
46#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
47 46
48/* use 0 for production, 1 for verification, >2 for debug */ 47/* use 0 for production, 1 for verification, >2 for debug */
49#ifdef DE600_DEBUG 48#ifdef DE600_DEBUG
diff --git a/include/asm-i386/delay.h b/include/asm-i386/delay.h
index 9ae5e3782ed8..32d6678d0bbf 100644
--- a/include/asm-i386/delay.h
+++ b/include/asm-i386/delay.h
@@ -16,6 +16,13 @@ extern void __ndelay(unsigned long nsecs);
16extern void __const_udelay(unsigned long usecs); 16extern void __const_udelay(unsigned long usecs);
17extern void __delay(unsigned long loops); 17extern void __delay(unsigned long loops);
18 18
19#if defined(CONFIG_PARAVIRT) && !defined(USE_REAL_TIME_DELAY)
20#define udelay(n) paravirt_ops.const_udelay((n) * 0x10c7ul)
21
22#define ndelay(n) paravirt_ops.const_udelay((n) * 5ul)
23
24#else /* !PARAVIRT || USE_REAL_TIME_DELAY */
25
19/* 0x10c7 is 2**32 / 1000000 (rounded up) */ 26/* 0x10c7 is 2**32 / 1000000 (rounded up) */
20#define udelay(n) (__builtin_constant_p(n) ? \ 27#define udelay(n) (__builtin_constant_p(n) ? \
21 ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ 28 ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
@@ -25,6 +32,7 @@ extern void __delay(unsigned long loops);
25#define ndelay(n) (__builtin_constant_p(n) ? \ 32#define ndelay(n) (__builtin_constant_p(n) ? \
26 ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ 33 ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
27 __ndelay(n)) 34 __ndelay(n))
35#endif
28 36
29void use_tsc_delay(void); 37void use_tsc_delay(void);
30 38
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
index 6cf2ac2bfde7..f19820f0834f 100644
--- a/include/asm-i386/desc.h
+++ b/include/asm-i386/desc.h
@@ -55,6 +55,9 @@ static inline void pack_gate(__u32 *a, __u32 *b,
55#define DESCTYPE_DPL3 0x60 /* DPL-3 */ 55#define DESCTYPE_DPL3 0x60 /* DPL-3 */
56#define DESCTYPE_S 0x10 /* !system */ 56#define DESCTYPE_S 0x10 /* !system */
57 57
58#ifdef CONFIG_PARAVIRT
59#include <asm/paravirt.h>
60#else
58#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8)) 61#define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
59 62
60#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr)) 63#define load_gdt(dtr) __asm__ __volatile("lgdt %0"::"m" (*dtr))
@@ -105,7 +108,11 @@ static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const vo
105 write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); 108 write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b);
106} 109}
107 110
108static inline void set_ldt(void *addr, unsigned int entries) 111#define set_ldt native_set_ldt
112#endif /* CONFIG_PARAVIRT */
113
114static inline fastcall void native_set_ldt(const void *addr,
115 unsigned int entries)
109{ 116{
110 if (likely(entries == 0)) 117 if (likely(entries == 0))
111 __asm__ __volatile__("lldt %w0"::"q" (0)); 118 __asm__ __volatile__("lldt %w0"::"q" (0));
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 68df0dc3ab8f..86ff5e83be2f 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -256,11 +256,11 @@ static inline void flush_write_buffers(void)
256 256
257#endif /* __KERNEL__ */ 257#endif /* __KERNEL__ */
258 258
259#ifdef SLOW_IO_BY_JUMPING 259#if defined(CONFIG_PARAVIRT)
260#define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:" 260#include <asm/paravirt.h>
261#else 261#else
262
262#define __SLOW_DOWN_IO "outb %%al,$0x80;" 263#define __SLOW_DOWN_IO "outb %%al,$0x80;"
263#endif
264 264
265static inline void slow_down_io(void) { 265static inline void slow_down_io(void) {
266 __asm__ __volatile__( 266 __asm__ __volatile__(
@@ -271,6 +271,8 @@ static inline void slow_down_io(void) {
271 : : ); 271 : : );
272} 272}
273 273
274#endif
275
274#ifdef CONFIG_X86_NUMAQ 276#ifdef CONFIG_X86_NUMAQ
275extern void *xquad_portio; /* Where the IO area was mapped */ 277extern void *xquad_portio; /* Where the IO area was mapped */
276#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port) 278#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
index 331726b41128..9e15ce0006eb 100644
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -41,4 +41,7 @@ extern int irqbalance_disable(char *str);
41extern void fixup_irqs(cpumask_t map); 41extern void fixup_irqs(cpumask_t map);
42#endif 42#endif
43 43
44void init_IRQ(void);
45void __init native_init_IRQ(void);
46
44#endif /* _ASM_IRQ_H */ 47#endif /* _ASM_IRQ_H */
diff --git a/include/asm-i386/irqflags.h b/include/asm-i386/irqflags.h
index e1bdb97c07fa..9ce01f3fb7bc 100644
--- a/include/asm-i386/irqflags.h
+++ b/include/asm-i386/irqflags.h
@@ -10,6 +10,9 @@
10#ifndef _ASM_IRQFLAGS_H 10#ifndef _ASM_IRQFLAGS_H
11#define _ASM_IRQFLAGS_H 11#define _ASM_IRQFLAGS_H
12 12
13#ifdef CONFIG_PARAVIRT
14#include <asm/paravirt.h>
15#else
13#ifndef __ASSEMBLY__ 16#ifndef __ASSEMBLY__
14 17
15static inline unsigned long __raw_local_save_flags(void) 18static inline unsigned long __raw_local_save_flags(void)
@@ -25,9 +28,6 @@ static inline unsigned long __raw_local_save_flags(void)
25 return flags; 28 return flags;
26} 29}
27 30
28#define raw_local_save_flags(flags) \
29 do { (flags) = __raw_local_save_flags(); } while (0)
30
31static inline void raw_local_irq_restore(unsigned long flags) 31static inline void raw_local_irq_restore(unsigned long flags)
32{ 32{
33 __asm__ __volatile__( 33 __asm__ __volatile__(
@@ -66,18 +66,6 @@ static inline void halt(void)
66 __asm__ __volatile__("hlt": : :"memory"); 66 __asm__ __volatile__("hlt": : :"memory");
67} 67}
68 68
69static inline int raw_irqs_disabled_flags(unsigned long flags)
70{
71 return !(flags & (1 << 9));
72}
73
74static inline int raw_irqs_disabled(void)
75{
76 unsigned long flags = __raw_local_save_flags();
77
78 return raw_irqs_disabled_flags(flags);
79}
80
81/* 69/*
82 * For spinlocks, etc: 70 * For spinlocks, etc:
83 */ 71 */
@@ -90,9 +78,33 @@ static inline unsigned long __raw_local_irq_save(void)
90 return flags; 78 return flags;
91} 79}
92 80
81#else
82#define DISABLE_INTERRUPTS cli
83#define ENABLE_INTERRUPTS sti
84#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
85#define INTERRUPT_RETURN iret
86#define GET_CR0_INTO_EAX movl %cr0, %eax
87#endif /* __ASSEMBLY__ */
88#endif /* CONFIG_PARAVIRT */
89
90#ifndef __ASSEMBLY__
91#define raw_local_save_flags(flags) \
92 do { (flags) = __raw_local_save_flags(); } while (0)
93
93#define raw_local_irq_save(flags) \ 94#define raw_local_irq_save(flags) \
94 do { (flags) = __raw_local_irq_save(); } while (0) 95 do { (flags) = __raw_local_irq_save(); } while (0)
95 96
97static inline int raw_irqs_disabled_flags(unsigned long flags)
98{
99 return !(flags & (1 << 9));
100}
101
102static inline int raw_irqs_disabled(void)
103{
104 unsigned long flags = __raw_local_save_flags();
105
106 return raw_irqs_disabled_flags(flags);
107}
96#endif /* __ASSEMBLY__ */ 108#endif /* __ASSEMBLY__ */
97 109
98/* 110/*
diff --git a/include/asm-i386/mach-default/setup_arch.h b/include/asm-i386/mach-default/setup_arch.h
index fb42099e7bd4..605e3ccb991b 100644
--- a/include/asm-i386/mach-default/setup_arch.h
+++ b/include/asm-i386/mach-default/setup_arch.h
@@ -2,4 +2,6 @@
2 2
3/* no action for generic */ 3/* no action for generic */
4 4
5#ifndef ARCH_SETUP
5#define ARCH_SETUP 6#define ARCH_SETUP
7#endif
diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h
index 1820d9d73af3..5679d4993072 100644
--- a/include/asm-i386/msr.h
+++ b/include/asm-i386/msr.h
@@ -1,6 +1,10 @@
1#ifndef __ASM_MSR_H 1#ifndef __ASM_MSR_H
2#define __ASM_MSR_H 2#define __ASM_MSR_H
3 3
4#ifdef CONFIG_PARAVIRT
5#include <asm/paravirt.h>
6#else
7
4/* 8/*
5 * Access to machine-specific registers (available on 586 and better only) 9 * Access to machine-specific registers (available on 586 and better only)
6 * Note: the rd* operations modify the parameters directly (without using 10 * Note: the rd* operations modify the parameters directly (without using
@@ -77,6 +81,7 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val)
77 __asm__ __volatile__("rdpmc" \ 81 __asm__ __volatile__("rdpmc" \
78 : "=a" (low), "=d" (high) \ 82 : "=a" (low), "=d" (high) \
79 : "c" (counter)) 83 : "c" (counter))
84#endif /* !CONFIG_PARAVIRT */
80 85
81/* symbolic names for some interesting MSRs */ 86/* symbolic names for some interesting MSRs */
82/* Intel defined MSRs. */ 87/* Intel defined MSRs. */
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h
new file mode 100644
index 000000000000..a7551a44686f
--- /dev/null
+++ b/include/asm-i386/paravirt.h
@@ -0,0 +1,281 @@
1#ifndef __ASM_PARAVIRT_H
2#define __ASM_PARAVIRT_H
3/* Various instructions on x86 need to be replaced for
4 * para-virtualization: those hooks are defined here. */
5#include <linux/linkage.h>
6
7#ifdef CONFIG_PARAVIRT
8#ifndef __ASSEMBLY__
9struct thread_struct;
10struct Xgt_desc_struct;
11struct tss_struct;
12struct paravirt_ops
13{
14 unsigned int kernel_rpl;
15 int paravirt_enabled;
16 const char *name;
17
18 void (*arch_setup)(void);
19 char *(*memory_setup)(void);
20 void (*init_IRQ)(void);
21
22 void (*banner)(void);
23
24 unsigned long (*get_wallclock)(void);
25 int (*set_wallclock)(unsigned long);
26 void (*time_init)(void);
27
28 /* All the function pointers here are declared as "fastcall"
29 so that we get a specific register-based calling
30 convention. This makes it easier to implement inline
31 assembler replacements. */
32
33 void (fastcall *cpuid)(unsigned int *eax, unsigned int *ebx,
34 unsigned int *ecx, unsigned int *edx);
35
36 unsigned long (fastcall *get_debugreg)(int regno);
37 void (fastcall *set_debugreg)(int regno, unsigned long value);
38
39 void (fastcall *clts)(void);
40
41 unsigned long (fastcall *read_cr0)(void);
42 void (fastcall *write_cr0)(unsigned long);
43
44 unsigned long (fastcall *read_cr2)(void);
45 void (fastcall *write_cr2)(unsigned long);
46
47 unsigned long (fastcall *read_cr3)(void);
48 void (fastcall *write_cr3)(unsigned long);
49
50 unsigned long (fastcall *read_cr4_safe)(void);
51 unsigned long (fastcall *read_cr4)(void);
52 void (fastcall *write_cr4)(unsigned long);
53
54 unsigned long (fastcall *save_fl)(void);
55 void (fastcall *restore_fl)(unsigned long);
56 void (fastcall *irq_disable)(void);
57 void (fastcall *irq_enable)(void);
58 void (fastcall *safe_halt)(void);
59 void (fastcall *halt)(void);
60 void (fastcall *wbinvd)(void);
61
62 /* err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */
63 u64 (fastcall *read_msr)(unsigned int msr, int *err);
64 int (fastcall *write_msr)(unsigned int msr, u64 val);
65
66 u64 (fastcall *read_tsc)(void);
67 u64 (fastcall *read_pmc)(void);
68
69 void (fastcall *load_tr_desc)(void);
70 void (fastcall *load_gdt)(const struct Xgt_desc_struct *);
71 void (fastcall *load_idt)(const struct Xgt_desc_struct *);
72 void (fastcall *store_gdt)(struct Xgt_desc_struct *);
73 void (fastcall *store_idt)(struct Xgt_desc_struct *);
74 void (fastcall *set_ldt)(const void *desc, unsigned entries);
75 unsigned long (fastcall *store_tr)(void);
76 void (fastcall *load_tls)(struct thread_struct *t, unsigned int cpu);
77 void (fastcall *write_ldt_entry)(void *dt, int entrynum,
78 u32 low, u32 high);
79 void (fastcall *write_gdt_entry)(void *dt, int entrynum,
80 u32 low, u32 high);
81 void (fastcall *write_idt_entry)(void *dt, int entrynum,
82 u32 low, u32 high);
83 void (fastcall *load_esp0)(struct tss_struct *tss,
84 struct thread_struct *thread);
85
86 void (fastcall *set_iopl_mask)(unsigned mask);
87
88 void (fastcall *io_delay)(void);
89 void (*const_udelay)(unsigned long loops);
90
91 /* These two are jmp to, not actually called. */
92 void (fastcall *irq_enable_sysexit)(void);
93 void (fastcall *iret)(void);
94};
95
96extern struct paravirt_ops paravirt_ops;
97
98#define paravirt_enabled() (paravirt_ops.paravirt_enabled)
99
100static inline void load_esp0(struct tss_struct *tss,
101 struct thread_struct *thread)
102{
103 paravirt_ops.load_esp0(tss, thread);
104}
105
106#define ARCH_SETUP paravirt_ops.arch_setup();
107static inline unsigned long get_wallclock(void)
108{
109 return paravirt_ops.get_wallclock();
110}
111
112static inline int set_wallclock(unsigned long nowtime)
113{
114 return paravirt_ops.set_wallclock(nowtime);
115}
116
117static inline void do_time_init(void)
118{
119 return paravirt_ops.time_init();
120}
121
122/* The paravirtualized CPUID instruction. */
123static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
124 unsigned int *ecx, unsigned int *edx)
125{
126 paravirt_ops.cpuid(eax, ebx, ecx, edx);
127}
128
129/*
130 * These special macros can be used to get or set a debugging register
131 */
132#define get_debugreg(var, reg) var = paravirt_ops.get_debugreg(reg)
133#define set_debugreg(val, reg) paravirt_ops.set_debugreg(reg, val)
134
135#define clts() paravirt_ops.clts()
136
137#define read_cr0() paravirt_ops.read_cr0()
138#define write_cr0(x) paravirt_ops.write_cr0(x)
139
140#define read_cr2() paravirt_ops.read_cr2()
141#define write_cr2(x) paravirt_ops.write_cr2(x)
142
143#define read_cr3() paravirt_ops.read_cr3()
144#define write_cr3(x) paravirt_ops.write_cr3(x)
145
146#define read_cr4() paravirt_ops.read_cr4()
147#define read_cr4_safe(x) paravirt_ops.read_cr4_safe()
148#define write_cr4(x) paravirt_ops.write_cr4(x)
149
150static inline unsigned long __raw_local_save_flags(void)
151{
152 return paravirt_ops.save_fl();
153}
154
155static inline void raw_local_irq_restore(unsigned long flags)
156{
157 return paravirt_ops.restore_fl(flags);
158}
159
160static inline void raw_local_irq_disable(void)
161{
162 paravirt_ops.irq_disable();
163}
164
165static inline void raw_local_irq_enable(void)
166{
167 paravirt_ops.irq_enable();
168}
169
170static inline unsigned long __raw_local_irq_save(void)
171{
172 unsigned long flags = paravirt_ops.save_fl();
173
174 paravirt_ops.irq_disable();
175
176 return flags;
177}
178
179static inline void raw_safe_halt(void)
180{
181 paravirt_ops.safe_halt();
182}
183
184static inline void halt(void)
185{
186 paravirt_ops.safe_halt();
187}
188#define wbinvd() paravirt_ops.wbinvd()
189
190#define get_kernel_rpl() (paravirt_ops.kernel_rpl)
191
192#define rdmsr(msr,val1,val2) do { \
193 int _err; \
194 u64 _l = paravirt_ops.read_msr(msr,&_err); \
195 val1 = (u32)_l; \
196 val2 = _l >> 32; \
197} while(0)
198
199#define wrmsr(msr,val1,val2) do { \
200 u64 _l = ((u64)(val2) << 32) | (val1); \
201 paravirt_ops.write_msr((msr), _l); \
202} while(0)
203
204#define rdmsrl(msr,val) do { \
205 int _err; \
206 val = paravirt_ops.read_msr((msr),&_err); \
207} while(0)
208
209#define wrmsrl(msr,val) (paravirt_ops.write_msr((msr),(val)))
210#define wrmsr_safe(msr,a,b) ({ \
211 u64 _l = ((u64)(b) << 32) | (a); \
212 paravirt_ops.write_msr((msr),_l); \
213})
214
215/* rdmsr with exception handling */
216#define rdmsr_safe(msr,a,b) ({ \
217 int _err; \
218 u64 _l = paravirt_ops.read_msr(msr,&_err); \
219 (*a) = (u32)_l; \
220 (*b) = _l >> 32; \
221 _err; })
222
223#define rdtsc(low,high) do { \
224 u64 _l = paravirt_ops.read_tsc(); \
225 low = (u32)_l; \
226 high = _l >> 32; \
227} while(0)
228
229#define rdtscl(low) do { \
230 u64 _l = paravirt_ops.read_tsc(); \
231 low = (int)_l; \
232} while(0)
233
234#define rdtscll(val) (val = paravirt_ops.read_tsc())
235
236#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
237
238#define rdpmc(counter,low,high) do { \
239 u64 _l = paravirt_ops.read_pmc(); \
240 low = (u32)_l; \
241 high = _l >> 32; \
242} while(0)
243
244#define load_TR_desc() (paravirt_ops.load_tr_desc())
245#define load_gdt(dtr) (paravirt_ops.load_gdt(dtr))
246#define load_idt(dtr) (paravirt_ops.load_idt(dtr))
247#define set_ldt(addr, entries) (paravirt_ops.set_ldt((addr), (entries)))
248#define store_gdt(dtr) (paravirt_ops.store_gdt(dtr))
249#define store_idt(dtr) (paravirt_ops.store_idt(dtr))
250#define store_tr(tr) ((tr) = paravirt_ops.store_tr())
251#define load_TLS(t,cpu) (paravirt_ops.load_tls((t),(cpu)))
252#define write_ldt_entry(dt, entry, low, high) \
253 (paravirt_ops.write_ldt_entry((dt), (entry), (low), (high)))
254#define write_gdt_entry(dt, entry, low, high) \
255 (paravirt_ops.write_gdt_entry((dt), (entry), (low), (high)))
256#define write_idt_entry(dt, entry, low, high) \
257 (paravirt_ops.write_idt_entry((dt), (entry), (low), (high)))
258#define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask))
259
260/* The paravirtualized I/O functions */
261static inline void slow_down_io(void) {
262 paravirt_ops.io_delay();
263#ifdef REALLY_SLOW_IO
264 paravirt_ops.io_delay();
265 paravirt_ops.io_delay();
266 paravirt_ops.io_delay();
267#endif
268}
269
270#define CLI_STRING "pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_disable; popl %edx; popl %ecx; popl %eax"
271#define STI_STRING "pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_enable; popl %edx; popl %ecx; popl %eax"
272#else /* __ASSEMBLY__ */
273
274#define INTERRUPT_RETURN jmp *%cs:paravirt_ops+PARAVIRT_iret
275#define DISABLE_INTERRUPTS pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_disable; popl %edx; popl %ecx; popl %eax
276#define ENABLE_INTERRUPTS pushl %eax; pushl %ecx; pushl %edx; call *%cs:paravirt_ops+PARAVIRT_irq_enable; popl %edx; popl %ecx; popl %eax
277#define ENABLE_INTERRUPTS_SYSEXIT jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit
278#define GET_CR0_INTO_EAX call *paravirt_ops+PARAVIRT_read_cr0
279#endif /* __ASSEMBLY__ */
280#endif /* CONFIG_PARAVIRT */
281#endif /* __ASM_PARAVIRT_H */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 98fa73b71760..6c2c4457be0a 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -144,8 +144,8 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {}
144#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ 144#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
145#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ 145#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
146 146
147static inline void __cpuid(unsigned int *eax, unsigned int *ebx, 147static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx,
148 unsigned int *ecx, unsigned int *edx) 148 unsigned int *ecx, unsigned int *edx)
149{ 149{
150 /* ecx is often an input as well as an output. */ 150 /* ecx is often an input as well as an output. */
151 __asm__("cpuid" 151 __asm__("cpuid"
@@ -491,6 +491,12 @@ struct thread_struct {
491 .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ 491 .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \
492} 492}
493 493
494#ifdef CONFIG_PARAVIRT
495#include <asm/paravirt.h>
496#else
497#define paravirt_enabled() 0
498#define __cpuid native_cpuid
499
494static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) 500static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread)
495{ 501{
496 tss->esp0 = thread->esp0; 502 tss->esp0 = thread->esp0;
@@ -524,10 +530,13 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa
524 : /* no output */ \ 530 : /* no output */ \
525 :"r" (value)) 531 :"r" (value))
526 532
533#define set_iopl_mask native_set_iopl_mask
534#endif /* CONFIG_PARAVIRT */
535
527/* 536/*
528 * Set IOPL bits in EFLAGS from given mask 537 * Set IOPL bits in EFLAGS from given mask
529 */ 538 */
530static inline void set_iopl_mask(unsigned mask) 539static fastcall inline void native_set_iopl_mask(unsigned mask)
531{ 540{
532 unsigned int reg; 541 unsigned int reg;
533 __asm__ __volatile__ ("pushfl;" 542 __asm__ __volatile__ ("pushfl;"
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h
index 5bdda79b6b53..3c796af33776 100644
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -131,5 +131,7 @@
131#define SEGMENT_LDT 0x4 131#define SEGMENT_LDT 0x4
132#define SEGMENT_GDT 0x0 132#define SEGMENT_GDT 0x0
133 133
134#ifndef CONFIG_PARAVIRT
134#define get_kernel_rpl() 0 135#define get_kernel_rpl() 0
135#endif 136#endif
137#endif
diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h
index 2734909eff84..9930c5a355fc 100644
--- a/include/asm-i386/setup.h
+++ b/include/asm-i386/setup.h
@@ -70,6 +70,7 @@ extern unsigned char boot_params[PARAM_SIZE];
70struct e820entry; 70struct e820entry;
71 71
72char * __init machine_specific_memory_setup(void); 72char * __init machine_specific_memory_setup(void);
73char *memory_setup(void);
73 74
74int __init copy_e820_map(struct e820entry * biosmap, int nr_map); 75int __init copy_e820_map(struct e820entry * biosmap, int nr_map);
75int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map); 76int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map);
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index c18b71fae6b3..dea60709db29 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -7,8 +7,12 @@
7#include <asm/processor.h> 7#include <asm/processor.h>
8#include <linux/compiler.h> 8#include <linux/compiler.h>
9 9
10#ifdef CONFIG_PARAVIRT
11#include <asm/paravirt.h>
12#else
10#define CLI_STRING "cli" 13#define CLI_STRING "cli"
11#define STI_STRING "sti" 14#define STI_STRING "sti"
15#endif /* CONFIG_PARAVIRT */
12 16
13/* 17/*
14 * Your basic SMP spinlocks, allowing only a single CPU anywhere 18 * Your basic SMP spinlocks, allowing only a single CPU anywhere
diff --git a/include/asm-i386/suspend.h b/include/asm-i386/suspend.h
index 08be1e5009d4..30361526d568 100644
--- a/include/asm-i386/suspend.h
+++ b/include/asm-i386/suspend.h
@@ -23,12 +23,8 @@ arch_prepare_suspend(void)
23struct saved_context { 23struct saved_context {
24 u16 es, fs, gs, ss; 24 u16 es, fs, gs, ss;
25 unsigned long cr0, cr2, cr3, cr4; 25 unsigned long cr0, cr2, cr3, cr4;
26 u16 gdt_pad; 26 struct Xgt_desc_struct gdt;
27 u16 gdt_limit; 27 struct Xgt_desc_struct idt;
28 unsigned long gdt_base;
29 u16 idt_pad;
30 u16 idt_limit;
31 unsigned long idt_base;
32 u16 ldt; 28 u16 ldt;
33 u16 tss; 29 u16 tss;
34 unsigned long tr; 30 unsigned long tr;
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index a6dabbcd6e6a..a6d20d9a1a30 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -88,6 +88,9 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
88#define savesegment(seg, value) \ 88#define savesegment(seg, value) \
89 asm volatile("mov %%" #seg ",%0":"=rm" (value)) 89 asm volatile("mov %%" #seg ",%0":"=rm" (value))
90 90
91#ifdef CONFIG_PARAVIRT
92#include <asm/paravirt.h>
93#else
91#define read_cr0() ({ \ 94#define read_cr0() ({ \
92 unsigned int __dummy; \ 95 unsigned int __dummy; \
93 __asm__ __volatile__( \ 96 __asm__ __volatile__( \
@@ -139,17 +142,18 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t" \
139#define write_cr4(x) \ 142#define write_cr4(x) \
140 __asm__ __volatile__("movl %0,%%cr4": :"r" (x)) 143 __asm__ __volatile__("movl %0,%%cr4": :"r" (x))
141 144
142/* 145#define wbinvd() \
143 * Clear and set 'TS' bit respectively 146 __asm__ __volatile__ ("wbinvd": : :"memory")
144 */ 147
148/* Clear the 'TS' bit */
145#define clts() __asm__ __volatile__ ("clts") 149#define clts() __asm__ __volatile__ ("clts")
150#endif/* CONFIG_PARAVIRT */
151
152/* Set the 'TS' bit */
146#define stts() write_cr0(8 | read_cr0()) 153#define stts() write_cr0(8 | read_cr0())
147 154
148#endif /* __KERNEL__ */ 155#endif /* __KERNEL__ */
149 156
150#define wbinvd() \
151 __asm__ __volatile__ ("wbinvd": : :"memory")
152
153static inline unsigned long get_limit(unsigned long segment) 157static inline unsigned long get_limit(unsigned long segment)
154{ 158{
155 unsigned long __limit; 159 unsigned long __limit;
diff --git a/include/asm-i386/time.h b/include/asm-i386/time.h
new file mode 100644
index 000000000000..ea8065af825a
--- /dev/null
+++ b/include/asm-i386/time.h
@@ -0,0 +1,41 @@
1#ifndef _ASMi386_TIME_H
2#define _ASMi386_TIME_H
3
4#include <linux/efi.h>
5#include "mach_time.h"
6
7static inline unsigned long native_get_wallclock(void)
8{
9 unsigned long retval;
10
11 if (efi_enabled)
12 retval = efi_get_time();
13 else
14 retval = mach_get_cmos_time();
15
16 return retval;
17}
18
19static inline int native_set_wallclock(unsigned long nowtime)
20{
21 int retval;
22
23 if (efi_enabled)
24 retval = efi_set_rtc_mmss(nowtime);
25 else
26 retval = mach_set_rtc_mmss(nowtime);
27
28 return retval;
29}
30
31#ifdef CONFIG_PARAVIRT
32#include <asm/paravirt.h>
33#else /* !CONFIG_PARAVIRT */
34
35#define get_wallclock() native_get_wallclock()
36#define set_wallclock(x) native_set_wallclock(x)
37#define do_time_init() time_init_hook()
38
39#endif /* CONFIG_PARAVIRT */
40
41#endif