diff options
| -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 */ |
