diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2006-12-06 20:14:08 -0500 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-06 20:14:08 -0500 |
commit | 13623d79309dd82e1964458fa017979d16f33fa8 (patch) | |
tree | b994f0ba2cd7aec284e4132cf00acc0fecaa887e | |
parent | 6020c8f315709a508b027ef6749e85b125190947 (diff) |
[PATCH] paravirt: Add APIC accessors to paravirt-ops.
Add APIC accessors to paravirt-ops. Unfortunately, we need two write
functions, as some older broken hardware requires workarounds for
Pentium APIC errata - this is the purpose of apic_write_atomic.
AK: replaced __inline with inline
Signed-off-by: Zachary Amsden <zach@vmware.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
-rw-r--r-- | arch/i386/kernel/paravirt.c | 8 | ||||
-rw-r--r-- | include/asm-i386/apic.h | 15 | ||||
-rw-r--r-- | include/asm-i386/paravirt.h | 27 |
3 files changed, 47 insertions, 3 deletions
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 5a9bd3250a1a..fe82eb3adf42 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <asm/time.h> | 29 | #include <asm/time.h> |
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <asm/delay.h> | 31 | #include <asm/delay.h> |
32 | #include <asm/fixmap.h> | ||
33 | #include <asm/apic.h> | ||
32 | 34 | ||
33 | /* nop stub */ | 35 | /* nop stub */ |
34 | static void native_nop(void) | 36 | static void native_nop(void) |
@@ -446,6 +448,12 @@ struct paravirt_ops paravirt_ops = { | |||
446 | .io_delay = native_io_delay, | 448 | .io_delay = native_io_delay, |
447 | .const_udelay = __const_udelay, | 449 | .const_udelay = __const_udelay, |
448 | 450 | ||
451 | #ifdef CONFIG_X86_LOCAL_APIC | ||
452 | .apic_write = native_apic_write, | ||
453 | .apic_write_atomic = native_apic_write_atomic, | ||
454 | .apic_read = native_apic_read, | ||
455 | #endif | ||
456 | |||
449 | .irq_enable_sysexit = native_irq_enable_sysexit, | 457 | .irq_enable_sysexit = native_irq_enable_sysexit, |
450 | .iret = native_iret, | 458 | .iret = native_iret, |
451 | }; | 459 | }; |
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index b9529578fc37..41a44319905f 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h | |||
@@ -37,18 +37,27 @@ extern void generic_apic_probe(void); | |||
37 | /* | 37 | /* |
38 | * Basic functions accessing APICs. | 38 | * Basic functions accessing APICs. |
39 | */ | 39 | */ |
40 | #ifdef CONFIG_PARAVIRT | ||
41 | #include <asm/paravirt.h> | ||
42 | #else | ||
43 | #define apic_write native_apic_write | ||
44 | #define apic_write_atomic native_apic_write_atomic | ||
45 | #define apic_read native_apic_read | ||
46 | #endif | ||
40 | 47 | ||
41 | static __inline void apic_write(unsigned long reg, unsigned long v) | 48 | static __inline fastcall void native_apic_write(unsigned long reg, |
49 | unsigned long v) | ||
42 | { | 50 | { |
43 | *((volatile unsigned long *)(APIC_BASE+reg)) = v; | 51 | *((volatile unsigned long *)(APIC_BASE+reg)) = v; |
44 | } | 52 | } |
45 | 53 | ||
46 | static __inline void apic_write_atomic(unsigned long reg, unsigned long v) | 54 | static __inline fastcall void native_apic_write_atomic(unsigned long reg, |
55 | unsigned long v) | ||
47 | { | 56 | { |
48 | xchg((volatile unsigned long *)(APIC_BASE+reg), v); | 57 | xchg((volatile unsigned long *)(APIC_BASE+reg), v); |
49 | } | 58 | } |
50 | 59 | ||
51 | static __inline unsigned long apic_read(unsigned long reg) | 60 | static __inline fastcall unsigned long native_apic_read(unsigned long reg) |
52 | { | 61 | { |
53 | return *((volatile unsigned long *)(APIC_BASE+reg)); | 62 | return *((volatile unsigned long *)(APIC_BASE+reg)); |
54 | } | 63 | } |
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index dd707d8c8270..e2c803fadb14 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h | |||
@@ -115,6 +115,12 @@ struct paravirt_ops | |||
115 | void (fastcall *io_delay)(void); | 115 | void (fastcall *io_delay)(void); |
116 | void (*const_udelay)(unsigned long loops); | 116 | void (*const_udelay)(unsigned long loops); |
117 | 117 | ||
118 | #ifdef CONFIG_X86_LOCAL_APIC | ||
119 | void (fastcall *apic_write)(unsigned long reg, unsigned long v); | ||
120 | void (fastcall *apic_write_atomic)(unsigned long reg, unsigned long v); | ||
121 | unsigned long (fastcall *apic_read)(unsigned long reg); | ||
122 | #endif | ||
123 | |||
118 | /* These two are jmp to, not actually called. */ | 124 | /* These two are jmp to, not actually called. */ |
119 | void (fastcall *irq_enable_sysexit)(void); | 125 | void (fastcall *irq_enable_sysexit)(void); |
120 | void (fastcall *iret)(void); | 126 | void (fastcall *iret)(void); |
@@ -270,6 +276,27 @@ static inline void slow_down_io(void) { | |||
270 | #endif | 276 | #endif |
271 | } | 277 | } |
272 | 278 | ||
279 | #ifdef CONFIG_X86_LOCAL_APIC | ||
280 | /* | ||
281 | * Basic functions accessing APICs. | ||
282 | */ | ||
283 | static inline void apic_write(unsigned long reg, unsigned long v) | ||
284 | { | ||
285 | paravirt_ops.apic_write(reg,v); | ||
286 | } | ||
287 | |||
288 | static inline void apic_write_atomic(unsigned long reg, unsigned long v) | ||
289 | { | ||
290 | paravirt_ops.apic_write_atomic(reg,v); | ||
291 | } | ||
292 | |||
293 | static inline unsigned long apic_read(unsigned long reg) | ||
294 | { | ||
295 | return paravirt_ops.apic_read(reg); | ||
296 | } | ||
297 | #endif | ||
298 | |||
299 | |||
273 | /* These all sit in the .parainstructions section to tell us what to patch. */ | 300 | /* These all sit in the .parainstructions section to tell us what to patch. */ |
274 | struct paravirt_patch { | 301 | struct paravirt_patch { |
275 | u8 *instr; /* original instructions */ | 302 | u8 *instr; /* original instructions */ |