diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-18 12:17:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-18 12:17:37 -0400 |
commit | 13bba6fda98fe03a955665c9d4bf63c8fd9c19c0 (patch) | |
tree | f0058f8b307eab6da6106cda02b4edd0245977e3 /arch | |
parent | 0130b2d7010fe8e046b7a6c44911a1d3d0d16c96 (diff) | |
parent | b4ecc126991b30fe5f9a59dfacda046aeac124b2 (diff) |
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Fix performance regression caused by paravirt_ops on native kernels
xen: use header for EXPORT_SYMBOL_GPL
x86, 32-bit: fix kernel_trap_sp()
x86: fix percpu_{to,from}_op()
x86: mtrr: Fix high_width computation when phys-addr is >= 44bit
x86: Fix false positive section mismatch warnings in the apic code
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/Kconfig | 13 | ||||
-rw-r--r-- | arch/x86/include/asm/paravirt.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/percpu.h | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/ptrace.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/spinlock.h | 4 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mtrr/generic.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/paravirt.c | 2 | ||||
-rw-r--r-- | arch/x86/oprofile/backtrace.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/Makefile | 5 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 1 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 19 |
13 files changed, 58 insertions, 24 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index df9e885eee14..a6efe0a2e9ae 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -498,6 +498,19 @@ config PARAVIRT | |||
498 | over full virtualization. However, when run without a hypervisor | 498 | over full virtualization. However, when run without a hypervisor |
499 | the kernel is theoretically slower and slightly larger. | 499 | the kernel is theoretically slower and slightly larger. |
500 | 500 | ||
501 | config PARAVIRT_SPINLOCKS | ||
502 | bool "Paravirtualization layer for spinlocks" | ||
503 | depends on PARAVIRT && SMP && EXPERIMENTAL | ||
504 | ---help--- | ||
505 | Paravirtualized spinlocks allow a pvops backend to replace the | ||
506 | spinlock implementation with something virtualization-friendly | ||
507 | (for example, block the virtual CPU rather than spinning). | ||
508 | |||
509 | Unfortunately the downside is an up to 5% performance hit on | ||
510 | native kernels, with various workloads. | ||
511 | |||
512 | If you are unsure how to answer this question, answer N. | ||
513 | |||
501 | config PARAVIRT_CLOCK | 514 | config PARAVIRT_CLOCK |
502 | bool | 515 | bool |
503 | default n | 516 | default n |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 378e3691c08c..a53da004e08e 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -1443,7 +1443,7 @@ u64 _paravirt_ident_64(u64); | |||
1443 | 1443 | ||
1444 | #define paravirt_nop ((void *)_paravirt_nop) | 1444 | #define paravirt_nop ((void *)_paravirt_nop) |
1445 | 1445 | ||
1446 | #ifdef CONFIG_SMP | 1446 | #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS) |
1447 | 1447 | ||
1448 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) | 1448 | static inline int __raw_spin_is_locked(struct raw_spinlock *lock) |
1449 | { | 1449 | { |
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index aee103b26d01..02ecb30982a3 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
@@ -82,22 +82,22 @@ do { \ | |||
82 | case 1: \ | 82 | case 1: \ |
83 | asm(op "b %1,"__percpu_arg(0) \ | 83 | asm(op "b %1,"__percpu_arg(0) \ |
84 | : "+m" (var) \ | 84 | : "+m" (var) \ |
85 | : "ri" ((T__)val)); \ | 85 | : "qi" ((T__)(val))); \ |
86 | break; \ | 86 | break; \ |
87 | case 2: \ | 87 | case 2: \ |
88 | asm(op "w %1,"__percpu_arg(0) \ | 88 | asm(op "w %1,"__percpu_arg(0) \ |
89 | : "+m" (var) \ | 89 | : "+m" (var) \ |
90 | : "ri" ((T__)val)); \ | 90 | : "ri" ((T__)(val))); \ |
91 | break; \ | 91 | break; \ |
92 | case 4: \ | 92 | case 4: \ |
93 | asm(op "l %1,"__percpu_arg(0) \ | 93 | asm(op "l %1,"__percpu_arg(0) \ |
94 | : "+m" (var) \ | 94 | : "+m" (var) \ |
95 | : "ri" ((T__)val)); \ | 95 | : "ri" ((T__)(val))); \ |
96 | break; \ | 96 | break; \ |
97 | case 8: \ | 97 | case 8: \ |
98 | asm(op "q %1,"__percpu_arg(0) \ | 98 | asm(op "q %1,"__percpu_arg(0) \ |
99 | : "+m" (var) \ | 99 | : "+m" (var) \ |
100 | : "re" ((T__)val)); \ | 100 | : "re" ((T__)(val))); \ |
101 | break; \ | 101 | break; \ |
102 | default: __bad_percpu_size(); \ | 102 | default: __bad_percpu_size(); \ |
103 | } \ | 103 | } \ |
@@ -109,7 +109,7 @@ do { \ | |||
109 | switch (sizeof(var)) { \ | 109 | switch (sizeof(var)) { \ |
110 | case 1: \ | 110 | case 1: \ |
111 | asm(op "b "__percpu_arg(1)",%0" \ | 111 | asm(op "b "__percpu_arg(1)",%0" \ |
112 | : "=r" (ret__) \ | 112 | : "=q" (ret__) \ |
113 | : "m" (var)); \ | 113 | : "m" (var)); \ |
114 | break; \ | 114 | break; \ |
115 | case 2: \ | 115 | case 2: \ |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index e304b66abeea..624f133943ed 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -187,14 +187,15 @@ static inline int v8086_mode(struct pt_regs *regs) | |||
187 | 187 | ||
188 | /* | 188 | /* |
189 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | 189 | * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode |
190 | * when it traps. So regs will be the current sp. | 190 | * when it traps. The previous stack will be directly underneath the saved |
191 | * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | ||
191 | * | 192 | * |
192 | * This is valid only for kernel mode traps. | 193 | * This is valid only for kernel mode traps. |
193 | */ | 194 | */ |
194 | static inline unsigned long kernel_trap_sp(struct pt_regs *regs) | 195 | static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) |
195 | { | 196 | { |
196 | #ifdef CONFIG_X86_32 | 197 | #ifdef CONFIG_X86_32 |
197 | return (unsigned long)regs; | 198 | return (unsigned long)(®s->sp); |
198 | #else | 199 | #else |
199 | return regs->sp; | 200 | return regs->sp; |
200 | #endif | 201 | #endif |
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index e5e6caffec87..b7e5db876399 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h | |||
@@ -172,7 +172,7 @@ static inline int __ticket_spin_is_contended(raw_spinlock_t *lock) | |||
172 | return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1; | 172 | return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1; |
173 | } | 173 | } |
174 | 174 | ||
175 | #ifndef CONFIG_PARAVIRT | 175 | #ifndef CONFIG_PARAVIRT_SPINLOCKS |
176 | 176 | ||
177 | static inline int __raw_spin_is_locked(raw_spinlock_t *lock) | 177 | static inline int __raw_spin_is_locked(raw_spinlock_t *lock) |
178 | { | 178 | { |
@@ -206,7 +206,7 @@ static __always_inline void __raw_spin_lock_flags(raw_spinlock_t *lock, | |||
206 | __raw_spin_lock(lock); | 206 | __raw_spin_lock(lock); |
207 | } | 207 | } |
208 | 208 | ||
209 | #endif | 209 | #endif /* CONFIG_PARAVIRT_SPINLOCKS */ |
210 | 210 | ||
211 | static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) | 211 | static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) |
212 | { | 212 | { |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 145cce75cda7..88d1bfc847d3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -89,7 +89,8 @@ obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o | |||
89 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o | 89 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o |
90 | obj-$(CONFIG_KVM_GUEST) += kvm.o | 90 | obj-$(CONFIG_KVM_GUEST) += kvm.o |
91 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o | 91 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o |
92 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o paravirt-spinlocks.o | 92 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o |
93 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o | ||
93 | obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o | 94 | obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o |
94 | 95 | ||
95 | obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o | 96 | obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 1c11b819f245..302947775575 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -254,7 +254,7 @@ static int parse_unisys_oem(char *oemptr) | |||
254 | } | 254 | } |
255 | 255 | ||
256 | #ifdef CONFIG_ACPI | 256 | #ifdef CONFIG_ACPI |
257 | static int find_unisys_acpi_oem_table(unsigned long *oem_addr) | 257 | static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) |
258 | { | 258 | { |
259 | struct acpi_table_header *header = NULL; | 259 | struct acpi_table_header *header = NULL; |
260 | struct es7000_oem_table *table; | 260 | struct es7000_oem_table *table; |
@@ -285,7 +285,7 @@ static int find_unisys_acpi_oem_table(unsigned long *oem_addr) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static void unmap_unisys_acpi_oem_table(unsigned long oem_addr) | 288 | static void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) |
289 | { | 289 | { |
290 | if (!oem_addr) | 290 | if (!oem_addr) |
291 | return; | 291 | return; |
@@ -306,7 +306,7 @@ static int es7000_check_dsdt(void) | |||
306 | static int es7000_acpi_ret; | 306 | static int es7000_acpi_ret; |
307 | 307 | ||
308 | /* Hook from generic ACPI tables.c */ | 308 | /* Hook from generic ACPI tables.c */ |
309 | static int es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | 309 | static int __init es7000_acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
310 | { | 310 | { |
311 | unsigned long oem_addr = 0; | 311 | unsigned long oem_addr = 0; |
312 | int check_dsdt; | 312 | int check_dsdt; |
@@ -717,7 +717,7 @@ struct apic apic_es7000_cluster = { | |||
717 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, | 717 | .safe_wait_icr_idle = native_safe_apic_wait_icr_idle, |
718 | }; | 718 | }; |
719 | 719 | ||
720 | struct apic apic_es7000 = { | 720 | struct apic __refdata apic_es7000 = { |
721 | 721 | ||
722 | .name = "es7000", | 722 | .name = "es7000", |
723 | .probe = probe_es7000, | 723 | .probe = probe_es7000, |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 0b776c09aff3..d21d4fb161f7 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -275,7 +275,11 @@ static void __init print_mtrr_state(void) | |||
275 | } | 275 | } |
276 | printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", | 276 | printk(KERN_DEBUG "MTRR variable ranges %sabled:\n", |
277 | mtrr_state.enabled & 2 ? "en" : "dis"); | 277 | mtrr_state.enabled & 2 ? "en" : "dis"); |
278 | high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; | 278 | if (size_or_mask & 0xffffffffUL) |
279 | high_width = ffs(size_or_mask & 0xffffffffUL) - 1; | ||
280 | else | ||
281 | high_width = ffs(size_or_mask>>32) + 32 - 1; | ||
282 | high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; | ||
279 | for (i = 0; i < num_var_ranges; ++i) { | 283 | for (i = 0; i < num_var_ranges; ++i) { |
280 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) | 284 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) |
281 | printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", | 285 | printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n", |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 8e45f4464880..9faf43bea336 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -134,7 +134,9 @@ static void *get_call_destination(u8 type) | |||
134 | .pv_irq_ops = pv_irq_ops, | 134 | .pv_irq_ops = pv_irq_ops, |
135 | .pv_apic_ops = pv_apic_ops, | 135 | .pv_apic_ops = pv_apic_ops, |
136 | .pv_mmu_ops = pv_mmu_ops, | 136 | .pv_mmu_ops = pv_mmu_ops, |
137 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
137 | .pv_lock_ops = pv_lock_ops, | 138 | .pv_lock_ops = pv_lock_ops, |
139 | #endif | ||
138 | }; | 140 | }; |
139 | return *((void **)&tmpl + type); | 141 | return *((void **)&tmpl + type); |
140 | } | 142 | } |
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 04df67f8a7ba..044897be021f 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c | |||
@@ -76,9 +76,9 @@ void | |||
76 | x86_backtrace(struct pt_regs * const regs, unsigned int depth) | 76 | x86_backtrace(struct pt_regs * const regs, unsigned int depth) |
77 | { | 77 | { |
78 | struct frame_head *head = (struct frame_head *)frame_pointer(regs); | 78 | struct frame_head *head = (struct frame_head *)frame_pointer(regs); |
79 | unsigned long stack = kernel_trap_sp(regs); | ||
80 | 79 | ||
81 | if (!user_mode_vm(regs)) { | 80 | if (!user_mode_vm(regs)) { |
81 | unsigned long stack = kernel_stack_pointer(regs); | ||
82 | if (depth) | 82 | if (depth) |
83 | dump_trace(NULL, regs, (unsigned long *)stack, 0, | 83 | dump_trace(NULL, regs, (unsigned long *)stack, 0, |
84 | &backtrace_ops, &depth); | 84 | &backtrace_ops, &depth); |
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 3b767d03fd6a..172438f86a02 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -9,5 +9,6 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | |||
9 | time.o xen-asm.o xen-asm_$(BITS).o \ | 9 | time.o xen-asm.o xen-asm_$(BITS).o \ |
10 | grant-table.o suspend.o | 10 | grant-table.o suspend.o |
11 | 11 | ||
12 | obj-$(CONFIG_SMP) += smp.o spinlock.o | 12 | obj-$(CONFIG_SMP) += smp.o |
13 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o \ No newline at end of file | 13 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
14 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index e25a78e1113a..fba55b1a4021 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/highmem.h> | 42 | #include <linux/highmem.h> |
43 | #include <linux/debugfs.h> | 43 | #include <linux/debugfs.h> |
44 | #include <linux/bug.h> | 44 | #include <linux/bug.h> |
45 | #include <linux/module.h> | ||
45 | 46 | ||
46 | #include <asm/pgtable.h> | 47 | #include <asm/pgtable.h> |
47 | #include <asm/tlbflush.h> | 48 | #include <asm/tlbflush.h> |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 20139464943c..ca6596b05d53 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -62,15 +62,26 @@ void xen_setup_vcpu_info_placement(void); | |||
62 | #ifdef CONFIG_SMP | 62 | #ifdef CONFIG_SMP |
63 | void xen_smp_init(void); | 63 | void xen_smp_init(void); |
64 | 64 | ||
65 | void __init xen_init_spinlocks(void); | ||
66 | __cpuinit void xen_init_lock_cpu(int cpu); | ||
67 | void xen_uninit_lock_cpu(int cpu); | ||
68 | |||
69 | extern cpumask_var_t xen_cpu_initialized_map; | 65 | extern cpumask_var_t xen_cpu_initialized_map; |
70 | #else | 66 | #else |
71 | static inline void xen_smp_init(void) {} | 67 | static inline void xen_smp_init(void) {} |
72 | #endif | 68 | #endif |
73 | 69 | ||
70 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | ||
71 | void __init xen_init_spinlocks(void); | ||
72 | __cpuinit void xen_init_lock_cpu(int cpu); | ||
73 | void xen_uninit_lock_cpu(int cpu); | ||
74 | #else | ||
75 | static inline void xen_init_spinlocks(void) | ||
76 | { | ||
77 | } | ||
78 | static inline void xen_init_lock_cpu(int cpu) | ||
79 | { | ||
80 | } | ||
81 | static inline void xen_uninit_lock_cpu(int cpu) | ||
82 | { | ||
83 | } | ||
84 | #endif | ||
74 | 85 | ||
75 | /* Declare an asm function, along with symbols needed to make it | 86 | /* Declare an asm function, along with symbols needed to make it |
76 | inlineable */ | 87 | inlineable */ |