diff options
Diffstat (limited to 'arch/i386')
70 files changed, 1155 insertions, 1072 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 619d843ba231..b22f003eaa6d 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -14,6 +14,10 @@ config X86 | |||
14 | 486, 586, Pentiums, and various instruction-set-compatible chips by | 14 | 486, 586, Pentiums, and various instruction-set-compatible chips by |
15 | AMD, Cyrix, and others. | 15 | AMD, Cyrix, and others. |
16 | 16 | ||
17 | config SEMAPHORE_SLEEPERS | ||
18 | bool | ||
19 | default y | ||
20 | |||
17 | config MMU | 21 | config MMU |
18 | bool | 22 | bool |
19 | default y | 23 | default y |
@@ -33,6 +37,10 @@ config GENERIC_IOMAP | |||
33 | bool | 37 | bool |
34 | default y | 38 | default y |
35 | 39 | ||
40 | config ARCH_MAY_HAVE_PC_FDC | ||
41 | bool | ||
42 | default y | ||
43 | |||
36 | source "init/Kconfig" | 44 | source "init/Kconfig" |
37 | 45 | ||
38 | menu "Processor type and features" | 46 | menu "Processor type and features" |
@@ -754,6 +762,7 @@ config NUMA | |||
754 | depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) | 762 | depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) |
755 | default n if X86_PC | 763 | default n if X86_PC |
756 | default y if (X86_NUMAQ || X86_SUMMIT) | 764 | default y if (X86_NUMAQ || X86_SUMMIT) |
765 | select SPARSEMEM_STATIC | ||
757 | 766 | ||
758 | # Need comments to help the hapless user trying to turn on NUMA support | 767 | # Need comments to help the hapless user trying to turn on NUMA support |
759 | comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" | 768 | comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" |
@@ -1203,7 +1212,6 @@ config PCI_DIRECT | |||
1203 | config PCI_MMCONFIG | 1212 | config PCI_MMCONFIG |
1204 | bool | 1213 | bool |
1205 | depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) | 1214 | depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) |
1206 | select ACPI_BOOT | ||
1207 | default y | 1215 | default y |
1208 | 1216 | ||
1209 | source "drivers/pci/pcie/Kconfig" | 1217 | source "drivers/pci/pcie/Kconfig" |
@@ -1313,6 +1321,11 @@ config GENERIC_IRQ_PROBE | |||
1313 | bool | 1321 | bool |
1314 | default y | 1322 | default y |
1315 | 1323 | ||
1324 | config GENERIC_PENDING_IRQ | ||
1325 | bool | ||
1326 | depends on GENERIC_HARDIRQS && SMP | ||
1327 | default y | ||
1328 | |||
1316 | config X86_SMP | 1329 | config X86_SMP |
1317 | bool | 1330 | bool |
1318 | depends on SMP && !X86_VOYAGER | 1331 | depends on SMP && !X86_VOYAGER |
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 8cb420f40c58..ca668d9df164 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S | |||
@@ -82,7 +82,7 @@ start: | |||
82 | # This is the setup header, and it must start at %cs:2 (old 0x9020:2) | 82 | # This is the setup header, and it must start at %cs:2 (old 0x9020:2) |
83 | 83 | ||
84 | .ascii "HdrS" # header signature | 84 | .ascii "HdrS" # header signature |
85 | .word 0x0203 # header version number (>= 0x0105) | 85 | .word 0x0204 # header version number (>= 0x0105) |
86 | # or else old loadlin-1.5 will fail) | 86 | # or else old loadlin-1.5 will fail) |
87 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG | 87 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG |
88 | start_sys_seg: .word SYSSEG | 88 | start_sys_seg: .word SYSSEG |
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 6835f6d47c31..05798419a6a9 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -177,7 +177,9 @@ int main(int argc, char ** argv) | |||
177 | die("Output: seek failed"); | 177 | die("Output: seek failed"); |
178 | buf[0] = (sys_size & 0xff); | 178 | buf[0] = (sys_size & 0xff); |
179 | buf[1] = ((sys_size >> 8) & 0xff); | 179 | buf[1] = ((sys_size >> 8) & 0xff); |
180 | if (write(1, buf, 2) != 2) | 180 | buf[2] = ((sys_size >> 16) & 0xff); |
181 | buf[3] = ((sys_size >> 24) & 0xff); | ||
182 | if (write(1, buf, 4) != 4) | ||
181 | die("Write of image length failed"); | 183 | die("Write of image length failed"); |
182 | 184 | ||
183 | return 0; /* Everything is OK */ | 185 | return 0; /* Everything is OK */ |
diff --git a/arch/i386/defconfig b/arch/i386/defconfig index ca07b95c06b8..6a431b926019 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig | |||
@@ -131,8 +131,6 @@ CONFIG_SOFTWARE_SUSPEND=y | |||
131 | # ACPI (Advanced Configuration and Power Interface) Support | 131 | # ACPI (Advanced Configuration and Power Interface) Support |
132 | # | 132 | # |
133 | CONFIG_ACPI=y | 133 | CONFIG_ACPI=y |
134 | CONFIG_ACPI_BOOT=y | ||
135 | CONFIG_ACPI_INTERPRETER=y | ||
136 | CONFIG_ACPI_SLEEP=y | 134 | CONFIG_ACPI_SLEEP=y |
137 | CONFIG_ACPI_SLEEP_PROC_FS=y | 135 | CONFIG_ACPI_SLEEP_PROC_FS=y |
138 | CONFIG_ACPI_AC=y | 136 | CONFIG_ACPI_AC=y |
@@ -144,10 +142,8 @@ CONFIG_ACPI_THERMAL=y | |||
144 | # CONFIG_ACPI_ASUS is not set | 142 | # CONFIG_ACPI_ASUS is not set |
145 | # CONFIG_ACPI_TOSHIBA is not set | 143 | # CONFIG_ACPI_TOSHIBA is not set |
146 | # CONFIG_ACPI_DEBUG is not set | 144 | # CONFIG_ACPI_DEBUG is not set |
147 | CONFIG_ACPI_BUS=y | ||
148 | CONFIG_ACPI_EC=y | 145 | CONFIG_ACPI_EC=y |
149 | CONFIG_ACPI_POWER=y | 146 | CONFIG_ACPI_POWER=y |
150 | CONFIG_ACPI_PCI=y | ||
151 | CONFIG_ACPI_SYSTEM=y | 147 | CONFIG_ACPI_SYSTEM=y |
152 | # CONFIG_X86_PM_TIMER is not set | 148 | # CONFIG_X86_PM_TIMER is not set |
153 | 149 | ||
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 4cc83b322b36..f10de0f2c5e6 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -7,11 +7,11 @@ extra-y := head.o init_task.o vmlinux.lds | |||
7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ | 7 | obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ |
8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ | 8 | ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ |
9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ | 9 | pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ |
10 | doublefault.o quirks.o | 10 | doublefault.o quirks.o i8237.o |
11 | 11 | ||
12 | obj-y += cpu/ | 12 | obj-y += cpu/ |
13 | obj-y += timers/ | 13 | obj-y += timers/ |
14 | obj-$(CONFIG_ACPI_BOOT) += acpi/ | 14 | obj-$(CONFIG_ACPI) += acpi/ |
15 | obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o | 15 | obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o |
16 | obj-$(CONFIG_MCA) += mca.o | 16 | obj-$(CONFIG_MCA) += mca.o |
17 | obj-$(CONFIG_X86_MSR) += msr.o | 17 | obj-$(CONFIG_X86_MSR) += msr.o |
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index 5e291a20c03d..267ca48e1b6c 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_ACPI_BOOT) := boot.o | 1 | obj-y := boot.o |
2 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o | 2 | obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o |
3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o | 3 | obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o |
4 | 4 | ||
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index b7808a89d945..a63351c085c6 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -40,19 +40,25 @@ | |||
40 | 40 | ||
41 | #ifdef CONFIG_X86_64 | 41 | #ifdef CONFIG_X86_64 |
42 | 42 | ||
43 | static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { } | 43 | static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) |
44 | { | ||
45 | } | ||
44 | extern void __init clustered_apic_check(void); | 46 | extern void __init clustered_apic_check(void); |
45 | static inline int ioapic_setup_disabled(void) { return 0; } | 47 | static inline int ioapic_setup_disabled(void) |
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
46 | #include <asm/proto.h> | 52 | #include <asm/proto.h> |
47 | 53 | ||
48 | #else /* X86 */ | 54 | #else /* X86 */ |
49 | 55 | ||
50 | #ifdef CONFIG_X86_LOCAL_APIC | 56 | #ifdef CONFIG_X86_LOCAL_APIC |
51 | #include <mach_apic.h> | 57 | #include <mach_apic.h> |
52 | #include <mach_mpparse.h> | 58 | #include <mach_mpparse.h> |
53 | #endif /* CONFIG_X86_LOCAL_APIC */ | 59 | #endif /* CONFIG_X86_LOCAL_APIC */ |
54 | 60 | ||
55 | #endif /* X86 */ | 61 | #endif /* X86 */ |
56 | 62 | ||
57 | #define BAD_MADT_ENTRY(entry, end) ( \ | 63 | #define BAD_MADT_ENTRY(entry, end) ( \ |
58 | (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ | 64 | (!entry) || (unsigned long)entry + sizeof(*entry) > end || \ |
@@ -60,13 +66,8 @@ static inline int ioapic_setup_disabled(void) { return 0; } | |||
60 | 66 | ||
61 | #define PREFIX "ACPI: " | 67 | #define PREFIX "ACPI: " |
62 | 68 | ||
63 | #ifdef CONFIG_ACPI_PCI | ||
64 | int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ | 69 | int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ |
65 | int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ | 70 | int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ |
66 | #else | ||
67 | int acpi_noirq __initdata = 1; | ||
68 | int acpi_pci_disabled __initdata = 1; | ||
69 | #endif | ||
70 | int acpi_ht __initdata = 1; /* enable HT */ | 71 | int acpi_ht __initdata = 1; /* enable HT */ |
71 | 72 | ||
72 | int acpi_lapic; | 73 | int acpi_lapic; |
@@ -88,7 +89,7 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; | |||
88 | 89 | ||
89 | #define MAX_MADT_ENTRIES 256 | 90 | #define MAX_MADT_ENTRIES 256 |
90 | u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = | 91 | u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] = |
91 | { [0 ... MAX_MADT_ENTRIES-1] = 0xff }; | 92 | {[0 ... MAX_MADT_ENTRIES - 1] = 0xff }; |
92 | EXPORT_SYMBOL(x86_acpiid_to_apicid); | 93 | EXPORT_SYMBOL(x86_acpiid_to_apicid); |
93 | 94 | ||
94 | /* -------------------------------------------------------------------------- | 95 | /* -------------------------------------------------------------------------- |
@@ -99,7 +100,7 @@ EXPORT_SYMBOL(x86_acpiid_to_apicid); | |||
99 | * The default interrupt routing model is PIC (8259). This gets | 100 | * The default interrupt routing model is PIC (8259). This gets |
100 | * overriden if IOAPICs are enumerated (below). | 101 | * overriden if IOAPICs are enumerated (below). |
101 | */ | 102 | */ |
102 | enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; | 103 | enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; |
103 | 104 | ||
104 | #ifdef CONFIG_X86_64 | 105 | #ifdef CONFIG_X86_64 |
105 | 106 | ||
@@ -107,7 +108,7 @@ enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; | |||
107 | char *__acpi_map_table(unsigned long phys_addr, unsigned long size) | 108 | char *__acpi_map_table(unsigned long phys_addr, unsigned long size) |
108 | { | 109 | { |
109 | if (!phys_addr || !size) | 110 | if (!phys_addr || !size) |
110 | return NULL; | 111 | return NULL; |
111 | 112 | ||
112 | if (phys_addr < (end_pfn_map << PAGE_SHIFT)) | 113 | if (phys_addr < (end_pfn_map << PAGE_SHIFT)) |
113 | return __va(phys_addr); | 114 | return __va(phys_addr); |
@@ -134,8 +135,8 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) | |||
134 | unsigned long base, offset, mapped_size; | 135 | unsigned long base, offset, mapped_size; |
135 | int idx; | 136 | int idx; |
136 | 137 | ||
137 | if (phys + size < 8*1024*1024) | 138 | if (phys + size < 8 * 1024 * 1024) |
138 | return __va(phys); | 139 | return __va(phys); |
139 | 140 | ||
140 | offset = phys & (PAGE_SIZE - 1); | 141 | offset = phys & (PAGE_SIZE - 1); |
141 | mapped_size = PAGE_SIZE - offset; | 142 | mapped_size = PAGE_SIZE - offset; |
@@ -154,7 +155,7 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) | |||
154 | mapped_size += PAGE_SIZE; | 155 | mapped_size += PAGE_SIZE; |
155 | } | 156 | } |
156 | 157 | ||
157 | return ((unsigned char *) base + offset); | 158 | return ((unsigned char *)base + offset); |
158 | } | 159 | } |
159 | #endif | 160 | #endif |
160 | 161 | ||
@@ -172,7 +173,7 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
172 | if (!phys_addr || !size) | 173 | if (!phys_addr || !size) |
173 | return -EINVAL; | 174 | return -EINVAL; |
174 | 175 | ||
175 | mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); | 176 | mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); |
176 | if (!mcfg) { | 177 | if (!mcfg) { |
177 | printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); | 178 | printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); |
178 | return -ENODEV; | 179 | return -ENODEV; |
@@ -209,20 +210,17 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
209 | 210 | ||
210 | return 0; | 211 | return 0; |
211 | } | 212 | } |
212 | #endif /* CONFIG_PCI_MMCONFIG */ | 213 | #endif /* CONFIG_PCI_MMCONFIG */ |
213 | 214 | ||
214 | #ifdef CONFIG_X86_LOCAL_APIC | 215 | #ifdef CONFIG_X86_LOCAL_APIC |
215 | static int __init | 216 | static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) |
216 | acpi_parse_madt ( | ||
217 | unsigned long phys_addr, | ||
218 | unsigned long size) | ||
219 | { | 217 | { |
220 | struct acpi_table_madt *madt = NULL; | 218 | struct acpi_table_madt *madt = NULL; |
221 | 219 | ||
222 | if (!phys_addr || !size) | 220 | if (!phys_addr || !size) |
223 | return -EINVAL; | 221 | return -EINVAL; |
224 | 222 | ||
225 | madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); | 223 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); |
226 | if (!madt) { | 224 | if (!madt) { |
227 | printk(KERN_WARNING PREFIX "Unable to map MADT\n"); | 225 | printk(KERN_WARNING PREFIX "Unable to map MADT\n"); |
228 | return -ENODEV; | 226 | return -ENODEV; |
@@ -232,22 +230,20 @@ acpi_parse_madt ( | |||
232 | acpi_lapic_addr = (u64) madt->lapic_address; | 230 | acpi_lapic_addr = (u64) madt->lapic_address; |
233 | 231 | ||
234 | printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", | 232 | printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", |
235 | madt->lapic_address); | 233 | madt->lapic_address); |
236 | } | 234 | } |
237 | 235 | ||
238 | acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); | 236 | acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); |
239 | 237 | ||
240 | return 0; | 238 | return 0; |
241 | } | 239 | } |
242 | 240 | ||
243 | |||
244 | static int __init | 241 | static int __init |
245 | acpi_parse_lapic ( | 242 | acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) |
246 | acpi_table_entry_header *header, const unsigned long end) | ||
247 | { | 243 | { |
248 | struct acpi_table_lapic *processor = NULL; | 244 | struct acpi_table_lapic *processor = NULL; |
249 | 245 | ||
250 | processor = (struct acpi_table_lapic*) header; | 246 | processor = (struct acpi_table_lapic *)header; |
251 | 247 | ||
252 | if (BAD_MADT_ENTRY(processor, end)) | 248 | if (BAD_MADT_ENTRY(processor, end)) |
253 | return -EINVAL; | 249 | return -EINVAL; |
@@ -260,20 +256,19 @@ acpi_parse_lapic ( | |||
260 | 256 | ||
261 | x86_acpiid_to_apicid[processor->acpi_id] = processor->id; | 257 | x86_acpiid_to_apicid[processor->acpi_id] = processor->id; |
262 | 258 | ||
263 | mp_register_lapic ( | 259 | mp_register_lapic(processor->id, /* APIC ID */ |
264 | processor->id, /* APIC ID */ | 260 | processor->flags.enabled); /* Enabled? */ |
265 | processor->flags.enabled); /* Enabled? */ | ||
266 | 261 | ||
267 | return 0; | 262 | return 0; |
268 | } | 263 | } |
269 | 264 | ||
270 | static int __init | 265 | static int __init |
271 | acpi_parse_lapic_addr_ovr ( | 266 | acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header, |
272 | acpi_table_entry_header *header, const unsigned long end) | 267 | const unsigned long end) |
273 | { | 268 | { |
274 | struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; | 269 | struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL; |
275 | 270 | ||
276 | lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header; | 271 | lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header; |
277 | 272 | ||
278 | if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) | 273 | if (BAD_MADT_ENTRY(lapic_addr_ovr, end)) |
279 | return -EINVAL; | 274 | return -EINVAL; |
@@ -284,12 +279,11 @@ acpi_parse_lapic_addr_ovr ( | |||
284 | } | 279 | } |
285 | 280 | ||
286 | static int __init | 281 | static int __init |
287 | acpi_parse_lapic_nmi ( | 282 | acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end) |
288 | acpi_table_entry_header *header, const unsigned long end) | ||
289 | { | 283 | { |
290 | struct acpi_table_lapic_nmi *lapic_nmi = NULL; | 284 | struct acpi_table_lapic_nmi *lapic_nmi = NULL; |
291 | 285 | ||
292 | lapic_nmi = (struct acpi_table_lapic_nmi*) header; | 286 | lapic_nmi = (struct acpi_table_lapic_nmi *)header; |
293 | 287 | ||
294 | if (BAD_MADT_ENTRY(lapic_nmi, end)) | 288 | if (BAD_MADT_ENTRY(lapic_nmi, end)) |
295 | return -EINVAL; | 289 | return -EINVAL; |
@@ -302,37 +296,32 @@ acpi_parse_lapic_nmi ( | |||
302 | return 0; | 296 | return 0; |
303 | } | 297 | } |
304 | 298 | ||
299 | #endif /*CONFIG_X86_LOCAL_APIC */ | ||
305 | 300 | ||
306 | #endif /*CONFIG_X86_LOCAL_APIC*/ | 301 | #ifdef CONFIG_X86_IO_APIC |
307 | |||
308 | #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) | ||
309 | 302 | ||
310 | static int __init | 303 | static int __init |
311 | acpi_parse_ioapic ( | 304 | acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) |
312 | acpi_table_entry_header *header, const unsigned long end) | ||
313 | { | 305 | { |
314 | struct acpi_table_ioapic *ioapic = NULL; | 306 | struct acpi_table_ioapic *ioapic = NULL; |
315 | 307 | ||
316 | ioapic = (struct acpi_table_ioapic*) header; | 308 | ioapic = (struct acpi_table_ioapic *)header; |
317 | 309 | ||
318 | if (BAD_MADT_ENTRY(ioapic, end)) | 310 | if (BAD_MADT_ENTRY(ioapic, end)) |
319 | return -EINVAL; | 311 | return -EINVAL; |
320 | 312 | ||
321 | acpi_table_print_madt_entry(header); | 313 | acpi_table_print_madt_entry(header); |
322 | 314 | ||
323 | mp_register_ioapic ( | 315 | mp_register_ioapic(ioapic->id, |
324 | ioapic->id, | 316 | ioapic->address, ioapic->global_irq_base); |
325 | ioapic->address, | 317 | |
326 | ioapic->global_irq_base); | ||
327 | |||
328 | return 0; | 318 | return 0; |
329 | } | 319 | } |
330 | 320 | ||
331 | /* | 321 | /* |
332 | * Parse Interrupt Source Override for the ACPI SCI | 322 | * Parse Interrupt Source Override for the ACPI SCI |
333 | */ | 323 | */ |
334 | static void | 324 | static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) |
335 | acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) | ||
336 | { | 325 | { |
337 | if (trigger == 0) /* compatible SCI trigger is level */ | 326 | if (trigger == 0) /* compatible SCI trigger is level */ |
338 | trigger = 3; | 327 | trigger = 3; |
@@ -348,7 +337,7 @@ acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) | |||
348 | polarity = acpi_sci_flags.polarity; | 337 | polarity = acpi_sci_flags.polarity; |
349 | 338 | ||
350 | /* | 339 | /* |
351 | * mp_config_acpi_legacy_irqs() already setup IRQs < 16 | 340 | * mp_config_acpi_legacy_irqs() already setup IRQs < 16 |
352 | * If GSI is < 16, this will update its flags, | 341 | * If GSI is < 16, this will update its flags, |
353 | * else it will create a new mp_irqs[] entry. | 342 | * else it will create a new mp_irqs[] entry. |
354 | */ | 343 | */ |
@@ -363,12 +352,12 @@ acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) | |||
363 | } | 352 | } |
364 | 353 | ||
365 | static int __init | 354 | static int __init |
366 | acpi_parse_int_src_ovr ( | 355 | acpi_parse_int_src_ovr(acpi_table_entry_header * header, |
367 | acpi_table_entry_header *header, const unsigned long end) | 356 | const unsigned long end) |
368 | { | 357 | { |
369 | struct acpi_table_int_src_ovr *intsrc = NULL; | 358 | struct acpi_table_int_src_ovr *intsrc = NULL; |
370 | 359 | ||
371 | intsrc = (struct acpi_table_int_src_ovr*) header; | 360 | intsrc = (struct acpi_table_int_src_ovr *)header; |
372 | 361 | ||
373 | if (BAD_MADT_ENTRY(intsrc, end)) | 362 | if (BAD_MADT_ENTRY(intsrc, end)) |
374 | return -EINVAL; | 363 | return -EINVAL; |
@@ -377,33 +366,30 @@ acpi_parse_int_src_ovr ( | |||
377 | 366 | ||
378 | if (intsrc->bus_irq == acpi_fadt.sci_int) { | 367 | if (intsrc->bus_irq == acpi_fadt.sci_int) { |
379 | acpi_sci_ioapic_setup(intsrc->global_irq, | 368 | acpi_sci_ioapic_setup(intsrc->global_irq, |
380 | intsrc->flags.polarity, intsrc->flags.trigger); | 369 | intsrc->flags.polarity, |
370 | intsrc->flags.trigger); | ||
381 | return 0; | 371 | return 0; |
382 | } | 372 | } |
383 | 373 | ||
384 | if (acpi_skip_timer_override && | 374 | if (acpi_skip_timer_override && |
385 | intsrc->bus_irq == 0 && intsrc->global_irq == 2) { | 375 | intsrc->bus_irq == 0 && intsrc->global_irq == 2) { |
386 | printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); | 376 | printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); |
387 | return 0; | 377 | return 0; |
388 | } | 378 | } |
389 | 379 | ||
390 | mp_override_legacy_irq ( | 380 | mp_override_legacy_irq(intsrc->bus_irq, |
391 | intsrc->bus_irq, | 381 | intsrc->flags.polarity, |
392 | intsrc->flags.polarity, | 382 | intsrc->flags.trigger, intsrc->global_irq); |
393 | intsrc->flags.trigger, | ||
394 | intsrc->global_irq); | ||
395 | 383 | ||
396 | return 0; | 384 | return 0; |
397 | } | 385 | } |
398 | 386 | ||
399 | |||
400 | static int __init | 387 | static int __init |
401 | acpi_parse_nmi_src ( | 388 | acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end) |
402 | acpi_table_entry_header *header, const unsigned long end) | ||
403 | { | 389 | { |
404 | struct acpi_table_nmi_src *nmi_src = NULL; | 390 | struct acpi_table_nmi_src *nmi_src = NULL; |
405 | 391 | ||
406 | nmi_src = (struct acpi_table_nmi_src*) header; | 392 | nmi_src = (struct acpi_table_nmi_src *)header; |
407 | 393 | ||
408 | if (BAD_MADT_ENTRY(nmi_src, end)) | 394 | if (BAD_MADT_ENTRY(nmi_src, end)) |
409 | return -EINVAL; | 395 | return -EINVAL; |
@@ -415,9 +401,7 @@ acpi_parse_nmi_src ( | |||
415 | return 0; | 401 | return 0; |
416 | } | 402 | } |
417 | 403 | ||
418 | #endif /* CONFIG_X86_IO_APIC */ | 404 | #endif /* CONFIG_X86_IO_APIC */ |
419 | |||
420 | #ifdef CONFIG_ACPI_BUS | ||
421 | 405 | ||
422 | /* | 406 | /* |
423 | * acpi_pic_sci_set_trigger() | 407 | * acpi_pic_sci_set_trigger() |
@@ -433,8 +417,7 @@ acpi_parse_nmi_src ( | |||
433 | * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0) | 417 | * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0) |
434 | */ | 418 | */ |
435 | 419 | ||
436 | void __init | 420 | void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) |
437 | acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | ||
438 | { | 421 | { |
439 | unsigned int mask = 1 << irq; | 422 | unsigned int mask = 1 << irq; |
440 | unsigned int old, new; | 423 | unsigned int old, new; |
@@ -454,10 +437,10 @@ acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
454 | * routing tables.. | 437 | * routing tables.. |
455 | */ | 438 | */ |
456 | switch (trigger) { | 439 | switch (trigger) { |
457 | case 1: /* Edge - clear */ | 440 | case 1: /* Edge - clear */ |
458 | new &= ~mask; | 441 | new &= ~mask; |
459 | break; | 442 | break; |
460 | case 3: /* Level - set */ | 443 | case 3: /* Level - set */ |
461 | new |= mask; | 444 | new |= mask; |
462 | break; | 445 | break; |
463 | } | 446 | } |
@@ -470,21 +453,22 @@ acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
470 | outb(new >> 8, 0x4d1); | 453 | outb(new >> 8, 0x4d1); |
471 | } | 454 | } |
472 | 455 | ||
473 | |||
474 | #endif /* CONFIG_ACPI_BUS */ | ||
475 | |||
476 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | 456 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) |
477 | { | 457 | { |
478 | #ifdef CONFIG_X86_IO_APIC | 458 | #ifdef CONFIG_X86_IO_APIC |
479 | if (use_pci_vector() && !platform_legacy_irq(gsi)) | 459 | if (use_pci_vector() && !platform_legacy_irq(gsi)) |
480 | *irq = IO_APIC_VECTOR(gsi); | 460 | *irq = IO_APIC_VECTOR(gsi); |
481 | else | 461 | else |
482 | #endif | 462 | #endif |
483 | *irq = gsi; | 463 | *irq = gsi; |
484 | return 0; | 464 | return 0; |
485 | } | 465 | } |
486 | 466 | ||
487 | unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) | 467 | /* |
468 | * success: return IRQ number (>=0) | ||
469 | * failure: return < 0 | ||
470 | */ | ||
471 | int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) | ||
488 | { | 472 | { |
489 | unsigned int irq; | 473 | unsigned int irq; |
490 | unsigned int plat_gsi = gsi; | 474 | unsigned int plat_gsi = gsi; |
@@ -497,7 +481,7 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) | |||
497 | extern void eisa_set_level_irq(unsigned int irq); | 481 | extern void eisa_set_level_irq(unsigned int irq); |
498 | 482 | ||
499 | if (edge_level == ACPI_LEVEL_SENSITIVE) | 483 | if (edge_level == ACPI_LEVEL_SENSITIVE) |
500 | eisa_set_level_irq(gsi); | 484 | eisa_set_level_irq(gsi); |
501 | } | 485 | } |
502 | #endif | 486 | #endif |
503 | 487 | ||
@@ -509,60 +493,58 @@ unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low) | |||
509 | acpi_gsi_to_irq(plat_gsi, &irq); | 493 | acpi_gsi_to_irq(plat_gsi, &irq); |
510 | return irq; | 494 | return irq; |
511 | } | 495 | } |
496 | |||
512 | EXPORT_SYMBOL(acpi_register_gsi); | 497 | EXPORT_SYMBOL(acpi_register_gsi); |
513 | 498 | ||
514 | /* | 499 | /* |
515 | * ACPI based hotplug support for CPU | 500 | * ACPI based hotplug support for CPU |
516 | */ | 501 | */ |
517 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 502 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
518 | int | 503 | int acpi_map_lsapic(acpi_handle handle, int *pcpu) |
519 | acpi_map_lsapic(acpi_handle handle, int *pcpu) | ||
520 | { | 504 | { |
521 | /* TBD */ | 505 | /* TBD */ |
522 | return -EINVAL; | 506 | return -EINVAL; |
523 | } | 507 | } |
524 | EXPORT_SYMBOL(acpi_map_lsapic); | ||
525 | 508 | ||
509 | EXPORT_SYMBOL(acpi_map_lsapic); | ||
526 | 510 | ||
527 | int | 511 | int acpi_unmap_lsapic(int cpu) |
528 | acpi_unmap_lsapic(int cpu) | ||
529 | { | 512 | { |
530 | /* TBD */ | 513 | /* TBD */ |
531 | return -EINVAL; | 514 | return -EINVAL; |
532 | } | 515 | } |
516 | |||
533 | EXPORT_SYMBOL(acpi_unmap_lsapic); | 517 | EXPORT_SYMBOL(acpi_unmap_lsapic); |
534 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 518 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
535 | 519 | ||
536 | int | 520 | int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) |
537 | acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
538 | { | 521 | { |
539 | /* TBD */ | 522 | /* TBD */ |
540 | return -EINVAL; | 523 | return -EINVAL; |
541 | } | 524 | } |
525 | |||
542 | EXPORT_SYMBOL(acpi_register_ioapic); | 526 | EXPORT_SYMBOL(acpi_register_ioapic); |
543 | 527 | ||
544 | int | 528 | int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) |
545 | acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | ||
546 | { | 529 | { |
547 | /* TBD */ | 530 | /* TBD */ |
548 | return -EINVAL; | 531 | return -EINVAL; |
549 | } | 532 | } |
533 | |||
550 | EXPORT_SYMBOL(acpi_unregister_ioapic); | 534 | EXPORT_SYMBOL(acpi_unregister_ioapic); |
551 | 535 | ||
552 | static unsigned long __init | 536 | static unsigned long __init |
553 | acpi_scan_rsdp ( | 537 | acpi_scan_rsdp(unsigned long start, unsigned long length) |
554 | unsigned long start, | ||
555 | unsigned long length) | ||
556 | { | 538 | { |
557 | unsigned long offset = 0; | 539 | unsigned long offset = 0; |
558 | unsigned long sig_len = sizeof("RSD PTR ") - 1; | 540 | unsigned long sig_len = sizeof("RSD PTR ") - 1; |
559 | 541 | ||
560 | /* | 542 | /* |
561 | * Scan all 16-byte boundaries of the physical memory region for the | 543 | * Scan all 16-byte boundaries of the physical memory region for the |
562 | * RSDP signature. | 544 | * RSDP signature. |
563 | */ | 545 | */ |
564 | for (offset = 0; offset < length; offset += 16) { | 546 | for (offset = 0; offset < length; offset += 16) { |
565 | if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) | 547 | if (strncmp((char *)(start + offset), "RSD PTR ", sig_len)) |
566 | continue; | 548 | continue; |
567 | return (start + offset); | 549 | return (start + offset); |
568 | } | 550 | } |
@@ -575,20 +557,19 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) | |||
575 | struct acpi_table_sbf *sb; | 557 | struct acpi_table_sbf *sb; |
576 | 558 | ||
577 | if (!phys_addr || !size) | 559 | if (!phys_addr || !size) |
578 | return -EINVAL; | 560 | return -EINVAL; |
579 | 561 | ||
580 | sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); | 562 | sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size); |
581 | if (!sb) { | 563 | if (!sb) { |
582 | printk(KERN_WARNING PREFIX "Unable to map SBF\n"); | 564 | printk(KERN_WARNING PREFIX "Unable to map SBF\n"); |
583 | return -ENODEV; | 565 | return -ENODEV; |
584 | } | 566 | } |
585 | 567 | ||
586 | sbf_port = sb->sbf_cmos; /* Save CMOS port */ | 568 | sbf_port = sb->sbf_cmos; /* Save CMOS port */ |
587 | 569 | ||
588 | return 0; | 570 | return 0; |
589 | } | 571 | } |
590 | 572 | ||
591 | |||
592 | #ifdef CONFIG_HPET_TIMER | 573 | #ifdef CONFIG_HPET_TIMER |
593 | 574 | ||
594 | static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | 575 | static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) |
@@ -598,7 +579,7 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | |||
598 | if (!phys || !size) | 579 | if (!phys || !size) |
599 | return -EINVAL; | 580 | return -EINVAL; |
600 | 581 | ||
601 | hpet_tbl = (struct acpi_table_hpet *) __acpi_map_table(phys, size); | 582 | hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size); |
602 | if (!hpet_tbl) { | 583 | if (!hpet_tbl) { |
603 | printk(KERN_WARNING PREFIX "Unable to map HPET\n"); | 584 | printk(KERN_WARNING PREFIX "Unable to map HPET\n"); |
604 | return -ENODEV; | 585 | return -ENODEV; |
@@ -609,22 +590,21 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) | |||
609 | "memory.\n"); | 590 | "memory.\n"); |
610 | return -1; | 591 | return -1; |
611 | } | 592 | } |
612 | |||
613 | #ifdef CONFIG_X86_64 | 593 | #ifdef CONFIG_X86_64 |
614 | vxtime.hpet_address = hpet_tbl->addr.addrl | | 594 | vxtime.hpet_address = hpet_tbl->addr.addrl | |
615 | ((long) hpet_tbl->addr.addrh << 32); | 595 | ((long)hpet_tbl->addr.addrh << 32); |
616 | 596 | ||
617 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", | 597 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", |
618 | hpet_tbl->id, vxtime.hpet_address); | 598 | hpet_tbl->id, vxtime.hpet_address); |
619 | #else /* X86 */ | 599 | #else /* X86 */ |
620 | { | 600 | { |
621 | extern unsigned long hpet_address; | 601 | extern unsigned long hpet_address; |
622 | 602 | ||
623 | hpet_address = hpet_tbl->addr.addrl; | 603 | hpet_address = hpet_tbl->addr.addrl; |
624 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", | 604 | printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", |
625 | hpet_tbl->id, hpet_address); | 605 | hpet_tbl->id, hpet_address); |
626 | } | 606 | } |
627 | #endif /* X86 */ | 607 | #endif /* X86 */ |
628 | 608 | ||
629 | return 0; | 609 | return 0; |
630 | } | 610 | } |
@@ -640,28 +620,25 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) | |||
640 | { | 620 | { |
641 | struct fadt_descriptor_rev2 *fadt = NULL; | 621 | struct fadt_descriptor_rev2 *fadt = NULL; |
642 | 622 | ||
643 | fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size); | 623 | fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size); |
644 | if(!fadt) { | 624 | if (!fadt) { |
645 | printk(KERN_WARNING PREFIX "Unable to map FADT\n"); | 625 | printk(KERN_WARNING PREFIX "Unable to map FADT\n"); |
646 | return 0; | 626 | return 0; |
647 | } | 627 | } |
648 | |||
649 | #ifdef CONFIG_ACPI_INTERPRETER | ||
650 | /* initialize sci_int early for INT_SRC_OVR MADT parsing */ | 628 | /* initialize sci_int early for INT_SRC_OVR MADT parsing */ |
651 | acpi_fadt.sci_int = fadt->sci_int; | 629 | acpi_fadt.sci_int = fadt->sci_int; |
652 | #endif | ||
653 | 630 | ||
654 | #ifdef CONFIG_ACPI_BUS | ||
655 | /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ | 631 | /* initialize rev and apic_phys_dest_mode for x86_64 genapic */ |
656 | acpi_fadt.revision = fadt->revision; | 632 | acpi_fadt.revision = fadt->revision; |
657 | acpi_fadt.force_apic_physical_destination_mode = fadt->force_apic_physical_destination_mode; | 633 | acpi_fadt.force_apic_physical_destination_mode = |
658 | #endif | 634 | fadt->force_apic_physical_destination_mode; |
659 | 635 | ||
660 | #ifdef CONFIG_X86_PM_TIMER | 636 | #ifdef CONFIG_X86_PM_TIMER |
661 | /* detect the location of the ACPI PM Timer */ | 637 | /* detect the location of the ACPI PM Timer */ |
662 | if (fadt->revision >= FADT2_REVISION_ID) { | 638 | if (fadt->revision >= FADT2_REVISION_ID) { |
663 | /* FADT rev. 2 */ | 639 | /* FADT rev. 2 */ |
664 | if (fadt->xpm_tmr_blk.address_space_id != ACPI_ADR_SPACE_SYSTEM_IO) | 640 | if (fadt->xpm_tmr_blk.address_space_id != |
641 | ACPI_ADR_SPACE_SYSTEM_IO) | ||
665 | return 0; | 642 | return 0; |
666 | 643 | ||
667 | pmtmr_ioport = fadt->xpm_tmr_blk.address; | 644 | pmtmr_ioport = fadt->xpm_tmr_blk.address; |
@@ -670,16 +647,15 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) | |||
670 | pmtmr_ioport = fadt->V1_pm_tmr_blk; | 647 | pmtmr_ioport = fadt->V1_pm_tmr_blk; |
671 | } | 648 | } |
672 | if (pmtmr_ioport) | 649 | if (pmtmr_ioport) |
673 | printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport); | 650 | printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", |
651 | pmtmr_ioport); | ||
674 | #endif | 652 | #endif |
675 | return 0; | 653 | return 0; |
676 | } | 654 | } |
677 | 655 | ||
678 | 656 | unsigned long __init acpi_find_rsdp(void) | |
679 | unsigned long __init | ||
680 | acpi_find_rsdp (void) | ||
681 | { | 657 | { |
682 | unsigned long rsdp_phys = 0; | 658 | unsigned long rsdp_phys = 0; |
683 | 659 | ||
684 | if (efi_enabled) { | 660 | if (efi_enabled) { |
685 | if (efi.acpi20) | 661 | if (efi.acpi20) |
@@ -691,9 +667,9 @@ acpi_find_rsdp (void) | |||
691 | * Scan memory looking for the RSDP signature. First search EBDA (low | 667 | * Scan memory looking for the RSDP signature. First search EBDA (low |
692 | * memory) paragraphs and then search upper memory (E0000-FFFFF). | 668 | * memory) paragraphs and then search upper memory (E0000-FFFFF). |
693 | */ | 669 | */ |
694 | rsdp_phys = acpi_scan_rsdp (0, 0x400); | 670 | rsdp_phys = acpi_scan_rsdp(0, 0x400); |
695 | if (!rsdp_phys) | 671 | if (!rsdp_phys) |
696 | rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); | 672 | rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000); |
697 | 673 | ||
698 | return rsdp_phys; | 674 | return rsdp_phys; |
699 | } | 675 | } |
@@ -703,8 +679,7 @@ acpi_find_rsdp (void) | |||
703 | * Parse LAPIC entries in MADT | 679 | * Parse LAPIC entries in MADT |
704 | * returns 0 on success, < 0 on error | 680 | * returns 0 on success, < 0 on error |
705 | */ | 681 | */ |
706 | static int __init | 682 | static int __init acpi_parse_madt_lapic_entries(void) |
707 | acpi_parse_madt_lapic_entries(void) | ||
708 | { | 683 | { |
709 | int count; | 684 | int count; |
710 | 685 | ||
@@ -713,28 +688,31 @@ acpi_parse_madt_lapic_entries(void) | |||
713 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). | 688 | * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). |
714 | */ | 689 | */ |
715 | 690 | ||
716 | count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); | 691 | count = |
692 | acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, | ||
693 | acpi_parse_lapic_addr_ovr, 0); | ||
717 | if (count < 0) { | 694 | if (count < 0) { |
718 | printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); | 695 | printk(KERN_ERR PREFIX |
696 | "Error parsing LAPIC address override entry\n"); | ||
719 | return count; | 697 | return count; |
720 | } | 698 | } |
721 | 699 | ||
722 | mp_register_lapic_address(acpi_lapic_addr); | 700 | mp_register_lapic_address(acpi_lapic_addr); |
723 | 701 | ||
724 | count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, | 702 | count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, |
725 | MAX_APICS); | 703 | MAX_APICS); |
726 | if (!count) { | 704 | if (!count) { |
727 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); | 705 | printk(KERN_ERR PREFIX "No LAPIC entries present\n"); |
728 | /* TBD: Cleanup to allow fallback to MPS */ | 706 | /* TBD: Cleanup to allow fallback to MPS */ |
729 | return -ENODEV; | 707 | return -ENODEV; |
730 | } | 708 | } else if (count < 0) { |
731 | else if (count < 0) { | ||
732 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); | 709 | printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); |
733 | /* TBD: Cleanup to allow fallback to MPS */ | 710 | /* TBD: Cleanup to allow fallback to MPS */ |
734 | return count; | 711 | return count; |
735 | } | 712 | } |
736 | 713 | ||
737 | count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); | 714 | count = |
715 | acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); | ||
738 | if (count < 0) { | 716 | if (count < 0) { |
739 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); | 717 | printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); |
740 | /* TBD: Cleanup to allow fallback to MPS */ | 718 | /* TBD: Cleanup to allow fallback to MPS */ |
@@ -742,15 +720,14 @@ acpi_parse_madt_lapic_entries(void) | |||
742 | } | 720 | } |
743 | return 0; | 721 | return 0; |
744 | } | 722 | } |
745 | #endif /* CONFIG_X86_LOCAL_APIC */ | 723 | #endif /* CONFIG_X86_LOCAL_APIC */ |
746 | 724 | ||
747 | #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) | 725 | #ifdef CONFIG_X86_IO_APIC |
748 | /* | 726 | /* |
749 | * Parse IOAPIC related entries in MADT | 727 | * Parse IOAPIC related entries in MADT |
750 | * returns 0 on success, < 0 on error | 728 | * returns 0 on success, < 0 on error |
751 | */ | 729 | */ |
752 | static int __init | 730 | static int __init acpi_parse_madt_ioapic_entries(void) |
753 | acpi_parse_madt_ioapic_entries(void) | ||
754 | { | 731 | { |
755 | int count; | 732 | int count; |
756 | 733 | ||
@@ -762,30 +739,34 @@ acpi_parse_madt_ioapic_entries(void) | |||
762 | */ | 739 | */ |
763 | if (acpi_disabled || acpi_noirq) { | 740 | if (acpi_disabled || acpi_noirq) { |
764 | return -ENODEV; | 741 | return -ENODEV; |
765 | } | 742 | } |
766 | 743 | ||
767 | /* | 744 | /* |
768 | * if "noapic" boot option, don't look for IO-APICs | 745 | * if "noapic" boot option, don't look for IO-APICs |
769 | */ | 746 | */ |
770 | if (skip_ioapic_setup) { | 747 | if (skip_ioapic_setup) { |
771 | printk(KERN_INFO PREFIX "Skipping IOAPIC probe " | 748 | printk(KERN_INFO PREFIX "Skipping IOAPIC probe " |
772 | "due to 'noapic' option.\n"); | 749 | "due to 'noapic' option.\n"); |
773 | return -ENODEV; | 750 | return -ENODEV; |
774 | } | 751 | } |
775 | 752 | ||
776 | count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); | 753 | count = |
754 | acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, | ||
755 | MAX_IO_APICS); | ||
777 | if (!count) { | 756 | if (!count) { |
778 | printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); | 757 | printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); |
779 | return -ENODEV; | 758 | return -ENODEV; |
780 | } | 759 | } else if (count < 0) { |
781 | else if (count < 0) { | ||
782 | printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); | 760 | printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); |
783 | return count; | 761 | return count; |
784 | } | 762 | } |
785 | 763 | ||
786 | count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); | 764 | count = |
765 | acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, | ||
766 | NR_IRQ_VECTORS); | ||
787 | if (count < 0) { | 767 | if (count < 0) { |
788 | printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); | 768 | printk(KERN_ERR PREFIX |
769 | "Error parsing interrupt source overrides entry\n"); | ||
789 | /* TBD: Cleanup to allow fallback to MPS */ | 770 | /* TBD: Cleanup to allow fallback to MPS */ |
790 | return count; | 771 | return count; |
791 | } | 772 | } |
@@ -800,7 +781,9 @@ acpi_parse_madt_ioapic_entries(void) | |||
800 | /* Fill in identity legacy mapings where no override */ | 781 | /* Fill in identity legacy mapings where no override */ |
801 | mp_config_acpi_legacy_irqs(); | 782 | mp_config_acpi_legacy_irqs(); |
802 | 783 | ||
803 | count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); | 784 | count = |
785 | acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, | ||
786 | NR_IRQ_VECTORS); | ||
804 | if (count < 0) { | 787 | if (count < 0) { |
805 | printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); | 788 | printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); |
806 | /* TBD: Cleanup to allow fallback to MPS */ | 789 | /* TBD: Cleanup to allow fallback to MPS */ |
@@ -814,11 +797,9 @@ static inline int acpi_parse_madt_ioapic_entries(void) | |||
814 | { | 797 | { |
815 | return -1; | 798 | return -1; |
816 | } | 799 | } |
817 | #endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */ | 800 | #endif /* !CONFIG_X86_IO_APIC */ |
818 | |||
819 | 801 | ||
820 | static void __init | 802 | static void __init acpi_process_madt(void) |
821 | acpi_process_madt(void) | ||
822 | { | 803 | { |
823 | #ifdef CONFIG_X86_LOCAL_APIC | 804 | #ifdef CONFIG_X86_LOCAL_APIC |
824 | int count, error; | 805 | int count, error; |
@@ -833,6 +814,9 @@ acpi_process_madt(void) | |||
833 | if (!error) { | 814 | if (!error) { |
834 | acpi_lapic = 1; | 815 | acpi_lapic = 1; |
835 | 816 | ||
817 | #ifdef CONFIG_X86_GENERICARCH | ||
818 | generic_bigsmp_probe(); | ||
819 | #endif | ||
836 | /* | 820 | /* |
837 | * Parse MADT IO-APIC entries | 821 | * Parse MADT IO-APIC entries |
838 | */ | 822 | */ |
@@ -850,7 +834,8 @@ acpi_process_madt(void) | |||
850 | /* | 834 | /* |
851 | * Dell Precision Workstation 410, 610 come here. | 835 | * Dell Precision Workstation 410, 610 come here. |
852 | */ | 836 | */ |
853 | printk(KERN_ERR PREFIX "Invalid BIOS MADT, disabling ACPI\n"); | 837 | printk(KERN_ERR PREFIX |
838 | "Invalid BIOS MADT, disabling ACPI\n"); | ||
854 | disable_acpi(); | 839 | disable_acpi(); |
855 | } | 840 | } |
856 | } | 841 | } |
@@ -862,7 +847,6 @@ extern int acpi_force; | |||
862 | 847 | ||
863 | #ifdef __i386__ | 848 | #ifdef __i386__ |
864 | 849 | ||
865 | #ifdef CONFIG_ACPI_PCI | ||
866 | static int __init disable_acpi_irq(struct dmi_system_id *d) | 850 | static int __init disable_acpi_irq(struct dmi_system_id *d) |
867 | { | 851 | { |
868 | if (!acpi_force) { | 852 | if (!acpi_force) { |
@@ -882,12 +866,11 @@ static int __init disable_acpi_pci(struct dmi_system_id *d) | |||
882 | } | 866 | } |
883 | return 0; | 867 | return 0; |
884 | } | 868 | } |
885 | #endif | ||
886 | 869 | ||
887 | static int __init dmi_disable_acpi(struct dmi_system_id *d) | 870 | static int __init dmi_disable_acpi(struct dmi_system_id *d) |
888 | { | 871 | { |
889 | if (!acpi_force) { | 872 | if (!acpi_force) { |
890 | printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); | 873 | printk(KERN_NOTICE "%s detected: acpi off\n", d->ident); |
891 | disable_acpi(); | 874 | disable_acpi(); |
892 | } else { | 875 | } else { |
893 | printk(KERN_NOTICE | 876 | printk(KERN_NOTICE |
@@ -902,7 +885,8 @@ static int __init dmi_disable_acpi(struct dmi_system_id *d) | |||
902 | static int __init force_acpi_ht(struct dmi_system_id *d) | 885 | static int __init force_acpi_ht(struct dmi_system_id *d) |
903 | { | 886 | { |
904 | if (!acpi_force) { | 887 | if (!acpi_force) { |
905 | printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); | 888 | printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", |
889 | d->ident); | ||
906 | disable_acpi(); | 890 | disable_acpi(); |
907 | acpi_ht = 1; | 891 | acpi_ht = 1; |
908 | } else { | 892 | } else { |
@@ -921,155 +905,155 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
921 | * Boxes that need ACPI disabled | 905 | * Boxes that need ACPI disabled |
922 | */ | 906 | */ |
923 | { | 907 | { |
924 | .callback = dmi_disable_acpi, | 908 | .callback = dmi_disable_acpi, |
925 | .ident = "IBM Thinkpad", | 909 | .ident = "IBM Thinkpad", |
926 | .matches = { | 910 | .matches = { |
927 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | 911 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
928 | DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), | 912 | DMI_MATCH(DMI_BOARD_NAME, "2629H1G"), |
929 | }, | 913 | }, |
930 | }, | 914 | }, |
931 | 915 | ||
932 | /* | 916 | /* |
933 | * Boxes that need acpi=ht | 917 | * Boxes that need acpi=ht |
934 | */ | 918 | */ |
935 | { | 919 | { |
936 | .callback = force_acpi_ht, | 920 | .callback = force_acpi_ht, |
937 | .ident = "FSC Primergy T850", | 921 | .ident = "FSC Primergy T850", |
938 | .matches = { | 922 | .matches = { |
939 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 923 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
940 | DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), | 924 | DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), |
941 | }, | 925 | }, |
942 | }, | 926 | }, |
943 | { | 927 | { |
944 | .callback = force_acpi_ht, | 928 | .callback = force_acpi_ht, |
945 | .ident = "DELL GX240", | 929 | .ident = "DELL GX240", |
946 | .matches = { | 930 | .matches = { |
947 | DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), | 931 | DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), |
948 | DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), | 932 | DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), |
949 | }, | 933 | }, |
950 | }, | 934 | }, |
951 | { | 935 | { |
952 | .callback = force_acpi_ht, | 936 | .callback = force_acpi_ht, |
953 | .ident = "HP VISUALIZE NT Workstation", | 937 | .ident = "HP VISUALIZE NT Workstation", |
954 | .matches = { | 938 | .matches = { |
955 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 939 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
956 | DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), | 940 | DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"), |
957 | }, | 941 | }, |
958 | }, | 942 | }, |
959 | { | 943 | { |
960 | .callback = force_acpi_ht, | 944 | .callback = force_acpi_ht, |
961 | .ident = "Compaq Workstation W8000", | 945 | .ident = "Compaq Workstation W8000", |
962 | .matches = { | 946 | .matches = { |
963 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 947 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
964 | DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), | 948 | DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"), |
965 | }, | 949 | }, |
966 | }, | 950 | }, |
967 | { | 951 | { |
968 | .callback = force_acpi_ht, | 952 | .callback = force_acpi_ht, |
969 | .ident = "ASUS P4B266", | 953 | .ident = "ASUS P4B266", |
970 | .matches = { | 954 | .matches = { |
971 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 955 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
972 | DMI_MATCH(DMI_BOARD_NAME, "P4B266"), | 956 | DMI_MATCH(DMI_BOARD_NAME, "P4B266"), |
973 | }, | 957 | }, |
974 | }, | 958 | }, |
975 | { | 959 | { |
976 | .callback = force_acpi_ht, | 960 | .callback = force_acpi_ht, |
977 | .ident = "ASUS P2B-DS", | 961 | .ident = "ASUS P2B-DS", |
978 | .matches = { | 962 | .matches = { |
979 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 963 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
980 | DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), | 964 | DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"), |
981 | }, | 965 | }, |
982 | }, | 966 | }, |
983 | { | 967 | { |
984 | .callback = force_acpi_ht, | 968 | .callback = force_acpi_ht, |
985 | .ident = "ASUS CUR-DLS", | 969 | .ident = "ASUS CUR-DLS", |
986 | .matches = { | 970 | .matches = { |
987 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 971 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
988 | DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), | 972 | DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"), |
989 | }, | 973 | }, |
990 | }, | 974 | }, |
991 | { | 975 | { |
992 | .callback = force_acpi_ht, | 976 | .callback = force_acpi_ht, |
993 | .ident = "ABIT i440BX-W83977", | 977 | .ident = "ABIT i440BX-W83977", |
994 | .matches = { | 978 | .matches = { |
995 | DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"), | 979 | DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"), |
996 | DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), | 980 | DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"), |
997 | }, | 981 | }, |
998 | }, | 982 | }, |
999 | { | 983 | { |
1000 | .callback = force_acpi_ht, | 984 | .callback = force_acpi_ht, |
1001 | .ident = "IBM Bladecenter", | 985 | .ident = "IBM Bladecenter", |
1002 | .matches = { | 986 | .matches = { |
1003 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | 987 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
1004 | DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), | 988 | DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"), |
1005 | }, | 989 | }, |
1006 | }, | 990 | }, |
1007 | { | 991 | { |
1008 | .callback = force_acpi_ht, | 992 | .callback = force_acpi_ht, |
1009 | .ident = "IBM eServer xSeries 360", | 993 | .ident = "IBM eServer xSeries 360", |
1010 | .matches = { | 994 | .matches = { |
1011 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | 995 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
1012 | DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), | 996 | DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"), |
1013 | }, | 997 | }, |
1014 | }, | 998 | }, |
1015 | { | 999 | { |
1016 | .callback = force_acpi_ht, | 1000 | .callback = force_acpi_ht, |
1017 | .ident = "IBM eserver xSeries 330", | 1001 | .ident = "IBM eserver xSeries 330", |
1018 | .matches = { | 1002 | .matches = { |
1019 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | 1003 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
1020 | DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), | 1004 | DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"), |
1021 | }, | 1005 | }, |
1022 | }, | 1006 | }, |
1023 | { | 1007 | { |
1024 | .callback = force_acpi_ht, | 1008 | .callback = force_acpi_ht, |
1025 | .ident = "IBM eserver xSeries 440", | 1009 | .ident = "IBM eserver xSeries 440", |
1026 | .matches = { | 1010 | .matches = { |
1027 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), | 1011 | DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), |
1028 | DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), | 1012 | DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"), |
1029 | }, | 1013 | }, |
1030 | }, | 1014 | }, |
1031 | 1015 | ||
1032 | #ifdef CONFIG_ACPI_PCI | ||
1033 | /* | 1016 | /* |
1034 | * Boxes that need ACPI PCI IRQ routing disabled | 1017 | * Boxes that need ACPI PCI IRQ routing disabled |
1035 | */ | 1018 | */ |
1036 | { | 1019 | { |
1037 | .callback = disable_acpi_irq, | 1020 | .callback = disable_acpi_irq, |
1038 | .ident = "ASUS A7V", | 1021 | .ident = "ASUS A7V", |
1039 | .matches = { | 1022 | .matches = { |
1040 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), | 1023 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"), |
1041 | DMI_MATCH(DMI_BOARD_NAME, "<A7V>"), | 1024 | DMI_MATCH(DMI_BOARD_NAME, "<A7V>"), |
1042 | /* newer BIOS, Revision 1011, does work */ | 1025 | /* newer BIOS, Revision 1011, does work */ |
1043 | DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"), | 1026 | DMI_MATCH(DMI_BIOS_VERSION, |
1044 | }, | 1027 | "ASUS A7V ACPI BIOS Revision 1007"), |
1045 | }, | 1028 | }, |
1029 | }, | ||
1046 | 1030 | ||
1047 | /* | 1031 | /* |
1048 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled | 1032 | * Boxes that need ACPI PCI IRQ routing and PCI scan disabled |
1049 | */ | 1033 | */ |
1050 | { /* _BBN 0 bug */ | 1034 | { /* _BBN 0 bug */ |
1051 | .callback = disable_acpi_pci, | 1035 | .callback = disable_acpi_pci, |
1052 | .ident = "ASUS PR-DLS", | 1036 | .ident = "ASUS PR-DLS", |
1053 | .matches = { | 1037 | .matches = { |
1054 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | 1038 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), |
1055 | DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), | 1039 | DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"), |
1056 | DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"), | 1040 | DMI_MATCH(DMI_BIOS_VERSION, |
1057 | DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") | 1041 | "ASUS PR-DLS ACPI BIOS Revision 1010"), |
1058 | }, | 1042 | DMI_MATCH(DMI_BIOS_DATE, "03/21/2003") |
1059 | }, | 1043 | }, |
1044 | }, | ||
1060 | { | 1045 | { |
1061 | .callback = disable_acpi_pci, | 1046 | .callback = disable_acpi_pci, |
1062 | .ident = "Acer TravelMate 36x Laptop", | 1047 | .ident = "Acer TravelMate 36x Laptop", |
1063 | .matches = { | 1048 | .matches = { |
1064 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 1049 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
1065 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), | 1050 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
1066 | }, | 1051 | }, |
1067 | }, | 1052 | }, |
1068 | #endif | 1053 | {} |
1069 | { } | ||
1070 | }; | 1054 | }; |
1071 | 1055 | ||
1072 | #endif /* __i386__ */ | 1056 | #endif /* __i386__ */ |
1073 | 1057 | ||
1074 | /* | 1058 | /* |
1075 | * acpi_boot_table_init() and acpi_boot_init() | 1059 | * acpi_boot_table_init() and acpi_boot_init() |
@@ -1094,8 +1078,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
1094 | * !0: failure | 1078 | * !0: failure |
1095 | */ | 1079 | */ |
1096 | 1080 | ||
1097 | int __init | 1081 | int __init acpi_boot_table_init(void) |
1098 | acpi_boot_table_init(void) | ||
1099 | { | 1082 | { |
1100 | int error; | 1083 | int error; |
1101 | 1084 | ||
@@ -1108,7 +1091,7 @@ acpi_boot_table_init(void) | |||
1108 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1091 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
1109 | */ | 1092 | */ |
1110 | if (acpi_disabled && !acpi_ht) | 1093 | if (acpi_disabled && !acpi_ht) |
1111 | return 1; | 1094 | return 1; |
1112 | 1095 | ||
1113 | /* | 1096 | /* |
1114 | * Initialize the ACPI boot-time table parser. | 1097 | * Initialize the ACPI boot-time table parser. |
@@ -1118,7 +1101,6 @@ acpi_boot_table_init(void) | |||
1118 | disable_acpi(); | 1101 | disable_acpi(); |
1119 | return error; | 1102 | return error; |
1120 | } | 1103 | } |
1121 | |||
1122 | #ifdef __i386__ | 1104 | #ifdef __i386__ |
1123 | check_acpi_pci(); | 1105 | check_acpi_pci(); |
1124 | #endif | 1106 | #endif |
@@ -1142,7 +1124,6 @@ acpi_boot_table_init(void) | |||
1142 | return 0; | 1124 | return 0; |
1143 | } | 1125 | } |
1144 | 1126 | ||
1145 | |||
1146 | int __init acpi_boot_init(void) | 1127 | int __init acpi_boot_init(void) |
1147 | { | 1128 | { |
1148 | /* | 1129 | /* |
@@ -1150,7 +1131,7 @@ int __init acpi_boot_init(void) | |||
1150 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1131 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
1151 | */ | 1132 | */ |
1152 | if (acpi_disabled && !acpi_ht) | 1133 | if (acpi_disabled && !acpi_ht) |
1153 | return 1; | 1134 | return 1; |
1154 | 1135 | ||
1155 | acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); | 1136 | acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); |
1156 | 1137 | ||
@@ -1168,4 +1149,3 @@ int __init acpi_boot_init(void) | |||
1168 | 1149 | ||
1169 | return 0; | 1150 | return 0; |
1170 | } | 1151 | } |
1171 | |||
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 726a5ca4b165..f1b9d2a46dab 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c | |||
@@ -8,44 +8,44 @@ | |||
8 | #include <asm/pci-direct.h> | 8 | #include <asm/pci-direct.h> |
9 | #include <asm/acpi.h> | 9 | #include <asm/acpi.h> |
10 | 10 | ||
11 | static int __init check_bridge(int vendor, int device) | 11 | static int __init check_bridge(int vendor, int device) |
12 | { | 12 | { |
13 | /* According to Nvidia all timer overrides are bogus. Just ignore | 13 | /* According to Nvidia all timer overrides are bogus. Just ignore |
14 | them all. */ | 14 | them all. */ |
15 | if (vendor == PCI_VENDOR_ID_NVIDIA) { | 15 | if (vendor == PCI_VENDOR_ID_NVIDIA) { |
16 | acpi_skip_timer_override = 1; | 16 | acpi_skip_timer_override = 1; |
17 | } | 17 | } |
18 | return 0; | 18 | return 0; |
19 | } | 19 | } |
20 | 20 | ||
21 | void __init check_acpi_pci(void) | 21 | void __init check_acpi_pci(void) |
22 | { | 22 | { |
23 | int num,slot,func; | 23 | int num, slot, func; |
24 | 24 | ||
25 | /* Assume the machine supports type 1. If not it will | 25 | /* Assume the machine supports type 1. If not it will |
26 | always read ffffffff and should not have any side effect. */ | 26 | always read ffffffff and should not have any side effect. */ |
27 | 27 | ||
28 | /* Poor man's PCI discovery */ | 28 | /* Poor man's PCI discovery */ |
29 | for (num = 0; num < 32; num++) { | 29 | for (num = 0; num < 32; num++) { |
30 | for (slot = 0; slot < 32; slot++) { | 30 | for (slot = 0; slot < 32; slot++) { |
31 | for (func = 0; func < 8; func++) { | 31 | for (func = 0; func < 8; func++) { |
32 | u32 class; | 32 | u32 class; |
33 | u32 vendor; | 33 | u32 vendor; |
34 | class = read_pci_config(num,slot,func, | 34 | class = read_pci_config(num, slot, func, |
35 | PCI_CLASS_REVISION); | 35 | PCI_CLASS_REVISION); |
36 | if (class == 0xffffffff) | 36 | if (class == 0xffffffff) |
37 | break; | 37 | break; |
38 | 38 | ||
39 | if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) | 39 | if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) |
40 | continue; | 40 | continue; |
41 | 41 | ||
42 | vendor = read_pci_config(num, slot, func, | 42 | vendor = read_pci_config(num, slot, func, |
43 | PCI_VENDOR_ID); | 43 | PCI_VENDOR_ID); |
44 | 44 | ||
45 | if (check_bridge(vendor&0xffff, vendor >> 16)) | 45 | if (check_bridge(vendor & 0xffff, vendor >> 16)) |
46 | return; | 46 | return; |
47 | } | 47 | } |
48 | 48 | ||
49 | } | 49 | } |
50 | } | 50 | } |
51 | } | 51 | } |
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c index c1af93032ff3..1cb2b186a3af 100644 --- a/arch/i386/kernel/acpi/sleep.c +++ b/arch/i386/kernel/acpi/sleep.c | |||
@@ -20,12 +20,13 @@ extern void zap_low_mappings(void); | |||
20 | 20 | ||
21 | extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); | 21 | extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); |
22 | 22 | ||
23 | static void init_low_mapping(pgd_t *pgd, int pgd_limit) | 23 | static void init_low_mapping(pgd_t * pgd, int pgd_limit) |
24 | { | 24 | { |
25 | int pgd_ofs = 0; | 25 | int pgd_ofs = 0; |
26 | 26 | ||
27 | while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { | 27 | while ((pgd_ofs < pgd_limit) |
28 | set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD)); | 28 | && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { |
29 | set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD)); | ||
29 | pgd_ofs++, pgd++; | 30 | pgd_ofs++, pgd++; |
30 | } | 31 | } |
31 | flush_tlb_all(); | 32 | flush_tlb_all(); |
@@ -37,12 +38,13 @@ static void init_low_mapping(pgd_t *pgd, int pgd_limit) | |||
37 | * Create an identity mapped page table and copy the wakeup routine to | 38 | * Create an identity mapped page table and copy the wakeup routine to |
38 | * low memory. | 39 | * low memory. |
39 | */ | 40 | */ |
40 | int acpi_save_state_mem (void) | 41 | int acpi_save_state_mem(void) |
41 | { | 42 | { |
42 | if (!acpi_wakeup_address) | 43 | if (!acpi_wakeup_address) |
43 | return 1; | 44 | return 1; |
44 | init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); | 45 | init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD); |
45 | memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); | 46 | memcpy((void *)acpi_wakeup_address, &wakeup_start, |
47 | &wakeup_end - &wakeup_start); | ||
46 | acpi_copy_wakeup_routine(acpi_wakeup_address); | 48 | acpi_copy_wakeup_routine(acpi_wakeup_address); |
47 | 49 | ||
48 | return 0; | 50 | return 0; |
@@ -51,7 +53,7 @@ int acpi_save_state_mem (void) | |||
51 | /* | 53 | /* |
52 | * acpi_restore_state - undo effects of acpi_save_state_mem | 54 | * acpi_restore_state - undo effects of acpi_save_state_mem |
53 | */ | 55 | */ |
54 | void acpi_restore_state_mem (void) | 56 | void acpi_restore_state_mem(void) |
55 | { | 57 | { |
56 | zap_low_mappings(); | 58 | zap_low_mappings(); |
57 | } | 59 | } |
@@ -67,7 +69,8 @@ void acpi_restore_state_mem (void) | |||
67 | void __init acpi_reserve_bootmem(void) | 69 | void __init acpi_reserve_bootmem(void) |
68 | { | 70 | { |
69 | if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) { | 71 | if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) { |
70 | printk(KERN_ERR "ACPI: Wakeup code way too big, S3 disabled.\n"); | 72 | printk(KERN_ERR |
73 | "ACPI: Wakeup code way too big, S3 disabled.\n"); | ||
71 | return; | 74 | return; |
72 | } | 75 | } |
73 | 76 | ||
@@ -90,10 +93,8 @@ static int __init acpi_sleep_setup(char *str) | |||
90 | return 1; | 93 | return 1; |
91 | } | 94 | } |
92 | 95 | ||
93 | |||
94 | __setup("acpi_sleep=", acpi_sleep_setup); | 96 | __setup("acpi_sleep=", acpi_sleep_setup); |
95 | 97 | ||
96 | |||
97 | static __init int reset_videomode_after_s3(struct dmi_system_id *d) | 98 | static __init int reset_videomode_after_s3(struct dmi_system_id *d) |
98 | { | 99 | { |
99 | acpi_video_flags |= 2; | 100 | acpi_video_flags |= 2; |
@@ -101,14 +102,14 @@ static __init int reset_videomode_after_s3(struct dmi_system_id *d) | |||
101 | } | 102 | } |
102 | 103 | ||
103 | static __initdata struct dmi_system_id acpisleep_dmi_table[] = { | 104 | static __initdata struct dmi_system_id acpisleep_dmi_table[] = { |
104 | { /* Reset video mode after returning from ACPI S3 sleep */ | 105 | { /* Reset video mode after returning from ACPI S3 sleep */ |
105 | .callback = reset_videomode_after_s3, | 106 | .callback = reset_videomode_after_s3, |
106 | .ident = "Toshiba Satellite 4030cdt", | 107 | .ident = "Toshiba Satellite 4030cdt", |
107 | .matches = { | 108 | .matches = { |
108 | DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), | 109 | DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), |
109 | }, | 110 | }, |
110 | }, | 111 | }, |
111 | { } | 112 | {} |
112 | }; | 113 | }; |
113 | 114 | ||
114 | static int __init acpisleep_dmi_init(void) | 115 | static int __init acpisleep_dmi_init(void) |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 4553ffd94b1f..46ce9b248f55 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -613,8 +613,8 @@ void __devinit cpu_init(void) | |||
613 | memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu), | 613 | memcpy(thread->tls_array, &per_cpu(cpu_gdt_table, cpu), |
614 | GDT_ENTRY_TLS_ENTRIES * 8); | 614 | GDT_ENTRY_TLS_ENTRIES * 8); |
615 | 615 | ||
616 | __asm__ __volatile__("lgdt %0" : : "m" (cpu_gdt_descr[cpu])); | 616 | load_gdt(&cpu_gdt_descr[cpu]); |
617 | __asm__ __volatile__("lidt %0" : : "m" (idt_descr)); | 617 | load_idt(&idt_descr); |
618 | 618 | ||
619 | /* | 619 | /* |
620 | * Delete NT | 620 | * Delete NT |
@@ -642,12 +642,12 @@ void __devinit cpu_init(void) | |||
642 | asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); | 642 | asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); |
643 | 643 | ||
644 | /* Clear all 6 debug registers: */ | 644 | /* Clear all 6 debug registers: */ |
645 | 645 | set_debugreg(0, 0); | |
646 | #define CD(register) set_debugreg(0, register) | 646 | set_debugreg(0, 1); |
647 | 647 | set_debugreg(0, 2); | |
648 | CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7); | 648 | set_debugreg(0, 3); |
649 | 649 | set_debugreg(0, 6); | |
650 | #undef CD | 650 | set_debugreg(0, 7); |
651 | 651 | ||
652 | /* | 652 | /* |
653 | * Force FPU initialization: | 653 | * Force FPU initialization: |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 60a9e54dd20e..822c8ce9d1f1 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/cpufreq.h> | 31 | #include <linux/cpufreq.h> |
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/compiler.h> | ||
34 | #include <asm/io.h> | 35 | #include <asm/io.h> |
35 | #include <asm/delay.h> | 36 | #include <asm/delay.h> |
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
@@ -57,6 +58,8 @@ static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; | |||
57 | 58 | ||
58 | static struct cpufreq_driver acpi_cpufreq_driver; | 59 | static struct cpufreq_driver acpi_cpufreq_driver; |
59 | 60 | ||
61 | static unsigned int acpi_pstate_strict; | ||
62 | |||
60 | static int | 63 | static int |
61 | acpi_processor_write_port( | 64 | acpi_processor_write_port( |
62 | u16 port, | 65 | u16 port, |
@@ -163,34 +166,44 @@ acpi_processor_set_performance ( | |||
163 | } | 166 | } |
164 | 167 | ||
165 | /* | 168 | /* |
166 | * Then we read the 'status_register' and compare the value with the | 169 | * Assume the write went through when acpi_pstate_strict is not used. |
167 | * target state's 'status' to make sure the transition was successful. | 170 | * As read status_register is an expensive operation and there |
168 | * Note that we'll poll for up to 1ms (100 cycles of 10us) before | 171 | * are no specific error cases where an IO port write will fail. |
169 | * giving up. | ||
170 | */ | 172 | */ |
171 | 173 | if (acpi_pstate_strict) { | |
172 | port = data->acpi_data.status_register.address; | 174 | /* Then we read the 'status_register' and compare the value |
173 | bit_width = data->acpi_data.status_register.bit_width; | 175 | * with the target state's 'status' to make sure the |
174 | 176 | * transition was successful. | |
175 | dprintk("Looking for 0x%08x from port 0x%04x\n", | 177 | * Note that we'll poll for up to 1ms (100 cycles of 10us) |
176 | (u32) data->acpi_data.states[state].status, port); | 178 | * before giving up. |
177 | 179 | */ | |
178 | for (i=0; i<100; i++) { | 180 | |
179 | ret = acpi_processor_read_port(port, bit_width, &value); | 181 | port = data->acpi_data.status_register.address; |
180 | if (ret) { | 182 | bit_width = data->acpi_data.status_register.bit_width; |
181 | dprintk("Invalid port width 0x%04x\n", bit_width); | 183 | |
182 | retval = ret; | 184 | dprintk("Looking for 0x%08x from port 0x%04x\n", |
183 | goto migrate_end; | 185 | (u32) data->acpi_data.states[state].status, port); |
186 | |||
187 | for (i=0; i<100; i++) { | ||
188 | ret = acpi_processor_read_port(port, bit_width, &value); | ||
189 | if (ret) { | ||
190 | dprintk("Invalid port width 0x%04x\n", bit_width); | ||
191 | retval = ret; | ||
192 | goto migrate_end; | ||
193 | } | ||
194 | if (value == (u32) data->acpi_data.states[state].status) | ||
195 | break; | ||
196 | udelay(10); | ||
184 | } | 197 | } |
185 | if (value == (u32) data->acpi_data.states[state].status) | 198 | } else { |
186 | break; | 199 | i = 0; |
187 | udelay(10); | 200 | value = (u32) data->acpi_data.states[state].status; |
188 | } | 201 | } |
189 | 202 | ||
190 | /* notify cpufreq */ | 203 | /* notify cpufreq */ |
191 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); | 204 | cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); |
192 | 205 | ||
193 | if (value != (u32) data->acpi_data.states[state].status) { | 206 | if (unlikely(value != (u32) data->acpi_data.states[state].status)) { |
194 | unsigned int tmp = cpufreq_freqs.new; | 207 | unsigned int tmp = cpufreq_freqs.new; |
195 | cpufreq_freqs.new = cpufreq_freqs.old; | 208 | cpufreq_freqs.new = cpufreq_freqs.old; |
196 | cpufreq_freqs.old = tmp; | 209 | cpufreq_freqs.old = tmp; |
@@ -537,6 +550,8 @@ acpi_cpufreq_exit (void) | |||
537 | return; | 550 | return; |
538 | } | 551 | } |
539 | 552 | ||
553 | module_param(acpi_pstate_strict, uint, 0644); | ||
554 | MODULE_PARM_DESC(acpi_pstate_strict, "value 0 or non-zero. non-zero -> strict ACPI checks are performed during frequency changes."); | ||
540 | 555 | ||
541 | late_initcall(acpi_cpufreq_init); | 556 | late_initcall(acpi_cpufreq_init); |
542 | module_exit(acpi_cpufreq_exit); | 557 | module_exit(acpi_cpufreq_exit); |
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 06aa76049b80..8ef38544453c 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c | |||
@@ -64,8 +64,6 @@ static int dont_scale_voltage; | |||
64 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) | 64 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) |
65 | 65 | ||
66 | 66 | ||
67 | #define __hlt() __asm__ __volatile__("hlt": : :"memory") | ||
68 | |||
69 | /* Clock ratios multiplied by 10 */ | 67 | /* Clock ratios multiplied by 10 */ |
70 | static int clock_ratio[32]; | 68 | static int clock_ratio[32]; |
71 | static int eblcr_table[32]; | 69 | static int eblcr_table[32]; |
@@ -168,11 +166,9 @@ static void do_powersaver(union msr_longhaul *longhaul, | |||
168 | outb(0xFE,0x21); /* TMR0 only */ | 166 | outb(0xFE,0x21); /* TMR0 only */ |
169 | outb(0xFF,0x80); /* delay */ | 167 | outb(0xFF,0x80); /* delay */ |
170 | 168 | ||
171 | local_irq_enable(); | 169 | safe_halt(); |
172 | |||
173 | __hlt(); | ||
174 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 170 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
175 | __hlt(); | 171 | halt(); |
176 | 172 | ||
177 | local_irq_disable(); | 173 | local_irq_disable(); |
178 | 174 | ||
@@ -251,9 +247,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index) | |||
251 | bcr2.bits.CLOCKMUL = clock_ratio_index; | 247 | bcr2.bits.CLOCKMUL = clock_ratio_index; |
252 | local_irq_disable(); | 248 | local_irq_disable(); |
253 | wrmsrl (MSR_VIA_BCR2, bcr2.val); | 249 | wrmsrl (MSR_VIA_BCR2, bcr2.val); |
254 | local_irq_enable(); | 250 | safe_halt(); |
255 | |||
256 | __hlt(); | ||
257 | 251 | ||
258 | /* Disable software clock multiplier */ | 252 | /* Disable software clock multiplier */ |
259 | rdmsrl (MSR_VIA_BCR2, bcr2.val); | 253 | rdmsrl (MSR_VIA_BCR2, bcr2.val); |
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index ba4b01138c8f..ff87cc22b323 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c | |||
@@ -132,11 +132,7 @@ static void __init set_cx86_memwb(void) | |||
132 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); | 132 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); |
133 | /* set 'Not Write-through' */ | 133 | /* set 'Not Write-through' */ |
134 | cr0 = 0x20000000; | 134 | cr0 = 0x20000000; |
135 | __asm__("movl %%cr0,%%eax\n\t" | 135 | write_cr0(read_cr0() | cr0); |
136 | "orl %0,%%eax\n\t" | ||
137 | "movl %%eax,%%cr0\n" | ||
138 | : : "r" (cr0) | ||
139 | :"ax"); | ||
140 | /* CCR2 bit 2: lock NW bit and set WT1 */ | 136 | /* CCR2 bit 2: lock NW bit and set WT1 */ |
141 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); | 137 | setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); |
142 | } | 138 | } |
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index a2c33c1a46c5..43601de0f633 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c | |||
@@ -82,16 +82,13 @@ static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) | |||
82 | */ | 82 | */ |
83 | static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) | 83 | static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) |
84 | { | 84 | { |
85 | unsigned int eax; | 85 | unsigned int eax, ebx, ecx, edx; |
86 | 86 | ||
87 | if (c->cpuid_level < 4) | 87 | if (c->cpuid_level < 4) |
88 | return 1; | 88 | return 1; |
89 | 89 | ||
90 | __asm__("cpuid" | 90 | /* Intel has a non-standard dependency on %ecx for this CPUID level. */ |
91 | : "=a" (eax) | 91 | cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); |
92 | : "0" (4), "c" (0) | ||
93 | : "bx", "dx"); | ||
94 | |||
95 | if (eax & 0x1f) | 92 | if (eax & 0x1f) |
96 | return ((eax >> 26) + 1); | 93 | return ((eax >> 26) + 1); |
97 | else | 94 | else |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 6c55b50cf048..9e0d5f83cb9f 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -305,6 +305,9 @@ static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |||
305 | { | 305 | { |
306 | struct _cpuid4_info *this_leaf; | 306 | struct _cpuid4_info *this_leaf; |
307 | unsigned long num_threads_sharing; | 307 | unsigned long num_threads_sharing; |
308 | #ifdef CONFIG_X86_HT | ||
309 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
310 | #endif | ||
308 | 311 | ||
309 | this_leaf = CPUID4_INFO_IDX(cpu, index); | 312 | this_leaf = CPUID4_INFO_IDX(cpu, index); |
310 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; | 313 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; |
@@ -314,10 +317,12 @@ static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |||
314 | #ifdef CONFIG_X86_HT | 317 | #ifdef CONFIG_X86_HT |
315 | else if (num_threads_sharing == smp_num_siblings) | 318 | else if (num_threads_sharing == smp_num_siblings) |
316 | this_leaf->shared_cpu_map = cpu_sibling_map[cpu]; | 319 | this_leaf->shared_cpu_map = cpu_sibling_map[cpu]; |
317 | #endif | 320 | else if (num_threads_sharing == (c->x86_num_cores * smp_num_siblings)) |
321 | this_leaf->shared_cpu_map = cpu_core_map[cpu]; | ||
318 | else | 322 | else |
319 | printk(KERN_INFO "Number of CPUs sharing cache didn't match " | 323 | printk(KERN_DEBUG "Number of CPUs sharing cache didn't match " |
320 | "any known set of CPUs\n"); | 324 | "any known set of CPUs\n"); |
325 | #endif | ||
321 | } | 326 | } |
322 | #else | 327 | #else |
323 | static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} | 328 | static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} |
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 764cac64e211..dd4ebd6af7e4 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -561,7 +561,7 @@ struct mtrr_value { | |||
561 | 561 | ||
562 | static struct mtrr_value * mtrr_state; | 562 | static struct mtrr_value * mtrr_state; |
563 | 563 | ||
564 | static int mtrr_save(struct sys_device * sysdev, u32 state) | 564 | static int mtrr_save(struct sys_device * sysdev, pm_message_t state) |
565 | { | 565 | { |
566 | int i; | 566 | int i; |
567 | int size = num_var_ranges * sizeof(struct mtrr_value); | 567 | int size = num_var_ranges * sizeof(struct mtrr_value); |
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index e5fab12f7926..913be77bb844 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c | |||
@@ -153,7 +153,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) | |||
153 | disable_local_APIC(); | 153 | disable_local_APIC(); |
154 | atomic_dec(&waiting_for_crash_ipi); | 154 | atomic_dec(&waiting_for_crash_ipi); |
155 | /* Assume hlt works */ | 155 | /* Assume hlt works */ |
156 | __asm__("hlt"); | 156 | halt(); |
157 | for(;;); | 157 | for(;;); |
158 | 158 | ||
159 | return 1; | 159 | return 1; |
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c index a3cdf894302b..58516e2ac172 100644 --- a/arch/i386/kernel/dmi_scan.c +++ b/arch/i386/kernel/dmi_scan.c | |||
@@ -6,32 +6,28 @@ | |||
6 | #include <linux/bootmem.h> | 6 | #include <linux/bootmem.h> |
7 | 7 | ||
8 | 8 | ||
9 | struct dmi_header { | ||
10 | u8 type; | ||
11 | u8 length; | ||
12 | u16 handle; | ||
13 | }; | ||
14 | |||
15 | #undef DMI_DEBUG | ||
16 | |||
17 | #ifdef DMI_DEBUG | ||
18 | #define dmi_printk(x) printk x | ||
19 | #else | ||
20 | #define dmi_printk(x) | ||
21 | #endif | ||
22 | |||
23 | static char * __init dmi_string(struct dmi_header *dm, u8 s) | 9 | static char * __init dmi_string(struct dmi_header *dm, u8 s) |
24 | { | 10 | { |
25 | u8 *bp = ((u8 *) dm) + dm->length; | 11 | u8 *bp = ((u8 *) dm) + dm->length; |
12 | char *str = ""; | ||
26 | 13 | ||
27 | if (!s) | 14 | if (s) { |
28 | return ""; | ||
29 | s--; | ||
30 | while (s > 0 && *bp) { | ||
31 | bp += strlen(bp) + 1; | ||
32 | s--; | 15 | s--; |
33 | } | 16 | while (s > 0 && *bp) { |
34 | return bp; | 17 | bp += strlen(bp) + 1; |
18 | s--; | ||
19 | } | ||
20 | |||
21 | if (*bp != 0) { | ||
22 | str = alloc_bootmem(strlen(bp) + 1); | ||
23 | if (str != NULL) | ||
24 | strcpy(str, bp); | ||
25 | else | ||
26 | printk(KERN_ERR "dmi_string: out of memory.\n"); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | return str; | ||
35 | } | 31 | } |
36 | 32 | ||
37 | /* | 33 | /* |
@@ -84,69 +80,76 @@ static int __init dmi_checksum(u8 *buf) | |||
84 | return sum == 0; | 80 | return sum == 0; |
85 | } | 81 | } |
86 | 82 | ||
87 | static int __init dmi_iterate(void (*decode)(struct dmi_header *)) | 83 | static char *dmi_ident[DMI_STRING_MAX]; |
84 | static LIST_HEAD(dmi_devices); | ||
85 | |||
86 | /* | ||
87 | * Save a DMI string | ||
88 | */ | ||
89 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | ||
88 | { | 90 | { |
89 | u8 buf[15]; | 91 | char *p, *d = (char*) dm; |
90 | char __iomem *p, *q; | ||
91 | 92 | ||
92 | /* | 93 | if (dmi_ident[slot]) |
93 | * no iounmap() for that ioremap(); it would be a no-op, but it's | 94 | return; |
94 | * so early in setup that sucker gets confused into doing what | 95 | |
95 | * it shouldn't if we actually call it. | 96 | p = dmi_string(dm, d[string]); |
96 | */ | ||
97 | p = ioremap(0xF0000, 0x10000); | ||
98 | if (p == NULL) | 97 | if (p == NULL) |
99 | return -1; | 98 | return; |
100 | 99 | ||
101 | for (q = p; q < p + 0x10000; q += 16) { | 100 | dmi_ident[slot] = p; |
102 | memcpy_fromio(buf, q, 15); | 101 | } |
103 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
104 | u16 num = (buf[13] << 8) | buf[12]; | ||
105 | u16 len = (buf[7] << 8) | buf[6]; | ||
106 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
107 | (buf[9] << 8) | buf[8]; | ||
108 | 102 | ||
109 | /* | 103 | static void __init dmi_save_devices(struct dmi_header *dm) |
110 | * DMI version 0.0 means that the real version is taken from | 104 | { |
111 | * the SMBIOS version, which we don't know at this point. | 105 | int i, count = (dm->length - sizeof(struct dmi_header)) / 2; |
112 | */ | 106 | struct dmi_device *dev; |
113 | if (buf[14] != 0) | 107 | |
114 | printk(KERN_INFO "DMI %d.%d present.\n", | 108 | for (i = 0; i < count; i++) { |
115 | buf[14] >> 4, buf[14] & 0xF); | 109 | char *d = ((char *) dm) + (i * 2); |
116 | else | ||
117 | printk(KERN_INFO "DMI present.\n"); | ||
118 | 110 | ||
119 | dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", | 111 | /* Skip disabled device */ |
120 | num, len)); | 112 | if ((*d & 0x80) == 0) |
121 | dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base)); | 113 | continue; |
122 | 114 | ||
123 | if (dmi_table(base,len, num, decode) == 0) | 115 | dev = alloc_bootmem(sizeof(*dev)); |
124 | return 0; | 116 | if (!dev) { |
117 | printk(KERN_ERR "dmi_save_devices: out of memory.\n"); | ||
118 | break; | ||
125 | } | 119 | } |
120 | |||
121 | dev->type = *d++ & 0x7f; | ||
122 | dev->name = dmi_string(dm, *d); | ||
123 | dev->device_data = NULL; | ||
124 | |||
125 | list_add(&dev->list, &dmi_devices); | ||
126 | } | 126 | } |
127 | return -1; | ||
128 | } | 127 | } |
129 | 128 | ||
130 | static char *dmi_ident[DMI_STRING_MAX]; | 129 | static void __init dmi_save_ipmi_device(struct dmi_header *dm) |
131 | |||
132 | /* | ||
133 | * Save a DMI string | ||
134 | */ | ||
135 | static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | ||
136 | { | 130 | { |
137 | char *d = (char*)dm; | 131 | struct dmi_device *dev; |
138 | char *p = dmi_string(dm, d[string]); | 132 | void * data; |
139 | 133 | ||
140 | if (p == NULL || *p == 0) | 134 | data = alloc_bootmem(dm->length); |
135 | if (data == NULL) { | ||
136 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
141 | return; | 137 | return; |
142 | if (dmi_ident[slot]) | 138 | } |
139 | |||
140 | memcpy(data, dm, dm->length); | ||
141 | |||
142 | dev = alloc_bootmem(sizeof(*dev)); | ||
143 | if (!dev) { | ||
144 | printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); | ||
143 | return; | 145 | return; |
146 | } | ||
144 | 147 | ||
145 | dmi_ident[slot] = alloc_bootmem(strlen(p) + 1); | 148 | dev->type = DMI_DEV_TYPE_IPMI; |
146 | if(dmi_ident[slot]) | 149 | dev->name = "IPMI controller"; |
147 | strcpy(dmi_ident[slot], p); | 150 | dev->device_data = data; |
148 | else | 151 | |
149 | printk(KERN_ERR "dmi_save_ident: out of memory.\n"); | 152 | list_add(&dev->list, &dmi_devices); |
150 | } | 153 | } |
151 | 154 | ||
152 | /* | 155 | /* |
@@ -156,42 +159,69 @@ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) | |||
156 | */ | 159 | */ |
157 | static void __init dmi_decode(struct dmi_header *dm) | 160 | static void __init dmi_decode(struct dmi_header *dm) |
158 | { | 161 | { |
159 | u8 *data __attribute__((__unused__)) = (u8 *)dm; | ||
160 | |||
161 | switch(dm->type) { | 162 | switch(dm->type) { |
162 | case 0: | 163 | case 0: /* BIOS Information */ |
163 | dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4]))); | ||
164 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); | 164 | dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); |
165 | dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5]))); | ||
166 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); | 165 | dmi_save_ident(dm, DMI_BIOS_VERSION, 5); |
167 | dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8]))); | ||
168 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); | 166 | dmi_save_ident(dm, DMI_BIOS_DATE, 8); |
169 | break; | 167 | break; |
170 | case 1: | 168 | case 1: /* System Information */ |
171 | dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4]))); | ||
172 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); | 169 | dmi_save_ident(dm, DMI_SYS_VENDOR, 4); |
173 | dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5]))); | ||
174 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); | 170 | dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); |
175 | dmi_printk(("Version: %s\n", dmi_string(dm, data[6]))); | ||
176 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); | 171 | dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); |
177 | dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7]))); | ||
178 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); | 172 | dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); |
179 | break; | 173 | break; |
180 | case 2: | 174 | case 2: /* Base Board Information */ |
181 | dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4]))); | ||
182 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); | 175 | dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); |
183 | dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5]))); | ||
184 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); | 176 | dmi_save_ident(dm, DMI_BOARD_NAME, 5); |
185 | dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6]))); | ||
186 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); | 177 | dmi_save_ident(dm, DMI_BOARD_VERSION, 6); |
187 | break; | 178 | break; |
179 | case 10: /* Onboard Devices Information */ | ||
180 | dmi_save_devices(dm); | ||
181 | break; | ||
182 | case 38: /* IPMI Device Information */ | ||
183 | dmi_save_ipmi_device(dm); | ||
188 | } | 184 | } |
189 | } | 185 | } |
190 | 186 | ||
191 | void __init dmi_scan_machine(void) | 187 | void __init dmi_scan_machine(void) |
192 | { | 188 | { |
193 | if (dmi_iterate(dmi_decode)) | 189 | u8 buf[15]; |
194 | printk(KERN_INFO "DMI not present.\n"); | 190 | char __iomem *p, *q; |
191 | |||
192 | /* | ||
193 | * no iounmap() for that ioremap(); it would be a no-op, but it's | ||
194 | * so early in setup that sucker gets confused into doing what | ||
195 | * it shouldn't if we actually call it. | ||
196 | */ | ||
197 | p = ioremap(0xF0000, 0x10000); | ||
198 | if (p == NULL) | ||
199 | goto out; | ||
200 | |||
201 | for (q = p; q < p + 0x10000; q += 16) { | ||
202 | memcpy_fromio(buf, q, 15); | ||
203 | if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { | ||
204 | u16 num = (buf[13] << 8) | buf[12]; | ||
205 | u16 len = (buf[7] << 8) | buf[6]; | ||
206 | u32 base = (buf[11] << 24) | (buf[10] << 16) | | ||
207 | (buf[9] << 8) | buf[8]; | ||
208 | |||
209 | /* | ||
210 | * DMI version 0.0 means that the real version is taken from | ||
211 | * the SMBIOS version, which we don't know at this point. | ||
212 | */ | ||
213 | if (buf[14] != 0) | ||
214 | printk(KERN_INFO "DMI %d.%d present.\n", | ||
215 | buf[14] >> 4, buf[14] & 0xF); | ||
216 | else | ||
217 | printk(KERN_INFO "DMI present.\n"); | ||
218 | |||
219 | if (dmi_table(base,len, num, dmi_decode) == 0) | ||
220 | return; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | out: printk(KERN_INFO "DMI not present.\n"); | ||
195 | } | 225 | } |
196 | 226 | ||
197 | 227 | ||
@@ -218,9 +248,9 @@ int dmi_check_system(struct dmi_system_id *list) | |||
218 | /* No match */ | 248 | /* No match */ |
219 | goto fail; | 249 | goto fail; |
220 | } | 250 | } |
251 | count++; | ||
221 | if (d->callback && d->callback(d)) | 252 | if (d->callback && d->callback(d)) |
222 | break; | 253 | break; |
223 | count++; | ||
224 | fail: d++; | 254 | fail: d++; |
225 | } | 255 | } |
226 | 256 | ||
@@ -240,3 +270,32 @@ char *dmi_get_system_info(int field) | |||
240 | return dmi_ident[field]; | 270 | return dmi_ident[field]; |
241 | } | 271 | } |
242 | EXPORT_SYMBOL(dmi_get_system_info); | 272 | EXPORT_SYMBOL(dmi_get_system_info); |
273 | |||
274 | /** | ||
275 | * dmi_find_device - find onboard device by type/name | ||
276 | * @type: device type or %DMI_DEV_TYPE_ANY to match all device types | ||
277 | * @desc: device name string or %NULL to match all | ||
278 | * @from: previous device found in search, or %NULL for new search. | ||
279 | * | ||
280 | * Iterates through the list of known onboard devices. If a device is | ||
281 | * found with a matching @vendor and @device, a pointer to its device | ||
282 | * structure is returned. Otherwise, %NULL is returned. | ||
283 | * A new search is initiated by passing %NULL to the @from argument. | ||
284 | * If @from is not %NULL, searches continue from next device. | ||
285 | */ | ||
286 | struct dmi_device * dmi_find_device(int type, const char *name, | ||
287 | struct dmi_device *from) | ||
288 | { | ||
289 | struct list_head *d, *head = from ? &from->list : &dmi_devices; | ||
290 | |||
291 | for(d = head->next; d != &dmi_devices; d = d->next) { | ||
292 | struct dmi_device *dev = list_entry(d, struct dmi_device, list); | ||
293 | |||
294 | if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && | ||
295 | ((name == NULL) || (strcmp(dev->name, name) == 0))) | ||
296 | return dev; | ||
297 | } | ||
298 | |||
299 | return NULL; | ||
300 | } | ||
301 | EXPORT_SYMBOL(dmi_find_device); | ||
diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c index 789af3e9fb1f..5edb1d379add 100644 --- a/arch/i386/kernel/doublefault.c +++ b/arch/i386/kernel/doublefault.c | |||
@@ -20,7 +20,7 @@ static void doublefault_fn(void) | |||
20 | struct Xgt_desc_struct gdt_desc = {0, 0}; | 20 | struct Xgt_desc_struct gdt_desc = {0, 0}; |
21 | unsigned long gdt, tss; | 21 | unsigned long gdt, tss; |
22 | 22 | ||
23 | __asm__ __volatile__("sgdt %0": "=m" (gdt_desc): :"memory"); | 23 | store_gdt(&gdt_desc); |
24 | gdt = gdt_desc.address; | 24 | gdt = gdt_desc.address; |
25 | 25 | ||
26 | printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); | 26 | printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); |
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 385883ea8c19..ecad519fd395 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c | |||
@@ -79,7 +79,7 @@ static void efi_call_phys_prelog(void) | |||
79 | * directory. If I have PSE, I just need to duplicate one entry in | 79 | * directory. If I have PSE, I just need to duplicate one entry in |
80 | * page directory. | 80 | * page directory. |
81 | */ | 81 | */ |
82 | __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); | 82 | cr4 = read_cr4(); |
83 | 83 | ||
84 | if (cr4 & X86_CR4_PSE) { | 84 | if (cr4 & X86_CR4_PSE) { |
85 | efi_bak_pg_dir_pointer[0].pgd = | 85 | efi_bak_pg_dir_pointer[0].pgd = |
@@ -104,8 +104,7 @@ static void efi_call_phys_prelog(void) | |||
104 | local_flush_tlb(); | 104 | local_flush_tlb(); |
105 | 105 | ||
106 | cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address); | 106 | cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address); |
107 | __asm__ __volatile__("lgdt %0":"=m" | 107 | load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0])); |
108 | (*(struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]))); | ||
109 | } | 108 | } |
110 | 109 | ||
111 | static void efi_call_phys_epilog(void) | 110 | static void efi_call_phys_epilog(void) |
@@ -114,8 +113,8 @@ static void efi_call_phys_epilog(void) | |||
114 | 113 | ||
115 | cpu_gdt_descr[0].address = | 114 | cpu_gdt_descr[0].address = |
116 | (unsigned long) __va(cpu_gdt_descr[0].address); | 115 | (unsigned long) __va(cpu_gdt_descr[0].address); |
117 | __asm__ __volatile__("lgdt %0":"=m"(cpu_gdt_descr)); | 116 | load_gdt(&cpu_gdt_descr[0]); |
118 | __asm__ __volatile__("movl %%cr4, %0":"=r"(cr4)); | 117 | cr4 = read_cr4(); |
119 | 118 | ||
120 | if (cr4 & X86_CR4_PSE) { | 119 | if (cr4 & X86_CR4_PSE) { |
121 | swapper_pg_dir[pgd_index(0)].pgd = | 120 | swapper_pg_dir[pgd_index(0)].pgd = |
@@ -233,22 +232,23 @@ void __init efi_map_memmap(void) | |||
233 | { | 232 | { |
234 | memmap.map = NULL; | 233 | memmap.map = NULL; |
235 | 234 | ||
236 | memmap.map = (efi_memory_desc_t *) | 235 | memmap.map = bt_ioremap((unsigned long) memmap.phys_map, |
237 | bt_ioremap((unsigned long) memmap.phys_map, | 236 | (memmap.nr_map * memmap.desc_size)); |
238 | (memmap.nr_map * sizeof(efi_memory_desc_t))); | ||
239 | |||
240 | if (memmap.map == NULL) | 237 | if (memmap.map == NULL) |
241 | printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); | 238 | printk(KERN_ERR PFX "Could not remap the EFI memmap!\n"); |
239 | |||
240 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); | ||
242 | } | 241 | } |
243 | 242 | ||
244 | #if EFI_DEBUG | 243 | #if EFI_DEBUG |
245 | static void __init print_efi_memmap(void) | 244 | static void __init print_efi_memmap(void) |
246 | { | 245 | { |
247 | efi_memory_desc_t *md; | 246 | efi_memory_desc_t *md; |
247 | void *p; | ||
248 | int i; | 248 | int i; |
249 | 249 | ||
250 | for (i = 0; i < memmap.nr_map; i++) { | 250 | for (p = memmap.map, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { |
251 | md = &memmap.map[i]; | 251 | md = p; |
252 | printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " | 252 | printk(KERN_INFO "mem%02u: type=%u, attr=0x%llx, " |
253 | "range=[0x%016llx-0x%016llx) (%lluMB)\n", | 253 | "range=[0x%016llx-0x%016llx) (%lluMB)\n", |
254 | i, md->type, md->attribute, md->phys_addr, | 254 | i, md->type, md->attribute, md->phys_addr, |
@@ -271,10 +271,10 @@ void efi_memmap_walk(efi_freemem_callback_t callback, void *arg) | |||
271 | } prev, curr; | 271 | } prev, curr; |
272 | efi_memory_desc_t *md; | 272 | efi_memory_desc_t *md; |
273 | unsigned long start, end; | 273 | unsigned long start, end; |
274 | int i; | 274 | void *p; |
275 | 275 | ||
276 | for (i = 0; i < memmap.nr_map; i++) { | 276 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
277 | md = &memmap.map[i]; | 277 | md = p; |
278 | 278 | ||
279 | if ((md->num_pages == 0) || (!is_available_memory(md))) | 279 | if ((md->num_pages == 0) || (!is_available_memory(md))) |
280 | continue; | 280 | continue; |
@@ -325,6 +325,7 @@ void __init efi_init(void) | |||
325 | memmap.phys_map = EFI_MEMMAP; | 325 | memmap.phys_map = EFI_MEMMAP; |
326 | memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; | 326 | memmap.nr_map = EFI_MEMMAP_SIZE/EFI_MEMDESC_SIZE; |
327 | memmap.desc_version = EFI_MEMDESC_VERSION; | 327 | memmap.desc_version = EFI_MEMDESC_VERSION; |
328 | memmap.desc_size = EFI_MEMDESC_SIZE; | ||
328 | 329 | ||
329 | efi.systab = (efi_system_table_t *) | 330 | efi.systab = (efi_system_table_t *) |
330 | boot_ioremap((unsigned long) efi_phys.systab, | 331 | boot_ioremap((unsigned long) efi_phys.systab, |
@@ -428,22 +429,30 @@ void __init efi_init(void) | |||
428 | printk(KERN_ERR PFX "Could not map the runtime service table!\n"); | 429 | printk(KERN_ERR PFX "Could not map the runtime service table!\n"); |
429 | 430 | ||
430 | /* Map the EFI memory map for use until paging_init() */ | 431 | /* Map the EFI memory map for use until paging_init() */ |
431 | 432 | memmap.map = boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE); | |
432 | memmap.map = (efi_memory_desc_t *) | ||
433 | boot_ioremap((unsigned long) EFI_MEMMAP, EFI_MEMMAP_SIZE); | ||
434 | |||
435 | if (memmap.map == NULL) | 433 | if (memmap.map == NULL) |
436 | printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); | 434 | printk(KERN_ERR PFX "Could not map the EFI memory map!\n"); |
437 | 435 | ||
438 | if (EFI_MEMDESC_SIZE != sizeof(efi_memory_desc_t)) { | 436 | memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size); |
439 | printk(KERN_WARNING PFX "Warning! Kernel-defined memdesc doesn't " | 437 | |
440 | "match the one from EFI!\n"); | ||
441 | } | ||
442 | #if EFI_DEBUG | 438 | #if EFI_DEBUG |
443 | print_efi_memmap(); | 439 | print_efi_memmap(); |
444 | #endif | 440 | #endif |
445 | } | 441 | } |
446 | 442 | ||
443 | static inline void __init check_range_for_systab(efi_memory_desc_t *md) | ||
444 | { | ||
445 | if (((unsigned long)md->phys_addr <= (unsigned long)efi_phys.systab) && | ||
446 | ((unsigned long)efi_phys.systab < md->phys_addr + | ||
447 | ((unsigned long)md->num_pages << EFI_PAGE_SHIFT))) { | ||
448 | unsigned long addr; | ||
449 | |||
450 | addr = md->virt_addr - md->phys_addr + | ||
451 | (unsigned long)efi_phys.systab; | ||
452 | efi.systab = (efi_system_table_t *)addr; | ||
453 | } | ||
454 | } | ||
455 | |||
447 | /* | 456 | /* |
448 | * This function will switch the EFI runtime services to virtual mode. | 457 | * This function will switch the EFI runtime services to virtual mode. |
449 | * Essentially, look through the EFI memmap and map every region that | 458 | * Essentially, look through the EFI memmap and map every region that |
@@ -457,43 +466,32 @@ void __init efi_enter_virtual_mode(void) | |||
457 | { | 466 | { |
458 | efi_memory_desc_t *md; | 467 | efi_memory_desc_t *md; |
459 | efi_status_t status; | 468 | efi_status_t status; |
460 | int i; | 469 | void *p; |
461 | 470 | ||
462 | efi.systab = NULL; | 471 | efi.systab = NULL; |
463 | 472 | ||
464 | for (i = 0; i < memmap.nr_map; i++) { | 473 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
465 | md = &memmap.map[i]; | 474 | md = p; |
466 | 475 | ||
467 | if (md->attribute & EFI_MEMORY_RUNTIME) { | 476 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) |
468 | md->virt_addr = | 477 | continue; |
469 | (unsigned long)ioremap(md->phys_addr, | ||
470 | md->num_pages << EFI_PAGE_SHIFT); | ||
471 | if (!(unsigned long)md->virt_addr) { | ||
472 | printk(KERN_ERR PFX "ioremap of 0x%lX failed\n", | ||
473 | (unsigned long)md->phys_addr); | ||
474 | } | ||
475 | 478 | ||
476 | if (((unsigned long)md->phys_addr <= | 479 | md->virt_addr = (unsigned long)ioremap(md->phys_addr, |
477 | (unsigned long)efi_phys.systab) && | 480 | md->num_pages << EFI_PAGE_SHIFT); |
478 | ((unsigned long)efi_phys.systab < | 481 | if (!(unsigned long)md->virt_addr) { |
479 | md->phys_addr + | 482 | printk(KERN_ERR PFX "ioremap of 0x%lX failed\n", |
480 | ((unsigned long)md->num_pages << | 483 | (unsigned long)md->phys_addr); |
481 | EFI_PAGE_SHIFT))) { | ||
482 | unsigned long addr; | ||
483 | |||
484 | addr = md->virt_addr - md->phys_addr + | ||
485 | (unsigned long)efi_phys.systab; | ||
486 | efi.systab = (efi_system_table_t *)addr; | ||
487 | } | ||
488 | } | 484 | } |
485 | /* update the virtual address of the EFI system table */ | ||
486 | check_range_for_systab(md); | ||
489 | } | 487 | } |
490 | 488 | ||
491 | if (!efi.systab) | 489 | if (!efi.systab) |
492 | BUG(); | 490 | BUG(); |
493 | 491 | ||
494 | status = phys_efi_set_virtual_address_map( | 492 | status = phys_efi_set_virtual_address_map( |
495 | sizeof(efi_memory_desc_t) * memmap.nr_map, | 493 | memmap.desc_size * memmap.nr_map, |
496 | sizeof(efi_memory_desc_t), | 494 | memmap.desc_size, |
497 | memmap.desc_version, | 495 | memmap.desc_version, |
498 | memmap.phys_map); | 496 | memmap.phys_map); |
499 | 497 | ||
@@ -533,10 +531,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
533 | { | 531 | { |
534 | struct resource *res; | 532 | struct resource *res; |
535 | efi_memory_desc_t *md; | 533 | efi_memory_desc_t *md; |
536 | int i; | 534 | void *p; |
537 | 535 | ||
538 | for (i = 0; i < memmap.nr_map; i++) { | 536 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
539 | md = &memmap.map[i]; | 537 | md = p; |
540 | 538 | ||
541 | if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > | 539 | if ((md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT)) > |
542 | 0x100000000ULL) | 540 | 0x100000000ULL) |
@@ -613,10 +611,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, | |||
613 | u32 efi_mem_type(unsigned long phys_addr) | 611 | u32 efi_mem_type(unsigned long phys_addr) |
614 | { | 612 | { |
615 | efi_memory_desc_t *md; | 613 | efi_memory_desc_t *md; |
616 | int i; | 614 | void *p; |
617 | 615 | ||
618 | for (i = 0; i < memmap.nr_map; i++) { | 616 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
619 | md = &memmap.map[i]; | 617 | md = p; |
620 | if ((md->phys_addr <= phys_addr) && (phys_addr < | 618 | if ((md->phys_addr <= phys_addr) && (phys_addr < |
621 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) | 619 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) |
622 | return md->type; | 620 | return md->type; |
@@ -627,10 +625,10 @@ u32 efi_mem_type(unsigned long phys_addr) | |||
627 | u64 efi_mem_attributes(unsigned long phys_addr) | 625 | u64 efi_mem_attributes(unsigned long phys_addr) |
628 | { | 626 | { |
629 | efi_memory_desc_t *md; | 627 | efi_memory_desc_t *md; |
630 | int i; | 628 | void *p; |
631 | 629 | ||
632 | for (i = 0; i < memmap.nr_map; i++) { | 630 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
633 | md = &memmap.map[i]; | 631 | md = p; |
634 | if ((md->phys_addr <= phys_addr) && (phys_addr < | 632 | if ((md->phys_addr <= phys_addr) && (phys_addr < |
635 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) | 633 | (md->phys_addr + (md-> num_pages << EFI_PAGE_SHIFT)) )) |
636 | return md->attribute; | 634 | return md->attribute; |
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index a991d4e5edd2..3aad03839660 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S | |||
@@ -203,7 +203,7 @@ sysenter_past_esp: | |||
203 | GET_THREAD_INFO(%ebp) | 203 | GET_THREAD_INFO(%ebp) |
204 | 204 | ||
205 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ | 205 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ |
206 | testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp) | 206 | testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) |
207 | jnz syscall_trace_entry | 207 | jnz syscall_trace_entry |
208 | cmpl $(nr_syscalls), %eax | 208 | cmpl $(nr_syscalls), %eax |
209 | jae syscall_badsys | 209 | jae syscall_badsys |
@@ -226,9 +226,9 @@ ENTRY(system_call) | |||
226 | pushl %eax # save orig_eax | 226 | pushl %eax # save orig_eax |
227 | SAVE_ALL | 227 | SAVE_ALL |
228 | GET_THREAD_INFO(%ebp) | 228 | GET_THREAD_INFO(%ebp) |
229 | # system call tracing in operation | 229 | # system call tracing in operation / emulation |
230 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ | 230 | /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ |
231 | testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp) | 231 | testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) |
232 | jnz syscall_trace_entry | 232 | jnz syscall_trace_entry |
233 | cmpl $(nr_syscalls), %eax | 233 | cmpl $(nr_syscalls), %eax |
234 | jae syscall_badsys | 234 | jae syscall_badsys |
@@ -338,6 +338,9 @@ syscall_trace_entry: | |||
338 | movl %esp, %eax | 338 | movl %esp, %eax |
339 | xorl %edx,%edx | 339 | xorl %edx,%edx |
340 | call do_syscall_trace | 340 | call do_syscall_trace |
341 | cmpl $0, %eax | ||
342 | jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, | ||
343 | # so must skip actual syscall | ||
341 | movl ORIG_EAX(%esp), %eax | 344 | movl ORIG_EAX(%esp), %eax |
342 | cmpl $(nr_syscalls), %eax | 345 | cmpl $(nr_syscalls), %eax |
343 | jnae syscall_call | 346 | jnae syscall_call |
@@ -504,7 +507,7 @@ label: \ | |||
504 | pushl $__KERNEL_CS; \ | 507 | pushl $__KERNEL_CS; \ |
505 | pushl $sysenter_past_esp | 508 | pushl $sysenter_past_esp |
506 | 509 | ||
507 | ENTRY(debug) | 510 | KPROBE_ENTRY(debug) |
508 | cmpl $sysenter_entry,(%esp) | 511 | cmpl $sysenter_entry,(%esp) |
509 | jne debug_stack_correct | 512 | jne debug_stack_correct |
510 | FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) | 513 | FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) |
@@ -515,7 +518,7 @@ debug_stack_correct: | |||
515 | movl %esp,%eax # pt_regs pointer | 518 | movl %esp,%eax # pt_regs pointer |
516 | call do_debug | 519 | call do_debug |
517 | jmp ret_from_exception | 520 | jmp ret_from_exception |
518 | 521 | .previous .text | |
519 | /* | 522 | /* |
520 | * NMI is doubly nasty. It can happen _while_ we're handling | 523 | * NMI is doubly nasty. It can happen _while_ we're handling |
521 | * a debug fault, and the debug fault hasn't yet been able to | 524 | * a debug fault, and the debug fault hasn't yet been able to |
@@ -588,13 +591,14 @@ nmi_16bit_stack: | |||
588 | .long 1b,iret_exc | 591 | .long 1b,iret_exc |
589 | .previous | 592 | .previous |
590 | 593 | ||
591 | ENTRY(int3) | 594 | KPROBE_ENTRY(int3) |
592 | pushl $-1 # mark this as an int | 595 | pushl $-1 # mark this as an int |
593 | SAVE_ALL | 596 | SAVE_ALL |
594 | xorl %edx,%edx # zero error code | 597 | xorl %edx,%edx # zero error code |
595 | movl %esp,%eax # pt_regs pointer | 598 | movl %esp,%eax # pt_regs pointer |
596 | call do_int3 | 599 | call do_int3 |
597 | jmp ret_from_exception | 600 | jmp ret_from_exception |
601 | .previous .text | ||
598 | 602 | ||
599 | ENTRY(overflow) | 603 | ENTRY(overflow) |
600 | pushl $0 | 604 | pushl $0 |
@@ -628,17 +632,19 @@ ENTRY(stack_segment) | |||
628 | pushl $do_stack_segment | 632 | pushl $do_stack_segment |
629 | jmp error_code | 633 | jmp error_code |
630 | 634 | ||
631 | ENTRY(general_protection) | 635 | KPROBE_ENTRY(general_protection) |
632 | pushl $do_general_protection | 636 | pushl $do_general_protection |
633 | jmp error_code | 637 | jmp error_code |
638 | .previous .text | ||
634 | 639 | ||
635 | ENTRY(alignment_check) | 640 | ENTRY(alignment_check) |
636 | pushl $do_alignment_check | 641 | pushl $do_alignment_check |
637 | jmp error_code | 642 | jmp error_code |
638 | 643 | ||
639 | ENTRY(page_fault) | 644 | KPROBE_ENTRY(page_fault) |
640 | pushl $do_page_fault | 645 | pushl $do_page_fault |
641 | jmp error_code | 646 | jmp error_code |
647 | .previous .text | ||
642 | 648 | ||
643 | #ifdef CONFIG_X86_MCE | 649 | #ifdef CONFIG_X86_MCE |
644 | ENTRY(machine_check) | 650 | ENTRY(machine_check) |
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 4477bb107098..0480ca9e9e57 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -77,6 +77,32 @@ ENTRY(startup_32) | |||
77 | subl %edi,%ecx | 77 | subl %edi,%ecx |
78 | shrl $2,%ecx | 78 | shrl $2,%ecx |
79 | rep ; stosl | 79 | rep ; stosl |
80 | /* | ||
81 | * Copy bootup parameters out of the way. | ||
82 | * Note: %esi still has the pointer to the real-mode data. | ||
83 | * With the kexec as boot loader, parameter segment might be loaded beyond | ||
84 | * kernel image and might not even be addressable by early boot page tables. | ||
85 | * (kexec on panic case). Hence copy out the parameters before initializing | ||
86 | * page tables. | ||
87 | */ | ||
88 | movl $(boot_params - __PAGE_OFFSET),%edi | ||
89 | movl $(PARAM_SIZE/4),%ecx | ||
90 | cld | ||
91 | rep | ||
92 | movsl | ||
93 | movl boot_params - __PAGE_OFFSET + NEW_CL_POINTER,%esi | ||
94 | andl %esi,%esi | ||
95 | jnz 2f # New command line protocol | ||
96 | cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR | ||
97 | jne 1f | ||
98 | movzwl OLD_CL_OFFSET,%esi | ||
99 | addl $(OLD_CL_BASE_ADDR),%esi | ||
100 | 2: | ||
101 | movl $(saved_command_line - __PAGE_OFFSET),%edi | ||
102 | movl $(COMMAND_LINE_SIZE/4),%ecx | ||
103 | rep | ||
104 | movsl | ||
105 | 1: | ||
80 | 106 | ||
81 | /* | 107 | /* |
82 | * Initialize page tables. This creates a PDE and a set of page | 108 | * Initialize page tables. This creates a PDE and a set of page |
@@ -214,28 +240,6 @@ ENTRY(startup_32_smp) | |||
214 | */ | 240 | */ |
215 | call setup_idt | 241 | call setup_idt |
216 | 242 | ||
217 | /* | ||
218 | * Copy bootup parameters out of the way. | ||
219 | * Note: %esi still has the pointer to the real-mode data. | ||
220 | */ | ||
221 | movl $boot_params,%edi | ||
222 | movl $(PARAM_SIZE/4),%ecx | ||
223 | cld | ||
224 | rep | ||
225 | movsl | ||
226 | movl boot_params+NEW_CL_POINTER,%esi | ||
227 | andl %esi,%esi | ||
228 | jnz 2f # New command line protocol | ||
229 | cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR | ||
230 | jne 1f | ||
231 | movzwl OLD_CL_OFFSET,%esi | ||
232 | addl $(OLD_CL_BASE_ADDR),%esi | ||
233 | 2: | ||
234 | movl $saved_command_line,%edi | ||
235 | movl $(COMMAND_LINE_SIZE/4),%ecx | ||
236 | rep | ||
237 | movsl | ||
238 | 1: | ||
239 | checkCPUtype: | 243 | checkCPUtype: |
240 | 244 | ||
241 | movl $-1,X86_CPUID # -1 for no CPUID initially | 245 | movl $-1,X86_CPUID # -1 for no CPUID initially |
diff --git a/arch/i386/kernel/i8237.c b/arch/i386/kernel/i8237.c new file mode 100644 index 000000000000..c36d1c006c2f --- /dev/null +++ b/arch/i386/kernel/i8237.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * i8237.c: 8237A DMA controller suspend functions. | ||
3 | * | ||
4 | * Written by Pierre Ossman, 2005. | ||
5 | */ | ||
6 | |||
7 | #include <linux/init.h> | ||
8 | #include <linux/sysdev.h> | ||
9 | |||
10 | #include <asm/dma.h> | ||
11 | |||
12 | /* | ||
13 | * This module just handles suspend/resume issues with the | ||
14 | * 8237A DMA controller (used for ISA and LPC). | ||
15 | * Allocation is handled in kernel/dma.c and normal usage is | ||
16 | * in asm/dma.h. | ||
17 | */ | ||
18 | |||
19 | static int i8237A_resume(struct sys_device *dev) | ||
20 | { | ||
21 | unsigned long flags; | ||
22 | int i; | ||
23 | |||
24 | flags = claim_dma_lock(); | ||
25 | |||
26 | dma_outb(DMA1_RESET_REG, 0); | ||
27 | dma_outb(DMA2_RESET_REG, 0); | ||
28 | |||
29 | for (i = 0;i < 8;i++) { | ||
30 | set_dma_addr(i, 0x000000); | ||
31 | /* DMA count is a bit weird so this is not 0 */ | ||
32 | set_dma_count(i, 1); | ||
33 | } | ||
34 | |||
35 | /* Enable cascade DMA or channel 0-3 won't work */ | ||
36 | enable_dma(4); | ||
37 | |||
38 | release_dma_lock(flags); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int i8237A_suspend(struct sys_device *dev, pm_message_t state) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static struct sysdev_class i8237_sysdev_class = { | ||
49 | set_kset_name("i8237"), | ||
50 | .suspend = i8237A_suspend, | ||
51 | .resume = i8237A_resume, | ||
52 | }; | ||
53 | |||
54 | static struct sys_device device_i8237A = { | ||
55 | .id = 0, | ||
56 | .cls = &i8237_sysdev_class, | ||
57 | }; | ||
58 | |||
59 | static int __init i8237A_init_sysfs(void) | ||
60 | { | ||
61 | int error = sysdev_class_register(&i8237_sysdev_class); | ||
62 | if (!error) | ||
63 | error = sysdev_register(&device_i8237A); | ||
64 | return error; | ||
65 | } | ||
66 | |||
67 | device_initcall(i8237A_init_sysfs); | ||
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 6578f40bd501..889eda2d7b17 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/sysdev.h> | 35 | #include <linux/sysdev.h> |
36 | |||
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
38 | #include <asm/desc.h> | 39 | #include <asm/desc.h> |
@@ -77,7 +78,7 @@ static struct irq_pin_list { | |||
77 | int apic, pin, next; | 78 | int apic, pin, next; |
78 | } irq_2_pin[PIN_MAP_SIZE]; | 79 | } irq_2_pin[PIN_MAP_SIZE]; |
79 | 80 | ||
80 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; | 81 | int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; |
81 | #ifdef CONFIG_PCI_MSI | 82 | #ifdef CONFIG_PCI_MSI |
82 | #define vector_to_irq(vector) \ | 83 | #define vector_to_irq(vector) \ |
83 | (platform_legacy_irq(vector) ? vector : vector_irq[vector]) | 84 | (platform_legacy_irq(vector) ? vector : vector_irq[vector]) |
@@ -222,13 +223,21 @@ static void clear_IO_APIC (void) | |||
222 | clear_IO_APIC_pin(apic, pin); | 223 | clear_IO_APIC_pin(apic, pin); |
223 | } | 224 | } |
224 | 225 | ||
226 | #ifdef CONFIG_SMP | ||
225 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | 227 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) |
226 | { | 228 | { |
227 | unsigned long flags; | 229 | unsigned long flags; |
228 | int pin; | 230 | int pin; |
229 | struct irq_pin_list *entry = irq_2_pin + irq; | 231 | struct irq_pin_list *entry = irq_2_pin + irq; |
230 | unsigned int apicid_value; | 232 | unsigned int apicid_value; |
233 | cpumask_t tmp; | ||
231 | 234 | ||
235 | cpus_and(tmp, cpumask, cpu_online_map); | ||
236 | if (cpus_empty(tmp)) | ||
237 | tmp = TARGET_CPUS; | ||
238 | |||
239 | cpus_and(cpumask, tmp, CPU_MASK_ALL); | ||
240 | |||
232 | apicid_value = cpu_mask_to_apicid(cpumask); | 241 | apicid_value = cpu_mask_to_apicid(cpumask); |
233 | /* Prepare to do the io_apic_write */ | 242 | /* Prepare to do the io_apic_write */ |
234 | apicid_value = apicid_value << 24; | 243 | apicid_value = apicid_value << 24; |
@@ -242,6 +251,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
242 | break; | 251 | break; |
243 | entry = irq_2_pin + entry->next; | 252 | entry = irq_2_pin + entry->next; |
244 | } | 253 | } |
254 | set_irq_info(irq, cpumask); | ||
245 | spin_unlock_irqrestore(&ioapic_lock, flags); | 255 | spin_unlock_irqrestore(&ioapic_lock, flags); |
246 | } | 256 | } |
247 | 257 | ||
@@ -259,7 +269,6 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
259 | # define Dprintk(x...) | 269 | # define Dprintk(x...) |
260 | # endif | 270 | # endif |
261 | 271 | ||
262 | cpumask_t __cacheline_aligned pending_irq_balance_cpumask[NR_IRQS]; | ||
263 | 272 | ||
264 | #define IRQBALANCE_CHECK_ARCH -999 | 273 | #define IRQBALANCE_CHECK_ARCH -999 |
265 | static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; | 274 | static int irqbalance_disabled = IRQBALANCE_CHECK_ARCH; |
@@ -328,12 +337,7 @@ static inline void balance_irq(int cpu, int irq) | |||
328 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); | 337 | cpus_and(allowed_mask, cpu_online_map, irq_affinity[irq]); |
329 | new_cpu = move(cpu, allowed_mask, now, 1); | 338 | new_cpu = move(cpu, allowed_mask, now, 1); |
330 | if (cpu != new_cpu) { | 339 | if (cpu != new_cpu) { |
331 | irq_desc_t *desc = irq_desc + irq; | 340 | set_pending_irq(irq, cpumask_of_cpu(new_cpu)); |
332 | unsigned long flags; | ||
333 | |||
334 | spin_lock_irqsave(&desc->lock, flags); | ||
335 | pending_irq_balance_cpumask[irq] = cpumask_of_cpu(new_cpu); | ||
336 | spin_unlock_irqrestore(&desc->lock, flags); | ||
337 | } | 341 | } |
338 | } | 342 | } |
339 | 343 | ||
@@ -528,16 +532,12 @@ tryanotherirq: | |||
528 | cpus_and(tmp, target_cpu_mask, allowed_mask); | 532 | cpus_and(tmp, target_cpu_mask, allowed_mask); |
529 | 533 | ||
530 | if (!cpus_empty(tmp)) { | 534 | if (!cpus_empty(tmp)) { |
531 | irq_desc_t *desc = irq_desc + selected_irq; | ||
532 | unsigned long flags; | ||
533 | 535 | ||
534 | Dprintk("irq = %d moved to cpu = %d\n", | 536 | Dprintk("irq = %d moved to cpu = %d\n", |
535 | selected_irq, min_loaded); | 537 | selected_irq, min_loaded); |
536 | /* mark for change destination */ | 538 | /* mark for change destination */ |
537 | spin_lock_irqsave(&desc->lock, flags); | 539 | set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded)); |
538 | pending_irq_balance_cpumask[selected_irq] = | 540 | |
539 | cpumask_of_cpu(min_loaded); | ||
540 | spin_unlock_irqrestore(&desc->lock, flags); | ||
541 | /* Since we made a change, come back sooner to | 541 | /* Since we made a change, come back sooner to |
542 | * check for more variation. | 542 | * check for more variation. |
543 | */ | 543 | */ |
@@ -568,7 +568,8 @@ static int balanced_irq(void *unused) | |||
568 | 568 | ||
569 | /* push everything to CPU 0 to give us a starting point. */ | 569 | /* push everything to CPU 0 to give us a starting point. */ |
570 | for (i = 0 ; i < NR_IRQS ; i++) { | 570 | for (i = 0 ; i < NR_IRQS ; i++) { |
571 | pending_irq_balance_cpumask[i] = cpumask_of_cpu(0); | 571 | pending_irq_cpumask[i] = cpumask_of_cpu(0); |
572 | set_pending_irq(i, cpumask_of_cpu(0)); | ||
572 | } | 573 | } |
573 | 574 | ||
574 | for ( ; ; ) { | 575 | for ( ; ; ) { |
@@ -647,20 +648,9 @@ int __init irqbalance_disable(char *str) | |||
647 | 648 | ||
648 | __setup("noirqbalance", irqbalance_disable); | 649 | __setup("noirqbalance", irqbalance_disable); |
649 | 650 | ||
650 | static inline void move_irq(int irq) | ||
651 | { | ||
652 | /* note - we hold the desc->lock */ | ||
653 | if (unlikely(!cpus_empty(pending_irq_balance_cpumask[irq]))) { | ||
654 | set_ioapic_affinity_irq(irq, pending_irq_balance_cpumask[irq]); | ||
655 | cpus_clear(pending_irq_balance_cpumask[irq]); | ||
656 | } | ||
657 | } | ||
658 | |||
659 | late_initcall(balanced_irq_init); | 651 | late_initcall(balanced_irq_init); |
660 | |||
661 | #else /* !CONFIG_IRQBALANCE */ | ||
662 | static inline void move_irq(int irq) { } | ||
663 | #endif /* CONFIG_IRQBALANCE */ | 652 | #endif /* CONFIG_IRQBALANCE */ |
653 | #endif /* CONFIG_SMP */ | ||
664 | 654 | ||
665 | #ifndef CONFIG_SMP | 655 | #ifndef CONFIG_SMP |
666 | void fastcall send_IPI_self(int vector) | 656 | void fastcall send_IPI_self(int vector) |
@@ -820,6 +810,7 @@ EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | |||
820 | * we need to reprogram the ioredtbls to cater for the cpus which have come online | 810 | * we need to reprogram the ioredtbls to cater for the cpus which have come online |
821 | * so mask in all cases should simply be TARGET_CPUS | 811 | * so mask in all cases should simply be TARGET_CPUS |
822 | */ | 812 | */ |
813 | #ifdef CONFIG_SMP | ||
823 | void __init setup_ioapic_dest(void) | 814 | void __init setup_ioapic_dest(void) |
824 | { | 815 | { |
825 | int pin, ioapic, irq, irq_entry; | 816 | int pin, ioapic, irq, irq_entry; |
@@ -838,6 +829,7 @@ void __init setup_ioapic_dest(void) | |||
838 | 829 | ||
839 | } | 830 | } |
840 | } | 831 | } |
832 | #endif | ||
841 | 833 | ||
842 | /* | 834 | /* |
843 | * EISA Edge/Level control register, ELCR | 835 | * EISA Edge/Level control register, ELCR |
@@ -1127,7 +1119,7 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1127 | } | 1119 | } |
1128 | 1120 | ||
1129 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ | 1121 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ |
1130 | u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; | 1122 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; |
1131 | 1123 | ||
1132 | int assign_irq_vector(int irq) | 1124 | int assign_irq_vector(int irq) |
1133 | { | 1125 | { |
@@ -1249,6 +1241,7 @@ static void __init setup_IO_APIC_irqs(void) | |||
1249 | spin_lock_irqsave(&ioapic_lock, flags); | 1241 | spin_lock_irqsave(&ioapic_lock, flags); |
1250 | io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); | 1242 | io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); |
1251 | io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); | 1243 | io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); |
1244 | set_native_irq_info(irq, TARGET_CPUS); | ||
1252 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1245 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1253 | } | 1246 | } |
1254 | } | 1247 | } |
@@ -1944,6 +1937,7 @@ static void ack_edge_ioapic_vector(unsigned int vector) | |||
1944 | { | 1937 | { |
1945 | int irq = vector_to_irq(vector); | 1938 | int irq = vector_to_irq(vector); |
1946 | 1939 | ||
1940 | move_irq(vector); | ||
1947 | ack_edge_ioapic_irq(irq); | 1941 | ack_edge_ioapic_irq(irq); |
1948 | } | 1942 | } |
1949 | 1943 | ||
@@ -1958,6 +1952,7 @@ static void end_level_ioapic_vector (unsigned int vector) | |||
1958 | { | 1952 | { |
1959 | int irq = vector_to_irq(vector); | 1953 | int irq = vector_to_irq(vector); |
1960 | 1954 | ||
1955 | move_irq(vector); | ||
1961 | end_level_ioapic_irq(irq); | 1956 | end_level_ioapic_irq(irq); |
1962 | } | 1957 | } |
1963 | 1958 | ||
@@ -1975,14 +1970,17 @@ static void unmask_IO_APIC_vector (unsigned int vector) | |||
1975 | unmask_IO_APIC_irq(irq); | 1970 | unmask_IO_APIC_irq(irq); |
1976 | } | 1971 | } |
1977 | 1972 | ||
1973 | #ifdef CONFIG_SMP | ||
1978 | static void set_ioapic_affinity_vector (unsigned int vector, | 1974 | static void set_ioapic_affinity_vector (unsigned int vector, |
1979 | cpumask_t cpu_mask) | 1975 | cpumask_t cpu_mask) |
1980 | { | 1976 | { |
1981 | int irq = vector_to_irq(vector); | 1977 | int irq = vector_to_irq(vector); |
1982 | 1978 | ||
1979 | set_native_irq_info(vector, cpu_mask); | ||
1983 | set_ioapic_affinity_irq(irq, cpu_mask); | 1980 | set_ioapic_affinity_irq(irq, cpu_mask); |
1984 | } | 1981 | } |
1985 | #endif | 1982 | #endif |
1983 | #endif | ||
1986 | 1984 | ||
1987 | /* | 1985 | /* |
1988 | * Level and edge triggered IO-APIC interrupts need different handling, | 1986 | * Level and edge triggered IO-APIC interrupts need different handling, |
@@ -1992,7 +1990,7 @@ static void set_ioapic_affinity_vector (unsigned int vector, | |||
1992 | * edge-triggered handler, without risking IRQ storms and other ugly | 1990 | * edge-triggered handler, without risking IRQ storms and other ugly |
1993 | * races. | 1991 | * races. |
1994 | */ | 1992 | */ |
1995 | static struct hw_interrupt_type ioapic_edge_type = { | 1993 | static struct hw_interrupt_type ioapic_edge_type __read_mostly = { |
1996 | .typename = "IO-APIC-edge", | 1994 | .typename = "IO-APIC-edge", |
1997 | .startup = startup_edge_ioapic, | 1995 | .startup = startup_edge_ioapic, |
1998 | .shutdown = shutdown_edge_ioapic, | 1996 | .shutdown = shutdown_edge_ioapic, |
@@ -2000,10 +1998,12 @@ static struct hw_interrupt_type ioapic_edge_type = { | |||
2000 | .disable = disable_edge_ioapic, | 1998 | .disable = disable_edge_ioapic, |
2001 | .ack = ack_edge_ioapic, | 1999 | .ack = ack_edge_ioapic, |
2002 | .end = end_edge_ioapic, | 2000 | .end = end_edge_ioapic, |
2001 | #ifdef CONFIG_SMP | ||
2003 | .set_affinity = set_ioapic_affinity, | 2002 | .set_affinity = set_ioapic_affinity, |
2003 | #endif | ||
2004 | }; | 2004 | }; |
2005 | 2005 | ||
2006 | static struct hw_interrupt_type ioapic_level_type = { | 2006 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { |
2007 | .typename = "IO-APIC-level", | 2007 | .typename = "IO-APIC-level", |
2008 | .startup = startup_level_ioapic, | 2008 | .startup = startup_level_ioapic, |
2009 | .shutdown = shutdown_level_ioapic, | 2009 | .shutdown = shutdown_level_ioapic, |
@@ -2011,7 +2011,9 @@ static struct hw_interrupt_type ioapic_level_type = { | |||
2011 | .disable = disable_level_ioapic, | 2011 | .disable = disable_level_ioapic, |
2012 | .ack = mask_and_ack_level_ioapic, | 2012 | .ack = mask_and_ack_level_ioapic, |
2013 | .end = end_level_ioapic, | 2013 | .end = end_level_ioapic, |
2014 | #ifdef CONFIG_SMP | ||
2014 | .set_affinity = set_ioapic_affinity, | 2015 | .set_affinity = set_ioapic_affinity, |
2016 | #endif | ||
2015 | }; | 2017 | }; |
2016 | 2018 | ||
2017 | static inline void init_IO_APIC_traps(void) | 2019 | static inline void init_IO_APIC_traps(void) |
@@ -2074,7 +2076,7 @@ static void ack_lapic_irq (unsigned int irq) | |||
2074 | 2076 | ||
2075 | static void end_lapic_irq (unsigned int i) { /* nothing */ } | 2077 | static void end_lapic_irq (unsigned int i) { /* nothing */ } |
2076 | 2078 | ||
2077 | static struct hw_interrupt_type lapic_irq_type = { | 2079 | static struct hw_interrupt_type lapic_irq_type __read_mostly = { |
2078 | .typename = "local-APIC-edge", | 2080 | .typename = "local-APIC-edge", |
2079 | .startup = NULL, /* startup_irq() not used for IRQ0 */ | 2081 | .startup = NULL, /* startup_irq() not used for IRQ0 */ |
2080 | .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ | 2082 | .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ |
@@ -2421,7 +2423,7 @@ device_initcall(ioapic_init_sysfs); | |||
2421 | ACPI-based IOAPIC Configuration | 2423 | ACPI-based IOAPIC Configuration |
2422 | -------------------------------------------------------------------------- */ | 2424 | -------------------------------------------------------------------------- */ |
2423 | 2425 | ||
2424 | #ifdef CONFIG_ACPI_BOOT | 2426 | #ifdef CONFIG_ACPI |
2425 | 2427 | ||
2426 | int __init io_apic_get_unique_id (int ioapic, int apic_id) | 2428 | int __init io_apic_get_unique_id (int ioapic, int apic_id) |
2427 | { | 2429 | { |
@@ -2569,9 +2571,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2569 | spin_lock_irqsave(&ioapic_lock, flags); | 2571 | spin_lock_irqsave(&ioapic_lock, flags); |
2570 | io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); | 2572 | io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); |
2571 | io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); | 2573 | io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); |
2574 | set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); | ||
2572 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2575 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2573 | 2576 | ||
2574 | return 0; | 2577 | return 0; |
2575 | } | 2578 | } |
2576 | 2579 | ||
2577 | #endif /*CONFIG_ACPI_BOOT*/ | 2580 | #endif /* CONFIG_ACPI */ |
diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c index 8b25160393c1..f2b37654777f 100644 --- a/arch/i386/kernel/ioport.c +++ b/arch/i386/kernel/ioport.c | |||
@@ -132,6 +132,7 @@ asmlinkage long sys_iopl(unsigned long unused) | |||
132 | volatile struct pt_regs * regs = (struct pt_regs *) &unused; | 132 | volatile struct pt_regs * regs = (struct pt_regs *) &unused; |
133 | unsigned int level = regs->ebx; | 133 | unsigned int level = regs->ebx; |
134 | unsigned int old = (regs->eflags >> 12) & 3; | 134 | unsigned int old = (regs->eflags >> 12) & 3; |
135 | struct thread_struct *t = ¤t->thread; | ||
135 | 136 | ||
136 | if (level > 3) | 137 | if (level > 3) |
137 | return -EINVAL; | 138 | return -EINVAL; |
@@ -140,8 +141,8 @@ asmlinkage long sys_iopl(unsigned long unused) | |||
140 | if (!capable(CAP_SYS_RAWIO)) | 141 | if (!capable(CAP_SYS_RAWIO)) |
141 | return -EPERM; | 142 | return -EPERM; |
142 | } | 143 | } |
143 | regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12); | 144 | t->iopl = level << 12; |
144 | /* Make sure we return the long way (not sysenter) */ | 145 | regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl; |
145 | set_thread_flag(TIF_IRET); | 146 | set_iopl_mask(t->iopl); |
146 | return 0; | 147 | return 0; |
147 | } | 148 | } |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index a6d8c45961d3..6345b430b105 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -62,32 +62,32 @@ static inline int is_IF_modifier(kprobe_opcode_t opcode) | |||
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | 64 | ||
65 | int arch_prepare_kprobe(struct kprobe *p) | 65 | int __kprobes arch_prepare_kprobe(struct kprobe *p) |
66 | { | 66 | { |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | void arch_copy_kprobe(struct kprobe *p) | 70 | void __kprobes arch_copy_kprobe(struct kprobe *p) |
71 | { | 71 | { |
72 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 72 | memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
73 | p->opcode = *p->addr; | 73 | p->opcode = *p->addr; |
74 | } | 74 | } |
75 | 75 | ||
76 | void arch_arm_kprobe(struct kprobe *p) | 76 | void __kprobes arch_arm_kprobe(struct kprobe *p) |
77 | { | 77 | { |
78 | *p->addr = BREAKPOINT_INSTRUCTION; | 78 | *p->addr = BREAKPOINT_INSTRUCTION; |
79 | flush_icache_range((unsigned long) p->addr, | 79 | flush_icache_range((unsigned long) p->addr, |
80 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | 80 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); |
81 | } | 81 | } |
82 | 82 | ||
83 | void arch_disarm_kprobe(struct kprobe *p) | 83 | void __kprobes arch_disarm_kprobe(struct kprobe *p) |
84 | { | 84 | { |
85 | *p->addr = p->opcode; | 85 | *p->addr = p->opcode; |
86 | flush_icache_range((unsigned long) p->addr, | 86 | flush_icache_range((unsigned long) p->addr, |
87 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | 87 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); |
88 | } | 88 | } |
89 | 89 | ||
90 | void arch_remove_kprobe(struct kprobe *p) | 90 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
91 | { | 91 | { |
92 | } | 92 | } |
93 | 93 | ||
@@ -127,7 +127,8 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
127 | regs->eip = (unsigned long)&p->ainsn.insn; | 127 | regs->eip = (unsigned long)&p->ainsn.insn; |
128 | } | 128 | } |
129 | 129 | ||
130 | void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) | 130 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, |
131 | struct pt_regs *regs) | ||
131 | { | 132 | { |
132 | unsigned long *sara = (unsigned long *)®s->esp; | 133 | unsigned long *sara = (unsigned long *)®s->esp; |
133 | struct kretprobe_instance *ri; | 134 | struct kretprobe_instance *ri; |
@@ -150,7 +151,7 @@ void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) | |||
150 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | 151 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they |
151 | * remain disabled thorough out this function. | 152 | * remain disabled thorough out this function. |
152 | */ | 153 | */ |
153 | static int kprobe_handler(struct pt_regs *regs) | 154 | static int __kprobes kprobe_handler(struct pt_regs *regs) |
154 | { | 155 | { |
155 | struct kprobe *p; | 156 | struct kprobe *p; |
156 | int ret = 0; | 157 | int ret = 0; |
@@ -176,7 +177,8 @@ static int kprobe_handler(struct pt_regs *regs) | |||
176 | Disarm the probe we just hit, and ignore it. */ | 177 | Disarm the probe we just hit, and ignore it. */ |
177 | p = get_kprobe(addr); | 178 | p = get_kprobe(addr); |
178 | if (p) { | 179 | if (p) { |
179 | if (kprobe_status == KPROBE_HIT_SS) { | 180 | if (kprobe_status == KPROBE_HIT_SS && |
181 | *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { | ||
180 | regs->eflags &= ~TF_MASK; | 182 | regs->eflags &= ~TF_MASK; |
181 | regs->eflags |= kprobe_saved_eflags; | 183 | regs->eflags |= kprobe_saved_eflags; |
182 | unlock_kprobes(); | 184 | unlock_kprobes(); |
@@ -220,7 +222,10 @@ static int kprobe_handler(struct pt_regs *regs) | |||
220 | * either a probepoint or a debugger breakpoint | 222 | * either a probepoint or a debugger breakpoint |
221 | * at this address. In either case, no further | 223 | * at this address. In either case, no further |
222 | * handling of this interrupt is appropriate. | 224 | * handling of this interrupt is appropriate. |
225 | * Back up over the (now missing) int3 and run | ||
226 | * the original instruction. | ||
223 | */ | 227 | */ |
228 | regs->eip -= sizeof(kprobe_opcode_t); | ||
224 | ret = 1; | 229 | ret = 1; |
225 | } | 230 | } |
226 | /* Not one of ours: let kernel handle it */ | 231 | /* Not one of ours: let kernel handle it */ |
@@ -259,7 +264,7 @@ no_kprobe: | |||
259 | /* | 264 | /* |
260 | * Called when we hit the probe point at kretprobe_trampoline | 265 | * Called when we hit the probe point at kretprobe_trampoline |
261 | */ | 266 | */ |
262 | int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | 267 | int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) |
263 | { | 268 | { |
264 | struct kretprobe_instance *ri = NULL; | 269 | struct kretprobe_instance *ri = NULL; |
265 | struct hlist_head *head; | 270 | struct hlist_head *head; |
@@ -338,7 +343,7 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
338 | * that is atop the stack is the address following the copied instruction. | 343 | * that is atop the stack is the address following the copied instruction. |
339 | * We need to make it the address following the original instruction. | 344 | * We need to make it the address following the original instruction. |
340 | */ | 345 | */ |
341 | static void resume_execution(struct kprobe *p, struct pt_regs *regs) | 346 | static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) |
342 | { | 347 | { |
343 | unsigned long *tos = (unsigned long *)®s->esp; | 348 | unsigned long *tos = (unsigned long *)®s->esp; |
344 | unsigned long next_eip = 0; | 349 | unsigned long next_eip = 0; |
@@ -444,8 +449,8 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
444 | /* | 449 | /* |
445 | * Wrapper routine to for handling exceptions. | 450 | * Wrapper routine to for handling exceptions. |
446 | */ | 451 | */ |
447 | int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | 452 | int __kprobes kprobe_exceptions_notify(struct notifier_block *self, |
448 | void *data) | 453 | unsigned long val, void *data) |
449 | { | 454 | { |
450 | struct die_args *args = (struct die_args *)data; | 455 | struct die_args *args = (struct die_args *)data; |
451 | switch (val) { | 456 | switch (val) { |
@@ -473,7 +478,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | |||
473 | return NOTIFY_DONE; | 478 | return NOTIFY_DONE; |
474 | } | 479 | } |
475 | 480 | ||
476 | int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 481 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
477 | { | 482 | { |
478 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 483 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
479 | unsigned long addr; | 484 | unsigned long addr; |
@@ -495,7 +500,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
495 | return 1; | 500 | return 1; |
496 | } | 501 | } |
497 | 502 | ||
498 | void jprobe_return(void) | 503 | void __kprobes jprobe_return(void) |
499 | { | 504 | { |
500 | preempt_enable_no_resched(); | 505 | preempt_enable_no_resched(); |
501 | asm volatile (" xchgl %%ebx,%%esp \n" | 506 | asm volatile (" xchgl %%ebx,%%esp \n" |
@@ -506,7 +511,7 @@ void jprobe_return(void) | |||
506 | (jprobe_saved_esp):"memory"); | 511 | (jprobe_saved_esp):"memory"); |
507 | } | 512 | } |
508 | 513 | ||
509 | int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 514 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
510 | { | 515 | { |
511 | u8 *addr = (u8 *) (regs->eip - 1); | 516 | u8 *addr = (u8 *) (regs->eip - 1); |
512 | unsigned long stack_addr = (unsigned long)jprobe_saved_esp; | 517 | unsigned long stack_addr = (unsigned long)jprobe_saved_esp; |
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c index bb50afbee921..fe1ffa55587d 100644 --- a/arch/i386/kernel/ldt.c +++ b/arch/i386/kernel/ldt.c | |||
@@ -177,7 +177,7 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) | |||
177 | static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) | 177 | static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) |
178 | { | 178 | { |
179 | struct mm_struct * mm = current->mm; | 179 | struct mm_struct * mm = current->mm; |
180 | __u32 entry_1, entry_2, *lp; | 180 | __u32 entry_1, entry_2; |
181 | int error; | 181 | int error; |
182 | struct user_desc ldt_info; | 182 | struct user_desc ldt_info; |
183 | 183 | ||
@@ -205,8 +205,6 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) | |||
205 | goto out_unlock; | 205 | goto out_unlock; |
206 | } | 206 | } |
207 | 207 | ||
208 | lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt); | ||
209 | |||
210 | /* Allow LDTs to be cleared by the user. */ | 208 | /* Allow LDTs to be cleared by the user. */ |
211 | if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { | 209 | if (ldt_info.base_addr == 0 && ldt_info.limit == 0) { |
212 | if (oldmode || LDT_empty(&ldt_info)) { | 210 | if (oldmode || LDT_empty(&ldt_info)) { |
@@ -223,8 +221,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode) | |||
223 | 221 | ||
224 | /* Install the new entry ... */ | 222 | /* Install the new entry ... */ |
225 | install: | 223 | install: |
226 | *lp = entry_1; | 224 | write_ldt_entry(mm->context.ldt, ldt_info.entry_number, entry_1, entry_2); |
227 | *(lp+1) = entry_2; | ||
228 | error = 0; | 225 | error = 0; |
229 | 226 | ||
230 | out_unlock: | 227 | out_unlock: |
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index cb699a2aa1f8..a912fed48482 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c | |||
@@ -17,13 +17,7 @@ | |||
17 | #include <asm/apic.h> | 17 | #include <asm/apic.h> |
18 | #include <asm/cpufeature.h> | 18 | #include <asm/cpufeature.h> |
19 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
20 | 20 | #include <asm/system.h> | |
21 | static inline unsigned long read_cr3(void) | ||
22 | { | ||
23 | unsigned long cr3; | ||
24 | asm volatile("movl %%cr3,%0": "=r"(cr3)); | ||
25 | return cr3; | ||
26 | } | ||
27 | 21 | ||
28 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) | 22 | #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) |
29 | 23 | ||
@@ -99,10 +93,7 @@ static void set_idt(void *newidt, __u16 limit) | |||
99 | curidt.size = limit; | 93 | curidt.size = limit; |
100 | curidt.address = (unsigned long)newidt; | 94 | curidt.address = (unsigned long)newidt; |
101 | 95 | ||
102 | __asm__ __volatile__ ( | 96 | load_idt(&curidt); |
103 | "lidtl %0\n" | ||
104 | : : "m" (curidt) | ||
105 | ); | ||
106 | }; | 97 | }; |
107 | 98 | ||
108 | 99 | ||
@@ -114,10 +105,7 @@ static void set_gdt(void *newgdt, __u16 limit) | |||
114 | curgdt.size = limit; | 105 | curgdt.size = limit; |
115 | curgdt.address = (unsigned long)newgdt; | 106 | curgdt.address = (unsigned long)newgdt; |
116 | 107 | ||
117 | __asm__ __volatile__ ( | 108 | load_gdt(&curgdt); |
118 | "lgdtl %0\n" | ||
119 | : : "m" (curgdt) | ||
120 | ); | ||
121 | }; | 109 | }; |
122 | 110 | ||
123 | static void load_segments(void) | 111 | static void load_segments(void) |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index a77c612aad00..165f13158c60 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -164,7 +164,8 @@ static void collect_cpu_info (void *unused) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 166 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
167 | __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); | 167 | /* see notes above for revision 1.07. Apparent chip bug */ |
168 | serialize_cpu(); | ||
168 | /* get the current revision from MSR 0x8B */ | 169 | /* get the current revision from MSR 0x8B */ |
169 | rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); | 170 | rdmsr(MSR_IA32_UCODE_REV, val[0], uci->rev); |
170 | pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", | 171 | pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", |
@@ -377,7 +378,9 @@ static void do_update_one (void * unused) | |||
377 | (unsigned long) uci->mc->bits >> 16 >> 16); | 378 | (unsigned long) uci->mc->bits >> 16 >> 16); |
378 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | 379 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); |
379 | 380 | ||
380 | __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx"); | 381 | /* see notes above for revision 1.07. Apparent chip bug */ |
382 | serialize_cpu(); | ||
383 | |||
381 | /* get the current revision from MSR 0x8B */ | 384 | /* get the current revision from MSR 0x8B */ |
382 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | 385 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); |
383 | 386 | ||
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index ce838abb27d8..cafaeffe3818 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -65,6 +65,8 @@ int nr_ioapics; | |||
65 | int pic_mode; | 65 | int pic_mode; |
66 | unsigned long mp_lapic_addr; | 66 | unsigned long mp_lapic_addr; |
67 | 67 | ||
68 | unsigned int def_to_bigsmp = 0; | ||
69 | |||
68 | /* Processor that is doing the boot up */ | 70 | /* Processor that is doing the boot up */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 71 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | /* Internal processor count */ | 72 | /* Internal processor count */ |
@@ -120,7 +122,7 @@ static int MP_valid_apicid(int apicid, int version) | |||
120 | 122 | ||
121 | static void __init MP_processor_info (struct mpc_config_processor *m) | 123 | static void __init MP_processor_info (struct mpc_config_processor *m) |
122 | { | 124 | { |
123 | int ver, apicid; | 125 | int ver, apicid, cpu, found_bsp = 0; |
124 | physid_mask_t tmp; | 126 | physid_mask_t tmp; |
125 | 127 | ||
126 | if (!(m->mpc_cpuflag & CPU_ENABLED)) | 128 | if (!(m->mpc_cpuflag & CPU_ENABLED)) |
@@ -179,6 +181,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
179 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { | 181 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { |
180 | Dprintk(" Bootup CPU\n"); | 182 | Dprintk(" Bootup CPU\n"); |
181 | boot_cpu_physical_apicid = m->mpc_apicid; | 183 | boot_cpu_physical_apicid = m->mpc_apicid; |
184 | found_bsp = 1; | ||
182 | } | 185 | } |
183 | 186 | ||
184 | if (num_processors >= NR_CPUS) { | 187 | if (num_processors >= NR_CPUS) { |
@@ -202,6 +205,11 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
202 | return; | 205 | return; |
203 | } | 206 | } |
204 | 207 | ||
208 | if (found_bsp) | ||
209 | cpu = 0; | ||
210 | else | ||
211 | cpu = num_processors - 1; | ||
212 | cpu_set(cpu, cpu_possible_map); | ||
205 | tmp = apicid_to_cpu_present(apicid); | 213 | tmp = apicid_to_cpu_present(apicid); |
206 | physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); | 214 | physids_or(phys_cpu_present_map, phys_cpu_present_map, tmp); |
207 | 215 | ||
@@ -213,6 +221,13 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
213 | ver = 0x10; | 221 | ver = 0x10; |
214 | } | 222 | } |
215 | apic_version[m->mpc_apicid] = ver; | 223 | apic_version[m->mpc_apicid] = ver; |
224 | if ((num_processors > 8) && | ||
225 | APIC_XAPIC(ver) && | ||
226 | (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) | ||
227 | def_to_bigsmp = 1; | ||
228 | else | ||
229 | def_to_bigsmp = 0; | ||
230 | |||
216 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; | 231 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; |
217 | } | 232 | } |
218 | 233 | ||
@@ -653,8 +668,6 @@ void __init get_smp_config (void) | |||
653 | struct intel_mp_floating *mpf = mpf_found; | 668 | struct intel_mp_floating *mpf = mpf_found; |
654 | 669 | ||
655 | /* | 670 | /* |
656 | * ACPI may be used to obtain the entire SMP configuration or just to | ||
657 | * enumerate/configure processors (CONFIG_ACPI_BOOT). Note that | ||
658 | * ACPI supports both logical (e.g. Hyper-Threading) and physical | 671 | * ACPI supports both logical (e.g. Hyper-Threading) and physical |
659 | * processors, where MPS only supports physical. | 672 | * processors, where MPS only supports physical. |
660 | */ | 673 | */ |
@@ -810,7 +823,7 @@ void __init find_smp_config (void) | |||
810 | ACPI-based MP Configuration | 823 | ACPI-based MP Configuration |
811 | -------------------------------------------------------------------------- */ | 824 | -------------------------------------------------------------------------- */ |
812 | 825 | ||
813 | #ifdef CONFIG_ACPI_BOOT | 826 | #ifdef CONFIG_ACPI |
814 | 827 | ||
815 | void __init mp_register_lapic_address ( | 828 | void __init mp_register_lapic_address ( |
816 | u64 address) | 829 | u64 address) |
@@ -856,7 +869,7 @@ void __init mp_register_lapic ( | |||
856 | MP_processor_info(&processor); | 869 | MP_processor_info(&processor); |
857 | } | 870 | } |
858 | 871 | ||
859 | #if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) | 872 | #ifdef CONFIG_X86_IO_APIC |
860 | 873 | ||
861 | #define MP_ISA_BUS 0 | 874 | #define MP_ISA_BUS 0 |
862 | #define MP_MAX_IOAPIC_PIN 127 | 875 | #define MP_MAX_IOAPIC_PIN 127 |
@@ -1071,11 +1084,9 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) | |||
1071 | */ | 1084 | */ |
1072 | static int gsi_to_irq[MAX_GSI_NUM]; | 1085 | static int gsi_to_irq[MAX_GSI_NUM]; |
1073 | 1086 | ||
1074 | #ifdef CONFIG_ACPI_BUS | ||
1075 | /* Don't set up the ACPI SCI because it's already set up */ | 1087 | /* Don't set up the ACPI SCI because it's already set up */ |
1076 | if (acpi_fadt.sci_int == gsi) | 1088 | if (acpi_fadt.sci_int == gsi) |
1077 | return gsi; | 1089 | return gsi; |
1078 | #endif | ||
1079 | 1090 | ||
1080 | ioapic = mp_find_ioapic(gsi); | 1091 | ioapic = mp_find_ioapic(gsi); |
1081 | if (ioapic < 0) { | 1092 | if (ioapic < 0) { |
@@ -1118,13 +1129,11 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) | |||
1118 | if (gsi < MAX_GSI_NUM) { | 1129 | if (gsi < MAX_GSI_NUM) { |
1119 | if (gsi > 15) | 1130 | if (gsi > 15) |
1120 | gsi = pci_irq++; | 1131 | gsi = pci_irq++; |
1121 | #ifdef CONFIG_ACPI_BUS | ||
1122 | /* | 1132 | /* |
1123 | * Don't assign IRQ used by ACPI SCI | 1133 | * Don't assign IRQ used by ACPI SCI |
1124 | */ | 1134 | */ |
1125 | if (gsi == acpi_fadt.sci_int) | 1135 | if (gsi == acpi_fadt.sci_int) |
1126 | gsi = pci_irq++; | 1136 | gsi = pci_irq++; |
1127 | #endif | ||
1128 | gsi_to_irq[irq] = gsi; | 1137 | gsi_to_irq[irq] = gsi; |
1129 | } else { | 1138 | } else { |
1130 | printk(KERN_ERR "GSI %u is too high\n", gsi); | 1139 | printk(KERN_ERR "GSI %u is too high\n", gsi); |
@@ -1138,5 +1147,5 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) | |||
1138 | return gsi; | 1147 | return gsi; |
1139 | } | 1148 | } |
1140 | 1149 | ||
1141 | #endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/ | 1150 | #endif /* CONFIG_X86_IO_APIC */ |
1142 | #endif /*CONFIG_ACPI_BOOT*/ | 1151 | #endif /* CONFIG_ACPI */ |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index b2f03c39a6fe..03100d6fc5d6 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -46,23 +46,13 @@ | |||
46 | 46 | ||
47 | static struct class *msr_class; | 47 | static struct class *msr_class; |
48 | 48 | ||
49 | /* Note: "err" is handled in a funny way below. Otherwise one version | ||
50 | of gcc or another breaks. */ | ||
51 | |||
52 | static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) | 49 | static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) |
53 | { | 50 | { |
54 | int err; | 51 | int err; |
55 | 52 | ||
56 | asm volatile ("1: wrmsr\n" | 53 | err = wrmsr_safe(reg, eax, edx); |
57 | "2:\n" | 54 | if (err) |
58 | ".section .fixup,\"ax\"\n" | 55 | err = -EIO; |
59 | "3: movl %4,%0\n" | ||
60 | " jmp 2b\n" | ||
61 | ".previous\n" | ||
62 | ".section __ex_table,\"a\"\n" | ||
63 | " .align 4\n" " .long 1b,3b\n" ".previous":"=&bDS" (err) | ||
64 | :"a"(eax), "d"(edx), "c"(reg), "i"(-EIO), "0"(0)); | ||
65 | |||
66 | return err; | 56 | return err; |
67 | } | 57 | } |
68 | 58 | ||
@@ -70,18 +60,9 @@ static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) | |||
70 | { | 60 | { |
71 | int err; | 61 | int err; |
72 | 62 | ||
73 | asm volatile ("1: rdmsr\n" | 63 | err = rdmsr_safe(reg, eax, edx); |
74 | "2:\n" | 64 | if (err) |
75 | ".section .fixup,\"ax\"\n" | 65 | err = -EIO; |
76 | "3: movl %4,%0\n" | ||
77 | " jmp 2b\n" | ||
78 | ".previous\n" | ||
79 | ".section __ex_table,\"a\"\n" | ||
80 | " .align 4\n" | ||
81 | " .long 1b,3b\n" | ||
82 | ".previous":"=&bDS" (err), "=a"(*eax), "=d"(*edx) | ||
83 | :"c"(reg), "i"(-EIO), "0"(0)); | ||
84 | |||
85 | return err; | 66 | return err; |
86 | } | 67 | } |
87 | 68 | ||
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 8c242bb1ef45..0178457db721 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -478,6 +478,11 @@ void touch_nmi_watchdog (void) | |||
478 | */ | 478 | */ |
479 | for (i = 0; i < NR_CPUS; i++) | 479 | for (i = 0; i < NR_CPUS; i++) |
480 | alert_counter[i] = 0; | 480 | alert_counter[i] = 0; |
481 | |||
482 | /* | ||
483 | * Tickle the softlockup detector too: | ||
484 | */ | ||
485 | touch_softlockup_watchdog(); | ||
481 | } | 486 | } |
482 | 487 | ||
483 | extern void die_nmi(struct pt_regs *, const char *msg); | 488 | extern void die_nmi(struct pt_regs *, const char *msg); |
@@ -501,8 +506,11 @@ void nmi_watchdog_tick (struct pt_regs * regs) | |||
501 | */ | 506 | */ |
502 | alert_counter[cpu]++; | 507 | alert_counter[cpu]++; |
503 | if (alert_counter[cpu] == 5*nmi_hz) | 508 | if (alert_counter[cpu] == 5*nmi_hz) |
509 | /* | ||
510 | * die_nmi will return ONLY if NOTIFY_STOP happens.. | ||
511 | */ | ||
504 | die_nmi(regs, "NMI Watchdog detected LOCKUP"); | 512 | die_nmi(regs, "NMI Watchdog detected LOCKUP"); |
505 | } else { | 513 | |
506 | last_irq_sums[cpu] = sum; | 514 | last_irq_sums[cpu] = sum; |
507 | alert_counter[cpu] = 0; | 515 | alert_counter[cpu] = 0; |
508 | } | 516 | } |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index e3f362e8af5b..b45cbf93d439 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -164,7 +164,7 @@ static inline void play_dead(void) | |||
164 | */ | 164 | */ |
165 | local_irq_disable(); | 165 | local_irq_disable(); |
166 | while (1) | 166 | while (1) |
167 | __asm__ __volatile__("hlt":::"memory"); | 167 | halt(); |
168 | } | 168 | } |
169 | #else | 169 | #else |
170 | static inline void play_dead(void) | 170 | static inline void play_dead(void) |
@@ -313,16 +313,12 @@ void show_regs(struct pt_regs * regs) | |||
313 | printk(" DS: %04x ES: %04x\n", | 313 | printk(" DS: %04x ES: %04x\n", |
314 | 0xffff & regs->xds,0xffff & regs->xes); | 314 | 0xffff & regs->xds,0xffff & regs->xes); |
315 | 315 | ||
316 | __asm__("movl %%cr0, %0": "=r" (cr0)); | 316 | cr0 = read_cr0(); |
317 | __asm__("movl %%cr2, %0": "=r" (cr2)); | 317 | cr2 = read_cr2(); |
318 | __asm__("movl %%cr3, %0": "=r" (cr3)); | 318 | cr3 = read_cr3(); |
319 | /* This could fault if %cr4 does not exist */ | 319 | if (current_cpu_data.x86 > 4) { |
320 | __asm__("1: movl %%cr4, %0 \n" | 320 | cr4 = read_cr4(); |
321 | "2: \n" | 321 | } |
322 | ".section __ex_table,\"a\" \n" | ||
323 | ".long 1b,2b \n" | ||
324 | ".previous \n" | ||
325 | : "=r" (cr4): "0" (0)); | ||
326 | printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); | 322 | printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); |
327 | show_trace(NULL, ®s->esp); | 323 | show_trace(NULL, ®s->esp); |
328 | } | 324 | } |
@@ -682,21 +678,26 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas | |||
682 | __unlazy_fpu(prev_p); | 678 | __unlazy_fpu(prev_p); |
683 | 679 | ||
684 | /* | 680 | /* |
685 | * Reload esp0, LDT and the page table pointer: | 681 | * Reload esp0. |
686 | */ | 682 | */ |
687 | load_esp0(tss, next); | 683 | load_esp0(tss, next); |
688 | 684 | ||
689 | /* | 685 | /* |
690 | * Load the per-thread Thread-Local Storage descriptor. | 686 | * Save away %fs and %gs. No need to save %es and %ds, as |
687 | * those are always kernel segments while inside the kernel. | ||
688 | * Doing this before setting the new TLS descriptors avoids | ||
689 | * the situation where we temporarily have non-reloadable | ||
690 | * segments in %fs and %gs. This could be an issue if the | ||
691 | * NMI handler ever used %fs or %gs (it does not today), or | ||
692 | * if the kernel is running inside of a hypervisor layer. | ||
691 | */ | 693 | */ |
692 | load_TLS(next, cpu); | 694 | savesegment(fs, prev->fs); |
695 | savesegment(gs, prev->gs); | ||
693 | 696 | ||
694 | /* | 697 | /* |
695 | * Save away %fs and %gs. No need to save %es and %ds, as | 698 | * Load the per-thread Thread-Local Storage descriptor. |
696 | * those are always kernel segments while inside the kernel. | ||
697 | */ | 699 | */ |
698 | asm volatile("mov %%fs,%0":"=m" (prev->fs)); | 700 | load_TLS(next, cpu); |
699 | asm volatile("mov %%gs,%0":"=m" (prev->gs)); | ||
700 | 701 | ||
701 | /* | 702 | /* |
702 | * Restore %fs and %gs if needed. | 703 | * Restore %fs and %gs if needed. |
@@ -711,6 +712,12 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas | |||
711 | loadsegment(gs, next->gs); | 712 | loadsegment(gs, next->gs); |
712 | 713 | ||
713 | /* | 714 | /* |
715 | * Restore IOPL if needed. | ||
716 | */ | ||
717 | if (unlikely(prev->iopl != next->iopl)) | ||
718 | set_iopl_mask(next->iopl); | ||
719 | |||
720 | /* | ||
714 | * Now maybe reload the debug registers | 721 | * Now maybe reload the debug registers |
715 | */ | 722 | */ |
716 | if (unlikely(next->debugreg[7])) { | 723 | if (unlikely(next->debugreg[7])) { |
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 0da59b42843c..340980203b09 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
@@ -271,6 +271,8 @@ static void clear_singlestep(struct task_struct *child) | |||
271 | void ptrace_disable(struct task_struct *child) | 271 | void ptrace_disable(struct task_struct *child) |
272 | { | 272 | { |
273 | clear_singlestep(child); | 273 | clear_singlestep(child); |
274 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
275 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
274 | } | 276 | } |
275 | 277 | ||
276 | /* | 278 | /* |
@@ -509,15 +511,20 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
509 | } | 511 | } |
510 | break; | 512 | break; |
511 | 513 | ||
514 | case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */ | ||
512 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 515 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
513 | case PTRACE_CONT: /* restart after signal. */ | 516 | case PTRACE_CONT: /* restart after signal. */ |
514 | ret = -EIO; | 517 | ret = -EIO; |
515 | if (!valid_signal(data)) | 518 | if (!valid_signal(data)) |
516 | break; | 519 | break; |
517 | if (request == PTRACE_SYSCALL) { | 520 | if (request == PTRACE_SYSEMU) { |
521 | set_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
522 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
523 | } else if (request == PTRACE_SYSCALL) { | ||
518 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 524 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
519 | } | 525 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); |
520 | else { | 526 | } else { |
527 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
521 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 528 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
522 | } | 529 | } |
523 | child->exit_code = data; | 530 | child->exit_code = data; |
@@ -542,10 +549,17 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
542 | wake_up_process(child); | 549 | wake_up_process(child); |
543 | break; | 550 | break; |
544 | 551 | ||
552 | case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */ | ||
545 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | 553 | case PTRACE_SINGLESTEP: /* set the trap flag. */ |
546 | ret = -EIO; | 554 | ret = -EIO; |
547 | if (!valid_signal(data)) | 555 | if (!valid_signal(data)) |
548 | break; | 556 | break; |
557 | |||
558 | if (request == PTRACE_SYSEMU_SINGLESTEP) | ||
559 | set_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
560 | else | ||
561 | clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); | ||
562 | |||
549 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 563 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
550 | set_singlestep(child); | 564 | set_singlestep(child); |
551 | child->exit_code = data; | 565 | child->exit_code = data; |
@@ -678,26 +692,52 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) | |||
678 | * - triggered by current->work.syscall_trace | 692 | * - triggered by current->work.syscall_trace |
679 | */ | 693 | */ |
680 | __attribute__((regparm(3))) | 694 | __attribute__((regparm(3))) |
681 | void do_syscall_trace(struct pt_regs *regs, int entryexit) | 695 | int do_syscall_trace(struct pt_regs *regs, int entryexit) |
682 | { | 696 | { |
697 | int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0; | ||
698 | /* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall | ||
699 | * interception. */ | ||
700 | int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP); | ||
701 | |||
683 | /* do the secure computing check first */ | 702 | /* do the secure computing check first */ |
684 | secure_computing(regs->orig_eax); | 703 | secure_computing(regs->orig_eax); |
685 | 704 | ||
686 | if (unlikely(current->audit_context) && entryexit) | 705 | if (unlikely(current->audit_context)) { |
687 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); | 706 | if (entryexit) |
707 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); | ||
708 | /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only | ||
709 | * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is | ||
710 | * not used, entry.S will call us only on syscall exit, not | ||
711 | * entry; so when TIF_SYSCALL_AUDIT is used we must avoid | ||
712 | * calling send_sigtrap() on syscall entry. | ||
713 | * | ||
714 | * Note that when PTRACE_SYSEMU_SINGLESTEP is used, | ||
715 | * is_singlestep is false, despite his name, so we will still do | ||
716 | * the correct thing. | ||
717 | */ | ||
718 | else if (is_singlestep) | ||
719 | goto out; | ||
720 | } | ||
688 | 721 | ||
689 | if (!(current->ptrace & PT_PTRACED)) | 722 | if (!(current->ptrace & PT_PTRACED)) |
690 | goto out; | 723 | goto out; |
691 | 724 | ||
725 | /* If a process stops on the 1st tracepoint with SYSCALL_TRACE | ||
726 | * and then is resumed with SYSEMU_SINGLESTEP, it will come in | ||
727 | * here. We have to check this and return */ | ||
728 | if (is_sysemu && entryexit) | ||
729 | return 0; | ||
730 | |||
692 | /* Fake a debug trap */ | 731 | /* Fake a debug trap */ |
693 | if (test_thread_flag(TIF_SINGLESTEP)) | 732 | if (is_singlestep) |
694 | send_sigtrap(current, regs, 0); | 733 | send_sigtrap(current, regs, 0); |
695 | 734 | ||
696 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 735 | if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu) |
697 | goto out; | 736 | goto out; |
698 | 737 | ||
699 | /* the 0x80 provides a way for the tracing parent to distinguish | 738 | /* the 0x80 provides a way for the tracing parent to distinguish |
700 | between a syscall stop and SIGTRAP delivery */ | 739 | between a syscall stop and SIGTRAP delivery */ |
740 | /* Note that the debugger could change the result of test_thread_flag!*/ | ||
701 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); | 741 | ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); |
702 | 742 | ||
703 | /* | 743 | /* |
@@ -709,9 +749,16 @@ void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
709 | send_sig(current->exit_code, current, 1); | 749 | send_sig(current->exit_code, current, 1); |
710 | current->exit_code = 0; | 750 | current->exit_code = 0; |
711 | } | 751 | } |
752 | ret = is_sysemu; | ||
712 | out: | 753 | out: |
713 | if (unlikely(current->audit_context) && !entryexit) | 754 | if (unlikely(current->audit_context) && !entryexit) |
714 | audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, | 755 | audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, |
715 | regs->ebx, regs->ecx, regs->edx, regs->esi); | 756 | regs->ebx, regs->ecx, regs->edx, regs->esi); |
757 | if (ret == 0) | ||
758 | return 0; | ||
716 | 759 | ||
760 | regs->orig_eax = -1; /* force skip of syscall restarting */ | ||
761 | if (unlikely(current->audit_context)) | ||
762 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); | ||
763 | return 1; | ||
717 | } | 764 | } |
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index c71fef31dc47..1cbb9c0f4704 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/dmi.h> | 13 | #include <linux/dmi.h> |
14 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
15 | #include <asm/apic.h> | 15 | #include <asm/apic.h> |
16 | #include <asm/desc.h> | ||
16 | #include "mach_reboot.h" | 17 | #include "mach_reboot.h" |
17 | #include <linux/reboot_fixups.h> | 18 | #include <linux/reboot_fixups.h> |
18 | 19 | ||
@@ -242,13 +243,13 @@ void machine_real_restart(unsigned char *code, int length) | |||
242 | 243 | ||
243 | /* Set up the IDT for real mode. */ | 244 | /* Set up the IDT for real mode. */ |
244 | 245 | ||
245 | __asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt)); | 246 | load_idt(&real_mode_idt); |
246 | 247 | ||
247 | /* Set up a GDT from which we can load segment descriptors for real | 248 | /* Set up a GDT from which we can load segment descriptors for real |
248 | mode. The GDT is not used in real mode; it is just needed here to | 249 | mode. The GDT is not used in real mode; it is just needed here to |
249 | prepare the descriptors. */ | 250 | prepare the descriptors. */ |
250 | 251 | ||
251 | __asm__ __volatile__ ("lgdt %0" : : "m" (real_mode_gdt)); | 252 | load_gdt(&real_mode_gdt); |
252 | 253 | ||
253 | /* Load the data segment registers, and thus the descriptors ready for | 254 | /* Load the data segment registers, and thus the descriptors ready for |
254 | real mode. The base address of each segment is 0x100, 16 times the | 255 | real mode. The base address of each segment is 0x100, 16 times the |
@@ -316,7 +317,7 @@ void machine_emergency_restart(void) | |||
316 | if (!reboot_thru_bios) { | 317 | if (!reboot_thru_bios) { |
317 | if (efi_enabled) { | 318 | if (efi_enabled) { |
318 | efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); | 319 | efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); |
319 | __asm__ __volatile__("lidt %0": :"m" (no_idt)); | 320 | load_idt(&no_idt); |
320 | __asm__ __volatile__("int3"); | 321 | __asm__ __volatile__("int3"); |
321 | } | 322 | } |
322 | /* rebooting needs to touch the page at absolute addr 0 */ | 323 | /* rebooting needs to touch the page at absolute addr 0 */ |
@@ -325,7 +326,7 @@ void machine_emergency_restart(void) | |||
325 | mach_reboot_fixups(); /* for board specific fixups */ | 326 | mach_reboot_fixups(); /* for board specific fixups */ |
326 | mach_reboot(); | 327 | mach_reboot(); |
327 | /* That didn't work - force a triple fault.. */ | 328 | /* That didn't work - force a triple fault.. */ |
328 | __asm__ __volatile__("lidt %0": :"m" (no_idt)); | 329 | load_idt(&no_idt); |
329 | __asm__ __volatile__("int3"); | 330 | __asm__ __volatile__("int3"); |
330 | } | 331 | } |
331 | } | 332 | } |
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c index 469f496e55c0..7455ab643943 100644 --- a/arch/i386/kernel/semaphore.c +++ b/arch/i386/kernel/semaphore.c | |||
@@ -13,171 +13,9 @@ | |||
13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> | 13 | * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org> |
14 | */ | 14 | */ |
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
16 | #include <linux/sched.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <asm/semaphore.h> | 16 | #include <asm/semaphore.h> |
20 | 17 | ||
21 | /* | 18 | /* |
22 | * Semaphores are implemented using a two-way counter: | ||
23 | * The "count" variable is decremented for each process | ||
24 | * that tries to acquire the semaphore, while the "sleeping" | ||
25 | * variable is a count of such acquires. | ||
26 | * | ||
27 | * Notably, the inline "up()" and "down()" functions can | ||
28 | * efficiently test if they need to do any extra work (up | ||
29 | * needs to do something only if count was negative before | ||
30 | * the increment operation. | ||
31 | * | ||
32 | * "sleeping" and the contention routine ordering is protected | ||
33 | * by the spinlock in the semaphore's waitqueue head. | ||
34 | * | ||
35 | * Note that these functions are only called when there is | ||
36 | * contention on the lock, and as such all this is the | ||
37 | * "non-critical" part of the whole semaphore business. The | ||
38 | * critical part is the inline stuff in <asm/semaphore.h> | ||
39 | * where we want to avoid any extra jumps and calls. | ||
40 | */ | ||
41 | |||
42 | /* | ||
43 | * Logic: | ||
44 | * - only on a boundary condition do we need to care. When we go | ||
45 | * from a negative count to a non-negative, we wake people up. | ||
46 | * - when we go from a non-negative count to a negative do we | ||
47 | * (a) synchronize with the "sleeper" count and (b) make sure | ||
48 | * that we're on the wakeup list before we synchronize so that | ||
49 | * we cannot lose wakeup events. | ||
50 | */ | ||
51 | |||
52 | static fastcall void __attribute_used__ __up(struct semaphore *sem) | ||
53 | { | ||
54 | wake_up(&sem->wait); | ||
55 | } | ||
56 | |||
57 | static fastcall void __attribute_used__ __sched __down(struct semaphore * sem) | ||
58 | { | ||
59 | struct task_struct *tsk = current; | ||
60 | DECLARE_WAITQUEUE(wait, tsk); | ||
61 | unsigned long flags; | ||
62 | |||
63 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
64 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
65 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
66 | |||
67 | sem->sleepers++; | ||
68 | for (;;) { | ||
69 | int sleepers = sem->sleepers; | ||
70 | |||
71 | /* | ||
72 | * Add "everybody else" into it. They aren't | ||
73 | * playing, because we own the spinlock in | ||
74 | * the wait_queue_head. | ||
75 | */ | ||
76 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
77 | sem->sleepers = 0; | ||
78 | break; | ||
79 | } | ||
80 | sem->sleepers = 1; /* us - see -1 above */ | ||
81 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
82 | |||
83 | schedule(); | ||
84 | |||
85 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
86 | tsk->state = TASK_UNINTERRUPTIBLE; | ||
87 | } | ||
88 | remove_wait_queue_locked(&sem->wait, &wait); | ||
89 | wake_up_locked(&sem->wait); | ||
90 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
91 | tsk->state = TASK_RUNNING; | ||
92 | } | ||
93 | |||
94 | static fastcall int __attribute_used__ __sched __down_interruptible(struct semaphore * sem) | ||
95 | { | ||
96 | int retval = 0; | ||
97 | struct task_struct *tsk = current; | ||
98 | DECLARE_WAITQUEUE(wait, tsk); | ||
99 | unsigned long flags; | ||
100 | |||
101 | tsk->state = TASK_INTERRUPTIBLE; | ||
102 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
103 | add_wait_queue_exclusive_locked(&sem->wait, &wait); | ||
104 | |||
105 | sem->sleepers++; | ||
106 | for (;;) { | ||
107 | int sleepers = sem->sleepers; | ||
108 | |||
109 | /* | ||
110 | * With signals pending, this turns into | ||
111 | * the trylock failure case - we won't be | ||
112 | * sleeping, and we* can't get the lock as | ||
113 | * it has contention. Just correct the count | ||
114 | * and exit. | ||
115 | */ | ||
116 | if (signal_pending(current)) { | ||
117 | retval = -EINTR; | ||
118 | sem->sleepers = 0; | ||
119 | atomic_add(sleepers, &sem->count); | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Add "everybody else" into it. They aren't | ||
125 | * playing, because we own the spinlock in | ||
126 | * wait_queue_head. The "-1" is because we're | ||
127 | * still hoping to get the semaphore. | ||
128 | */ | ||
129 | if (!atomic_add_negative(sleepers - 1, &sem->count)) { | ||
130 | sem->sleepers = 0; | ||
131 | break; | ||
132 | } | ||
133 | sem->sleepers = 1; /* us - see -1 above */ | ||
134 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
135 | |||
136 | schedule(); | ||
137 | |||
138 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
139 | tsk->state = TASK_INTERRUPTIBLE; | ||
140 | } | ||
141 | remove_wait_queue_locked(&sem->wait, &wait); | ||
142 | wake_up_locked(&sem->wait); | ||
143 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
144 | |||
145 | tsk->state = TASK_RUNNING; | ||
146 | return retval; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Trylock failed - make sure we correct for | ||
151 | * having decremented the count. | ||
152 | * | ||
153 | * We could have done the trylock with a | ||
154 | * single "cmpxchg" without failure cases, | ||
155 | * but then it wouldn't work on a 386. | ||
156 | */ | ||
157 | static fastcall int __attribute_used__ __down_trylock(struct semaphore * sem) | ||
158 | { | ||
159 | int sleepers; | ||
160 | unsigned long flags; | ||
161 | |||
162 | spin_lock_irqsave(&sem->wait.lock, flags); | ||
163 | sleepers = sem->sleepers + 1; | ||
164 | sem->sleepers = 0; | ||
165 | |||
166 | /* | ||
167 | * Add "everybody else" and us into it. They aren't | ||
168 | * playing, because we own the spinlock in the | ||
169 | * wait_queue_head. | ||
170 | */ | ||
171 | if (!atomic_add_negative(sleepers, &sem->count)) { | ||
172 | wake_up_locked(&sem->wait); | ||
173 | } | ||
174 | |||
175 | spin_unlock_irqrestore(&sem->wait.lock, flags); | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | |||
180 | /* | ||
181 | * The semaphore operations have a special calling sequence that | 19 | * The semaphore operations have a special calling sequence that |
182 | * allow us to do a simpler in-line version of them. These routines | 20 | * allow us to do a simpler in-line version of them. These routines |
183 | * need to convert that sequence back into the C sequence when | 21 | * need to convert that sequence back into the C sequence when |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index af4de58cab54..a659d274914c 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -82,19 +82,19 @@ EXPORT_SYMBOL(efi_enabled); | |||
82 | /* cpu data as detected by the assembly code in head.S */ | 82 | /* cpu data as detected by the assembly code in head.S */ |
83 | struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; | 83 | struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; |
84 | /* common cpu data for all cpus */ | 84 | /* common cpu data for all cpus */ |
85 | struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; | 85 | struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; |
86 | EXPORT_SYMBOL(boot_cpu_data); | 86 | EXPORT_SYMBOL(boot_cpu_data); |
87 | 87 | ||
88 | unsigned long mmu_cr4_features; | 88 | unsigned long mmu_cr4_features; |
89 | 89 | ||
90 | #ifdef CONFIG_ACPI_INTERPRETER | 90 | #ifdef CONFIG_ACPI |
91 | int acpi_disabled = 0; | 91 | int acpi_disabled = 0; |
92 | #else | 92 | #else |
93 | int acpi_disabled = 1; | 93 | int acpi_disabled = 1; |
94 | #endif | 94 | #endif |
95 | EXPORT_SYMBOL(acpi_disabled); | 95 | EXPORT_SYMBOL(acpi_disabled); |
96 | 96 | ||
97 | #ifdef CONFIG_ACPI_BOOT | 97 | #ifdef CONFIG_ACPI |
98 | int __initdata acpi_force = 0; | 98 | int __initdata acpi_force = 0; |
99 | extern acpi_interrupt_flags acpi_sci_flags; | 99 | extern acpi_interrupt_flags acpi_sci_flags; |
100 | #endif | 100 | #endif |
@@ -370,12 +370,16 @@ static void __init limit_regions(unsigned long long size) | |||
370 | int i; | 370 | int i; |
371 | 371 | ||
372 | if (efi_enabled) { | 372 | if (efi_enabled) { |
373 | for (i = 0; i < memmap.nr_map; i++) { | 373 | efi_memory_desc_t *md; |
374 | current_addr = memmap.map[i].phys_addr + | 374 | void *p; |
375 | (memmap.map[i].num_pages << 12); | 375 | |
376 | if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) { | 376 | for (p = memmap.map, i = 0; p < memmap.map_end; |
377 | p += memmap.desc_size, i++) { | ||
378 | md = p; | ||
379 | current_addr = md->phys_addr + (md->num_pages << 12); | ||
380 | if (md->type == EFI_CONVENTIONAL_MEMORY) { | ||
377 | if (current_addr >= size) { | 381 | if (current_addr >= size) { |
378 | memmap.map[i].num_pages -= | 382 | md->num_pages -= |
379 | (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); | 383 | (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); |
380 | memmap.nr_map = i + 1; | 384 | memmap.nr_map = i + 1; |
381 | return; | 385 | return; |
@@ -794,7 +798,7 @@ static void __init parse_cmdline_early (char ** cmdline_p) | |||
794 | } | 798 | } |
795 | #endif | 799 | #endif |
796 | 800 | ||
797 | #ifdef CONFIG_ACPI_BOOT | 801 | #ifdef CONFIG_ACPI |
798 | /* "acpi=off" disables both ACPI table parsing and interpreter */ | 802 | /* "acpi=off" disables both ACPI table parsing and interpreter */ |
799 | else if (!memcmp(from, "acpi=off", 8)) { | 803 | else if (!memcmp(from, "acpi=off", 8)) { |
800 | disable_acpi(); | 804 | disable_acpi(); |
@@ -850,7 +854,7 @@ static void __init parse_cmdline_early (char ** cmdline_p) | |||
850 | else if (!memcmp(from, "noapic", 6)) | 854 | else if (!memcmp(from, "noapic", 6)) |
851 | disable_ioapic_setup(); | 855 | disable_ioapic_setup(); |
852 | #endif /* CONFIG_X86_LOCAL_APIC */ | 856 | #endif /* CONFIG_X86_LOCAL_APIC */ |
853 | #endif /* CONFIG_ACPI_BOOT */ | 857 | #endif /* CONFIG_ACPI */ |
854 | 858 | ||
855 | #ifdef CONFIG_X86_LOCAL_APIC | 859 | #ifdef CONFIG_X86_LOCAL_APIC |
856 | /* enable local APIC */ | 860 | /* enable local APIC */ |
@@ -1575,14 +1579,20 @@ void __init setup_arch(char **cmdline_p) | |||
1575 | if (efi_enabled) | 1579 | if (efi_enabled) |
1576 | efi_map_memmap(); | 1580 | efi_map_memmap(); |
1577 | 1581 | ||
1578 | #ifdef CONFIG_ACPI_BOOT | 1582 | #ifdef CONFIG_ACPI |
1579 | /* | 1583 | /* |
1580 | * Parse the ACPI tables for possible boot-time SMP configuration. | 1584 | * Parse the ACPI tables for possible boot-time SMP configuration. |
1581 | */ | 1585 | */ |
1582 | acpi_boot_table_init(); | 1586 | acpi_boot_table_init(); |
1583 | acpi_boot_init(); | 1587 | acpi_boot_init(); |
1584 | #endif | ||
1585 | 1588 | ||
1589 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) | ||
1590 | if (def_to_bigsmp) | ||
1591 | printk(KERN_WARNING "More than 8 CPUs detected and " | ||
1592 | "CONFIG_X86_PC cannot handle it.\nUse " | ||
1593 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | ||
1594 | #endif | ||
1595 | #endif | ||
1586 | #ifdef CONFIG_X86_LOCAL_APIC | 1596 | #ifdef CONFIG_X86_LOCAL_APIC |
1587 | if (smp_found_config) | 1597 | if (smp_found_config) |
1588 | get_smp_config(); | 1598 | get_smp_config(); |
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 140e340569c6..61eb0c8a6e47 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -278,9 +278,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, | |||
278 | int tmp, err = 0; | 278 | int tmp, err = 0; |
279 | 279 | ||
280 | tmp = 0; | 280 | tmp = 0; |
281 | __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp)); | 281 | savesegment(gs, tmp); |
282 | err |= __put_user(tmp, (unsigned int __user *)&sc->gs); | 282 | err |= __put_user(tmp, (unsigned int __user *)&sc->gs); |
283 | __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp)); | 283 | savesegment(fs, tmp); |
284 | err |= __put_user(tmp, (unsigned int __user *)&sc->fs); | 284 | err |= __put_user(tmp, (unsigned int __user *)&sc->fs); |
285 | 285 | ||
286 | err |= __put_user(regs->xes, (unsigned int __user *)&sc->es); | 286 | err |= __put_user(regs->xes, (unsigned int __user *)&sc->es); |
@@ -604,7 +604,9 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
604 | * We want the common case to go fast, which | 604 | * We want the common case to go fast, which |
605 | * is why we may in certain cases get here from | 605 | * is why we may in certain cases get here from |
606 | * kernel mode. Just return without doing anything | 606 | * kernel mode. Just return without doing anything |
607 | * if so. | 607 | * if so. vm86 regs switched out by assembly code |
608 | * before reaching here, so testing against kernel | ||
609 | * CS suffices. | ||
608 | */ | 610 | */ |
609 | if (!user_mode(regs)) | 611 | if (!user_mode(regs)) |
610 | return 1; | 612 | return 1; |
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index cec4bde67161..48b55db3680f 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c | |||
@@ -576,7 +576,7 @@ static void stop_this_cpu (void * dummy) | |||
576 | local_irq_disable(); | 576 | local_irq_disable(); |
577 | disable_local_APIC(); | 577 | disable_local_APIC(); |
578 | if (cpu_data[smp_processor_id()].hlt_works_ok) | 578 | if (cpu_data[smp_processor_id()].hlt_works_ok) |
579 | for(;;) __asm__("hlt"); | 579 | for(;;) halt(); |
580 | for (;;); | 580 | for (;;); |
581 | } | 581 | } |
582 | 582 | ||
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 8ac8e9fd5614..5e4893d2b9f2 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -88,6 +88,8 @@ EXPORT_SYMBOL(cpu_online_map); | |||
88 | cpumask_t cpu_callin_map; | 88 | cpumask_t cpu_callin_map; |
89 | cpumask_t cpu_callout_map; | 89 | cpumask_t cpu_callout_map; |
90 | EXPORT_SYMBOL(cpu_callout_map); | 90 | EXPORT_SYMBOL(cpu_callout_map); |
91 | cpumask_t cpu_possible_map; | ||
92 | EXPORT_SYMBOL(cpu_possible_map); | ||
91 | static cpumask_t smp_commenced_mask; | 93 | static cpumask_t smp_commenced_mask; |
92 | 94 | ||
93 | /* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there | 95 | /* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there |
@@ -1017,8 +1019,8 @@ int __devinit smp_prepare_cpu(int cpu) | |||
1017 | tsc_sync_disabled = 1; | 1019 | tsc_sync_disabled = 1; |
1018 | 1020 | ||
1019 | /* init low mem mapping */ | 1021 | /* init low mem mapping */ |
1020 | memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, | 1022 | clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
1021 | sizeof(swapper_pg_dir[0]) * KERNEL_PGD_PTRS); | 1023 | KERNEL_PGD_PTRS); |
1022 | flush_tlb_all(); | 1024 | flush_tlb_all(); |
1023 | schedule_work(&task); | 1025 | schedule_work(&task); |
1024 | wait_for_completion(&done); | 1026 | wait_for_completion(&done); |
@@ -1265,6 +1267,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
1265 | cpu_set(smp_processor_id(), cpu_online_map); | 1267 | cpu_set(smp_processor_id(), cpu_online_map); |
1266 | cpu_set(smp_processor_id(), cpu_callout_map); | 1268 | cpu_set(smp_processor_id(), cpu_callout_map); |
1267 | cpu_set(smp_processor_id(), cpu_present_map); | 1269 | cpu_set(smp_processor_id(), cpu_present_map); |
1270 | cpu_set(smp_processor_id(), cpu_possible_map); | ||
1268 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 1271 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
1269 | } | 1272 | } |
1270 | 1273 | ||
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 0ee9dee8af06..eefea7c55008 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c | |||
@@ -194,10 +194,7 @@ int do_settimeofday(struct timespec *tv) | |||
194 | set_normalized_timespec(&xtime, sec, nsec); | 194 | set_normalized_timespec(&xtime, sec, nsec); |
195 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); | 195 | set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); |
196 | 196 | ||
197 | time_adjust = 0; /* stop active adjtime() */ | 197 | ntp_clear(); |
198 | time_status |= STA_UNSYNC; | ||
199 | time_maxerror = NTP_PHASE_LIMIT; | ||
200 | time_esterror = NTP_PHASE_LIMIT; | ||
201 | write_sequnlock_irq(&xtime_lock); | 198 | write_sequnlock_irq(&xtime_lock); |
202 | clock_was_set(); | 199 | clock_was_set(); |
203 | return 0; | 200 | return 0; |
@@ -252,8 +249,7 @@ EXPORT_SYMBOL(profile_pc); | |||
252 | * timer_interrupt() needs to keep up the real-time clock, | 249 | * timer_interrupt() needs to keep up the real-time clock, |
253 | * as well as call the "do_timer()" routine every clocktick | 250 | * as well as call the "do_timer()" routine every clocktick |
254 | */ | 251 | */ |
255 | static inline void do_timer_interrupt(int irq, void *dev_id, | 252 | static inline void do_timer_interrupt(int irq, struct pt_regs *regs) |
256 | struct pt_regs *regs) | ||
257 | { | 253 | { |
258 | #ifdef CONFIG_X86_IO_APIC | 254 | #ifdef CONFIG_X86_IO_APIC |
259 | if (timer_ack) { | 255 | if (timer_ack) { |
@@ -307,7 +303,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
307 | 303 | ||
308 | cur_timer->mark_offset(); | 304 | cur_timer->mark_offset(); |
309 | 305 | ||
310 | do_timer_interrupt(irq, NULL, regs); | 306 | do_timer_interrupt(irq, regs); |
311 | 307 | ||
312 | write_sequnlock(&xtime_lock); | 308 | write_sequnlock(&xtime_lock); |
313 | return IRQ_HANDLED; | 309 | return IRQ_HANDLED; |
@@ -348,7 +344,7 @@ static void sync_cmos_clock(unsigned long dummy) | |||
348 | * This code is run on a timer. If the clock is set, that timer | 344 | * This code is run on a timer. If the clock is set, that timer |
349 | * may not expire at the correct time. Thus, we adjust... | 345 | * may not expire at the correct time. Thus, we adjust... |
350 | */ | 346 | */ |
351 | if ((time_status & STA_UNSYNC) != 0) | 347 | if (!ntp_synced()) |
352 | /* | 348 | /* |
353 | * Not synced, exit, do not restart a timer (if one is | 349 | * Not synced, exit, do not restart a timer (if one is |
354 | * running, let it run out). | 350 | * running, let it run out). |
@@ -383,6 +379,7 @@ void notify_arch_cmos_timer(void) | |||
383 | 379 | ||
384 | static long clock_cmos_diff, sleep_start; | 380 | static long clock_cmos_diff, sleep_start; |
385 | 381 | ||
382 | static struct timer_opts *last_timer; | ||
386 | static int timer_suspend(struct sys_device *dev, pm_message_t state) | 383 | static int timer_suspend(struct sys_device *dev, pm_message_t state) |
387 | { | 384 | { |
388 | /* | 385 | /* |
@@ -391,6 +388,10 @@ static int timer_suspend(struct sys_device *dev, pm_message_t state) | |||
391 | clock_cmos_diff = -get_cmos_time(); | 388 | clock_cmos_diff = -get_cmos_time(); |
392 | clock_cmos_diff += get_seconds(); | 389 | clock_cmos_diff += get_seconds(); |
393 | sleep_start = get_cmos_time(); | 390 | sleep_start = get_cmos_time(); |
391 | last_timer = cur_timer; | ||
392 | cur_timer = &timer_none; | ||
393 | if (last_timer->suspend) | ||
394 | last_timer->suspend(state); | ||
394 | return 0; | 395 | return 0; |
395 | } | 396 | } |
396 | 397 | ||
@@ -404,6 +405,7 @@ static int timer_resume(struct sys_device *dev) | |||
404 | if (is_hpet_enabled()) | 405 | if (is_hpet_enabled()) |
405 | hpet_reenable(); | 406 | hpet_reenable(); |
406 | #endif | 407 | #endif |
408 | setup_pit_timer(); | ||
407 | sec = get_cmos_time() + clock_cmos_diff; | 409 | sec = get_cmos_time() + clock_cmos_diff; |
408 | sleep_length = (get_cmos_time() - sleep_start) * HZ; | 410 | sleep_length = (get_cmos_time() - sleep_start) * HZ; |
409 | write_seqlock_irqsave(&xtime_lock, flags); | 411 | write_seqlock_irqsave(&xtime_lock, flags); |
@@ -412,6 +414,11 @@ static int timer_resume(struct sys_device *dev) | |||
412 | write_sequnlock_irqrestore(&xtime_lock, flags); | 414 | write_sequnlock_irqrestore(&xtime_lock, flags); |
413 | jiffies += sleep_length; | 415 | jiffies += sleep_length; |
414 | wall_jiffies += sleep_length; | 416 | wall_jiffies += sleep_length; |
417 | if (last_timer->resume) | ||
418 | last_timer->resume(); | ||
419 | cur_timer = last_timer; | ||
420 | last_timer = NULL; | ||
421 | touch_softlockup_watchdog(); | ||
415 | return 0; | 422 | return 0; |
416 | } | 423 | } |
417 | 424 | ||
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c index ef8dac5dd33b..d973a8b681fd 100644 --- a/arch/i386/kernel/timers/timer_hpet.c +++ b/arch/i386/kernel/timers/timer_hpet.c | |||
@@ -18,8 +18,8 @@ | |||
18 | #include "mach_timer.h" | 18 | #include "mach_timer.h" |
19 | #include <asm/hpet.h> | 19 | #include <asm/hpet.h> |
20 | 20 | ||
21 | static unsigned long __read_mostly hpet_usec_quotient; /* convert hpet clks to usec */ | 21 | static unsigned long hpet_usec_quotient __read_mostly; /* convert hpet clks to usec */ |
22 | static unsigned long tsc_hpet_quotient; /* convert tsc to hpet clks */ | 22 | static unsigned long tsc_hpet_quotient __read_mostly; /* convert tsc to hpet clks */ |
23 | static unsigned long hpet_last; /* hpet counter value at last tick*/ | 23 | static unsigned long hpet_last; /* hpet counter value at last tick*/ |
24 | static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ | 24 | static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */ |
25 | static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ | 25 | static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */ |
@@ -136,6 +136,8 @@ static void delay_hpet(unsigned long loops) | |||
136 | } while ((hpet_end - hpet_start) < (loops)); | 136 | } while ((hpet_end - hpet_start) < (loops)); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct timer_opts timer_hpet; | ||
140 | |||
139 | static int __init init_hpet(char* override) | 141 | static int __init init_hpet(char* override) |
140 | { | 142 | { |
141 | unsigned long result, remain; | 143 | unsigned long result, remain; |
@@ -163,6 +165,8 @@ static int __init init_hpet(char* override) | |||
163 | } | 165 | } |
164 | set_cyc2ns_scale(cpu_khz/1000); | 166 | set_cyc2ns_scale(cpu_khz/1000); |
165 | } | 167 | } |
168 | /* set this only when cpu_has_tsc */ | ||
169 | timer_hpet.read_timer = read_timer_tsc; | ||
166 | } | 170 | } |
167 | 171 | ||
168 | /* | 172 | /* |
@@ -177,6 +181,19 @@ static int __init init_hpet(char* override) | |||
177 | return 0; | 181 | return 0; |
178 | } | 182 | } |
179 | 183 | ||
184 | static int hpet_resume(void) | ||
185 | { | ||
186 | write_seqlock(&monotonic_lock); | ||
187 | /* Assume this is the last mark offset time */ | ||
188 | rdtsc(last_tsc_low, last_tsc_high); | ||
189 | |||
190 | if (hpet_use_timer) | ||
191 | hpet_last = hpet_readl(HPET_T0_CMP) - hpet_tick; | ||
192 | else | ||
193 | hpet_last = hpet_readl(HPET_COUNTER); | ||
194 | write_sequnlock(&monotonic_lock); | ||
195 | return 0; | ||
196 | } | ||
180 | /************************************************************/ | 197 | /************************************************************/ |
181 | 198 | ||
182 | /* tsc timer_opts struct */ | 199 | /* tsc timer_opts struct */ |
@@ -186,7 +203,7 @@ static struct timer_opts timer_hpet __read_mostly = { | |||
186 | .get_offset = get_offset_hpet, | 203 | .get_offset = get_offset_hpet, |
187 | .monotonic_clock = monotonic_clock_hpet, | 204 | .monotonic_clock = monotonic_clock_hpet, |
188 | .delay = delay_hpet, | 205 | .delay = delay_hpet, |
189 | .read_timer = read_timer_tsc, | 206 | .resume = hpet_resume, |
190 | }; | 207 | }; |
191 | 208 | ||
192 | struct init_timer_opts __initdata timer_hpet_init = { | 209 | struct init_timer_opts __initdata timer_hpet_init = { |
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index 06de036a820c..eddb64038234 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c | |||
@@ -175,30 +175,3 @@ void setup_pit_timer(void) | |||
175 | outb(LATCH >> 8 , PIT_CH0); /* MSB */ | 175 | outb(LATCH >> 8 , PIT_CH0); /* MSB */ |
176 | spin_unlock_irqrestore(&i8253_lock, flags); | 176 | spin_unlock_irqrestore(&i8253_lock, flags); |
177 | } | 177 | } |
178 | |||
179 | static int timer_resume(struct sys_device *dev) | ||
180 | { | ||
181 | setup_pit_timer(); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static struct sysdev_class timer_sysclass = { | ||
186 | set_kset_name("timer_pit"), | ||
187 | .resume = timer_resume, | ||
188 | }; | ||
189 | |||
190 | static struct sys_device device_timer = { | ||
191 | .id = 0, | ||
192 | .cls = &timer_sysclass, | ||
193 | }; | ||
194 | |||
195 | static int __init init_timer_sysfs(void) | ||
196 | { | ||
197 | int error = sysdev_class_register(&timer_sysclass); | ||
198 | if (!error) | ||
199 | error = sysdev_register(&device_timer); | ||
200 | return error; | ||
201 | } | ||
202 | |||
203 | device_initcall(init_timer_sysfs); | ||
204 | |||
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c index 4ef20e663498..264edaaac315 100644 --- a/arch/i386/kernel/timers/timer_pm.c +++ b/arch/i386/kernel/timers/timer_pm.c | |||
@@ -186,6 +186,14 @@ static void mark_offset_pmtmr(void) | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | static int pmtmr_resume(void) | ||
190 | { | ||
191 | write_seqlock(&monotonic_lock); | ||
192 | /* Assume this is the last mark offset time */ | ||
193 | offset_tick = read_pmtmr(); | ||
194 | write_sequnlock(&monotonic_lock); | ||
195 | return 0; | ||
196 | } | ||
189 | 197 | ||
190 | static unsigned long long monotonic_clock_pmtmr(void) | 198 | static unsigned long long monotonic_clock_pmtmr(void) |
191 | { | 199 | { |
@@ -247,6 +255,7 @@ static struct timer_opts timer_pmtmr = { | |||
247 | .monotonic_clock = monotonic_clock_pmtmr, | 255 | .monotonic_clock = monotonic_clock_pmtmr, |
248 | .delay = delay_pmtmr, | 256 | .delay = delay_pmtmr, |
249 | .read_timer = read_timer_tsc, | 257 | .read_timer = read_timer_tsc, |
258 | .resume = pmtmr_resume, | ||
250 | }; | 259 | }; |
251 | 260 | ||
252 | struct init_timer_opts __initdata timer_pmtmr_init = { | 261 | struct init_timer_opts __initdata timer_pmtmr_init = { |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 8f4e4d5bc560..6dd470cc9f72 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
@@ -543,6 +543,19 @@ static int __init init_tsc(char* override) | |||
543 | return -ENODEV; | 543 | return -ENODEV; |
544 | } | 544 | } |
545 | 545 | ||
546 | static int tsc_resume(void) | ||
547 | { | ||
548 | write_seqlock(&monotonic_lock); | ||
549 | /* Assume this is the last mark offset time */ | ||
550 | rdtsc(last_tsc_low, last_tsc_high); | ||
551 | #ifdef CONFIG_HPET_TIMER | ||
552 | if (is_hpet_enabled() && hpet_use_timer) | ||
553 | hpet_last = hpet_readl(HPET_COUNTER); | ||
554 | #endif | ||
555 | write_sequnlock(&monotonic_lock); | ||
556 | return 0; | ||
557 | } | ||
558 | |||
546 | #ifndef CONFIG_X86_TSC | 559 | #ifndef CONFIG_X86_TSC |
547 | /* disable flag for tsc. Takes effect by clearing the TSC cpu flag | 560 | /* disable flag for tsc. Takes effect by clearing the TSC cpu flag |
548 | * in cpu/common.c */ | 561 | * in cpu/common.c */ |
@@ -573,6 +586,7 @@ static struct timer_opts timer_tsc = { | |||
573 | .monotonic_clock = monotonic_clock_tsc, | 586 | .monotonic_clock = monotonic_clock_tsc, |
574 | .delay = delay_tsc, | 587 | .delay = delay_tsc, |
575 | .read_timer = read_timer_tsc, | 588 | .read_timer = read_timer_tsc, |
589 | .resume = tsc_resume, | ||
576 | }; | 590 | }; |
577 | 591 | ||
578 | struct init_timer_opts __initdata timer_tsc_init = { | 592 | struct init_timer_opts __initdata timer_tsc_init = { |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index cd2d5d5514fe..09a58cb6daa7 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -210,7 +210,7 @@ void show_registers(struct pt_regs *regs) | |||
210 | unsigned short ss; | 210 | unsigned short ss; |
211 | 211 | ||
212 | esp = (unsigned long) (®s->esp); | 212 | esp = (unsigned long) (®s->esp); |
213 | ss = __KERNEL_DS; | 213 | savesegment(ss, ss); |
214 | if (user_mode(regs)) { | 214 | if (user_mode(regs)) { |
215 | in_kernel = 0; | 215 | in_kernel = 0; |
216 | esp = regs->esp; | 216 | esp = regs->esp; |
@@ -267,9 +267,6 @@ static void handle_BUG(struct pt_regs *regs) | |||
267 | char c; | 267 | char c; |
268 | unsigned long eip; | 268 | unsigned long eip; |
269 | 269 | ||
270 | if (user_mode(regs)) | ||
271 | goto no_bug; /* Not in kernel */ | ||
272 | |||
273 | eip = regs->eip; | 270 | eip = regs->eip; |
274 | 271 | ||
275 | if (eip < PAGE_OFFSET) | 272 | if (eip < PAGE_OFFSET) |
@@ -366,8 +363,9 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e | |||
366 | die(str, regs, err); | 363 | die(str, regs, err); |
367 | } | 364 | } |
368 | 365 | ||
369 | static void do_trap(int trapnr, int signr, char *str, int vm86, | 366 | static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, |
370 | struct pt_regs * regs, long error_code, siginfo_t *info) | 367 | struct pt_regs * regs, long error_code, |
368 | siginfo_t *info) | ||
371 | { | 369 | { |
372 | struct task_struct *tsk = current; | 370 | struct task_struct *tsk = current; |
373 | tsk->thread.error_code = error_code; | 371 | tsk->thread.error_code = error_code; |
@@ -463,7 +461,8 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | |||
463 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) | 461 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0) |
464 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) | 462 | DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0) |
465 | 463 | ||
466 | fastcall void do_general_protection(struct pt_regs * regs, long error_code) | 464 | fastcall void __kprobes do_general_protection(struct pt_regs * regs, |
465 | long error_code) | ||
467 | { | 466 | { |
468 | int cpu = get_cpu(); | 467 | int cpu = get_cpu(); |
469 | struct tss_struct *tss = &per_cpu(init_tss, cpu); | 468 | struct tss_struct *tss = &per_cpu(init_tss, cpu); |
@@ -568,6 +567,10 @@ static DEFINE_SPINLOCK(nmi_print_lock); | |||
568 | 567 | ||
569 | void die_nmi (struct pt_regs *regs, const char *msg) | 568 | void die_nmi (struct pt_regs *regs, const char *msg) |
570 | { | 569 | { |
570 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 0, SIGINT) == | ||
571 | NOTIFY_STOP) | ||
572 | return; | ||
573 | |||
571 | spin_lock(&nmi_print_lock); | 574 | spin_lock(&nmi_print_lock); |
572 | /* | 575 | /* |
573 | * We are in trouble anyway, lets at least try | 576 | * We are in trouble anyway, lets at least try |
@@ -656,7 +659,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
656 | 659 | ||
657 | ++nmi_count(cpu); | 660 | ++nmi_count(cpu); |
658 | 661 | ||
659 | if (!nmi_callback(regs, cpu)) | 662 | if (!rcu_dereference(nmi_callback)(regs, cpu)) |
660 | default_do_nmi(regs); | 663 | default_do_nmi(regs); |
661 | 664 | ||
662 | nmi_exit(); | 665 | nmi_exit(); |
@@ -664,7 +667,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code) | |||
664 | 667 | ||
665 | void set_nmi_callback(nmi_callback_t callback) | 668 | void set_nmi_callback(nmi_callback_t callback) |
666 | { | 669 | { |
667 | nmi_callback = callback; | 670 | rcu_assign_pointer(nmi_callback, callback); |
668 | } | 671 | } |
669 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 672 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
670 | 673 | ||
@@ -675,7 +678,7 @@ void unset_nmi_callback(void) | |||
675 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | 678 | EXPORT_SYMBOL_GPL(unset_nmi_callback); |
676 | 679 | ||
677 | #ifdef CONFIG_KPROBES | 680 | #ifdef CONFIG_KPROBES |
678 | fastcall void do_int3(struct pt_regs *regs, long error_code) | 681 | fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) |
679 | { | 682 | { |
680 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | 683 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) |
681 | == NOTIFY_STOP) | 684 | == NOTIFY_STOP) |
@@ -709,7 +712,7 @@ fastcall void do_int3(struct pt_regs *regs, long error_code) | |||
709 | * find every occurrence of the TF bit that could be saved away even | 712 | * find every occurrence of the TF bit that could be saved away even |
710 | * by user code) | 713 | * by user code) |
711 | */ | 714 | */ |
712 | fastcall void do_debug(struct pt_regs * regs, long error_code) | 715 | fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code) |
713 | { | 716 | { |
714 | unsigned int condition; | 717 | unsigned int condition; |
715 | struct task_struct *tsk = current; | 718 | struct task_struct *tsk = current; |
@@ -1008,7 +1011,7 @@ void __init trap_init_f00f_bug(void) | |||
1008 | * it uses the read-only mapped virtual address. | 1011 | * it uses the read-only mapped virtual address. |
1009 | */ | 1012 | */ |
1010 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); | 1013 | idt_descr.address = fix_to_virt(FIX_F00F_IDT); |
1011 | __asm__ __volatile__("lidt %0" : : "m" (idt_descr)); | 1014 | load_idt(&idt_descr); |
1012 | } | 1015 | } |
1013 | #endif | 1016 | #endif |
1014 | 1017 | ||
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index ec0f68ce6886..16b485009622 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
@@ -294,8 +294,8 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
294 | */ | 294 | */ |
295 | info->regs32->eax = 0; | 295 | info->regs32->eax = 0; |
296 | tsk->thread.saved_esp0 = tsk->thread.esp0; | 296 | tsk->thread.saved_esp0 = tsk->thread.esp0; |
297 | asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs)); | 297 | savesegment(fs, tsk->thread.saved_fs); |
298 | asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs)); | 298 | savesegment(gs, tsk->thread.saved_gs); |
299 | 299 | ||
300 | tss = &per_cpu(init_tss, get_cpu()); | 300 | tss = &per_cpu(init_tss, get_cpu()); |
301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; | 301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
@@ -542,7 +542,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) | |||
542 | unsigned char opcode; | 542 | unsigned char opcode; |
543 | unsigned char __user *csp; | 543 | unsigned char __user *csp; |
544 | unsigned char __user *ssp; | 544 | unsigned char __user *ssp; |
545 | unsigned short ip, sp; | 545 | unsigned short ip, sp, orig_flags; |
546 | int data32, pref_done; | 546 | int data32, pref_done; |
547 | 547 | ||
548 | #define CHECK_IF_IN_TRAP \ | 548 | #define CHECK_IF_IN_TRAP \ |
@@ -551,8 +551,12 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) | |||
551 | #define VM86_FAULT_RETURN do { \ | 551 | #define VM86_FAULT_RETURN do { \ |
552 | if (VMPI.force_return_for_pic && (VEFLAGS & (IF_MASK | VIF_MASK))) \ | 552 | if (VMPI.force_return_for_pic && (VEFLAGS & (IF_MASK | VIF_MASK))) \ |
553 | return_to_32bit(regs, VM86_PICRETURN); \ | 553 | return_to_32bit(regs, VM86_PICRETURN); \ |
554 | if (orig_flags & TF_MASK) \ | ||
555 | handle_vm86_trap(regs, 0, 1); \ | ||
554 | return; } while (0) | 556 | return; } while (0) |
555 | 557 | ||
558 | orig_flags = *(unsigned short *)®s->eflags; | ||
559 | |||
556 | csp = (unsigned char __user *) (regs->cs << 4); | 560 | csp = (unsigned char __user *) (regs->cs << 4); |
557 | ssp = (unsigned char __user *) (regs->ss << 4); | 561 | ssp = (unsigned char __user *) (regs->ss << 4); |
558 | sp = SP(regs); | 562 | sp = SP(regs); |
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 761972f8cb6c..13b9c62cbbb4 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S | |||
@@ -22,6 +22,7 @@ SECTIONS | |||
22 | *(.text) | 22 | *(.text) |
23 | SCHED_TEXT | 23 | SCHED_TEXT |
24 | LOCK_TEXT | 24 | LOCK_TEXT |
25 | KPROBES_TEXT | ||
25 | *(.fixup) | 26 | *(.fixup) |
26 | *(.gnu.warning) | 27 | *(.gnu.warning) |
27 | } = 0x9090 | 28 | } = 0x9090 |
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/i386/kernel/vsyscall-sigreturn.S index c8fcf75b9be3..68afa50dd7cf 100644 --- a/arch/i386/kernel/vsyscall-sigreturn.S +++ b/arch/i386/kernel/vsyscall-sigreturn.S | |||
@@ -15,7 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | .text | 17 | .text |
18 | .org __kernel_vsyscall+32 | 18 | .org __kernel_vsyscall+32,0x90 |
19 | .globl __kernel_sigreturn | 19 | .globl __kernel_sigreturn |
20 | .type __kernel_sigreturn,@function | 20 | .type __kernel_sigreturn,@function |
21 | __kernel_sigreturn: | 21 | __kernel_sigreturn: |
@@ -35,6 +35,7 @@ __kernel_rt_sigreturn: | |||
35 | int $0x80 | 35 | int $0x80 |
36 | .LEND_rt_sigreturn: | 36 | .LEND_rt_sigreturn: |
37 | .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn | 37 | .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn |
38 | .balign 32 | ||
38 | .previous | 39 | .previous |
39 | 40 | ||
40 | .section .eh_frame,"a",@progbits | 41 | .section .eh_frame,"a",@progbits |
diff --git a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c index 23395fff35d1..b64314069e78 100644 --- a/arch/i386/mach-default/topology.c +++ b/arch/i386/mach-default/topology.c | |||
@@ -76,7 +76,7 @@ static int __init topology_init(void) | |||
76 | for_each_online_node(i) | 76 | for_each_online_node(i) |
77 | arch_register_node(i); | 77 | arch_register_node(i); |
78 | 78 | ||
79 | for_each_cpu(i) | 79 | for_each_present_cpu(i) |
80 | arch_register_cpu(i); | 80 | arch_register_cpu(i); |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
@@ -87,7 +87,7 @@ static int __init topology_init(void) | |||
87 | { | 87 | { |
88 | int i; | 88 | int i; |
89 | 89 | ||
90 | for_each_cpu(i) | 90 | for_each_present_cpu(i) |
91 | arch_register_cpu(i); | 91 | arch_register_cpu(i); |
92 | return 0; | 92 | return 0; |
93 | } | 93 | } |
diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h index 70691f0c4ce2..898ed905e119 100644 --- a/arch/i386/mach-es7000/es7000.h +++ b/arch/i386/mach-es7000/es7000.h | |||
@@ -104,7 +104,8 @@ struct mip_reg { | |||
104 | #define MIP_SW_APIC 0x1020b | 104 | #define MIP_SW_APIC 0x1020b |
105 | #define MIP_FUNC(VALUE) (VALUE & 0xff) | 105 | #define MIP_FUNC(VALUE) (VALUE & 0xff) |
106 | 106 | ||
107 | extern int parse_unisys_oem (char *oemptr, int oem_entries); | 107 | extern int parse_unisys_oem (char *oemptr); |
108 | extern int find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length); | 108 | extern int find_unisys_acpi_oem_table(unsigned long *oem_addr); |
109 | extern void setup_unisys (); | ||
109 | extern int es7000_start_cpu(int cpu, unsigned long eip); | 110 | extern int es7000_start_cpu(int cpu, unsigned long eip); |
110 | extern void es7000_sw_apic(void); | 111 | extern void es7000_sw_apic(void); |
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c index d5936d500479..dc6660511b07 100644 --- a/arch/i386/mach-es7000/es7000plat.c +++ b/arch/i386/mach-es7000/es7000plat.c | |||
@@ -51,7 +51,7 @@ struct mip_reg *host_reg; | |||
51 | int mip_port; | 51 | int mip_port; |
52 | unsigned long mip_addr, host_addr; | 52 | unsigned long mip_addr, host_addr; |
53 | 53 | ||
54 | #if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_ACPI_BOOT)) | 54 | #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI) |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * GSI override for ES7000 platforms. | 57 | * GSI override for ES7000 platforms. |
@@ -73,14 +73,31 @@ es7000_rename_gsi(int ioapic, int gsi) | |||
73 | return gsi; | 73 | return gsi; |
74 | } | 74 | } |
75 | 75 | ||
76 | #endif // (CONFIG_X86_IO_APIC) && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT) | 76 | #endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */ |
77 | |||
78 | void __init | ||
79 | setup_unisys () | ||
80 | { | ||
81 | /* | ||
82 | * Determine the generation of the ES7000 currently running. | ||
83 | * | ||
84 | * es7000_plat = 1 if the machine is a 5xx ES7000 box | ||
85 | * es7000_plat = 2 if the machine is a x86_64 ES7000 box | ||
86 | * | ||
87 | */ | ||
88 | if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2)) | ||
89 | es7000_plat = 2; | ||
90 | else | ||
91 | es7000_plat = 1; | ||
92 | ioapic_renumber_irq = es7000_rename_gsi; | ||
93 | } | ||
77 | 94 | ||
78 | /* | 95 | /* |
79 | * Parse the OEM Table | 96 | * Parse the OEM Table |
80 | */ | 97 | */ |
81 | 98 | ||
82 | int __init | 99 | int __init |
83 | parse_unisys_oem (char *oemptr, int oem_entries) | 100 | parse_unisys_oem (char *oemptr) |
84 | { | 101 | { |
85 | int i; | 102 | int i; |
86 | int success = 0; | 103 | int success = 0; |
@@ -95,7 +112,7 @@ parse_unisys_oem (char *oemptr, int oem_entries) | |||
95 | 112 | ||
96 | tp += 8; | 113 | tp += 8; |
97 | 114 | ||
98 | for (i=0; i <= oem_entries; i++) { | 115 | for (i=0; i <= 6; i++) { |
99 | type = *tp++; | 116 | type = *tp++; |
100 | size = *tp++; | 117 | size = *tp++; |
101 | tp -= 2; | 118 | tp -= 2; |
@@ -130,34 +147,18 @@ parse_unisys_oem (char *oemptr, int oem_entries) | |||
130 | default: | 147 | default: |
131 | break; | 148 | break; |
132 | } | 149 | } |
133 | if (i == 6) break; | ||
134 | tp += size; | 150 | tp += size; |
135 | } | 151 | } |
136 | 152 | ||
137 | if (success < 2) { | 153 | if (success < 2) { |
138 | es7000_plat = 0; | 154 | es7000_plat = 0; |
139 | } else { | 155 | } else |
140 | printk("\nEnabling ES7000 specific features...\n"); | 156 | setup_unisys(); |
141 | /* | ||
142 | * Determine the generation of the ES7000 currently running. | ||
143 | * | ||
144 | * es7000_plat = 0 if the machine is NOT a Unisys ES7000 box | ||
145 | * es7000_plat = 1 if the machine is a 5xx ES7000 box | ||
146 | * es7000_plat = 2 if the machine is a x86_64 ES7000 box | ||
147 | * | ||
148 | */ | ||
149 | if (!(boot_cpu_data.x86 <= 15 && boot_cpu_data.x86_model <= 2)) | ||
150 | es7000_plat = 2; | ||
151 | else | ||
152 | es7000_plat = 1; | ||
153 | |||
154 | ioapic_renumber_irq = es7000_rename_gsi; | ||
155 | } | ||
156 | return es7000_plat; | 157 | return es7000_plat; |
157 | } | 158 | } |
158 | 159 | ||
159 | int __init | 160 | int __init |
160 | find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length) | 161 | find_unisys_acpi_oem_table(unsigned long *oem_addr) |
161 | { | 162 | { |
162 | struct acpi_table_rsdp *rsdp = NULL; | 163 | struct acpi_table_rsdp *rsdp = NULL; |
163 | unsigned long rsdp_phys = 0; | 164 | unsigned long rsdp_phys = 0; |
@@ -201,13 +202,11 @@ find_unisys_acpi_oem_table(unsigned long *oem_addr, int *length) | |||
201 | acpi_table_print(header, sdt.entry[i].pa); | 202 | acpi_table_print(header, sdt.entry[i].pa); |
202 | t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); | 203 | t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); |
203 | addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); | 204 | addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); |
204 | *length = header->length; | ||
205 | *oem_addr = (unsigned long) addr; | 205 | *oem_addr = (unsigned long) addr; |
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
208 | } | 208 | } |
209 | } | 209 | } |
210 | Dprintk("ES7000: did not find Unisys ACPI OEM table!\n"); | ||
211 | return -1; | 210 | return -1; |
212 | } | 211 | } |
213 | 212 | ||
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index 25883b44f625..037b2af1a1f4 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c | |||
@@ -47,7 +47,10 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { | |||
47 | 47 | ||
48 | static __init int probe_bigsmp(void) | 48 | static __init int probe_bigsmp(void) |
49 | { | 49 | { |
50 | dmi_check_system(bigsmp_dmi_table); | 50 | if (def_to_bigsmp) |
51 | dmi_bigsmp = 1; | ||
52 | else | ||
53 | dmi_check_system(bigsmp_dmi_table); | ||
51 | return dmi_bigsmp; | 54 | return dmi_bigsmp; |
52 | } | 55 | } |
53 | 56 | ||
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index 5497c65a8790..cea5b3ce4b57 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -30,6 +30,25 @@ struct genapic *apic_probe[] __initdata = { | |||
30 | NULL, | 30 | NULL, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int cmdline_apic; | ||
34 | |||
35 | void __init generic_bigsmp_probe(void) | ||
36 | { | ||
37 | /* | ||
38 | * This routine is used to switch to bigsmp mode when | ||
39 | * - There is no apic= option specified by the user | ||
40 | * - generic_apic_probe() has choosen apic_default as the sub_arch | ||
41 | * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support | ||
42 | */ | ||
43 | |||
44 | if (!cmdline_apic && genapic == &apic_default) | ||
45 | if (apic_bigsmp.probe()) { | ||
46 | genapic = &apic_bigsmp; | ||
47 | printk(KERN_INFO "Overriding APIC driver with %s\n", | ||
48 | genapic->name); | ||
49 | } | ||
50 | } | ||
51 | |||
33 | void __init generic_apic_probe(char *command_line) | 52 | void __init generic_apic_probe(char *command_line) |
34 | { | 53 | { |
35 | char *s; | 54 | char *s; |
@@ -52,6 +71,7 @@ void __init generic_apic_probe(char *command_line) | |||
52 | if (!changed) | 71 | if (!changed) |
53 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); | 72 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); |
54 | *p = old; | 73 | *p = old; |
74 | cmdline_apic = changed; | ||
55 | } | 75 | } |
56 | for (i = 0; !changed && apic_probe[i]; i++) { | 76 | for (i = 0; !changed && apic_probe[i]; i++) { |
57 | if (apic_probe[i]->probe()) { | 77 | if (apic_probe[i]->probe()) { |
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index c6384061328a..cc69875d979b 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c | |||
@@ -234,10 +234,9 @@ voyager_power_off(void) | |||
234 | #endif | 234 | #endif |
235 | } | 235 | } |
236 | /* and wait for it to happen */ | 236 | /* and wait for it to happen */ |
237 | for(;;) { | 237 | local_irq_disable(); |
238 | __asm("cli"); | 238 | for(;;) |
239 | __asm("hlt"); | 239 | halt(); |
240 | } | ||
241 | } | 240 | } |
242 | 241 | ||
243 | /* copied from process.c */ | 242 | /* copied from process.c */ |
@@ -278,10 +277,9 @@ machine_restart(char *cmd) | |||
278 | outb(basebd | 0x08, VOYAGER_MC_SETUP); | 277 | outb(basebd | 0x08, VOYAGER_MC_SETUP); |
279 | outb(0x02, catbase + 0x21); | 278 | outb(0x02, catbase + 0x21); |
280 | } | 279 | } |
281 | for(;;) { | 280 | local_irq_disable(); |
282 | asm("cli"); | 281 | for(;;) |
283 | asm("hlt"); | 282 | halt(); |
284 | } | ||
285 | } | 283 | } |
286 | 284 | ||
287 | void | 285 | void |
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 0e1f4208b07c..46b0cf4a31e0 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c | |||
@@ -242,6 +242,8 @@ static cpumask_t smp_commenced_mask = CPU_MASK_NONE; | |||
242 | cpumask_t cpu_callin_map = CPU_MASK_NONE; | 242 | cpumask_t cpu_callin_map = CPU_MASK_NONE; |
243 | cpumask_t cpu_callout_map = CPU_MASK_NONE; | 243 | cpumask_t cpu_callout_map = CPU_MASK_NONE; |
244 | EXPORT_SYMBOL(cpu_callout_map); | 244 | EXPORT_SYMBOL(cpu_callout_map); |
245 | cpumask_t cpu_possible_map = CPU_MASK_ALL; | ||
246 | EXPORT_SYMBOL(cpu_possible_map); | ||
245 | 247 | ||
246 | /* The per processor IRQ masks (these are usually kept in sync) */ | 248 | /* The per processor IRQ masks (these are usually kept in sync) */ |
247 | static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; | 249 | static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; |
@@ -1015,7 +1017,7 @@ smp_stop_cpu_function(void *dummy) | |||
1015 | cpu_clear(smp_processor_id(), cpu_online_map); | 1017 | cpu_clear(smp_processor_id(), cpu_online_map); |
1016 | local_irq_disable(); | 1018 | local_irq_disable(); |
1017 | for(;;) | 1019 | for(;;) |
1018 | __asm__("hlt"); | 1020 | halt(); |
1019 | } | 1021 | } |
1020 | 1022 | ||
1021 | static DEFINE_SPINLOCK(call_lock); | 1023 | static DEFINE_SPINLOCK(call_lock); |
@@ -1910,6 +1912,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
1910 | { | 1912 | { |
1911 | cpu_set(smp_processor_id(), cpu_online_map); | 1913 | cpu_set(smp_processor_id(), cpu_online_map); |
1912 | cpu_set(smp_processor_id(), cpu_callout_map); | 1914 | cpu_set(smp_processor_id(), cpu_callout_map); |
1915 | cpu_set(smp_processor_id(), cpu_possible_map); | ||
1913 | } | 1916 | } |
1914 | 1917 | ||
1915 | int __devinit | 1918 | int __devinit |
diff --git a/arch/i386/math-emu/get_address.c b/arch/i386/math-emu/get_address.c index 91175738e948..9819b705efa4 100644 --- a/arch/i386/math-emu/get_address.c +++ b/arch/i386/math-emu/get_address.c | |||
@@ -155,7 +155,6 @@ static long pm_address(u_char FPU_modrm, u_char segment, | |||
155 | { | 155 | { |
156 | struct desc_struct descriptor; | 156 | struct desc_struct descriptor; |
157 | unsigned long base_address, limit, address, seg_top; | 157 | unsigned long base_address, limit, address, seg_top; |
158 | unsigned short selector; | ||
159 | 158 | ||
160 | segment--; | 159 | segment--; |
161 | 160 | ||
@@ -173,17 +172,11 @@ static long pm_address(u_char FPU_modrm, u_char segment, | |||
173 | /* fs and gs aren't used by the kernel, so they still have their | 172 | /* fs and gs aren't used by the kernel, so they still have their |
174 | user-space values. */ | 173 | user-space values. */ |
175 | case PREFIX_FS_-1: | 174 | case PREFIX_FS_-1: |
176 | /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register | 175 | /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */ |
177 | in the assembler statement. */ | 176 | savesegment(fs, addr->selector); |
178 | |||
179 | __asm__("mov %%fs,%0":"=r" (selector)); | ||
180 | addr->selector = selector; | ||
181 | break; | 177 | break; |
182 | case PREFIX_GS_-1: | 178 | case PREFIX_GS_-1: |
183 | /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register | 179 | savesegment(gs, addr->selector); |
184 | in the assembler statement. */ | ||
185 | __asm__("mov %%gs,%0":"=r" (selector)); | ||
186 | addr->selector = selector; | ||
187 | break; | 180 | break; |
188 | default: | 181 | default: |
189 | addr->selector = PM_REG_(segment); | 182 | addr->selector = PM_REG_(segment); |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index 6711ce3f6916..244d8ec66be2 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <asm/mmzone.h> | 37 | #include <asm/mmzone.h> |
38 | #include <bios_ebda.h> | 38 | #include <bios_ebda.h> |
39 | 39 | ||
40 | struct pglist_data *node_data[MAX_NUMNODES]; | 40 | struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; |
41 | EXPORT_SYMBOL(node_data); | 41 | EXPORT_SYMBOL(node_data); |
42 | bootmem_data_t node0_bdata; | 42 | bootmem_data_t node0_bdata; |
43 | 43 | ||
@@ -49,8 +49,8 @@ bootmem_data_t node0_bdata; | |||
49 | * 2) node_start_pfn - the starting page frame number for a node | 49 | * 2) node_start_pfn - the starting page frame number for a node |
50 | * 3) node_end_pfn - the ending page fram number for a node | 50 | * 3) node_end_pfn - the ending page fram number for a node |
51 | */ | 51 | */ |
52 | unsigned long node_start_pfn[MAX_NUMNODES]; | 52 | unsigned long node_start_pfn[MAX_NUMNODES] __read_mostly; |
53 | unsigned long node_end_pfn[MAX_NUMNODES]; | 53 | unsigned long node_end_pfn[MAX_NUMNODES] __read_mostly; |
54 | 54 | ||
55 | 55 | ||
56 | #ifdef CONFIG_DISCONTIGMEM | 56 | #ifdef CONFIG_DISCONTIGMEM |
@@ -66,7 +66,7 @@ unsigned long node_end_pfn[MAX_NUMNODES]; | |||
66 | * physnode_map[4-7] = 1; | 66 | * physnode_map[4-7] = 1; |
67 | * physnode_map[8- ] = -1; | 67 | * physnode_map[8- ] = -1; |
68 | */ | 68 | */ |
69 | s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1}; | 69 | s8 physnode_map[MAX_ELEMENTS] __read_mostly = { [0 ... (MAX_ELEMENTS - 1)] = -1}; |
70 | EXPORT_SYMBOL(physnode_map); | 70 | EXPORT_SYMBOL(physnode_map); |
71 | 71 | ||
72 | void memory_present(int nid, unsigned long start, unsigned long end) | 72 | void memory_present(int nid, unsigned long start, unsigned long end) |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 8e90339d6eaa..9edd4485b91e 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/vt_kern.h> /* For unblank_screen() */ | 21 | #include <linux/vt_kern.h> /* For unblank_screen() */ |
22 | #include <linux/highmem.h> | 22 | #include <linux/highmem.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/kprobes.h> | ||
24 | 25 | ||
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
@@ -199,6 +200,18 @@ static inline int is_prefetch(struct pt_regs *regs, unsigned long addr, | |||
199 | return 0; | 200 | return 0; |
200 | } | 201 | } |
201 | 202 | ||
203 | static noinline void force_sig_info_fault(int si_signo, int si_code, | ||
204 | unsigned long address, struct task_struct *tsk) | ||
205 | { | ||
206 | siginfo_t info; | ||
207 | |||
208 | info.si_signo = si_signo; | ||
209 | info.si_errno = 0; | ||
210 | info.si_code = si_code; | ||
211 | info.si_addr = (void __user *)address; | ||
212 | force_sig_info(si_signo, &info, tsk); | ||
213 | } | ||
214 | |||
202 | fastcall void do_invalid_op(struct pt_regs *, unsigned long); | 215 | fastcall void do_invalid_op(struct pt_regs *, unsigned long); |
203 | 216 | ||
204 | /* | 217 | /* |
@@ -211,18 +224,18 @@ fastcall void do_invalid_op(struct pt_regs *, unsigned long); | |||
211 | * bit 1 == 0 means read, 1 means write | 224 | * bit 1 == 0 means read, 1 means write |
212 | * bit 2 == 0 means kernel, 1 means user-mode | 225 | * bit 2 == 0 means kernel, 1 means user-mode |
213 | */ | 226 | */ |
214 | fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) | 227 | fastcall void __kprobes do_page_fault(struct pt_regs *regs, |
228 | unsigned long error_code) | ||
215 | { | 229 | { |
216 | struct task_struct *tsk; | 230 | struct task_struct *tsk; |
217 | struct mm_struct *mm; | 231 | struct mm_struct *mm; |
218 | struct vm_area_struct * vma; | 232 | struct vm_area_struct * vma; |
219 | unsigned long address; | 233 | unsigned long address; |
220 | unsigned long page; | 234 | unsigned long page; |
221 | int write; | 235 | int write, si_code; |
222 | siginfo_t info; | ||
223 | 236 | ||
224 | /* get the address */ | 237 | /* get the address */ |
225 | __asm__("movl %%cr2,%0":"=r" (address)); | 238 | address = read_cr2(); |
226 | 239 | ||
227 | if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, | 240 | if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, |
228 | SIGSEGV) == NOTIFY_STOP) | 241 | SIGSEGV) == NOTIFY_STOP) |
@@ -233,7 +246,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
233 | 246 | ||
234 | tsk = current; | 247 | tsk = current; |
235 | 248 | ||
236 | info.si_code = SEGV_MAPERR; | 249 | si_code = SEGV_MAPERR; |
237 | 250 | ||
238 | /* | 251 | /* |
239 | * We fault-in kernel-space virtual memory on-demand. The | 252 | * We fault-in kernel-space virtual memory on-demand. The |
@@ -313,7 +326,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
313 | * we can handle it.. | 326 | * we can handle it.. |
314 | */ | 327 | */ |
315 | good_area: | 328 | good_area: |
316 | info.si_code = SEGV_ACCERR; | 329 | si_code = SEGV_ACCERR; |
317 | write = 0; | 330 | write = 0; |
318 | switch (error_code & 3) { | 331 | switch (error_code & 3) { |
319 | default: /* 3: write, present */ | 332 | default: /* 3: write, present */ |
@@ -387,11 +400,7 @@ bad_area_nosemaphore: | |||
387 | /* Kernel addresses are always protection faults */ | 400 | /* Kernel addresses are always protection faults */ |
388 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); | 401 | tsk->thread.error_code = error_code | (address >= TASK_SIZE); |
389 | tsk->thread.trap_no = 14; | 402 | tsk->thread.trap_no = 14; |
390 | info.si_signo = SIGSEGV; | 403 | force_sig_info_fault(SIGSEGV, si_code, address, tsk); |
391 | info.si_errno = 0; | ||
392 | /* info.si_code has been set above */ | ||
393 | info.si_addr = (void __user *)address; | ||
394 | force_sig_info(SIGSEGV, &info, tsk); | ||
395 | return; | 404 | return; |
396 | } | 405 | } |
397 | 406 | ||
@@ -446,7 +455,7 @@ no_context: | |||
446 | printk(" at virtual address %08lx\n",address); | 455 | printk(" at virtual address %08lx\n",address); |
447 | printk(KERN_ALERT " printing eip:\n"); | 456 | printk(KERN_ALERT " printing eip:\n"); |
448 | printk("%08lx\n", regs->eip); | 457 | printk("%08lx\n", regs->eip); |
449 | asm("movl %%cr3,%0":"=r" (page)); | 458 | page = read_cr3(); |
450 | page = ((unsigned long *) __va(page))[address >> 22]; | 459 | page = ((unsigned long *) __va(page))[address >> 22]; |
451 | printk(KERN_ALERT "*pde = %08lx\n", page); | 460 | printk(KERN_ALERT "*pde = %08lx\n", page); |
452 | /* | 461 | /* |
@@ -500,11 +509,7 @@ do_sigbus: | |||
500 | tsk->thread.cr2 = address; | 509 | tsk->thread.cr2 = address; |
501 | tsk->thread.error_code = error_code; | 510 | tsk->thread.error_code = error_code; |
502 | tsk->thread.trap_no = 14; | 511 | tsk->thread.trap_no = 14; |
503 | info.si_signo = SIGBUS; | 512 | force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); |
504 | info.si_errno = 0; | ||
505 | info.si_code = BUS_ADRERR; | ||
506 | info.si_addr = (void __user *)address; | ||
507 | force_sig_info(SIGBUS, &info, tsk); | ||
508 | return; | 513 | return; |
509 | 514 | ||
510 | vmalloc_fault: | 515 | vmalloc_fault: |
@@ -523,7 +528,7 @@ vmalloc_fault: | |||
523 | pmd_t *pmd, *pmd_k; | 528 | pmd_t *pmd, *pmd_k; |
524 | pte_t *pte_k; | 529 | pte_t *pte_k; |
525 | 530 | ||
526 | asm("movl %%cr3,%0":"=r" (pgd_paddr)); | 531 | pgd_paddr = read_cr3(); |
527 | pgd = index + (pgd_t *)__va(pgd_paddr); | 532 | pgd = index + (pgd_t *)__va(pgd_paddr); |
528 | pgd_k = init_mm.pgd + index; | 533 | pgd_k = init_mm.pgd + index; |
529 | 534 | ||
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 3b099f32b948..d524127c9afc 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c | |||
@@ -22,12 +22,15 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | |||
22 | { | 22 | { |
23 | pgd_t *pgd; | 23 | pgd_t *pgd; |
24 | pud_t *pud; | 24 | pud_t *pud; |
25 | pmd_t *pmd = NULL; | 25 | pte_t *pte = NULL; |
26 | 26 | ||
27 | pgd = pgd_offset(mm, addr); | 27 | pgd = pgd_offset(mm, addr); |
28 | pud = pud_alloc(mm, pgd, addr); | 28 | pud = pud_alloc(mm, pgd, addr); |
29 | pmd = pmd_alloc(mm, pud, addr); | 29 | if (pud) |
30 | return (pte_t *) pmd; | 30 | pte = (pte_t *) pmd_alloc(mm, pud, addr); |
31 | BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); | ||
32 | |||
33 | return pte; | ||
31 | } | 34 | } |
32 | 35 | ||
33 | pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | 36 | pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) |
@@ -37,8 +40,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
37 | pmd_t *pmd = NULL; | 40 | pmd_t *pmd = NULL; |
38 | 41 | ||
39 | pgd = pgd_offset(mm, addr); | 42 | pgd = pgd_offset(mm, addr); |
40 | pud = pud_offset(pgd, addr); | 43 | if (pgd_present(*pgd)) { |
41 | pmd = pmd_offset(pud, addr); | 44 | pud = pud_offset(pgd, addr); |
45 | if (pud_present(*pud)) | ||
46 | pmd = pmd_offset(pud, addr); | ||
47 | } | ||
42 | return (pte_t *) pmd; | 48 | return (pte_t *) pmd; |
43 | } | 49 | } |
44 | 50 | ||
@@ -118,17 +124,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, | |||
118 | } | 124 | } |
119 | #endif | 125 | #endif |
120 | 126 | ||
121 | void hugetlb_clean_stale_pgtable(pte_t *pte) | ||
122 | { | ||
123 | pmd_t *pmd = (pmd_t *) pte; | ||
124 | struct page *page; | ||
125 | |||
126 | page = pmd_page(*pmd); | ||
127 | pmd_clear(pmd); | ||
128 | dec_page_state(nr_page_table_pages); | ||
129 | page_cache_release(page); | ||
130 | } | ||
131 | |||
132 | /* x86_64 also uses this file */ | 127 | /* x86_64 also uses this file */ |
133 | 128 | ||
134 | #ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA | 129 | #ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 12216b52e28b..2ebaf75f732e 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -198,9 +198,10 @@ int page_is_ram(unsigned long pagenr) | |||
198 | 198 | ||
199 | if (efi_enabled) { | 199 | if (efi_enabled) { |
200 | efi_memory_desc_t *md; | 200 | efi_memory_desc_t *md; |
201 | void *p; | ||
201 | 202 | ||
202 | for (i = 0; i < memmap.nr_map; i++) { | 203 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
203 | md = &memmap.map[i]; | 204 | md = p; |
204 | if (!is_available_memory(md)) | 205 | if (!is_available_memory(md)) |
205 | continue; | 206 | continue; |
206 | addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; | 207 | addr = (md->phys_addr+PAGE_SIZE-1) >> PAGE_SHIFT; |
@@ -348,7 +349,7 @@ static void __init pagetable_init (void) | |||
348 | * All user-space mappings are explicitly cleared after | 349 | * All user-space mappings are explicitly cleared after |
349 | * SMP startup. | 350 | * SMP startup. |
350 | */ | 351 | */ |
351 | pgd_base[0] = pgd_base[USER_PTRS_PER_PGD]; | 352 | set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]); |
352 | #endif | 353 | #endif |
353 | } | 354 | } |
354 | 355 | ||
@@ -392,7 +393,7 @@ void zap_low_mappings (void) | |||
392 | } | 393 | } |
393 | 394 | ||
394 | static int disable_nx __initdata = 0; | 395 | static int disable_nx __initdata = 0; |
395 | u64 __supported_pte_mask = ~_PAGE_NX; | 396 | u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; |
396 | 397 | ||
397 | /* | 398 | /* |
398 | * noexec = on|off | 399 | * noexec = on|off |
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index cb3da6baa704..f600fc244f02 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
13 | #include <asm/processor.h> | 13 | #include <asm/processor.h> |
14 | #include <asm/tlbflush.h> | 14 | #include <asm/tlbflush.h> |
15 | #include <asm/pgalloc.h> | ||
15 | 16 | ||
16 | static DEFINE_SPINLOCK(cpa_lock); | 17 | static DEFINE_SPINLOCK(cpa_lock); |
17 | static struct list_head df_list = LIST_HEAD_INIT(df_list); | 18 | static struct list_head df_list = LIST_HEAD_INIT(df_list); |
@@ -52,8 +53,8 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot) | |||
52 | addr = address & LARGE_PAGE_MASK; | 53 | addr = address & LARGE_PAGE_MASK; |
53 | pbase = (pte_t *)page_address(base); | 54 | pbase = (pte_t *)page_address(base); |
54 | for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { | 55 | for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { |
55 | pbase[i] = pfn_pte(addr >> PAGE_SHIFT, | 56 | set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT, |
56 | addr == address ? prot : PAGE_KERNEL); | 57 | addr == address ? prot : PAGE_KERNEL)); |
57 | } | 58 | } |
58 | return base; | 59 | return base; |
59 | } | 60 | } |
@@ -62,7 +63,7 @@ static void flush_kernel_map(void *dummy) | |||
62 | { | 63 | { |
63 | /* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */ | 64 | /* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */ |
64 | if (boot_cpu_data.x86_model >= 4) | 65 | if (boot_cpu_data.x86_model >= 4) |
65 | asm volatile("wbinvd":::"memory"); | 66 | wbinvd(); |
66 | /* Flush all to work around Errata in early athlons regarding | 67 | /* Flush all to work around Errata in early athlons regarding |
67 | * large page flushing. | 68 | * large page flushing. |
68 | */ | 69 | */ |
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index bd2f7afc7a2a..dcdce2c6c532 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c | |||
@@ -207,19 +207,19 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) | |||
207 | { | 207 | { |
208 | unsigned long flags; | 208 | unsigned long flags; |
209 | 209 | ||
210 | if (PTRS_PER_PMD == 1) | 210 | if (PTRS_PER_PMD == 1) { |
211 | memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); | ||
211 | spin_lock_irqsave(&pgd_lock, flags); | 212 | spin_lock_irqsave(&pgd_lock, flags); |
213 | } | ||
212 | 214 | ||
213 | memcpy((pgd_t *)pgd + USER_PTRS_PER_PGD, | 215 | clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, |
214 | swapper_pg_dir + USER_PTRS_PER_PGD, | 216 | swapper_pg_dir + USER_PTRS_PER_PGD, |
215 | (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); | 217 | KERNEL_PGD_PTRS); |
216 | |||
217 | if (PTRS_PER_PMD > 1) | 218 | if (PTRS_PER_PMD > 1) |
218 | return; | 219 | return; |
219 | 220 | ||
220 | pgd_list_add(pgd); | 221 | pgd_list_add(pgd); |
221 | spin_unlock_irqrestore(&pgd_lock, flags); | 222 | spin_unlock_irqrestore(&pgd_lock, flags); |
222 | memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); | ||
223 | } | 223 | } |
224 | 224 | ||
225 | /* never called when PTRS_PER_PMD > 1 */ | 225 | /* never called when PTRS_PER_PMD > 1 */ |
diff --git a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c index c90332de582b..5341d481d92f 100644 --- a/arch/i386/oprofile/init.c +++ b/arch/i386/oprofile/init.c | |||
@@ -15,9 +15,9 @@ | |||
15 | * with the NMI mode driver. | 15 | * with the NMI mode driver. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | extern int nmi_init(struct oprofile_operations * ops); | 18 | extern int op_nmi_init(struct oprofile_operations * ops); |
19 | extern int nmi_timer_init(struct oprofile_operations * ops); | 19 | extern int op_nmi_timer_init(struct oprofile_operations * ops); |
20 | extern void nmi_exit(void); | 20 | extern void op_nmi_exit(void); |
21 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); | 21 | extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); |
22 | 22 | ||
23 | 23 | ||
@@ -28,11 +28,11 @@ int __init oprofile_arch_init(struct oprofile_operations * ops) | |||
28 | ret = -ENODEV; | 28 | ret = -ENODEV; |
29 | 29 | ||
30 | #ifdef CONFIG_X86_LOCAL_APIC | 30 | #ifdef CONFIG_X86_LOCAL_APIC |
31 | ret = nmi_init(ops); | 31 | ret = op_nmi_init(ops); |
32 | #endif | 32 | #endif |
33 | #ifdef CONFIG_X86_IO_APIC | 33 | #ifdef CONFIG_X86_IO_APIC |
34 | if (ret < 0) | 34 | if (ret < 0) |
35 | ret = nmi_timer_init(ops); | 35 | ret = op_nmi_timer_init(ops); |
36 | #endif | 36 | #endif |
37 | ops->backtrace = x86_backtrace; | 37 | ops->backtrace = x86_backtrace; |
38 | 38 | ||
@@ -43,6 +43,6 @@ int __init oprofile_arch_init(struct oprofile_operations * ops) | |||
43 | void oprofile_arch_exit(void) | 43 | void oprofile_arch_exit(void) |
44 | { | 44 | { |
45 | #ifdef CONFIG_X86_LOCAL_APIC | 45 | #ifdef CONFIG_X86_LOCAL_APIC |
46 | nmi_exit(); | 46 | op_nmi_exit(); |
47 | #endif | 47 | #endif |
48 | } | 48 | } |
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index 255e4702d185..0493e8b8ec49 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c | |||
@@ -355,7 +355,7 @@ static int __init ppro_init(char ** cpu_type) | |||
355 | /* in order to get driverfs right */ | 355 | /* in order to get driverfs right */ |
356 | static int using_nmi; | 356 | static int using_nmi; |
357 | 357 | ||
358 | int __init nmi_init(struct oprofile_operations *ops) | 358 | int __init op_nmi_init(struct oprofile_operations *ops) |
359 | { | 359 | { |
360 | __u8 vendor = boot_cpu_data.x86_vendor; | 360 | __u8 vendor = boot_cpu_data.x86_vendor; |
361 | __u8 family = boot_cpu_data.x86; | 361 | __u8 family = boot_cpu_data.x86; |
@@ -420,7 +420,7 @@ int __init nmi_init(struct oprofile_operations *ops) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | 422 | ||
423 | void nmi_exit(void) | 423 | void op_nmi_exit(void) |
424 | { | 424 | { |
425 | if (using_nmi) | 425 | if (using_nmi) |
426 | exit_driverfs(); | 426 | exit_driverfs(); |
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c index c58d0c14f274..ad93cdd55d63 100644 --- a/arch/i386/oprofile/nmi_timer_int.c +++ b/arch/i386/oprofile/nmi_timer_int.c | |||
@@ -40,7 +40,7 @@ static void timer_stop(void) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | 42 | ||
43 | int __init nmi_timer_init(struct oprofile_operations * ops) | 43 | int __init op_nmi_timer_init(struct oprofile_operations * ops) |
44 | { | 44 | { |
45 | extern int nmi_active; | 45 | extern int nmi_active; |
46 | 46 | ||
diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile index 1bff03f36965..ead6122dd06d 100644 --- a/arch/i386/pci/Makefile +++ b/arch/i386/pci/Makefile | |||
@@ -5,7 +5,7 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o | |||
5 | obj-$(CONFIG_PCI_DIRECT) += direct.o | 5 | obj-$(CONFIG_PCI_DIRECT) += direct.o |
6 | 6 | ||
7 | pci-y := fixup.o | 7 | pci-y := fixup.o |
8 | pci-$(CONFIG_ACPI_PCI) += acpi.o | 8 | pci-$(CONFIG_ACPI) += acpi.o |
9 | pci-y += legacy.o irq.o | 9 | pci-y += legacy.o irq.o |
10 | 10 | ||
11 | pci-$(CONFIG_X86_VISWS) := visws.o fixup.o | 11 | pci-$(CONFIG_X86_VISWS) := visws.o fixup.o |
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 3cc480998a47..6d6338500c3c 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c | |||
@@ -283,9 +283,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
283 | /* Write-combine setting is ignored, it is changed via the mtrr | 283 | /* Write-combine setting is ignored, it is changed via the mtrr |
284 | * interfaces on this platform. | 284 | * interfaces on this platform. |
285 | */ | 285 | */ |
286 | if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 286 | if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
287 | vma->vm_end - vma->vm_start, | 287 | vma->vm_end - vma->vm_start, |
288 | vma->vm_page_prot)) | 288 | vma->vm_page_prot)) |
289 | return -EAGAIN; | 289 | return -EAGAIN; |
290 | 290 | ||
291 | return 0; | 291 | return 0; |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 86348b68fda1..326a2edc3834 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -1075,7 +1075,7 @@ static void pirq_penalize_isa_irq(int irq, int active) | |||
1075 | 1075 | ||
1076 | void pcibios_penalize_isa_irq(int irq, int active) | 1076 | void pcibios_penalize_isa_irq(int irq, int active) |
1077 | { | 1077 | { |
1078 | #ifdef CONFIG_ACPI_PCI | 1078 | #ifdef CONFIG_ACPI |
1079 | if (!acpi_noirq) | 1079 | if (!acpi_noirq) |
1080 | acpi_penalize_isa_irq(irq, active); | 1080 | acpi_penalize_isa_irq(irq, active); |
1081 | else | 1081 | else |
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index c547c1af6fa1..7b0b9ad848e5 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c | |||
@@ -42,25 +42,25 @@ void __save_processor_state(struct saved_context *ctxt) | |||
42 | /* | 42 | /* |
43 | * descriptor tables | 43 | * descriptor tables |
44 | */ | 44 | */ |
45 | asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit)); | 45 | store_gdt(&ctxt->gdt_limit); |
46 | asm volatile ("sidt %0" : "=m" (ctxt->idt_limit)); | 46 | store_idt(&ctxt->idt_limit); |
47 | asm volatile ("str %0" : "=m" (ctxt->tr)); | 47 | store_tr(ctxt->tr); |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * segment registers | 50 | * segment registers |
51 | */ | 51 | */ |
52 | asm volatile ("movw %%es, %0" : "=m" (ctxt->es)); | 52 | savesegment(es, ctxt->es); |
53 | asm volatile ("movw %%fs, %0" : "=m" (ctxt->fs)); | 53 | savesegment(fs, ctxt->fs); |
54 | asm volatile ("movw %%gs, %0" : "=m" (ctxt->gs)); | 54 | savesegment(gs, ctxt->gs); |
55 | asm volatile ("movw %%ss, %0" : "=m" (ctxt->ss)); | 55 | savesegment(ss, ctxt->ss); |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * control registers | 58 | * control registers |
59 | */ | 59 | */ |
60 | asm volatile ("movl %%cr0, %0" : "=r" (ctxt->cr0)); | 60 | ctxt->cr0 = read_cr0(); |
61 | asm volatile ("movl %%cr2, %0" : "=r" (ctxt->cr2)); | 61 | ctxt->cr2 = read_cr2(); |
62 | asm volatile ("movl %%cr3, %0" : "=r" (ctxt->cr3)); | 62 | ctxt->cr3 = read_cr3(); |
63 | asm volatile ("movl %%cr4, %0" : "=r" (ctxt->cr4)); | 63 | ctxt->cr4 = read_cr4(); |
64 | } | 64 | } |
65 | 65 | ||
66 | void save_processor_state(void) | 66 | void save_processor_state(void) |
@@ -84,7 +84,6 @@ static void fix_processor_context(void) | |||
84 | struct tss_struct * t = &per_cpu(init_tss, cpu); | 84 | struct tss_struct * t = &per_cpu(init_tss, cpu); |
85 | 85 | ||
86 | set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ | 86 | set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ |
87 | per_cpu(cpu_gdt_table, cpu)[GDT_ENTRY_TSS].b &= 0xfffffdff; | ||
88 | 87 | ||
89 | load_TR_desc(); /* This does ltr */ | 88 | load_TR_desc(); /* This does ltr */ |
90 | load_LDT(¤t->active_mm->context); /* This does lldt */ | 89 | load_LDT(¤t->active_mm->context); /* This does lldt */ |
@@ -109,25 +108,25 @@ void __restore_processor_state(struct saved_context *ctxt) | |||
109 | /* | 108 | /* |
110 | * control registers | 109 | * control registers |
111 | */ | 110 | */ |
112 | asm volatile ("movl %0, %%cr4" :: "r" (ctxt->cr4)); | 111 | write_cr4(ctxt->cr4); |
113 | asm volatile ("movl %0, %%cr3" :: "r" (ctxt->cr3)); | 112 | write_cr3(ctxt->cr3); |
114 | asm volatile ("movl %0, %%cr2" :: "r" (ctxt->cr2)); | 113 | write_cr2(ctxt->cr2); |
115 | asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0)); | 114 | write_cr2(ctxt->cr0); |
116 | 115 | ||
117 | /* | 116 | /* |
118 | * now restore the descriptor tables to their proper values | 117 | * now restore the descriptor tables to their proper values |
119 | * ltr is done i fix_processor_context(). | 118 | * ltr is done i fix_processor_context(). |
120 | */ | 119 | */ |
121 | asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit)); | 120 | load_gdt(&ctxt->gdt_limit); |
122 | asm volatile ("lidt %0" :: "m" (ctxt->idt_limit)); | 121 | load_idt(&ctxt->idt_limit); |
123 | 122 | ||
124 | /* | 123 | /* |
125 | * segment registers | 124 | * segment registers |
126 | */ | 125 | */ |
127 | asm volatile ("movw %0, %%es" :: "r" (ctxt->es)); | 126 | loadsegment(es, ctxt->es); |
128 | asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs)); | 127 | loadsegment(fs, ctxt->fs); |
129 | asm volatile ("movw %0, %%gs" :: "r" (ctxt->gs)); | 128 | loadsegment(gs, ctxt->gs); |
130 | asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss)); | 129 | loadsegment(ss, ctxt->ss); |
131 | 130 | ||
132 | /* | 131 | /* |
133 | * sysenter MSRs | 132 | * sysenter MSRs |