diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-01 22:17:41 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-01 22:17:41 -0400 |
commit | c4361bb64b81f5b81a7a08d58654493385a2f2b2 (patch) | |
tree | 8741c0b60ddfbc3fc4e17c8d200f6aa6ff32cca0 /arch/x86 | |
parent | 46368fa05164e1afdc1401294908cf30c6d8d981 (diff) | |
parent | 833bb3046b6cb320e775ea2160ddca87d53260d5 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/x86')
30 files changed, 311 insertions, 249 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 45161b816313..748e50a1a152 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -165,6 +165,9 @@ config AUDIT_ARCH | |||
165 | config ARCH_SUPPORTS_OPTIMIZED_INLINING | 165 | config ARCH_SUPPORTS_OPTIMIZED_INLINING |
166 | def_bool y | 166 | def_bool y |
167 | 167 | ||
168 | config ARCH_SUPPORTS_DEBUG_PAGEALLOC | ||
169 | def_bool y | ||
170 | |||
168 | # Use the generic interrupt handling code in kernel/irq/: | 171 | # Use the generic interrupt handling code in kernel/irq/: |
169 | config GENERIC_HARDIRQS | 172 | config GENERIC_HARDIRQS |
170 | bool | 173 | bool |
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index fdb45df608b6..a345cb5447a8 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -75,6 +75,7 @@ config DEBUG_STACK_USAGE | |||
75 | config DEBUG_PAGEALLOC | 75 | config DEBUG_PAGEALLOC |
76 | bool "Debug page memory allocations" | 76 | bool "Debug page memory allocations" |
77 | depends on DEBUG_KERNEL | 77 | depends on DEBUG_KERNEL |
78 | depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC | ||
78 | ---help--- | 79 | ---help--- |
79 | Unmap pages from the kernel linear mapping after free_pages(). | 80 | Unmap pages from the kernel linear mapping after free_pages(). |
80 | This results in a large slowdown, but helps to find certain types | 81 | This results in a large slowdown, but helps to find certain types |
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index 8c3c25f35578..5054c2ddd1a0 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | 4 | * Copyright 2007 rPath, Inc. - All Rights Reserved |
5 | * Copyright 2009 Intel Corporation; author H. Peter Anvin | ||
5 | * | 6 | * |
6 | * This file is part of the Linux kernel, and is made available under | 7 | * This file is part of the Linux kernel, and is made available under |
7 | * the terms of the GNU General Public License version 2. | 8 | * the terms of the GNU General Public License version 2. |
@@ -16,24 +17,38 @@ | |||
16 | 17 | ||
17 | #define SMAP 0x534d4150 /* ASCII "SMAP" */ | 18 | #define SMAP 0x534d4150 /* ASCII "SMAP" */ |
18 | 19 | ||
20 | struct e820_ext_entry { | ||
21 | struct e820entry std; | ||
22 | u32 ext_flags; | ||
23 | } __attribute__((packed)); | ||
24 | |||
19 | static int detect_memory_e820(void) | 25 | static int detect_memory_e820(void) |
20 | { | 26 | { |
21 | int count = 0; | 27 | int count = 0; |
22 | u32 next = 0; | 28 | u32 next = 0; |
23 | u32 size, id; | 29 | u32 size, id, edi; |
24 | u8 err; | 30 | u8 err; |
25 | struct e820entry *desc = boot_params.e820_map; | 31 | struct e820entry *desc = boot_params.e820_map; |
32 | static struct e820_ext_entry buf; /* static so it is zeroed */ | ||
33 | |||
34 | /* | ||
35 | * Set this here so that if the BIOS doesn't change this field | ||
36 | * but still doesn't change %ecx, we're still okay... | ||
37 | */ | ||
38 | buf.ext_flags = 1; | ||
26 | 39 | ||
27 | do { | 40 | do { |
28 | size = sizeof(struct e820entry); | 41 | size = sizeof buf; |
29 | 42 | ||
30 | /* Important: %edx is clobbered by some BIOSes, | 43 | /* Important: %edx and %esi are clobbered by some BIOSes, |
31 | so it must be either used for the error output | 44 | so they must be either used for the error output |
32 | or explicitly marked clobbered. */ | 45 | or explicitly marked clobbered. Given that, assume there |
33 | asm("int $0x15; setc %0" | 46 | is something out there clobbering %ebp and %edi, too. */ |
47 | asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0" | ||
34 | : "=d" (err), "+b" (next), "=a" (id), "+c" (size), | 48 | : "=d" (err), "+b" (next), "=a" (id), "+c" (size), |
35 | "=m" (*desc) | 49 | "=D" (edi), "+m" (buf) |
36 | : "D" (desc), "d" (SMAP), "a" (0xe820)); | 50 | : "D" (&buf), "d" (SMAP), "a" (0xe820) |
51 | : "esi"); | ||
37 | 52 | ||
38 | /* BIOSes which terminate the chain with CF = 1 as opposed | 53 | /* BIOSes which terminate the chain with CF = 1 as opposed |
39 | to %ebx = 0 don't always report the SMAP signature on | 54 | to %ebx = 0 don't always report the SMAP signature on |
@@ -51,8 +66,14 @@ static int detect_memory_e820(void) | |||
51 | break; | 66 | break; |
52 | } | 67 | } |
53 | 68 | ||
69 | /* ACPI 3.0 added the extended flags support. If bit 0 | ||
70 | in the extended flags is zero, we're supposed to simply | ||
71 | ignore the entry -- a backwards incompatible change! */ | ||
72 | if (size > 20 && !(buf.ext_flags & 1)) | ||
73 | continue; | ||
74 | |||
75 | *desc++ = buf.std; | ||
54 | count++; | 76 | count++; |
55 | desc++; | ||
56 | } while (next && count < ARRAY_SIZE(boot_params.e820_map)); | 77 | } while (next && count < ARRAY_SIZE(boot_params.e820_map)); |
57 | 78 | ||
58 | return boot_params.e820_entries = count; | 79 | return boot_params.e820_entries = count; |
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index 43894428c3c2..0f4ee7148afe 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h | |||
@@ -26,36 +26,20 @@ | |||
26 | 26 | ||
27 | #ifndef __ASSEMBLY__ | 27 | #ifndef __ASSEMBLY__ |
28 | #include <asm/hw_irq.h> | 28 | #include <asm/hw_irq.h> |
29 | #include <asm/kvm_para.h> | ||
29 | 30 | ||
30 | /*G:031 But first, how does our Guest contact the Host to ask for privileged | 31 | /*G:031 But first, how does our Guest contact the Host to ask for privileged |
31 | * operations? There are two ways: the direct way is to make a "hypercall", | 32 | * operations? There are two ways: the direct way is to make a "hypercall", |
32 | * to make requests of the Host Itself. | 33 | * to make requests of the Host Itself. |
33 | * | 34 | * |
34 | * Our hypercall mechanism uses the highest unused trap code (traps 32 and | 35 | * We use the KVM hypercall mechanism. Eighteen hypercalls are |
35 | * above are used by real hardware interrupts). Fifteen hypercalls are | ||
36 | * available: the hypercall number is put in the %eax register, and the | 36 | * available: the hypercall number is put in the %eax register, and the |
37 | * arguments (when required) are placed in %edx, %ebx and %ecx. If a return | 37 | * arguments (when required) are placed in %ebx, %ecx and %edx. If a return |
38 | * value makes sense, it's returned in %eax. | 38 | * value makes sense, it's returned in %eax. |
39 | * | 39 | * |
40 | * Grossly invalid calls result in Sudden Death at the hands of the vengeful | 40 | * Grossly invalid calls result in Sudden Death at the hands of the vengeful |
41 | * Host, rather than returning failure. This reflects Winston Churchill's | 41 | * Host, rather than returning failure. This reflects Winston Churchill's |
42 | * definition of a gentleman: "someone who is only rude intentionally". */ | 42 | * definition of a gentleman: "someone who is only rude intentionally". */ |
43 | static inline unsigned long | ||
44 | hcall(unsigned long call, | ||
45 | unsigned long arg1, unsigned long arg2, unsigned long arg3) | ||
46 | { | ||
47 | /* "int" is the Intel instruction to trigger a trap. */ | ||
48 | asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) | ||
49 | /* The call in %eax (aka "a") might be overwritten */ | ||
50 | : "=a"(call) | ||
51 | /* The arguments are in %eax, %edx, %ebx & %ecx */ | ||
52 | : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3) | ||
53 | /* "memory" means this might write somewhere in memory. | ||
54 | * This isn't true for all calls, but it's safe to tell | ||
55 | * gcc that it might happen so it doesn't get clever. */ | ||
56 | : "memory"); | ||
57 | return call; | ||
58 | } | ||
59 | /*:*/ | 43 | /*:*/ |
60 | 44 | ||
61 | /* Can't use our min() macro here: needs to be a constant */ | 45 | /* Can't use our min() macro here: needs to be a constant */ |
@@ -64,7 +48,7 @@ hcall(unsigned long call, | |||
64 | #define LHCALL_RING_SIZE 64 | 48 | #define LHCALL_RING_SIZE 64 |
65 | struct hcall_args { | 49 | struct hcall_args { |
66 | /* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */ | 50 | /* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */ |
67 | unsigned long arg0, arg2, arg3, arg1; | 51 | unsigned long arg0, arg1, arg2, arg3; |
68 | }; | 52 | }; |
69 | 53 | ||
70 | #endif /* !__ASSEMBLY__ */ | 54 | #endif /* !__ASSEMBLY__ */ |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index a977de23cb4d..a0301bfeb954 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -86,6 +86,9 @@ static inline void early_quirks(void) { } | |||
86 | 86 | ||
87 | extern void pci_iommu_alloc(void); | 87 | extern void pci_iommu_alloc(void); |
88 | 88 | ||
89 | /* MSI arch hook */ | ||
90 | #define arch_setup_msi_irqs arch_setup_msi_irqs | ||
91 | |||
89 | #endif /* __KERNEL__ */ | 92 | #endif /* __KERNEL__ */ |
90 | 93 | ||
91 | #ifdef CONFIG_X86_32 | 94 | #ifdef CONFIG_X86_32 |
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index a5074bd0f8be..48dcfa62ea07 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h | |||
@@ -24,28 +24,4 @@ struct saved_context { | |||
24 | unsigned long return_address; | 24 | unsigned long return_address; |
25 | } __attribute__((packed)); | 25 | } __attribute__((packed)); |
26 | 26 | ||
27 | #ifdef CONFIG_ACPI | ||
28 | extern unsigned long saved_eip; | ||
29 | extern unsigned long saved_esp; | ||
30 | extern unsigned long saved_ebp; | ||
31 | extern unsigned long saved_ebx; | ||
32 | extern unsigned long saved_esi; | ||
33 | extern unsigned long saved_edi; | ||
34 | |||
35 | static inline void acpi_save_register_state(unsigned long return_point) | ||
36 | { | ||
37 | saved_eip = return_point; | ||
38 | asm volatile("movl %%esp,%0" : "=m" (saved_esp)); | ||
39 | asm volatile("movl %%ebp,%0" : "=m" (saved_ebp)); | ||
40 | asm volatile("movl %%ebx,%0" : "=m" (saved_ebx)); | ||
41 | asm volatile("movl %%edi,%0" : "=m" (saved_edi)); | ||
42 | asm volatile("movl %%esi,%0" : "=m" (saved_esi)); | ||
43 | } | ||
44 | |||
45 | #define acpi_restore_register_state() do {} while (0) | ||
46 | |||
47 | /* routines for saving/restoring kernel state */ | ||
48 | extern int acpi_save_state_mem(void); | ||
49 | #endif | ||
50 | |||
51 | #endif /* _ASM_X86_SUSPEND_32_H */ | 27 | #endif /* _ASM_X86_SUSPEND_32_H */ |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 77cfb2cfb386..744299c0b774 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -217,10 +217,6 @@ static inline cpumask_t node_to_cpumask(int node) | |||
217 | { | 217 | { |
218 | return cpu_online_map; | 218 | return cpu_online_map; |
219 | } | 219 | } |
220 | static inline int node_to_first_cpu(int node) | ||
221 | { | ||
222 | return first_cpu(cpu_online_map); | ||
223 | } | ||
224 | 220 | ||
225 | static inline void setup_node_to_cpumask_map(void) { } | 221 | static inline void setup_node_to_cpumask_map(void) { } |
226 | 222 | ||
@@ -237,14 +233,6 @@ static inline void setup_node_to_cpumask_map(void) { } | |||
237 | 233 | ||
238 | #include <asm-generic/topology.h> | 234 | #include <asm-generic/topology.h> |
239 | 235 | ||
240 | #ifdef CONFIG_NUMA | ||
241 | /* Returns the number of the first CPU on Node 'node'. */ | ||
242 | static inline int node_to_first_cpu(int node) | ||
243 | { | ||
244 | return cpumask_first(cpumask_of_node(node)); | ||
245 | } | ||
246 | #endif | ||
247 | |||
248 | extern cpumask_t cpu_coregroup_map(int cpu); | 236 | extern cpumask_t cpu_coregroup_map(int cpu); |
249 | extern const struct cpumask *cpu_coregroup_mask(int cpu); | 237 | extern const struct cpumask *cpu_coregroup_mask(int cpu); |
250 | 238 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index da99ffcdfde6..1bb5c6cee3eb 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -3468,6 +3468,10 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
3468 | struct intel_iommu *iommu = NULL; | 3468 | struct intel_iommu *iommu = NULL; |
3469 | int index = 0; | 3469 | int index = 0; |
3470 | 3470 | ||
3471 | /* x86 doesn't support multiple MSI yet */ | ||
3472 | if (type == PCI_CAP_ID_MSI && nvec > 1) | ||
3473 | return 1; | ||
3474 | |||
3471 | irq_want = nr_irqs_gsi; | 3475 | irq_want = nr_irqs_gsi; |
3472 | sub_handle = 0; | 3476 | sub_handle = 0; |
3473 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 3477 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index fbf2f33e3080..5a6aa1c1162f 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
19 | #include <asm/bootparam.h> | 19 | #include <asm/bootparam.h> |
20 | #include <asm/elf.h> | 20 | #include <asm/elf.h> |
21 | #include <asm/suspend.h> | ||
21 | 22 | ||
22 | #include <xen/interface/xen.h> | 23 | #include <xen/interface/xen.h> |
23 | 24 | ||
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 8793ab33e2c1..e72f062fb4b5 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | #include <asm/ia32.h> | 17 | #include <asm/ia32.h> |
18 | #include <asm/bootparam.h> | 18 | #include <asm/bootparam.h> |
19 | #include <asm/suspend.h> | ||
19 | 20 | ||
20 | #include <xen/interface/xen.h> | 21 | #include <xen/interface/xen.h> |
21 | 22 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index 4c4214690dd1..fb73a52913a4 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c | |||
@@ -377,10 +377,6 @@ static const struct file_operations mtrr_fops = { | |||
377 | .release = mtrr_close, | 377 | .release = mtrr_close, |
378 | }; | 378 | }; |
379 | 379 | ||
380 | |||
381 | static struct proc_dir_entry *proc_root_mtrr; | ||
382 | |||
383 | |||
384 | static int mtrr_seq_show(struct seq_file *seq, void *offset) | 380 | static int mtrr_seq_show(struct seq_file *seq, void *offset) |
385 | { | 381 | { |
386 | char factor; | 382 | char factor; |
@@ -423,11 +419,7 @@ static int __init mtrr_if_init(void) | |||
423 | (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) | 419 | (!cpu_has(c, X86_FEATURE_CENTAUR_MCR))) |
424 | return -ENODEV; | 420 | return -ENODEV; |
425 | 421 | ||
426 | proc_root_mtrr = | 422 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); |
427 | proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops); | ||
428 | |||
429 | if (proc_root_mtrr) | ||
430 | proc_root_mtrr->owner = THIS_MODULE; | ||
431 | return 0; | 423 | return 0; |
432 | } | 424 | } |
433 | 425 | ||
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index bc1326105448..368b0a8836f9 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
@@ -50,7 +50,6 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) | |||
50 | */ | 50 | */ |
51 | static struct irqaction fpu_irq = { | 51 | static struct irqaction fpu_irq = { |
52 | .handler = math_error_irq, | 52 | .handler = math_error_irq, |
53 | .mask = CPU_MASK_NONE, | ||
54 | .name = "fpu", | 53 | .name = "fpu", |
55 | }; | 54 | }; |
56 | 55 | ||
@@ -83,7 +82,6 @@ void __init init_ISA_irqs(void) | |||
83 | */ | 82 | */ |
84 | static struct irqaction irq2 = { | 83 | static struct irqaction irq2 = { |
85 | .handler = no_action, | 84 | .handler = no_action, |
86 | .mask = CPU_MASK_NONE, | ||
87 | .name = "cascade", | 85 | .name = "cascade", |
88 | }; | 86 | }; |
89 | 87 | ||
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index c7a49e0ffbfb..8cd10537fd46 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c | |||
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | static struct irqaction irq2 = { | 46 | static struct irqaction irq2 = { |
47 | .handler = no_action, | 47 | .handler = no_action, |
48 | .mask = CPU_MASK_NONE, | ||
49 | .name = "cascade", | 48 | .name = "cascade", |
50 | }; | 49 | }; |
51 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 50 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c index 8815f3c7fec7..846510b78a09 100644 --- a/arch/x86/kernel/mfgpt_32.c +++ b/arch/x86/kernel/mfgpt_32.c | |||
@@ -348,7 +348,6 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id) | |||
348 | static struct irqaction mfgptirq = { | 348 | static struct irqaction mfgptirq = { |
349 | .handler = mfgpt_tick, | 349 | .handler = mfgpt_tick, |
350 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, | 350 | .flags = IRQF_DISABLED | IRQF_NOBALANCING, |
351 | .mask = CPU_MASK_NONE, | ||
352 | .name = "mfgpt-timer" | 351 | .name = "mfgpt-timer" |
353 | }; | 352 | }; |
354 | 353 | ||
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index c7c4776ff630..90f5b9ef5def 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -300,8 +300,7 @@ fs_initcall(pci_iommu_init); | |||
300 | static __devinit void via_no_dac(struct pci_dev *dev) | 300 | static __devinit void via_no_dac(struct pci_dev *dev) |
301 | { | 301 | { |
302 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | 302 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { |
303 | printk(KERN_INFO | 303 | dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); |
304 | "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | ||
305 | forbid_dac = 1; | 304 | forbid_dac = 1; |
306 | } | 305 | } |
307 | } | 306 | } |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a0d26237d7cf..b4158439bf63 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1049,7 +1049,6 @@ void __init x86_quirk_trap_init(void) | |||
1049 | static struct irqaction irq0 = { | 1049 | static struct irqaction irq0 = { |
1050 | .handler = timer_interrupt, | 1050 | .handler = timer_interrupt, |
1051 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, | 1051 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER, |
1052 | .mask = CPU_MASK_NONE, | ||
1053 | .name = "timer" | 1052 | .name = "timer" |
1054 | }; | 1053 | }; |
1055 | 1054 | ||
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index 241ec3923f61..5ba343e61844 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c | |||
@@ -116,7 +116,6 @@ unsigned long __init calibrate_cpu(void) | |||
116 | static struct irqaction irq0 = { | 116 | static struct irqaction irq0 = { |
117 | .handler = timer_interrupt, | 117 | .handler = timer_interrupt, |
118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, | 118 | .flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER, |
119 | .mask = CPU_MASK_NONE, | ||
120 | .name = "timer" | 119 | .name = "timer" |
121 | }; | 120 | }; |
122 | 121 | ||
@@ -125,7 +124,6 @@ void __init hpet_time_init(void) | |||
125 | if (!hpet_enable()) | 124 | if (!hpet_enable()) |
126 | setup_pit_timer(); | 125 | setup_pit_timer(); |
127 | 126 | ||
128 | irq0.mask = cpumask_of_cpu(0); | ||
129 | setup_irq(0, &irq0); | 127 | setup_irq(0, &irq0); |
130 | } | 128 | } |
131 | 129 | ||
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c index 33a788d5879c..d303369a7bad 100644 --- a/arch/x86/kernel/vmiclock_32.c +++ b/arch/x86/kernel/vmiclock_32.c | |||
@@ -202,7 +202,6 @@ static struct irqaction vmi_clock_action = { | |||
202 | .name = "vmi-timer", | 202 | .name = "vmi-timer", |
203 | .handler = vmi_timer_interrupt, | 203 | .handler = vmi_timer_interrupt, |
204 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, | 204 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, |
205 | .mask = CPU_MASK_ALL, | ||
206 | }; | 205 | }; |
207 | 206 | ||
208 | static void __devinit vmi_time_init_clockevent(void) | 207 | static void __devinit vmi_time_init_clockevent(void) |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 90e44a10e68a..e94a11e42f98 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -107,7 +107,7 @@ static void async_hcall(unsigned long call, unsigned long arg1, | |||
107 | local_irq_save(flags); | 107 | local_irq_save(flags); |
108 | if (lguest_data.hcall_status[next_call] != 0xFF) { | 108 | if (lguest_data.hcall_status[next_call] != 0xFF) { |
109 | /* Table full, so do normal hcall which will flush table. */ | 109 | /* Table full, so do normal hcall which will flush table. */ |
110 | hcall(call, arg1, arg2, arg3); | 110 | kvm_hypercall3(call, arg1, arg2, arg3); |
111 | } else { | 111 | } else { |
112 | lguest_data.hcalls[next_call].arg0 = call; | 112 | lguest_data.hcalls[next_call].arg0 = call; |
113 | lguest_data.hcalls[next_call].arg1 = arg1; | 113 | lguest_data.hcalls[next_call].arg1 = arg1; |
@@ -134,13 +134,32 @@ static void async_hcall(unsigned long call, unsigned long arg1, | |||
134 | * | 134 | * |
135 | * So, when we're in lazy mode, we call async_hcall() to store the call for | 135 | * So, when we're in lazy mode, we call async_hcall() to store the call for |
136 | * future processing: */ | 136 | * future processing: */ |
137 | static void lazy_hcall(unsigned long call, | 137 | static void lazy_hcall1(unsigned long call, |
138 | unsigned long arg1) | ||
139 | { | ||
140 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | ||
141 | kvm_hypercall1(call, arg1); | ||
142 | else | ||
143 | async_hcall(call, arg1, 0, 0); | ||
144 | } | ||
145 | |||
146 | static void lazy_hcall2(unsigned long call, | ||
147 | unsigned long arg1, | ||
148 | unsigned long arg2) | ||
149 | { | ||
150 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | ||
151 | kvm_hypercall2(call, arg1, arg2); | ||
152 | else | ||
153 | async_hcall(call, arg1, arg2, 0); | ||
154 | } | ||
155 | |||
156 | static void lazy_hcall3(unsigned long call, | ||
138 | unsigned long arg1, | 157 | unsigned long arg1, |
139 | unsigned long arg2, | 158 | unsigned long arg2, |
140 | unsigned long arg3) | 159 | unsigned long arg3) |
141 | { | 160 | { |
142 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) | 161 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) |
143 | hcall(call, arg1, arg2, arg3); | 162 | kvm_hypercall3(call, arg1, arg2, arg3); |
144 | else | 163 | else |
145 | async_hcall(call, arg1, arg2, arg3); | 164 | async_hcall(call, arg1, arg2, arg3); |
146 | } | 165 | } |
@@ -150,7 +169,7 @@ static void lazy_hcall(unsigned long call, | |||
150 | static void lguest_leave_lazy_mode(void) | 169 | static void lguest_leave_lazy_mode(void) |
151 | { | 170 | { |
152 | paravirt_leave_lazy(paravirt_get_lazy_mode()); | 171 | paravirt_leave_lazy(paravirt_get_lazy_mode()); |
153 | hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0); | 172 | kvm_hypercall0(LHCALL_FLUSH_ASYNC); |
154 | } | 173 | } |
155 | 174 | ||
156 | /*G:033 | 175 | /*G:033 |
@@ -229,7 +248,7 @@ static void lguest_write_idt_entry(gate_desc *dt, | |||
229 | /* Keep the local copy up to date. */ | 248 | /* Keep the local copy up to date. */ |
230 | native_write_idt_entry(dt, entrynum, g); | 249 | native_write_idt_entry(dt, entrynum, g); |
231 | /* Tell Host about this new entry. */ | 250 | /* Tell Host about this new entry. */ |
232 | hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); | 251 | kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]); |
233 | } | 252 | } |
234 | 253 | ||
235 | /* Changing to a different IDT is very rare: we keep the IDT up-to-date every | 254 | /* Changing to a different IDT is very rare: we keep the IDT up-to-date every |
@@ -241,7 +260,7 @@ static void lguest_load_idt(const struct desc_ptr *desc) | |||
241 | struct desc_struct *idt = (void *)desc->address; | 260 | struct desc_struct *idt = (void *)desc->address; |
242 | 261 | ||
243 | for (i = 0; i < (desc->size+1)/8; i++) | 262 | for (i = 0; i < (desc->size+1)/8; i++) |
244 | hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); | 263 | kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b); |
245 | } | 264 | } |
246 | 265 | ||
247 | /* | 266 | /* |
@@ -261,8 +280,8 @@ static void lguest_load_idt(const struct desc_ptr *desc) | |||
261 | */ | 280 | */ |
262 | static void lguest_load_gdt(const struct desc_ptr *desc) | 281 | static void lguest_load_gdt(const struct desc_ptr *desc) |
263 | { | 282 | { |
264 | BUG_ON((desc->size+1)/8 != GDT_ENTRIES); | 283 | BUG_ON((desc->size + 1) / 8 != GDT_ENTRIES); |
265 | hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0); | 284 | kvm_hypercall2(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES); |
266 | } | 285 | } |
267 | 286 | ||
268 | /* For a single GDT entry which changes, we do the lazy thing: alter our GDT, | 287 | /* For a single GDT entry which changes, we do the lazy thing: alter our GDT, |
@@ -272,7 +291,7 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | |||
272 | const void *desc, int type) | 291 | const void *desc, int type) |
273 | { | 292 | { |
274 | native_write_gdt_entry(dt, entrynum, desc, type); | 293 | native_write_gdt_entry(dt, entrynum, desc, type); |
275 | hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0); | 294 | kvm_hypercall2(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES); |
276 | } | 295 | } |
277 | 296 | ||
278 | /* OK, I lied. There are three "thread local storage" GDT entries which change | 297 | /* OK, I lied. There are three "thread local storage" GDT entries which change |
@@ -284,7 +303,7 @@ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) | |||
284 | * can't handle us removing entries we're currently using. So we clear | 303 | * can't handle us removing entries we're currently using. So we clear |
285 | * the GS register here: if it's needed it'll be reloaded anyway. */ | 304 | * the GS register here: if it's needed it'll be reloaded anyway. */ |
286 | lazy_load_gs(0); | 305 | lazy_load_gs(0); |
287 | lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0); | 306 | lazy_hcall2(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu); |
288 | } | 307 | } |
289 | 308 | ||
290 | /*G:038 That's enough excitement for now, back to ploughing through each of | 309 | /*G:038 That's enough excitement for now, back to ploughing through each of |
@@ -382,7 +401,7 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
382 | static unsigned long current_cr0; | 401 | static unsigned long current_cr0; |
383 | static void lguest_write_cr0(unsigned long val) | 402 | static void lguest_write_cr0(unsigned long val) |
384 | { | 403 | { |
385 | lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0); | 404 | lazy_hcall1(LHCALL_TS, val & X86_CR0_TS); |
386 | current_cr0 = val; | 405 | current_cr0 = val; |
387 | } | 406 | } |
388 | 407 | ||
@@ -396,7 +415,7 @@ static unsigned long lguest_read_cr0(void) | |||
396 | * the vowels have been optimized out. */ | 415 | * the vowels have been optimized out. */ |
397 | static void lguest_clts(void) | 416 | static void lguest_clts(void) |
398 | { | 417 | { |
399 | lazy_hcall(LHCALL_TS, 0, 0, 0); | 418 | lazy_hcall1(LHCALL_TS, 0); |
400 | current_cr0 &= ~X86_CR0_TS; | 419 | current_cr0 &= ~X86_CR0_TS; |
401 | } | 420 | } |
402 | 421 | ||
@@ -418,7 +437,7 @@ static bool cr3_changed = false; | |||
418 | static void lguest_write_cr3(unsigned long cr3) | 437 | static void lguest_write_cr3(unsigned long cr3) |
419 | { | 438 | { |
420 | lguest_data.pgdir = cr3; | 439 | lguest_data.pgdir = cr3; |
421 | lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0); | 440 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); |
422 | cr3_changed = true; | 441 | cr3_changed = true; |
423 | } | 442 | } |
424 | 443 | ||
@@ -490,11 +509,17 @@ static void lguest_write_cr4(unsigned long val) | |||
490 | * into a process' address space. We set the entry then tell the Host the | 509 | * into a process' address space. We set the entry then tell the Host the |
491 | * toplevel and address this corresponds to. The Guest uses one pagetable per | 510 | * toplevel and address this corresponds to. The Guest uses one pagetable per |
492 | * process, so we need to tell the Host which one we're changing (mm->pgd). */ | 511 | * process, so we need to tell the Host which one we're changing (mm->pgd). */ |
512 | static void lguest_pte_update(struct mm_struct *mm, unsigned long addr, | ||
513 | pte_t *ptep) | ||
514 | { | ||
515 | lazy_hcall3(LHCALL_SET_PTE, __pa(mm->pgd), addr, ptep->pte_low); | ||
516 | } | ||
517 | |||
493 | static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr, | 518 | static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr, |
494 | pte_t *ptep, pte_t pteval) | 519 | pte_t *ptep, pte_t pteval) |
495 | { | 520 | { |
496 | *ptep = pteval; | 521 | *ptep = pteval; |
497 | lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, pteval.pte_low); | 522 | lguest_pte_update(mm, addr, ptep); |
498 | } | 523 | } |
499 | 524 | ||
500 | /* The Guest calls this to set a top-level entry. Again, we set the entry then | 525 | /* The Guest calls this to set a top-level entry. Again, we set the entry then |
@@ -503,8 +528,8 @@ static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
503 | static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) | 528 | static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) |
504 | { | 529 | { |
505 | *pmdp = pmdval; | 530 | *pmdp = pmdval; |
506 | lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK, | 531 | lazy_hcall2(LHCALL_SET_PMD, __pa(pmdp) & PAGE_MASK, |
507 | (__pa(pmdp)&(PAGE_SIZE-1))/4, 0); | 532 | (__pa(pmdp) & (PAGE_SIZE - 1)) / 4); |
508 | } | 533 | } |
509 | 534 | ||
510 | /* There are a couple of legacy places where the kernel sets a PTE, but we | 535 | /* There are a couple of legacy places where the kernel sets a PTE, but we |
@@ -520,7 +545,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval) | |||
520 | { | 545 | { |
521 | *ptep = pteval; | 546 | *ptep = pteval; |
522 | if (cr3_changed) | 547 | if (cr3_changed) |
523 | lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); | 548 | lazy_hcall1(LHCALL_FLUSH_TLB, 1); |
524 | } | 549 | } |
525 | 550 | ||
526 | /* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on | 551 | /* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on |
@@ -536,7 +561,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval) | |||
536 | static void lguest_flush_tlb_single(unsigned long addr) | 561 | static void lguest_flush_tlb_single(unsigned long addr) |
537 | { | 562 | { |
538 | /* Simply set it to zero: if it was not, it will fault back in. */ | 563 | /* Simply set it to zero: if it was not, it will fault back in. */ |
539 | lazy_hcall(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); | 564 | lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); |
540 | } | 565 | } |
541 | 566 | ||
542 | /* This is what happens after the Guest has removed a large number of entries. | 567 | /* This is what happens after the Guest has removed a large number of entries. |
@@ -544,7 +569,7 @@ static void lguest_flush_tlb_single(unsigned long addr) | |||
544 | * have changed, ie. virtual addresses below PAGE_OFFSET. */ | 569 | * have changed, ie. virtual addresses below PAGE_OFFSET. */ |
545 | static void lguest_flush_tlb_user(void) | 570 | static void lguest_flush_tlb_user(void) |
546 | { | 571 | { |
547 | lazy_hcall(LHCALL_FLUSH_TLB, 0, 0, 0); | 572 | lazy_hcall1(LHCALL_FLUSH_TLB, 0); |
548 | } | 573 | } |
549 | 574 | ||
550 | /* This is called when the kernel page tables have changed. That's not very | 575 | /* This is called when the kernel page tables have changed. That's not very |
@@ -552,7 +577,7 @@ static void lguest_flush_tlb_user(void) | |||
552 | * slow), so it's worth separating this from the user flushing above. */ | 577 | * slow), so it's worth separating this from the user flushing above. */ |
553 | static void lguest_flush_tlb_kernel(void) | 578 | static void lguest_flush_tlb_kernel(void) |
554 | { | 579 | { |
555 | lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); | 580 | lazy_hcall1(LHCALL_FLUSH_TLB, 1); |
556 | } | 581 | } |
557 | 582 | ||
558 | /* | 583 | /* |
@@ -689,7 +714,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta, | |||
689 | } | 714 | } |
690 | 715 | ||
691 | /* Please wake us this far in the future. */ | 716 | /* Please wake us this far in the future. */ |
692 | hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0); | 717 | kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta); |
693 | return 0; | 718 | return 0; |
694 | } | 719 | } |
695 | 720 | ||
@@ -700,7 +725,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode, | |||
700 | case CLOCK_EVT_MODE_UNUSED: | 725 | case CLOCK_EVT_MODE_UNUSED: |
701 | case CLOCK_EVT_MODE_SHUTDOWN: | 726 | case CLOCK_EVT_MODE_SHUTDOWN: |
702 | /* A 0 argument shuts the clock down. */ | 727 | /* A 0 argument shuts the clock down. */ |
703 | hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0); | 728 | kvm_hypercall0(LHCALL_SET_CLOCKEVENT); |
704 | break; | 729 | break; |
705 | case CLOCK_EVT_MODE_ONESHOT: | 730 | case CLOCK_EVT_MODE_ONESHOT: |
706 | /* This is what we expect. */ | 731 | /* This is what we expect. */ |
@@ -775,8 +800,8 @@ static void lguest_time_init(void) | |||
775 | static void lguest_load_sp0(struct tss_struct *tss, | 800 | static void lguest_load_sp0(struct tss_struct *tss, |
776 | struct thread_struct *thread) | 801 | struct thread_struct *thread) |
777 | { | 802 | { |
778 | lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0, | 803 | lazy_hcall3(LHCALL_SET_STACK, __KERNEL_DS | 0x1, thread->sp0, |
779 | THREAD_SIZE/PAGE_SIZE); | 804 | THREAD_SIZE / PAGE_SIZE); |
780 | } | 805 | } |
781 | 806 | ||
782 | /* Let's just say, I wouldn't do debugging under a Guest. */ | 807 | /* Let's just say, I wouldn't do debugging under a Guest. */ |
@@ -849,7 +874,7 @@ static void set_lguest_basic_apic_ops(void) | |||
849 | /* STOP! Until an interrupt comes in. */ | 874 | /* STOP! Until an interrupt comes in. */ |
850 | static void lguest_safe_halt(void) | 875 | static void lguest_safe_halt(void) |
851 | { | 876 | { |
852 | hcall(LHCALL_HALT, 0, 0, 0); | 877 | kvm_hypercall0(LHCALL_HALT); |
853 | } | 878 | } |
854 | 879 | ||
855 | /* The SHUTDOWN hypercall takes a string to describe what's happening, and | 880 | /* The SHUTDOWN hypercall takes a string to describe what's happening, and |
@@ -859,7 +884,8 @@ static void lguest_safe_halt(void) | |||
859 | * rather than virtual addresses, so we use __pa() here. */ | 884 | * rather than virtual addresses, so we use __pa() here. */ |
860 | static void lguest_power_off(void) | 885 | static void lguest_power_off(void) |
861 | { | 886 | { |
862 | hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0); | 887 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"), |
888 | LGUEST_SHUTDOWN_POWEROFF); | ||
863 | } | 889 | } |
864 | 890 | ||
865 | /* | 891 | /* |
@@ -869,7 +895,7 @@ static void lguest_power_off(void) | |||
869 | */ | 895 | */ |
870 | static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) | 896 | static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p) |
871 | { | 897 | { |
872 | hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0); | 898 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF); |
873 | /* The hcall won't return, but to keep gcc happy, we're "done". */ | 899 | /* The hcall won't return, but to keep gcc happy, we're "done". */ |
874 | return NOTIFY_DONE; | 900 | return NOTIFY_DONE; |
875 | } | 901 | } |
@@ -910,7 +936,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) | |||
910 | len = sizeof(scratch) - 1; | 936 | len = sizeof(scratch) - 1; |
911 | scratch[len] = '\0'; | 937 | scratch[len] = '\0'; |
912 | memcpy(scratch, buf, len); | 938 | memcpy(scratch, buf, len); |
913 | hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0); | 939 | kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch)); |
914 | 940 | ||
915 | /* This routine returns the number of bytes actually written. */ | 941 | /* This routine returns the number of bytes actually written. */ |
916 | return len; | 942 | return len; |
@@ -920,7 +946,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count) | |||
920 | * Launcher to reboot us. */ | 946 | * Launcher to reboot us. */ |
921 | static void lguest_restart(char *reason) | 947 | static void lguest_restart(char *reason) |
922 | { | 948 | { |
923 | hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0); | 949 | kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART); |
924 | } | 950 | } |
925 | 951 | ||
926 | /*G:050 | 952 | /*G:050 |
@@ -1040,6 +1066,8 @@ __init void lguest_init(void) | |||
1040 | pv_mmu_ops.read_cr3 = lguest_read_cr3; | 1066 | pv_mmu_ops.read_cr3 = lguest_read_cr3; |
1041 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; | 1067 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; |
1042 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode; | 1068 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode; |
1069 | pv_mmu_ops.pte_update = lguest_pte_update; | ||
1070 | pv_mmu_ops.pte_update_defer = lguest_pte_update; | ||
1043 | 1071 | ||
1044 | #ifdef CONFIG_X86_LOCAL_APIC | 1072 | #ifdef CONFIG_X86_LOCAL_APIC |
1045 | /* apic read/write intercepts */ | 1073 | /* apic read/write intercepts */ |
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 10b9bd35a8ff..f79541989471 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
@@ -27,8 +27,8 @@ ENTRY(lguest_entry) | |||
27 | /* We make the "initialization" hypercall now to tell the Host about | 27 | /* We make the "initialization" hypercall now to tell the Host about |
28 | * us, and also find out where it put our page tables. */ | 28 | * us, and also find out where it put our page tables. */ |
29 | movl $LHCALL_LGUEST_INIT, %eax | 29 | movl $LHCALL_LGUEST_INIT, %eax |
30 | movl $lguest_data - __PAGE_OFFSET, %edx | 30 | movl $lguest_data - __PAGE_OFFSET, %ebx |
31 | int $LGUEST_TRAP_ENTRY | 31 | .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */ |
32 | 32 | ||
33 | /* Set up the initial stack so we can run C code. */ | 33 | /* Set up the initial stack so we can run C code. */ |
34 | movl $(init_thread_union+THREAD_SIZE),%esp | 34 | movl $(init_thread_union+THREAD_SIZE),%esp |
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 522db5e3d0bf..5bc5d1688c1c 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -19,49 +19,6 @@ void kunmap(struct page *page) | |||
19 | kunmap_high(page); | 19 | kunmap_high(page); |
20 | } | 20 | } |
21 | 21 | ||
22 | static void debug_kmap_atomic_prot(enum km_type type) | ||
23 | { | ||
24 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
25 | static unsigned warn_count = 10; | ||
26 | |||
27 | if (unlikely(warn_count == 0)) | ||
28 | return; | ||
29 | |||
30 | if (unlikely(in_interrupt())) { | ||
31 | if (in_irq()) { | ||
32 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
33 | type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && | ||
34 | type != KM_BOUNCE_READ) { | ||
35 | WARN_ON(1); | ||
36 | warn_count--; | ||
37 | } | ||
38 | } else if (!irqs_disabled()) { /* softirq */ | ||
39 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
40 | type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && | ||
41 | type != KM_SKB_SUNRPC_DATA && | ||
42 | type != KM_SKB_DATA_SOFTIRQ && | ||
43 | type != KM_BOUNCE_READ) { | ||
44 | WARN_ON(1); | ||
45 | warn_count--; | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | |||
50 | if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || | ||
51 | type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) { | ||
52 | if (!irqs_disabled()) { | ||
53 | WARN_ON(1); | ||
54 | warn_count--; | ||
55 | } | ||
56 | } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { | ||
57 | if (irq_count() == 0 && !irqs_disabled()) { | ||
58 | WARN_ON(1); | ||
59 | warn_count--; | ||
60 | } | ||
61 | } | ||
62 | #endif | ||
63 | } | ||
64 | |||
65 | /* | 22 | /* |
66 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because | 23 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because |
67 | * no global lock is needed and because the kmap code must perform a global TLB | 24 | * no global lock is needed and because the kmap code must perform a global TLB |
@@ -81,8 +38,9 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
81 | if (!PageHighMem(page)) | 38 | if (!PageHighMem(page)) |
82 | return page_address(page); | 39 | return page_address(page); |
83 | 40 | ||
84 | debug_kmap_atomic_prot(type); | 41 | debug_kmap_atomic(type); |
85 | 42 | ||
43 | debug_kmap_atomic(type); | ||
86 | idx = type + KM_TYPE_NR*smp_processor_id(); | 44 | idx = type + KM_TYPE_NR*smp_processor_id(); |
87 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 45 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
88 | BUG_ON(!pte_none(*(kmap_pte-idx))); | 46 | BUG_ON(!pte_none(*(kmap_pte-idx))); |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 699c9b2895ae..bff0c9032f8c 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/iomap.h> | 19 | #include <asm/iomap.h> |
20 | #include <asm/pat.h> | 20 | #include <asm/pat.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/highmem.h> | ||
22 | 23 | ||
23 | int is_io_mapping_possible(resource_size_t base, unsigned long size) | 24 | int is_io_mapping_possible(resource_size_t base, unsigned long size) |
24 | { | 25 | { |
@@ -71,6 +72,7 @@ iounmap_atomic(void *kvaddr, enum km_type type) | |||
71 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 72 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; |
72 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | 73 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); |
73 | 74 | ||
75 | debug_kmap_atomic(type); | ||
74 | /* | 76 | /* |
75 | * Force other mappings to Oops if they'll try to access this pte | 77 | * Force other mappings to Oops if they'll try to access this pte |
76 | * without first remap it. Keeping stale mappings around is a bad idea | 78 | * without first remap it. Keeping stale mappings around is a bad idea |
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index f6adf2c6d751..aaf26ae58cd5 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c | |||
@@ -69,11 +69,12 @@ void early_dump_pci_device(u8 bus, u8 slot, u8 func) | |||
69 | int j; | 69 | int j; |
70 | u32 val; | 70 | u32 val; |
71 | 71 | ||
72 | printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func); | 72 | printk(KERN_INFO "pci 0000:%02x:%02x.%d config space:", |
73 | bus, slot, func); | ||
73 | 74 | ||
74 | for (i = 0; i < 256; i += 4) { | 75 | for (i = 0; i < 256; i += 4) { |
75 | if (!(i & 0x0f)) | 76 | if (!(i & 0x0f)) |
76 | printk("\n%04x:",i); | 77 | printk("\n %02x:",i); |
77 | 78 | ||
78 | val = read_pci_config(bus, slot, func, i); | 79 | val = read_pci_config(bus, slot, func, i); |
79 | for (j = 0; j < 4; j++) { | 80 | for (j = 0; j < 4; j++) { |
@@ -96,20 +97,22 @@ void early_dump_pci_devices(void) | |||
96 | for (func = 0; func < 8; func++) { | 97 | for (func = 0; func < 8; func++) { |
97 | u32 class; | 98 | u32 class; |
98 | u8 type; | 99 | u8 type; |
100 | |||
99 | class = read_pci_config(bus, slot, func, | 101 | class = read_pci_config(bus, slot, func, |
100 | PCI_CLASS_REVISION); | 102 | PCI_CLASS_REVISION); |
101 | if (class == 0xffffffff) | 103 | if (class == 0xffffffff) |
102 | break; | 104 | continue; |
103 | 105 | ||
104 | early_dump_pci_device(bus, slot, func); | 106 | early_dump_pci_device(bus, slot, func); |
105 | 107 | ||
106 | /* No multi-function device? */ | 108 | if (func == 0) { |
107 | type = read_pci_config_byte(bus, slot, func, | 109 | type = read_pci_config_byte(bus, slot, |
110 | func, | ||
108 | PCI_HEADER_TYPE); | 111 | PCI_HEADER_TYPE); |
109 | if (!(type & 0x80)) | 112 | if (!(type & 0x80)) |
110 | break; | 113 | break; |
114 | } | ||
111 | } | 115 | } |
112 | } | 116 | } |
113 | } | 117 | } |
114 | } | 118 | } |
115 | |||
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 9c49919e4d1c..6dd89555fbfa 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -495,26 +495,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, | |||
495 | pci_siemens_interrupt_controller); | 495 | pci_siemens_interrupt_controller); |
496 | 496 | ||
497 | /* | 497 | /* |
498 | * Regular PCI devices have 256 bytes, but AMD Family 10h/11h CPUs have | ||
499 | * 4096 bytes configuration space for each function of their processor | ||
500 | * configuration space. | ||
501 | */ | ||
502 | static void amd_cpu_pci_cfg_space_size(struct pci_dev *dev) | ||
503 | { | ||
504 | dev->cfg_size = pci_cfg_space_size_ext(dev); | ||
505 | } | ||
506 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, amd_cpu_pci_cfg_space_size); | ||
507 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, amd_cpu_pci_cfg_space_size); | ||
508 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, amd_cpu_pci_cfg_space_size); | ||
509 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, amd_cpu_pci_cfg_space_size); | ||
510 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, amd_cpu_pci_cfg_space_size); | ||
511 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1300, amd_cpu_pci_cfg_space_size); | ||
512 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1301, amd_cpu_pci_cfg_space_size); | ||
513 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1302, amd_cpu_pci_cfg_space_size); | ||
514 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1303, amd_cpu_pci_cfg_space_size); | ||
515 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1304, amd_cpu_pci_cfg_space_size); | ||
516 | |||
517 | /* | ||
518 | * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from | 498 | * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from |
519 | * confusing the PCI engine: | 499 | * confusing the PCI engine: |
520 | */ | 500 | */ |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index f1065b129e9c..4061bb0f267d 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -50,8 +50,6 @@ static int __init pci_legacy_init(void) | |||
50 | if (pci_root_bus) | 50 | if (pci_root_bus) |
51 | pci_bus_add_devices(pci_root_bus); | 51 | pci_bus_add_devices(pci_root_bus); |
52 | 52 | ||
53 | pcibios_fixup_peer_bridges(); | ||
54 | |||
55 | return 0; | 53 | return 0; |
56 | } | 54 | } |
57 | 55 | ||
@@ -67,6 +65,7 @@ int __init pci_subsys_init(void) | |||
67 | pci_visws_init(); | 65 | pci_visws_init(); |
68 | #endif | 66 | #endif |
69 | pci_legacy_init(); | 67 | pci_legacy_init(); |
68 | pcibios_fixup_peer_bridges(); | ||
70 | pcibios_irq_init(); | 69 | pcibios_irq_init(); |
71 | pcibios_init(); | 70 | pcibios_init(); |
72 | 71 | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 89bf9242c80a..905bb526b133 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
16 | #include <linux/bitmap.h> | 16 | #include <linux/bitmap.h> |
17 | #include <linux/sort.h> | ||
17 | #include <asm/e820.h> | 18 | #include <asm/e820.h> |
18 | #include <asm/pci_x86.h> | 19 | #include <asm/pci_x86.h> |
19 | 20 | ||
@@ -24,24 +25,49 @@ | |||
24 | /* Indicate if the mmcfg resources have been placed into the resource table. */ | 25 | /* Indicate if the mmcfg resources have been placed into the resource table. */ |
25 | static int __initdata pci_mmcfg_resources_inserted; | 26 | static int __initdata pci_mmcfg_resources_inserted; |
26 | 27 | ||
28 | static __init int extend_mmcfg(int num) | ||
29 | { | ||
30 | struct acpi_mcfg_allocation *new; | ||
31 | int new_num = pci_mmcfg_config_num + num; | ||
32 | |||
33 | new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); | ||
34 | if (!new) | ||
35 | return -1; | ||
36 | |||
37 | if (pci_mmcfg_config) { | ||
38 | memcpy(new, pci_mmcfg_config, | ||
39 | sizeof(pci_mmcfg_config[0]) * new_num); | ||
40 | kfree(pci_mmcfg_config); | ||
41 | } | ||
42 | pci_mmcfg_config = new; | ||
43 | |||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end) | ||
48 | { | ||
49 | int i = pci_mmcfg_config_num; | ||
50 | |||
51 | pci_mmcfg_config_num++; | ||
52 | pci_mmcfg_config[i].address = addr; | ||
53 | pci_mmcfg_config[i].pci_segment = segment; | ||
54 | pci_mmcfg_config[i].start_bus_number = start; | ||
55 | pci_mmcfg_config[i].end_bus_number = end; | ||
56 | } | ||
57 | |||
27 | static const char __init *pci_mmcfg_e7520(void) | 58 | static const char __init *pci_mmcfg_e7520(void) |
28 | { | 59 | { |
29 | u32 win; | 60 | u32 win; |
30 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win); | 61 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win); |
31 | 62 | ||
32 | win = win & 0xf000; | 63 | win = win & 0xf000; |
33 | if(win == 0x0000 || win == 0xf000) | 64 | if (win == 0x0000 || win == 0xf000) |
34 | pci_mmcfg_config_num = 0; | 65 | return NULL; |
35 | else { | 66 | |
36 | pci_mmcfg_config_num = 1; | 67 | if (extend_mmcfg(1) == -1) |
37 | pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); | 68 | return NULL; |
38 | if (!pci_mmcfg_config) | 69 | |
39 | return NULL; | 70 | fill_one_mmcfg(win << 16, 0, 0, 255); |
40 | pci_mmcfg_config[0].address = win << 16; | ||
41 | pci_mmcfg_config[0].pci_segment = 0; | ||
42 | pci_mmcfg_config[0].start_bus_number = 0; | ||
43 | pci_mmcfg_config[0].end_bus_number = 255; | ||
44 | } | ||
45 | 71 | ||
46 | return "Intel Corporation E7520 Memory Controller Hub"; | 72 | return "Intel Corporation E7520 Memory Controller Hub"; |
47 | } | 73 | } |
@@ -50,13 +76,11 @@ static const char __init *pci_mmcfg_intel_945(void) | |||
50 | { | 76 | { |
51 | u32 pciexbar, mask = 0, len = 0; | 77 | u32 pciexbar, mask = 0, len = 0; |
52 | 78 | ||
53 | pci_mmcfg_config_num = 1; | ||
54 | |||
55 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar); | 79 | raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar); |
56 | 80 | ||
57 | /* Enable bit */ | 81 | /* Enable bit */ |
58 | if (!(pciexbar & 1)) | 82 | if (!(pciexbar & 1)) |
59 | pci_mmcfg_config_num = 0; | 83 | return NULL; |
60 | 84 | ||
61 | /* Size bits */ | 85 | /* Size bits */ |
62 | switch ((pciexbar >> 1) & 3) { | 86 | switch ((pciexbar >> 1) & 3) { |
@@ -73,28 +97,23 @@ static const char __init *pci_mmcfg_intel_945(void) | |||
73 | len = 0x04000000U; | 97 | len = 0x04000000U; |
74 | break; | 98 | break; |
75 | default: | 99 | default: |
76 | pci_mmcfg_config_num = 0; | 100 | return NULL; |
77 | } | 101 | } |
78 | 102 | ||
79 | /* Errata #2, things break when not aligned on a 256Mb boundary */ | 103 | /* Errata #2, things break when not aligned on a 256Mb boundary */ |
80 | /* Can only happen in 64M/128M mode */ | 104 | /* Can only happen in 64M/128M mode */ |
81 | 105 | ||
82 | if ((pciexbar & mask) & 0x0fffffffU) | 106 | if ((pciexbar & mask) & 0x0fffffffU) |
83 | pci_mmcfg_config_num = 0; | 107 | return NULL; |
84 | 108 | ||
85 | /* Don't hit the APIC registers and their friends */ | 109 | /* Don't hit the APIC registers and their friends */ |
86 | if ((pciexbar & mask) >= 0xf0000000U) | 110 | if ((pciexbar & mask) >= 0xf0000000U) |
87 | pci_mmcfg_config_num = 0; | 111 | return NULL; |
88 | 112 | ||
89 | if (pci_mmcfg_config_num) { | 113 | if (extend_mmcfg(1) == -1) |
90 | pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); | 114 | return NULL; |
91 | if (!pci_mmcfg_config) | 115 | |
92 | return NULL; | 116 | fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1); |
93 | pci_mmcfg_config[0].address = pciexbar & mask; | ||
94 | pci_mmcfg_config[0].pci_segment = 0; | ||
95 | pci_mmcfg_config[0].start_bus_number = 0; | ||
96 | pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1; | ||
97 | } | ||
98 | 117 | ||
99 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; | 118 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; |
100 | } | 119 | } |
@@ -138,22 +157,77 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
138 | busnbits = 8; | 157 | busnbits = 8; |
139 | } | 158 | } |
140 | 159 | ||
141 | pci_mmcfg_config_num = (1 << segnbits); | 160 | if (extend_mmcfg(1 << segnbits) == -1) |
142 | pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) * | ||
143 | pci_mmcfg_config_num, GFP_KERNEL); | ||
144 | if (!pci_mmcfg_config) | ||
145 | return NULL; | 161 | return NULL; |
146 | 162 | ||
147 | for (i = 0; i < (1 << segnbits); i++) { | 163 | for (i = 0; i < (1 << segnbits); i++) |
148 | pci_mmcfg_config[i].address = base + (1<<28) * i; | 164 | fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); |
149 | pci_mmcfg_config[i].pci_segment = i; | ||
150 | pci_mmcfg_config[i].start_bus_number = 0; | ||
151 | pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1; | ||
152 | } | ||
153 | 165 | ||
154 | return "AMD Family 10h NB"; | 166 | return "AMD Family 10h NB"; |
155 | } | 167 | } |
156 | 168 | ||
169 | static bool __initdata mcp55_checked; | ||
170 | static const char __init *pci_mmcfg_nvidia_mcp55(void) | ||
171 | { | ||
172 | int bus; | ||
173 | int mcp55_mmconf_found = 0; | ||
174 | |||
175 | static const u32 extcfg_regnum = 0x90; | ||
176 | static const u32 extcfg_regsize = 4; | ||
177 | static const u32 extcfg_enable_mask = 1<<31; | ||
178 | static const u32 extcfg_start_mask = 0xff<<16; | ||
179 | static const int extcfg_start_shift = 16; | ||
180 | static const u32 extcfg_size_mask = 0x3<<28; | ||
181 | static const int extcfg_size_shift = 28; | ||
182 | static const int extcfg_sizebus[] = {0x100, 0x80, 0x40, 0x20}; | ||
183 | static const u32 extcfg_base_mask[] = {0x7ff8, 0x7ffc, 0x7ffe, 0x7fff}; | ||
184 | static const int extcfg_base_lshift = 25; | ||
185 | |||
186 | /* | ||
187 | * do check if amd fam10h already took over | ||
188 | */ | ||
189 | if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked) | ||
190 | return NULL; | ||
191 | |||
192 | mcp55_checked = true; | ||
193 | for (bus = 0; bus < 256; bus++) { | ||
194 | u64 base; | ||
195 | u32 l, extcfg; | ||
196 | u16 vendor, device; | ||
197 | int start, size_index, end; | ||
198 | |||
199 | raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), 0, 4, &l); | ||
200 | vendor = l & 0xffff; | ||
201 | device = (l >> 16) & 0xffff; | ||
202 | |||
203 | if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device) | ||
204 | continue; | ||
205 | |||
206 | raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), extcfg_regnum, | ||
207 | extcfg_regsize, &extcfg); | ||
208 | |||
209 | if (!(extcfg & extcfg_enable_mask)) | ||
210 | continue; | ||
211 | |||
212 | if (extend_mmcfg(1) == -1) | ||
213 | continue; | ||
214 | |||
215 | size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; | ||
216 | base = extcfg & extcfg_base_mask[size_index]; | ||
217 | /* base could > 4G */ | ||
218 | base <<= extcfg_base_lshift; | ||
219 | start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; | ||
220 | end = start + extcfg_sizebus[size_index] - 1; | ||
221 | fill_one_mmcfg(base, 0, start, end); | ||
222 | mcp55_mmconf_found++; | ||
223 | } | ||
224 | |||
225 | if (!mcp55_mmconf_found) | ||
226 | return NULL; | ||
227 | |||
228 | return "nVidia MCP55"; | ||
229 | } | ||
230 | |||
157 | struct pci_mmcfg_hostbridge_probe { | 231 | struct pci_mmcfg_hostbridge_probe { |
158 | u32 bus; | 232 | u32 bus; |
159 | u32 devfn; | 233 | u32 devfn; |
@@ -171,8 +245,52 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { | |||
171 | 0x1200, pci_mmcfg_amd_fam10h }, | 245 | 0x1200, pci_mmcfg_amd_fam10h }, |
172 | { 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD, | 246 | { 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD, |
173 | 0x1200, pci_mmcfg_amd_fam10h }, | 247 | 0x1200, pci_mmcfg_amd_fam10h }, |
248 | { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_NVIDIA, | ||
249 | 0x0369, pci_mmcfg_nvidia_mcp55 }, | ||
174 | }; | 250 | }; |
175 | 251 | ||
252 | static int __init cmp_mmcfg(const void *x1, const void *x2) | ||
253 | { | ||
254 | const typeof(pci_mmcfg_config[0]) *m1 = x1; | ||
255 | const typeof(pci_mmcfg_config[0]) *m2 = x2; | ||
256 | int start1, start2; | ||
257 | |||
258 | start1 = m1->start_bus_number; | ||
259 | start2 = m2->start_bus_number; | ||
260 | |||
261 | return start1 - start2; | ||
262 | } | ||
263 | |||
264 | static void __init pci_mmcfg_check_end_bus_number(void) | ||
265 | { | ||
266 | int i; | ||
267 | typeof(pci_mmcfg_config[0]) *cfg, *cfgx; | ||
268 | |||
269 | /* sort them at first */ | ||
270 | sort(pci_mmcfg_config, pci_mmcfg_config_num, | ||
271 | sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL); | ||
272 | |||
273 | /* last one*/ | ||
274 | if (pci_mmcfg_config_num > 0) { | ||
275 | i = pci_mmcfg_config_num - 1; | ||
276 | cfg = &pci_mmcfg_config[i]; | ||
277 | if (cfg->end_bus_number < cfg->start_bus_number) | ||
278 | cfg->end_bus_number = 255; | ||
279 | } | ||
280 | |||
281 | /* don't overlap please */ | ||
282 | for (i = 0; i < pci_mmcfg_config_num - 1; i++) { | ||
283 | cfg = &pci_mmcfg_config[i]; | ||
284 | cfgx = &pci_mmcfg_config[i+1]; | ||
285 | |||
286 | if (cfg->end_bus_number < cfg->start_bus_number) | ||
287 | cfg->end_bus_number = 255; | ||
288 | |||
289 | if (cfg->end_bus_number >= cfgx->start_bus_number) | ||
290 | cfg->end_bus_number = cfgx->start_bus_number - 1; | ||
291 | } | ||
292 | } | ||
293 | |||
176 | static int __init pci_mmcfg_check_hostbridge(void) | 294 | static int __init pci_mmcfg_check_hostbridge(void) |
177 | { | 295 | { |
178 | u32 l; | 296 | u32 l; |
@@ -186,31 +304,33 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
186 | 304 | ||
187 | pci_mmcfg_config_num = 0; | 305 | pci_mmcfg_config_num = 0; |
188 | pci_mmcfg_config = NULL; | 306 | pci_mmcfg_config = NULL; |
189 | name = NULL; | ||
190 | 307 | ||
191 | for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) { | 308 | for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { |
192 | bus = pci_mmcfg_probes[i].bus; | 309 | bus = pci_mmcfg_probes[i].bus; |
193 | devfn = pci_mmcfg_probes[i].devfn; | 310 | devfn = pci_mmcfg_probes[i].devfn; |
194 | raw_pci_ops->read(0, bus, devfn, 0, 4, &l); | 311 | raw_pci_ops->read(0, bus, devfn, 0, 4, &l); |
195 | vendor = l & 0xffff; | 312 | vendor = l & 0xffff; |
196 | device = (l >> 16) & 0xffff; | 313 | device = (l >> 16) & 0xffff; |
197 | 314 | ||
315 | name = NULL; | ||
198 | if (pci_mmcfg_probes[i].vendor == vendor && | 316 | if (pci_mmcfg_probes[i].vendor == vendor && |
199 | pci_mmcfg_probes[i].device == device) | 317 | pci_mmcfg_probes[i].device == device) |
200 | name = pci_mmcfg_probes[i].probe(); | 318 | name = pci_mmcfg_probes[i].probe(); |
201 | } | ||
202 | 319 | ||
203 | if (name) { | 320 | if (name) |
204 | printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n", | 321 | printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", |
205 | name, pci_mmcfg_config_num ? "with" : "without"); | 322 | name); |
206 | } | 323 | } |
207 | 324 | ||
208 | return name != NULL; | 325 | /* some end_bus_number is crazy, fix it */ |
326 | pci_mmcfg_check_end_bus_number(); | ||
327 | |||
328 | return pci_mmcfg_config_num != 0; | ||
209 | } | 329 | } |
210 | 330 | ||
211 | static void __init pci_mmcfg_insert_resources(void) | 331 | static void __init pci_mmcfg_insert_resources(void) |
212 | { | 332 | { |
213 | #define PCI_MMCFG_RESOURCE_NAME_LEN 19 | 333 | #define PCI_MMCFG_RESOURCE_NAME_LEN 24 |
214 | int i; | 334 | int i; |
215 | struct resource *res; | 335 | struct resource *res; |
216 | char *names; | 336 | char *names; |
@@ -228,9 +348,10 @@ static void __init pci_mmcfg_insert_resources(void) | |||
228 | struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i]; | 348 | struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i]; |
229 | num_buses = cfg->end_bus_number - cfg->start_bus_number + 1; | 349 | num_buses = cfg->end_bus_number - cfg->start_bus_number + 1; |
230 | res->name = names; | 350 | res->name = names; |
231 | snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", | 351 | snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, |
232 | cfg->pci_segment); | 352 | "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment, |
233 | res->start = cfg->address; | 353 | cfg->start_bus_number, cfg->end_bus_number); |
354 | res->start = cfg->address + (cfg->start_bus_number << 20); | ||
234 | res->end = res->start + (num_buses << 20) - 1; | 355 | res->end = res->start + (num_buses << 20) - 1; |
235 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 356 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
236 | insert_resource(&iomem_resource, res); | 357 | insert_resource(&iomem_resource, res); |
@@ -354,8 +475,6 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
354 | (pci_mmcfg_config[0].address == 0)) | 475 | (pci_mmcfg_config[0].address == 0)) |
355 | return; | 476 | return; |
356 | 477 | ||
357 | cfg = &pci_mmcfg_config[0]; | ||
358 | |||
359 | for (i = 0; i < pci_mmcfg_config_num; i++) { | 478 | for (i = 0; i < pci_mmcfg_config_num; i++) { |
360 | int valid = 0; | 479 | int valid = 0; |
361 | u64 addr, size; | 480 | u64 addr, size; |
@@ -423,10 +542,10 @@ static void __init __pci_mmcfg_init(int early) | |||
423 | known_bridge = 1; | 542 | known_bridge = 1; |
424 | } | 543 | } |
425 | 544 | ||
426 | if (!known_bridge) { | 545 | if (!known_bridge) |
427 | acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); | 546 | acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); |
428 | pci_mmcfg_reject_broken(early); | 547 | |
429 | } | 548 | pci_mmcfg_reject_broken(early); |
430 | 549 | ||
431 | if ((pci_mmcfg_config_num == 0) || | 550 | if ((pci_mmcfg_config_num == 0) || |
432 | (pci_mmcfg_config == NULL) || | 551 | (pci_mmcfg_config == NULL) || |
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 30007ffc8e11..94349f8b2f96 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
@@ -112,13 +112,18 @@ static struct pci_raw_ops pci_mmcfg = { | |||
112 | static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) | 112 | static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) |
113 | { | 113 | { |
114 | void __iomem *addr; | 114 | void __iomem *addr; |
115 | u32 size; | 115 | u64 start, size; |
116 | 116 | ||
117 | size = (cfg->end_bus_number + 1) << 20; | 117 | start = cfg->start_bus_number; |
118 | addr = ioremap_nocache(cfg->address, size); | 118 | start <<= 20; |
119 | start += cfg->address; | ||
120 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
121 | size <<= 20; | ||
122 | addr = ioremap_nocache(start, size); | ||
119 | if (addr) { | 123 | if (addr) { |
120 | printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", | 124 | printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", |
121 | cfg->address, cfg->address + size - 1); | 125 | start, start + size - 1); |
126 | addr -= cfg->start_bus_number << 20; | ||
122 | } | 127 | } |
123 | return addr; | 128 | return addr; |
124 | } | 129 | } |
@@ -157,7 +162,7 @@ void __init pci_mmcfg_arch_free(void) | |||
157 | 162 | ||
158 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 163 | for (i = 0; i < pci_mmcfg_config_num; ++i) { |
159 | if (pci_mmcfg_virt[i].virt) { | 164 | if (pci_mmcfg_virt[i].virt) { |
160 | iounmap(pci_mmcfg_virt[i].virt); | 165 | iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); |
161 | pci_mmcfg_virt[i].virt = NULL; | 166 | pci_mmcfg_virt[i].virt = NULL; |
162 | pci_mmcfg_virt[i].cfg = NULL; | 167 | pci_mmcfg_virt[i].cfg = NULL; |
163 | } | 168 | } |
diff --git a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c index 274d06082f48..ce702c5b3a2c 100644 --- a/arch/x86/power/cpu_32.c +++ b/arch/x86/power/cpu_32.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/mtrr.h> | 12 | #include <asm/mtrr.h> |
13 | #include <asm/mce.h> | 13 | #include <asm/mce.h> |
14 | #include <asm/xcr.h> | 14 | #include <asm/xcr.h> |
15 | #include <asm/suspend.h> | ||
15 | 16 | ||
16 | static struct saved_context saved_context; | 17 | static struct saved_context saved_context; |
17 | 18 | ||
diff --git a/arch/x86/power/cpu_64.c b/arch/x86/power/cpu_64.c index e3b6cf70d62c..5343540f2607 100644 --- a/arch/x86/power/cpu_64.c +++ b/arch/x86/power/cpu_64.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/mtrr.h> | 16 | #include <asm/mtrr.h> |
17 | #include <asm/xcr.h> | 17 | #include <asm/xcr.h> |
18 | #include <asm/suspend.h> | ||
18 | 19 | ||
19 | static void fix_processor_context(void); | 20 | static void fix_processor_context(void); |
20 | 21 | ||
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index 6dd000dd7933..65fdc86e923f 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/page.h> | 14 | #include <asm/page.h> |
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/mtrr.h> | 16 | #include <asm/mtrr.h> |
17 | #include <asm/suspend.h> | ||
17 | 18 | ||
18 | /* References to section boundaries */ | 19 | /* References to section boundaries */ |
19 | extern const void __nosave_begin, __nosave_end; | 20 | extern const void __nosave_begin, __nosave_end; |