diff options
Diffstat (limited to 'arch/x86/kernel')
77 files changed, 775 insertions, 294 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 63bcf39f8f24..b7023430d4dc 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/dmi.h> | 32 | #include <linux/dmi.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/bootmem.h> | 35 | #include <linux/bootmem.h> |
35 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
36 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
@@ -489,6 +490,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) | |||
489 | * ACPI based hotplug support for CPU | 490 | * ACPI based hotplug support for CPU |
490 | */ | 491 | */ |
491 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 492 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
493 | #include <acpi/processor.h> | ||
492 | 494 | ||
493 | static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) | 495 | static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid) |
494 | { | 496 | { |
@@ -566,6 +568,8 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) | |||
566 | goto free_new_map; | 568 | goto free_new_map; |
567 | } | 569 | } |
568 | 570 | ||
571 | acpi_processor_set_pdc(handle); | ||
572 | |||
569 | cpu = cpumask_first(new_map); | 573 | cpu = cpumask_first(new_map); |
570 | acpi_map_cpu2node(handle, cpu, physid); | 574 | acpi_map_cpu2node(handle, cpu, physid); |
571 | 575 | ||
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index f9961034e557..82e508677b91 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char *str) | |||
162 | #endif | 162 | #endif |
163 | if (strncmp(str, "old_ordering", 12) == 0) | 163 | if (strncmp(str, "old_ordering", 12) == 0) |
164 | acpi_old_suspend_ordering(); | 164 | acpi_old_suspend_ordering(); |
165 | if (strncmp(str, "sci_force_enable", 16) == 0) | ||
166 | acpi_set_sci_en_on_resume(); | ||
167 | str = strchr(str, ','); | 165 | str = strchr(str, ','); |
168 | if (str != NULL) | 166 | if (str != NULL) |
169 | str += strspn(str, ", \t"); | 167 | str += strspn(str, ", \t"); |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 3a4bf35c179b..1a160d5d44d0 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/vmalloc.h> | 8 | #include <linux/vmalloc.h> |
9 | #include <linux/memory.h> | 9 | #include <linux/memory.h> |
10 | #include <linux/stop_machine.h> | 10 | #include <linux/stop_machine.h> |
11 | #include <linux/slab.h> | ||
11 | #include <asm/alternative.h> | 12 | #include <asm/alternative.h> |
12 | #include <asm/sections.h> | 13 | #include <asm/sections.h> |
13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index adb0ba025702..f854d89b7edf 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -18,8 +18,8 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/gfp.h> | ||
22 | #include <linux/bitmap.h> | 21 | #include <linux/bitmap.h> |
22 | #include <linux/slab.h> | ||
23 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
24 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev) | |||
118 | return false; | 118 | return false; |
119 | 119 | ||
120 | /* No device or no PCI device */ | 120 | /* No device or no PCI device */ |
121 | if (!dev || dev->bus != &pci_bus_type) | 121 | if (dev->bus != &pci_bus_type) |
122 | return false; | 122 | return false; |
123 | 123 | ||
124 | devid = get_device_id(dev); | 124 | devid = get_device_id(dev); |
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd) | |||
392 | u32 tail, head; | 392 | u32 tail, head; |
393 | u8 *target; | 393 | u8 *target; |
394 | 394 | ||
395 | WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED); | ||
395 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); | 396 | tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET); |
396 | target = iommu->cmd_buf + tail; | 397 | target = iommu->cmd_buf + tail; |
397 | memcpy_toio(target, cmd, sizeof(*cmd)); | 398 | memcpy_toio(target, cmd, sizeof(*cmd)); |
@@ -2186,7 +2187,7 @@ static void prealloc_protection_domains(void) | |||
2186 | struct dma_ops_domain *dma_dom; | 2187 | struct dma_ops_domain *dma_dom; |
2187 | u16 devid; | 2188 | u16 devid; |
2188 | 2189 | ||
2189 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2190 | for_each_pci_dev(dev) { |
2190 | 2191 | ||
2191 | /* Do we handle this device? */ | 2192 | /* Do we handle this device? */ |
2192 | if (!check_device(&dev->dev)) | 2193 | if (!check_device(&dev->dev)) |
@@ -2298,7 +2299,7 @@ static void cleanup_domain(struct protection_domain *domain) | |||
2298 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { | 2299 | list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) { |
2299 | struct device *dev = dev_data->dev; | 2300 | struct device *dev = dev_data->dev; |
2300 | 2301 | ||
2301 | do_detach(dev); | 2302 | __detach_device(dev); |
2302 | atomic_set(&dev_data->bind, 0); | 2303 | atomic_set(&dev_data->bind, 0); |
2303 | } | 2304 | } |
2304 | 2305 | ||
@@ -2327,6 +2328,7 @@ static struct protection_domain *protection_domain_alloc(void) | |||
2327 | return NULL; | 2328 | return NULL; |
2328 | 2329 | ||
2329 | spin_lock_init(&domain->lock); | 2330 | spin_lock_init(&domain->lock); |
2331 | mutex_init(&domain->api_lock); | ||
2330 | domain->id = domain_id_alloc(); | 2332 | domain->id = domain_id_alloc(); |
2331 | if (!domain->id) | 2333 | if (!domain->id) |
2332 | goto out_err; | 2334 | goto out_err; |
@@ -2379,9 +2381,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom) | |||
2379 | 2381 | ||
2380 | free_pagetable(domain); | 2382 | free_pagetable(domain); |
2381 | 2383 | ||
2382 | domain_id_free(domain->id); | 2384 | protection_domain_free(domain); |
2383 | |||
2384 | kfree(domain); | ||
2385 | 2385 | ||
2386 | dom->priv = NULL; | 2386 | dom->priv = NULL; |
2387 | } | 2387 | } |
@@ -2456,6 +2456,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
2456 | iova &= PAGE_MASK; | 2456 | iova &= PAGE_MASK; |
2457 | paddr &= PAGE_MASK; | 2457 | paddr &= PAGE_MASK; |
2458 | 2458 | ||
2459 | mutex_lock(&domain->api_lock); | ||
2460 | |||
2459 | for (i = 0; i < npages; ++i) { | 2461 | for (i = 0; i < npages; ++i) { |
2460 | ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); | 2462 | ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k); |
2461 | if (ret) | 2463 | if (ret) |
@@ -2465,6 +2467,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom, | |||
2465 | paddr += PAGE_SIZE; | 2467 | paddr += PAGE_SIZE; |
2466 | } | 2468 | } |
2467 | 2469 | ||
2470 | mutex_unlock(&domain->api_lock); | ||
2471 | |||
2468 | return 0; | 2472 | return 0; |
2469 | } | 2473 | } |
2470 | 2474 | ||
@@ -2477,12 +2481,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom, | |||
2477 | 2481 | ||
2478 | iova &= PAGE_MASK; | 2482 | iova &= PAGE_MASK; |
2479 | 2483 | ||
2484 | mutex_lock(&domain->api_lock); | ||
2485 | |||
2480 | for (i = 0; i < npages; ++i) { | 2486 | for (i = 0; i < npages; ++i) { |
2481 | iommu_unmap_page(domain, iova, PM_MAP_4k); | 2487 | iommu_unmap_page(domain, iova, PM_MAP_4k); |
2482 | iova += PAGE_SIZE; | 2488 | iova += PAGE_SIZE; |
2483 | } | 2489 | } |
2484 | 2490 | ||
2485 | iommu_flush_tlb_pde(domain); | 2491 | iommu_flush_tlb_pde(domain); |
2492 | |||
2493 | mutex_unlock(&domain->api_lock); | ||
2486 | } | 2494 | } |
2487 | 2495 | ||
2488 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, | 2496 | static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 9dc91b431470..6360abf993d4 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -19,8 +19,8 @@ | |||
19 | 19 | ||
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
22 | #include <linux/gfp.h> | ||
23 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/slab.h> | ||
24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/msi.h> | 26 | #include <linux/msi.h> |
@@ -138,9 +138,9 @@ int amd_iommus_present; | |||
138 | bool amd_iommu_np_cache __read_mostly; | 138 | bool amd_iommu_np_cache __read_mostly; |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Set to true if ACPI table parsing and hardware intialization went properly | 141 | * The ACPI table parsing functions set this variable on an error |
142 | */ | 142 | */ |
143 | static bool amd_iommu_initialized; | 143 | static int __initdata amd_iommu_init_err; |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * List of protection domains - used during resume | 146 | * List of protection domains - used during resume |
@@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table) | |||
391 | */ | 391 | */ |
392 | for (i = 0; i < table->length; ++i) | 392 | for (i = 0; i < table->length; ++i) |
393 | checksum += p[i]; | 393 | checksum += p[i]; |
394 | if (checksum != 0) | 394 | if (checksum != 0) { |
395 | /* ACPI table corrupt */ | 395 | /* ACPI table corrupt */ |
396 | return -ENODEV; | 396 | amd_iommu_init_err = -ENODEV; |
397 | return 0; | ||
398 | } | ||
397 | 399 | ||
398 | p += IVRS_HEADER_LENGTH; | 400 | p += IVRS_HEADER_LENGTH; |
399 | 401 | ||
@@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu) | |||
436 | if (cmd_buf == NULL) | 438 | if (cmd_buf == NULL) |
437 | return NULL; | 439 | return NULL; |
438 | 440 | ||
439 | iommu->cmd_buf_size = CMD_BUFFER_SIZE; | 441 | iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED; |
440 | 442 | ||
441 | return cmd_buf; | 443 | return cmd_buf; |
442 | } | 444 | } |
@@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu) | |||
472 | &entry, sizeof(entry)); | 474 | &entry, sizeof(entry)); |
473 | 475 | ||
474 | amd_iommu_reset_cmd_buffer(iommu); | 476 | amd_iommu_reset_cmd_buffer(iommu); |
477 | iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED); | ||
475 | } | 478 | } |
476 | 479 | ||
477 | static void __init free_command_buffer(struct amd_iommu *iommu) | 480 | static void __init free_command_buffer(struct amd_iommu *iommu) |
478 | { | 481 | { |
479 | free_pages((unsigned long)iommu->cmd_buf, | 482 | free_pages((unsigned long)iommu->cmd_buf, |
480 | get_order(iommu->cmd_buf_size)); | 483 | get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED))); |
481 | } | 484 | } |
482 | 485 | ||
483 | /* allocates the memory where the IOMMU will log its events to */ | 486 | /* allocates the memory where the IOMMU will log its events to */ |
@@ -920,11 +923,16 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
920 | h->mmio_phys); | 923 | h->mmio_phys); |
921 | 924 | ||
922 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); | 925 | iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); |
923 | if (iommu == NULL) | 926 | if (iommu == NULL) { |
924 | return -ENOMEM; | 927 | amd_iommu_init_err = -ENOMEM; |
928 | return 0; | ||
929 | } | ||
930 | |||
925 | ret = init_iommu_one(iommu, h); | 931 | ret = init_iommu_one(iommu, h); |
926 | if (ret) | 932 | if (ret) { |
927 | return ret; | 933 | amd_iommu_init_err = ret; |
934 | return 0; | ||
935 | } | ||
928 | break; | 936 | break; |
929 | default: | 937 | default: |
930 | break; | 938 | break; |
@@ -934,8 +942,6 @@ static int __init init_iommu_all(struct acpi_table_header *table) | |||
934 | } | 942 | } |
935 | WARN_ON(p != end); | 943 | WARN_ON(p != end); |
936 | 944 | ||
937 | amd_iommu_initialized = true; | ||
938 | |||
939 | return 0; | 945 | return 0; |
940 | } | 946 | } |
941 | 947 | ||
@@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void) | |||
1211 | if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) | 1217 | if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0) |
1212 | return -ENODEV; | 1218 | return -ENODEV; |
1213 | 1219 | ||
1220 | ret = amd_iommu_init_err; | ||
1221 | if (ret) | ||
1222 | goto out; | ||
1223 | |||
1214 | dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); | 1224 | dev_table_size = tbl_size(DEV_TABLE_ENTRY_SIZE); |
1215 | alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); | 1225 | alias_table_size = tbl_size(ALIAS_TABLE_ENTRY_SIZE); |
1216 | rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); | 1226 | rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE); |
@@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void) | |||
1270 | if (acpi_table_parse("IVRS", init_iommu_all) != 0) | 1280 | if (acpi_table_parse("IVRS", init_iommu_all) != 0) |
1271 | goto free; | 1281 | goto free; |
1272 | 1282 | ||
1273 | if (!amd_iommu_initialized) | 1283 | if (amd_iommu_init_err) { |
1284 | ret = amd_iommu_init_err; | ||
1274 | goto free; | 1285 | goto free; |
1286 | } | ||
1275 | 1287 | ||
1276 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) | 1288 | if (acpi_table_parse("IVRS", init_memory_definitions) != 0) |
1277 | goto free; | 1289 | goto free; |
1278 | 1290 | ||
1291 | if (amd_iommu_init_err) { | ||
1292 | ret = amd_iommu_init_err; | ||
1293 | goto free; | ||
1294 | } | ||
1295 | |||
1279 | ret = sysdev_class_register(&amd_iommu_sysdev_class); | 1296 | ret = sysdev_class_register(&amd_iommu_sysdev_class); |
1280 | if (ret) | 1297 | if (ret) |
1281 | goto free; | 1298 | goto free; |
@@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void) | |||
1288 | if (ret) | 1305 | if (ret) |
1289 | goto free; | 1306 | goto free; |
1290 | 1307 | ||
1308 | enable_iommus(); | ||
1309 | |||
1291 | if (iommu_pass_through) | 1310 | if (iommu_pass_through) |
1292 | ret = amd_iommu_init_passthrough(); | 1311 | ret = amd_iommu_init_passthrough(); |
1293 | else | 1312 | else |
@@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void) | |||
1300 | 1319 | ||
1301 | amd_iommu_init_notifier(); | 1320 | amd_iommu_init_notifier(); |
1302 | 1321 | ||
1303 | enable_iommus(); | ||
1304 | |||
1305 | if (iommu_pass_through) | 1322 | if (iommu_pass_through) |
1306 | goto out; | 1323 | goto out; |
1307 | 1324 | ||
@@ -1315,6 +1332,7 @@ out: | |||
1315 | return ret; | 1332 | return ret; |
1316 | 1333 | ||
1317 | free: | 1334 | free: |
1335 | disable_iommus(); | ||
1318 | 1336 | ||
1319 | amd_iommu_uninit_devices(); | 1337 | amd_iommu_uninit_devices(); |
1320 | 1338 | ||
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 4b7099526d2c..a35347501d36 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/sysdev.h> | 35 | #include <linux/sysdev.h> |
36 | #include <linux/slab.h> | ||
36 | #include <linux/pm.h> | 37 | #include <linux/pm.h> |
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
38 | #include <linux/sfi.h> | 39 | #include <linux/sfi.h> |
@@ -428,7 +429,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n, | |||
428 | 429 | ||
429 | static __init int apbt_late_init(void) | 430 | static __init int apbt_late_init(void) |
430 | { | 431 | { |
431 | if (disable_apbt_percpu) | 432 | if (disable_apbt_percpu || !apb_timer_block_enabled) |
432 | return 0; | 433 | return 0; |
433 | /* This notifier should be called after workqueue is ready */ | 434 | /* This notifier should be called after workqueue is ready */ |
434 | hotcpu_notifier(apbt_cpuhp_notify, -20); | 435 | hotcpu_notifier(apbt_cpuhp_notify, -20); |
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 3704997e8b25..b5d8b0bcf235 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c | |||
@@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void) | |||
393 | for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { | 393 | for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) { |
394 | int bus; | 394 | int bus; |
395 | int dev_base, dev_limit; | 395 | int dev_base, dev_limit; |
396 | u32 ctl; | ||
396 | 397 | ||
397 | bus = bus_dev_ranges[i].bus; | 398 | bus = bus_dev_ranges[i].bus; |
398 | dev_base = bus_dev_ranges[i].dev_base; | 399 | dev_base = bus_dev_ranges[i].dev_base; |
@@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void) | |||
406 | gart_iommu_aperture = 1; | 407 | gart_iommu_aperture = 1; |
407 | x86_init.iommu.iommu_init = gart_iommu_init; | 408 | x86_init.iommu.iommu_init = gart_iommu_init; |
408 | 409 | ||
409 | aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7; | 410 | ctl = read_pci_config(bus, slot, 3, |
411 | AMD64_GARTAPERTURECTL); | ||
412 | |||
413 | /* | ||
414 | * Before we do anything else disable the GART. It may | ||
415 | * still be enabled if we boot into a crash-kernel here. | ||
416 | * Reconfiguring the GART while it is enabled could have | ||
417 | * unknown side-effects. | ||
418 | */ | ||
419 | ctl &= ~GARTEN; | ||
420 | write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl); | ||
421 | |||
422 | aper_order = (ctl >> 1) & 7; | ||
410 | aper_size = (32 * 1024 * 1024) << aper_order; | 423 | aper_size = (32 * 1024 * 1024) << aper_order; |
411 | aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; | 424 | aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff; |
412 | aper_base <<= 25; | 425 | aper_base <<= 25; |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 00187f1fcfb7..e5a4a1e01618 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1640,8 +1640,10 @@ int __init APIC_init_uniprocessor(void) | |||
1640 | } | 1640 | } |
1641 | #endif | 1641 | #endif |
1642 | 1642 | ||
1643 | #ifndef CONFIG_SMP | ||
1643 | enable_IR_x2apic(); | 1644 | enable_IR_x2apic(); |
1644 | default_setup_apic_routing(); | 1645 | default_setup_apic_routing(); |
1646 | #endif | ||
1645 | 1647 | ||
1646 | verify_local_APIC(); | 1648 | verify_local_APIC(); |
1647 | connect_bsp_APIC(); | 1649 | connect_bsp_APIC(); |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index dd2b5f264643..03ba1b895f5e 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/errno.h> | 42 | #include <linux/errno.h> |
43 | #include <linux/acpi.h> | 43 | #include <linux/acpi.h> |
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/gfp.h> | ||
45 | #include <linux/nmi.h> | 46 | #include <linux/nmi.h> |
46 | #include <linux/smp.h> | 47 | #include <linux/smp.h> |
47 | #include <linux/io.h> | 48 | #include <linux/io.h> |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e4e0ddcb1546..eb2789c3f721 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/freezer.h> | 36 | #include <linux/freezer.h> |
37 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
38 | #include <linux/jiffies.h> /* time_after() */ | 38 | #include <linux/jiffies.h> /* time_after() */ |
39 | #include <linux/slab.h> | ||
39 | #ifdef CONFIG_ACPI | 40 | #ifdef CONFIG_ACPI |
40 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
41 | #endif | 42 | #endif |
@@ -1268,6 +1269,14 @@ void __setup_vector_irq(int cpu) | |||
1268 | /* Mark the inuse vectors */ | 1269 | /* Mark the inuse vectors */ |
1269 | for_each_irq_desc(irq, desc) { | 1270 | for_each_irq_desc(irq, desc) { |
1270 | cfg = desc->chip_data; | 1271 | cfg = desc->chip_data; |
1272 | |||
1273 | /* | ||
1274 | * If it is a legacy IRQ handled by the legacy PIC, this cpu | ||
1275 | * will be part of the irq_cfg's domain. | ||
1276 | */ | ||
1277 | if (irq < legacy_pic->nr_legacy_irqs && !IO_APIC_IRQ(irq)) | ||
1278 | cpumask_set_cpu(cpu, cfg->domain); | ||
1279 | |||
1271 | if (!cpumask_test_cpu(cpu, cfg->domain)) | 1280 | if (!cpumask_test_cpu(cpu, cfg->domain)) |
1272 | continue; | 1281 | continue; |
1273 | vector = cfg->vector; | 1282 | vector = cfg->vector; |
@@ -2536,6 +2545,9 @@ void irq_force_complete_move(int irq) | |||
2536 | struct irq_desc *desc = irq_to_desc(irq); | 2545 | struct irq_desc *desc = irq_to_desc(irq); |
2537 | struct irq_cfg *cfg = desc->chip_data; | 2546 | struct irq_cfg *cfg = desc->chip_data; |
2538 | 2547 | ||
2548 | if (!cfg) | ||
2549 | return; | ||
2550 | |||
2539 | __irq_complete_move(&desc, cfg->vector); | 2551 | __irq_complete_move(&desc, cfg->vector); |
2540 | } | 2552 | } |
2541 | #else | 2553 | #else |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index 8aa65adbd25d..1edaf15c0b8e 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/slab.h> | ||
21 | #include <linux/sysdev.h> | 22 | #include <linux/sysdev.h> |
22 | #include <linux/sysctl.h> | 23 | #include <linux/sysctl.h> |
23 | #include <linux/percpu.h> | 24 | #include <linux/percpu.h> |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 49dbeaef2a27..c085d52dbaf2 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
20 | #include <linux/slab.h> | ||
20 | #include <linux/cpu.h> | 21 | #include <linux/cpu.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
diff --git a/arch/x86/kernel/bootflag.c b/arch/x86/kernel/bootflag.c index 30f25a75fe28..5de7f4c56971 100644 --- a/arch/x86/kernel/bootflag.c +++ b/arch/x86/kernel/bootflag.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/slab.h> | ||
9 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
10 | #include <linux/acpi.h> | 9 | #include <linux/acpi.h> |
11 | #include <asm/io.h> | 10 | #include <asm/io.h> |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 1b1920fa7c80..459168083b77 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/cpufreq.h> | 33 | #include <linux/cpufreq.h> |
34 | #include <linux/compiler.h> | 34 | #include <linux/compiler.h> |
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | #include <linux/slab.h> | ||
36 | #include <trace/events/power.h> | 37 | #include <trace/events/power.h> |
37 | 38 | ||
38 | #include <linux/acpi.h> | 39 | #include <linux/acpi.h> |
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c index 006b278b0d5d..c587db472a75 100644 --- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | 22 | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
25 | #include <linux/cpufreq.h> | 24 | #include <linux/cpufreq.h> |
26 | 25 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index ac27ec2264d5..16e3483be9e3 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #include <linux/cpufreq.h> | 80 | #include <linux/cpufreq.h> |
81 | #include <linux/pci.h> | 81 | #include <linux/pci.h> |
82 | #include <linux/errno.h> | 82 | #include <linux/errno.h> |
83 | #include <linux/slab.h> | ||
83 | 84 | ||
84 | #include <asm/processor-cyrix.h> | 85 | #include <asm/processor-cyrix.h> |
85 | 86 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c index da5f70fcb766..e7b559d74c52 100644 --- a/arch/x86/kernel/cpu/cpufreq/longrun.c +++ b/arch/x86/kernel/cpu/cpufreq/longrun.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/slab.h> | ||
13 | #include <linux/cpufreq.h> | 12 | #include <linux/cpufreq.h> |
14 | #include <linux/timex.h> | 13 | #include <linux/timex.h> |
15 | 14 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 869615193720..7b8a8ba67b07 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/smp.h> | 26 | #include <linux/smp.h> |
27 | #include <linux/cpufreq.h> | 27 | #include <linux/cpufreq.h> |
28 | #include <linux/slab.h> | ||
29 | #include <linux/cpumask.h> | 28 | #include <linux/cpumask.h> |
30 | #include <linux/timex.h> | 29 | #include <linux/timex.h> |
31 | 30 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c index ff36d2979a90..ce7cde713e71 100644 --- a/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/cpufreq.h> | 31 | #include <linux/cpufreq.h> |
32 | #include <linux/compiler.h> | 32 | #include <linux/compiler.h> |
33 | #include <linux/slab.h> | ||
33 | 34 | ||
34 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
35 | #include <linux/io.h> | 36 | #include <linux/io.h> |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index cb01dac267d3..b3379d6a5c57 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/slab.h> | ||
17 | #include <linux/timex.h> | 16 | #include <linux/timex.h> |
18 | #include <linux/io.h> | 17 | #include <linux/io.h> |
19 | 18 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index d360b56e9825..b6215b9798e2 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -929,7 +929,8 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, | |||
929 | powernow_table[i].index = index; | 929 | powernow_table[i].index = index; |
930 | 930 | ||
931 | /* Frequency may be rounded for these */ | 931 | /* Frequency may be rounded for these */ |
932 | if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) { | 932 | if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) |
933 | || boot_cpu_data.x86 == 0x11) { | ||
933 | powernow_table[i].frequency = | 934 | powernow_table[i].frequency = |
934 | freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); | 935 | freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7); |
935 | } else | 936 | } else |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index 8d672ef162ce..9b1ff37de46a 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/sched.h> /* current */ | 20 | #include <linux/sched.h> /* current */ |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | #include <linux/gfp.h> | ||
23 | 24 | ||
24 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
25 | #include <asm/processor.h> | 26 | #include <asm/processor.h> |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 2ce8e0b5cc54..561758e95180 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/cpufreq.h> | 24 | #include <linux/cpufreq.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/slab.h> | ||
27 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
28 | 27 | ||
29 | #include "speedstep-lib.h" | 28 | #include "speedstep-lib.h" |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index ad0083abfa23..a94ec6be69fa 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/cpufreq.h> | 15 | #include <linux/cpufreq.h> |
16 | #include <linux/slab.h> | ||
17 | 16 | ||
18 | #include <asm/msr.h> | 17 | #include <asm/msr.h> |
19 | #include <asm/tsc.h> | 18 | #include <asm/tsc.h> |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index 04d73c114e49..8abd869baabf 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/cpufreq.h> | 19 | #include <linux/cpufreq.h> |
20 | #include <linux/slab.h> | ||
21 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
22 | #include <linux/io.h> | 21 | #include <linux/io.h> |
23 | #include <asm/ist.h> | 22 | #include <asm/ist.h> |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 7e1cca13af35..1366c7cfd483 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -47,6 +47,27 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | |||
47 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) | 47 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) |
48 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 48 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); |
49 | 49 | ||
50 | /* | ||
51 | * Atom erratum AAE44/AAF40/AAG38/AAH41: | ||
52 | * | ||
53 | * A race condition between speculative fetches and invalidating | ||
54 | * a large page. This is worked around in microcode, but we | ||
55 | * need the microcode to have already been loaded... so if it is | ||
56 | * not, recommend a BIOS update and disable large pages. | ||
57 | */ | ||
58 | if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) { | ||
59 | u32 ucode, junk; | ||
60 | |||
61 | wrmsr(MSR_IA32_UCODE_REV, 0, 0); | ||
62 | sync_core(); | ||
63 | rdmsr(MSR_IA32_UCODE_REV, junk, ucode); | ||
64 | |||
65 | if (ucode < 0x20e) { | ||
66 | printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n"); | ||
67 | clear_cpu_cap(c, X86_FEATURE_PSE); | ||
68 | } | ||
69 | } | ||
70 | |||
50 | #ifdef CONFIG_X86_64 | 71 | #ifdef CONFIG_X86_64 |
51 | set_cpu_cap(c, X86_FEATURE_SYSENTER32); | 72 | set_cpu_cap(c, X86_FEATURE_SYSENTER32); |
52 | #else | 73 | #else |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index b3eeb66c0a51..95962a93f99a 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -340,6 +340,10 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) | |||
340 | (boot_cpu_data.x86_mask < 0x1))) | 340 | (boot_cpu_data.x86_mask < 0x1))) |
341 | return; | 341 | return; |
342 | 342 | ||
343 | /* not in virtualized environments */ | ||
344 | if (num_k8_northbridges == 0) | ||
345 | return; | ||
346 | |||
343 | this_leaf->can_disable = true; | 347 | this_leaf->can_disable = true; |
344 | this_leaf->l3_indices = amd_calc_l3_indices(); | 348 | this_leaf->l3_indices = amd_calc_l3_indices(); |
345 | } | 349 | } |
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index 4ac6d48fe11b..bb34b03af252 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile | |||
@@ -7,3 +7,5 @@ obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o | |||
7 | obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o | 7 | obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o |
8 | 8 | ||
9 | obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o | 9 | obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o |
10 | |||
11 | obj-$(CONFIG_ACPI_APEI) += mce-apei.o | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c new file mode 100644 index 000000000000..745b54f9be89 --- /dev/null +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Bridge between MCE and APEI | ||
3 | * | ||
4 | * On some machine, corrected memory errors are reported via APEI | ||
5 | * generic hardware error source (GHES) instead of corrected Machine | ||
6 | * Check. These corrected memory errors can be reported to user space | ||
7 | * through /dev/mcelog via faking a corrected Machine Check, so that | ||
8 | * the error memory page can be offlined by /sbin/mcelog if the error | ||
9 | * count for one page is beyond the threshold. | ||
10 | * | ||
11 | * For fatal MCE, save MCE record into persistent storage via ERST, so | ||
12 | * that the MCE record can be logged after reboot via ERST. | ||
13 | * | ||
14 | * Copyright 2010 Intel Corp. | ||
15 | * Author: Huang Ying <ying.huang@intel.com> | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or | ||
18 | * modify it under the terms of the GNU General Public License version | ||
19 | * 2 as published by the Free Software Foundation. | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License | ||
27 | * along with this program; if not, write to the Free Software | ||
28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
29 | */ | ||
30 | |||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/acpi.h> | ||
33 | #include <linux/cper.h> | ||
34 | #include <acpi/apei.h> | ||
35 | #include <asm/mce.h> | ||
36 | |||
37 | #include "mce-internal.h" | ||
38 | |||
39 | void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err) | ||
40 | { | ||
41 | struct mce m; | ||
42 | |||
43 | /* Only corrected MC is reported */ | ||
44 | if (!corrected) | ||
45 | return; | ||
46 | |||
47 | mce_setup(&m); | ||
48 | m.bank = 1; | ||
49 | /* Fake a memory read corrected error with unknown channel */ | ||
50 | m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | 0x9f; | ||
51 | m.addr = mem_err->physical_addr; | ||
52 | mce_log(&m); | ||
53 | mce_notify_irq(); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(apei_mce_report_mem_error); | ||
56 | |||
57 | #define CPER_CREATOR_MCE \ | ||
58 | UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \ | ||
59 | 0x64, 0x90, 0xb8, 0x9d) | ||
60 | #define CPER_SECTION_TYPE_MCE \ | ||
61 | UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \ | ||
62 | 0x04, 0x4a, 0x38, 0xfc) | ||
63 | |||
64 | /* | ||
65 | * CPER specification (in UEFI specification 2.3 appendix N) requires | ||
66 | * byte-packed. | ||
67 | */ | ||
68 | struct cper_mce_record { | ||
69 | struct cper_record_header hdr; | ||
70 | struct cper_section_descriptor sec_hdr; | ||
71 | struct mce mce; | ||
72 | } __packed; | ||
73 | |||
74 | int apei_write_mce(struct mce *m) | ||
75 | { | ||
76 | struct cper_mce_record rcd; | ||
77 | |||
78 | memset(&rcd, 0, sizeof(rcd)); | ||
79 | memcpy(rcd.hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE); | ||
80 | rcd.hdr.revision = CPER_RECORD_REV; | ||
81 | rcd.hdr.signature_end = CPER_SIG_END; | ||
82 | rcd.hdr.section_count = 1; | ||
83 | rcd.hdr.error_severity = CPER_SER_FATAL; | ||
84 | /* timestamp, platform_id, partition_id are all invalid */ | ||
85 | rcd.hdr.validation_bits = 0; | ||
86 | rcd.hdr.record_length = sizeof(rcd); | ||
87 | rcd.hdr.creator_id = CPER_CREATOR_MCE; | ||
88 | rcd.hdr.notification_type = CPER_NOTIFY_MCE; | ||
89 | rcd.hdr.record_id = cper_next_record_id(); | ||
90 | rcd.hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR; | ||
91 | |||
92 | rcd.sec_hdr.section_offset = (void *)&rcd.mce - (void *)&rcd; | ||
93 | rcd.sec_hdr.section_length = sizeof(rcd.mce); | ||
94 | rcd.sec_hdr.revision = CPER_SEC_REV; | ||
95 | /* fru_id and fru_text is invalid */ | ||
96 | rcd.sec_hdr.validation_bits = 0; | ||
97 | rcd.sec_hdr.flags = CPER_SEC_PRIMARY; | ||
98 | rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE; | ||
99 | rcd.sec_hdr.section_severity = CPER_SER_FATAL; | ||
100 | |||
101 | memcpy(&rcd.mce, m, sizeof(*m)); | ||
102 | |||
103 | return erst_write(&rcd.hdr); | ||
104 | } | ||
105 | |||
106 | ssize_t apei_read_mce(struct mce *m, u64 *record_id) | ||
107 | { | ||
108 | struct cper_mce_record rcd; | ||
109 | ssize_t len; | ||
110 | |||
111 | len = erst_read_next(&rcd.hdr, sizeof(rcd)); | ||
112 | if (len <= 0) | ||
113 | return len; | ||
114 | /* Can not skip other records in storage via ERST unless clear them */ | ||
115 | else if (len != sizeof(rcd) || | ||
116 | uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) { | ||
117 | if (printk_ratelimit()) | ||
118 | pr_warning( | ||
119 | "MCE-APEI: Can not skip the unknown record in ERST"); | ||
120 | return -EIO; | ||
121 | } | ||
122 | |||
123 | memcpy(m, &rcd.mce, sizeof(*m)); | ||
124 | *record_id = rcd.hdr.record_id; | ||
125 | |||
126 | return sizeof(*m); | ||
127 | } | ||
128 | |||
129 | /* Check whether there is record in ERST */ | ||
130 | int apei_check_mce(void) | ||
131 | { | ||
132 | return erst_get_record_count(); | ||
133 | } | ||
134 | |||
135 | int apei_clear_mce(u64 record_id) | ||
136 | { | ||
137 | return erst_clear(record_id); | ||
138 | } | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 73734baa50f2..e7dbde7bfedb 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kdebug.h> | 22 | #include <linux/kdebug.h> |
23 | #include <linux/cpu.h> | 23 | #include <linux/cpu.h> |
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/gfp.h> | ||
25 | #include <asm/mce.h> | 26 | #include <asm/mce.h> |
26 | #include <asm/apic.h> | 27 | #include <asm/apic.h> |
27 | 28 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 32996f9fab67..fefcc69ee8b5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h | |||
@@ -28,3 +28,26 @@ extern int mce_ser; | |||
28 | 28 | ||
29 | extern struct mce_bank *mce_banks; | 29 | extern struct mce_bank *mce_banks; |
30 | 30 | ||
31 | #ifdef CONFIG_ACPI_APEI | ||
32 | int apei_write_mce(struct mce *m); | ||
33 | ssize_t apei_read_mce(struct mce *m, u64 *record_id); | ||
34 | int apei_check_mce(void); | ||
35 | int apei_clear_mce(u64 record_id); | ||
36 | #else | ||
37 | static inline int apei_write_mce(struct mce *m) | ||
38 | { | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | static inline ssize_t apei_read_mce(struct mce *m, u64 *record_id) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | static inline int apei_check_mce(void) | ||
46 | { | ||
47 | return 0; | ||
48 | } | ||
49 | static inline int apei_clear_mce(u64 record_id) | ||
50 | { | ||
51 | return -EINVAL; | ||
52 | } | ||
53 | #endif | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 3ab9c886b613..09535ca9b9d7 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/sysfs.h> | 27 | #include <linux/sysfs.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/slab.h> | ||
29 | #include <linux/init.h> | 30 | #include <linux/init.h> |
30 | #include <linux/kmod.h> | 31 | #include <linux/kmod.h> |
31 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
@@ -263,7 +264,7 @@ static void wait_for_panic(void) | |||
263 | 264 | ||
264 | static void mce_panic(char *msg, struct mce *final, char *exp) | 265 | static void mce_panic(char *msg, struct mce *final, char *exp) |
265 | { | 266 | { |
266 | int i; | 267 | int i, apei_err = 0; |
267 | 268 | ||
268 | if (!fake_panic) { | 269 | if (!fake_panic) { |
269 | /* | 270 | /* |
@@ -286,8 +287,11 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
286 | struct mce *m = &mcelog.entry[i]; | 287 | struct mce *m = &mcelog.entry[i]; |
287 | if (!(m->status & MCI_STATUS_VAL)) | 288 | if (!(m->status & MCI_STATUS_VAL)) |
288 | continue; | 289 | continue; |
289 | if (!(m->status & MCI_STATUS_UC)) | 290 | if (!(m->status & MCI_STATUS_UC)) { |
290 | print_mce(m); | 291 | print_mce(m); |
292 | if (!apei_err) | ||
293 | apei_err = apei_write_mce(m); | ||
294 | } | ||
291 | } | 295 | } |
292 | /* Now print uncorrected but with the final one last */ | 296 | /* Now print uncorrected but with the final one last */ |
293 | for (i = 0; i < MCE_LOG_LEN; i++) { | 297 | for (i = 0; i < MCE_LOG_LEN; i++) { |
@@ -296,11 +300,17 @@ static void mce_panic(char *msg, struct mce *final, char *exp) | |||
296 | continue; | 300 | continue; |
297 | if (!(m->status & MCI_STATUS_UC)) | 301 | if (!(m->status & MCI_STATUS_UC)) |
298 | continue; | 302 | continue; |
299 | if (!final || memcmp(m, final, sizeof(struct mce))) | 303 | if (!final || memcmp(m, final, sizeof(struct mce))) { |
300 | print_mce(m); | 304 | print_mce(m); |
305 | if (!apei_err) | ||
306 | apei_err = apei_write_mce(m); | ||
307 | } | ||
301 | } | 308 | } |
302 | if (final) | 309 | if (final) { |
303 | print_mce(final); | 310 | print_mce(final); |
311 | if (!apei_err) | ||
312 | apei_err = apei_write_mce(final); | ||
313 | } | ||
304 | if (cpu_missing) | 314 | if (cpu_missing) |
305 | printk(KERN_EMERG "Some CPUs didn't answer in synchronization\n"); | 315 | printk(KERN_EMERG "Some CPUs didn't answer in synchronization\n"); |
306 | print_mce_tail(); | 316 | print_mce_tail(); |
@@ -1492,6 +1502,43 @@ static void collect_tscs(void *data) | |||
1492 | rdtscll(cpu_tsc[smp_processor_id()]); | 1502 | rdtscll(cpu_tsc[smp_processor_id()]); |
1493 | } | 1503 | } |
1494 | 1504 | ||
1505 | static int mce_apei_read_done; | ||
1506 | |||
1507 | /* Collect MCE record of previous boot in persistent storage via APEI ERST. */ | ||
1508 | static int __mce_read_apei(char __user **ubuf, size_t usize) | ||
1509 | { | ||
1510 | int rc; | ||
1511 | u64 record_id; | ||
1512 | struct mce m; | ||
1513 | |||
1514 | if (usize < sizeof(struct mce)) | ||
1515 | return -EINVAL; | ||
1516 | |||
1517 | rc = apei_read_mce(&m, &record_id); | ||
1518 | /* Error or no more MCE record */ | ||
1519 | if (rc <= 0) { | ||
1520 | mce_apei_read_done = 1; | ||
1521 | return rc; | ||
1522 | } | ||
1523 | rc = -EFAULT; | ||
1524 | if (copy_to_user(*ubuf, &m, sizeof(struct mce))) | ||
1525 | return rc; | ||
1526 | /* | ||
1527 | * In fact, we should have cleared the record after that has | ||
1528 | * been flushed to the disk or sent to network in | ||
1529 | * /sbin/mcelog, but we have no interface to support that now, | ||
1530 | * so just clear it to avoid duplication. | ||
1531 | */ | ||
1532 | rc = apei_clear_mce(record_id); | ||
1533 | if (rc) { | ||
1534 | mce_apei_read_done = 1; | ||
1535 | return rc; | ||
1536 | } | ||
1537 | *ubuf += sizeof(struct mce); | ||
1538 | |||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1495 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | 1542 | static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, |
1496 | loff_t *off) | 1543 | loff_t *off) |
1497 | { | 1544 | { |
@@ -1505,15 +1552,19 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | |||
1505 | return -ENOMEM; | 1552 | return -ENOMEM; |
1506 | 1553 | ||
1507 | mutex_lock(&mce_read_mutex); | 1554 | mutex_lock(&mce_read_mutex); |
1555 | |||
1556 | if (!mce_apei_read_done) { | ||
1557 | err = __mce_read_apei(&buf, usize); | ||
1558 | if (err || buf != ubuf) | ||
1559 | goto out; | ||
1560 | } | ||
1561 | |||
1508 | next = rcu_dereference_check_mce(mcelog.next); | 1562 | next = rcu_dereference_check_mce(mcelog.next); |
1509 | 1563 | ||
1510 | /* Only supports full reads right now */ | 1564 | /* Only supports full reads right now */ |
1511 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { | 1565 | err = -EINVAL; |
1512 | mutex_unlock(&mce_read_mutex); | 1566 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) |
1513 | kfree(cpu_tsc); | 1567 | goto out; |
1514 | |||
1515 | return -EINVAL; | ||
1516 | } | ||
1517 | 1568 | ||
1518 | err = 0; | 1569 | err = 0; |
1519 | prev = 0; | 1570 | prev = 0; |
@@ -1561,10 +1612,15 @@ timeout: | |||
1561 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); | 1612 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); |
1562 | } | 1613 | } |
1563 | } | 1614 | } |
1615 | |||
1616 | if (err) | ||
1617 | err = -EFAULT; | ||
1618 | |||
1619 | out: | ||
1564 | mutex_unlock(&mce_read_mutex); | 1620 | mutex_unlock(&mce_read_mutex); |
1565 | kfree(cpu_tsc); | 1621 | kfree(cpu_tsc); |
1566 | 1622 | ||
1567 | return err ? -EFAULT : buf - ubuf; | 1623 | return err ? err : buf - ubuf; |
1568 | } | 1624 | } |
1569 | 1625 | ||
1570 | static unsigned int mce_poll(struct file *file, poll_table *wait) | 1626 | static unsigned int mce_poll(struct file *file, poll_table *wait) |
@@ -1572,6 +1628,8 @@ static unsigned int mce_poll(struct file *file, poll_table *wait) | |||
1572 | poll_wait(file, &mce_wait, wait); | 1628 | poll_wait(file, &mce_wait, wait); |
1573 | if (rcu_dereference_check_mce(mcelog.next)) | 1629 | if (rcu_dereference_check_mce(mcelog.next)) |
1574 | return POLLIN | POLLRDNORM; | 1630 | return POLLIN | POLLRDNORM; |
1631 | if (!mce_apei_read_done && apei_check_mce()) | ||
1632 | return POLLIN | POLLRDNORM; | ||
1575 | return 0; | 1633 | return 0; |
1576 | } | 1634 | } |
1577 | 1635 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index cda932ca3ade..224392d8fe8c 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
26 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index d15df6e49bf0..62b48e40920a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Author: Andi Kleen | 5 | * Author: Andi Kleen |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/gfp.h> | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
9 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
10 | #include <linux/percpu.h> | 11 | #include <linux/percpu.h> |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 9aa5dc76ff4a..fd31a441c61c 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/slab.h> | ||
10 | #include <linux/io.h> | 9 | #include <linux/io.h> |
11 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
12 | 11 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index e006e56f699c..79289632cb27 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/ctype.h> | 6 | #include <linux/ctype.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/slab.h> | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
9 | 10 | ||
10 | #define LINE_SIZE 80 | 11 | #define LINE_SIZE 80 |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 42aafd11e170..db5bdc8addf8 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/kdebug.h> | 21 | #include <linux/kdebug.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
26 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
@@ -28,6 +29,7 @@ | |||
28 | #include <asm/apic.h> | 29 | #include <asm/apic.h> |
29 | #include <asm/stacktrace.h> | 30 | #include <asm/stacktrace.h> |
30 | #include <asm/nmi.h> | 31 | #include <asm/nmi.h> |
32 | #include <asm/compat.h> | ||
31 | 33 | ||
32 | static u64 perf_event_mask __read_mostly; | 34 | static u64 perf_event_mask __read_mostly; |
33 | 35 | ||
@@ -133,8 +135,8 @@ struct x86_pmu { | |||
133 | int (*handle_irq)(struct pt_regs *); | 135 | int (*handle_irq)(struct pt_regs *); |
134 | void (*disable_all)(void); | 136 | void (*disable_all)(void); |
135 | void (*enable_all)(void); | 137 | void (*enable_all)(void); |
136 | void (*enable)(struct hw_perf_event *, int); | 138 | void (*enable)(struct perf_event *); |
137 | void (*disable)(struct hw_perf_event *, int); | 139 | void (*disable)(struct perf_event *); |
138 | unsigned eventsel; | 140 | unsigned eventsel; |
139 | unsigned perfctr; | 141 | unsigned perfctr; |
140 | u64 (*event_map)(int); | 142 | u64 (*event_map)(int); |
@@ -157,6 +159,11 @@ struct x86_pmu { | |||
157 | void (*put_event_constraints)(struct cpu_hw_events *cpuc, | 159 | void (*put_event_constraints)(struct cpu_hw_events *cpuc, |
158 | struct perf_event *event); | 160 | struct perf_event *event); |
159 | struct event_constraint *event_constraints; | 161 | struct event_constraint *event_constraints; |
162 | |||
163 | int (*cpu_prepare)(int cpu); | ||
164 | void (*cpu_starting)(int cpu); | ||
165 | void (*cpu_dying)(int cpu); | ||
166 | void (*cpu_dead)(int cpu); | ||
160 | }; | 167 | }; |
161 | 168 | ||
162 | static struct x86_pmu x86_pmu __read_mostly; | 169 | static struct x86_pmu x86_pmu __read_mostly; |
@@ -165,8 +172,7 @@ static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { | |||
165 | .enabled = 1, | 172 | .enabled = 1, |
166 | }; | 173 | }; |
167 | 174 | ||
168 | static int x86_perf_event_set_period(struct perf_event *event, | 175 | static int x86_perf_event_set_period(struct perf_event *event); |
169 | struct hw_perf_event *hwc, int idx); | ||
170 | 176 | ||
171 | /* | 177 | /* |
172 | * Generalized hw caching related hw_event table, filled | 178 | * Generalized hw caching related hw_event table, filled |
@@ -189,11 +195,12 @@ static u64 __read_mostly hw_cache_event_ids | |||
189 | * Returns the delta events processed. | 195 | * Returns the delta events processed. |
190 | */ | 196 | */ |
191 | static u64 | 197 | static u64 |
192 | x86_perf_event_update(struct perf_event *event, | 198 | x86_perf_event_update(struct perf_event *event) |
193 | struct hw_perf_event *hwc, int idx) | ||
194 | { | 199 | { |
200 | struct hw_perf_event *hwc = &event->hw; | ||
195 | int shift = 64 - x86_pmu.event_bits; | 201 | int shift = 64 - x86_pmu.event_bits; |
196 | u64 prev_raw_count, new_raw_count; | 202 | u64 prev_raw_count, new_raw_count; |
203 | int idx = hwc->idx; | ||
197 | s64 delta; | 204 | s64 delta; |
198 | 205 | ||
199 | if (idx == X86_PMC_IDX_FIXED_BTS) | 206 | if (idx == X86_PMC_IDX_FIXED_BTS) |
@@ -293,7 +300,7 @@ static inline bool bts_available(void) | |||
293 | return x86_pmu.enable_bts != NULL; | 300 | return x86_pmu.enable_bts != NULL; |
294 | } | 301 | } |
295 | 302 | ||
296 | static inline void init_debug_store_on_cpu(int cpu) | 303 | static void init_debug_store_on_cpu(int cpu) |
297 | { | 304 | { |
298 | struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; | 305 | struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds; |
299 | 306 | ||
@@ -305,7 +312,7 @@ static inline void init_debug_store_on_cpu(int cpu) | |||
305 | (u32)((u64)(unsigned long)ds >> 32)); | 312 | (u32)((u64)(unsigned long)ds >> 32)); |
306 | } | 313 | } |
307 | 314 | ||
308 | static inline void fini_debug_store_on_cpu(int cpu) | 315 | static void fini_debug_store_on_cpu(int cpu) |
309 | { | 316 | { |
310 | if (!per_cpu(cpu_hw_events, cpu).ds) | 317 | if (!per_cpu(cpu_hw_events, cpu).ds) |
311 | return; | 318 | return; |
@@ -638,7 +645,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
638 | if (test_bit(hwc->idx, used_mask)) | 645 | if (test_bit(hwc->idx, used_mask)) |
639 | break; | 646 | break; |
640 | 647 | ||
641 | set_bit(hwc->idx, used_mask); | 648 | __set_bit(hwc->idx, used_mask); |
642 | if (assign) | 649 | if (assign) |
643 | assign[i] = hwc->idx; | 650 | assign[i] = hwc->idx; |
644 | } | 651 | } |
@@ -687,7 +694,7 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) | |||
687 | if (j == X86_PMC_IDX_MAX) | 694 | if (j == X86_PMC_IDX_MAX) |
688 | break; | 695 | break; |
689 | 696 | ||
690 | set_bit(j, used_mask); | 697 | __set_bit(j, used_mask); |
691 | 698 | ||
692 | if (assign) | 699 | if (assign) |
693 | assign[i] = j; | 700 | assign[i] = j; |
@@ -780,6 +787,7 @@ static inline int match_prev_assignment(struct hw_perf_event *hwc, | |||
780 | hwc->last_tag == cpuc->tags[i]; | 787 | hwc->last_tag == cpuc->tags[i]; |
781 | } | 788 | } |
782 | 789 | ||
790 | static int x86_pmu_start(struct perf_event *event); | ||
783 | static void x86_pmu_stop(struct perf_event *event); | 791 | static void x86_pmu_stop(struct perf_event *event); |
784 | 792 | ||
785 | void hw_perf_enable(void) | 793 | void hw_perf_enable(void) |
@@ -796,6 +804,7 @@ void hw_perf_enable(void) | |||
796 | return; | 804 | return; |
797 | 805 | ||
798 | if (cpuc->n_added) { | 806 | if (cpuc->n_added) { |
807 | int n_running = cpuc->n_events - cpuc->n_added; | ||
799 | /* | 808 | /* |
800 | * apply assignment obtained either from | 809 | * apply assignment obtained either from |
801 | * hw_perf_group_sched_in() or x86_pmu_enable() | 810 | * hw_perf_group_sched_in() or x86_pmu_enable() |
@@ -803,8 +812,7 @@ void hw_perf_enable(void) | |||
803 | * step1: save events moving to new counters | 812 | * step1: save events moving to new counters |
804 | * step2: reprogram moved events into new counters | 813 | * step2: reprogram moved events into new counters |
805 | */ | 814 | */ |
806 | for (i = 0; i < cpuc->n_events; i++) { | 815 | for (i = 0; i < n_running; i++) { |
807 | |||
808 | event = cpuc->event_list[i]; | 816 | event = cpuc->event_list[i]; |
809 | hwc = &event->hw; | 817 | hwc = &event->hw; |
810 | 818 | ||
@@ -819,29 +827,18 @@ void hw_perf_enable(void) | |||
819 | continue; | 827 | continue; |
820 | 828 | ||
821 | x86_pmu_stop(event); | 829 | x86_pmu_stop(event); |
822 | |||
823 | hwc->idx = -1; | ||
824 | } | 830 | } |
825 | 831 | ||
826 | for (i = 0; i < cpuc->n_events; i++) { | 832 | for (i = 0; i < cpuc->n_events; i++) { |
827 | |||
828 | event = cpuc->event_list[i]; | 833 | event = cpuc->event_list[i]; |
829 | hwc = &event->hw; | 834 | hwc = &event->hw; |
830 | 835 | ||
831 | if (hwc->idx == -1) { | 836 | if (!match_prev_assignment(hwc, cpuc, i)) |
832 | x86_assign_hw_event(event, cpuc, i); | 837 | x86_assign_hw_event(event, cpuc, i); |
833 | x86_perf_event_set_period(event, hwc, hwc->idx); | 838 | else if (i < n_running) |
834 | } | 839 | continue; |
835 | /* | ||
836 | * need to mark as active because x86_pmu_disable() | ||
837 | * clear active_mask and events[] yet it preserves | ||
838 | * idx | ||
839 | */ | ||
840 | set_bit(hwc->idx, cpuc->active_mask); | ||
841 | cpuc->events[hwc->idx] = event; | ||
842 | 840 | ||
843 | x86_pmu.enable(hwc, hwc->idx); | 841 | x86_pmu_start(event); |
844 | perf_event_update_userpage(event); | ||
845 | } | 842 | } |
846 | cpuc->n_added = 0; | 843 | cpuc->n_added = 0; |
847 | perf_events_lapic_init(); | 844 | perf_events_lapic_init(); |
@@ -853,15 +850,16 @@ void hw_perf_enable(void) | |||
853 | x86_pmu.enable_all(); | 850 | x86_pmu.enable_all(); |
854 | } | 851 | } |
855 | 852 | ||
856 | static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, int idx) | 853 | static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc) |
857 | { | 854 | { |
858 | (void)checking_wrmsrl(hwc->config_base + idx, | 855 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, |
859 | hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); | 856 | hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE); |
860 | } | 857 | } |
861 | 858 | ||
862 | static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx) | 859 | static inline void x86_pmu_disable_event(struct perf_event *event) |
863 | { | 860 | { |
864 | (void)checking_wrmsrl(hwc->config_base + idx, hwc->config); | 861 | struct hw_perf_event *hwc = &event->hw; |
862 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config); | ||
865 | } | 863 | } |
866 | 864 | ||
867 | static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); | 865 | static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); |
@@ -871,12 +869,12 @@ static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); | |||
871 | * To be called with the event disabled in hw: | 869 | * To be called with the event disabled in hw: |
872 | */ | 870 | */ |
873 | static int | 871 | static int |
874 | x86_perf_event_set_period(struct perf_event *event, | 872 | x86_perf_event_set_period(struct perf_event *event) |
875 | struct hw_perf_event *hwc, int idx) | ||
876 | { | 873 | { |
874 | struct hw_perf_event *hwc = &event->hw; | ||
877 | s64 left = atomic64_read(&hwc->period_left); | 875 | s64 left = atomic64_read(&hwc->period_left); |
878 | s64 period = hwc->sample_period; | 876 | s64 period = hwc->sample_period; |
879 | int err, ret = 0; | 877 | int err, ret = 0, idx = hwc->idx; |
880 | 878 | ||
881 | if (idx == X86_PMC_IDX_FIXED_BTS) | 879 | if (idx == X86_PMC_IDX_FIXED_BTS) |
882 | return 0; | 880 | return 0; |
@@ -922,11 +920,11 @@ x86_perf_event_set_period(struct perf_event *event, | |||
922 | return ret; | 920 | return ret; |
923 | } | 921 | } |
924 | 922 | ||
925 | static void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx) | 923 | static void x86_pmu_enable_event(struct perf_event *event) |
926 | { | 924 | { |
927 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 925 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
928 | if (cpuc->enabled) | 926 | if (cpuc->enabled) |
929 | __x86_pmu_enable_event(hwc, idx); | 927 | __x86_pmu_enable_event(&event->hw); |
930 | } | 928 | } |
931 | 929 | ||
932 | /* | 930 | /* |
@@ -962,34 +960,32 @@ static int x86_pmu_enable(struct perf_event *event) | |||
962 | memcpy(cpuc->assign, assign, n*sizeof(int)); | 960 | memcpy(cpuc->assign, assign, n*sizeof(int)); |
963 | 961 | ||
964 | cpuc->n_events = n; | 962 | cpuc->n_events = n; |
965 | cpuc->n_added = n - n0; | 963 | cpuc->n_added += n - n0; |
966 | 964 | ||
967 | return 0; | 965 | return 0; |
968 | } | 966 | } |
969 | 967 | ||
970 | static int x86_pmu_start(struct perf_event *event) | 968 | static int x86_pmu_start(struct perf_event *event) |
971 | { | 969 | { |
972 | struct hw_perf_event *hwc = &event->hw; | 970 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
971 | int idx = event->hw.idx; | ||
973 | 972 | ||
974 | if (hwc->idx == -1) | 973 | if (idx == -1) |
975 | return -EAGAIN; | 974 | return -EAGAIN; |
976 | 975 | ||
977 | x86_perf_event_set_period(event, hwc, hwc->idx); | 976 | x86_perf_event_set_period(event); |
978 | x86_pmu.enable(hwc, hwc->idx); | 977 | cpuc->events[idx] = event; |
978 | __set_bit(idx, cpuc->active_mask); | ||
979 | x86_pmu.enable(event); | ||
980 | perf_event_update_userpage(event); | ||
979 | 981 | ||
980 | return 0; | 982 | return 0; |
981 | } | 983 | } |
982 | 984 | ||
983 | static void x86_pmu_unthrottle(struct perf_event *event) | 985 | static void x86_pmu_unthrottle(struct perf_event *event) |
984 | { | 986 | { |
985 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 987 | int ret = x86_pmu_start(event); |
986 | struct hw_perf_event *hwc = &event->hw; | 988 | WARN_ON_ONCE(ret); |
987 | |||
988 | if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX || | ||
989 | cpuc->events[hwc->idx] != event)) | ||
990 | return; | ||
991 | |||
992 | x86_pmu.enable(hwc, hwc->idx); | ||
993 | } | 989 | } |
994 | 990 | ||
995 | void perf_event_print_debug(void) | 991 | void perf_event_print_debug(void) |
@@ -1049,18 +1045,16 @@ static void x86_pmu_stop(struct perf_event *event) | |||
1049 | struct hw_perf_event *hwc = &event->hw; | 1045 | struct hw_perf_event *hwc = &event->hw; |
1050 | int idx = hwc->idx; | 1046 | int idx = hwc->idx; |
1051 | 1047 | ||
1052 | /* | 1048 | if (!__test_and_clear_bit(idx, cpuc->active_mask)) |
1053 | * Must be done before we disable, otherwise the nmi handler | 1049 | return; |
1054 | * could reenable again: | 1050 | |
1055 | */ | 1051 | x86_pmu.disable(event); |
1056 | clear_bit(idx, cpuc->active_mask); | ||
1057 | x86_pmu.disable(hwc, idx); | ||
1058 | 1052 | ||
1059 | /* | 1053 | /* |
1060 | * Drain the remaining delta count out of a event | 1054 | * Drain the remaining delta count out of a event |
1061 | * that we are disabling: | 1055 | * that we are disabling: |
1062 | */ | 1056 | */ |
1063 | x86_perf_event_update(event, hwc, idx); | 1057 | x86_perf_event_update(event); |
1064 | 1058 | ||
1065 | cpuc->events[idx] = NULL; | 1059 | cpuc->events[idx] = NULL; |
1066 | } | 1060 | } |
@@ -1108,7 +1102,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1108 | event = cpuc->events[idx]; | 1102 | event = cpuc->events[idx]; |
1109 | hwc = &event->hw; | 1103 | hwc = &event->hw; |
1110 | 1104 | ||
1111 | val = x86_perf_event_update(event, hwc, idx); | 1105 | val = x86_perf_event_update(event); |
1112 | if (val & (1ULL << (x86_pmu.event_bits - 1))) | 1106 | if (val & (1ULL << (x86_pmu.event_bits - 1))) |
1113 | continue; | 1107 | continue; |
1114 | 1108 | ||
@@ -1118,11 +1112,11 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1118 | handled = 1; | 1112 | handled = 1; |
1119 | data.period = event->hw.last_period; | 1113 | data.period = event->hw.last_period; |
1120 | 1114 | ||
1121 | if (!x86_perf_event_set_period(event, hwc, idx)) | 1115 | if (!x86_perf_event_set_period(event)) |
1122 | continue; | 1116 | continue; |
1123 | 1117 | ||
1124 | if (perf_event_overflow(event, 1, &data, regs)) | 1118 | if (perf_event_overflow(event, 1, &data, regs)) |
1125 | x86_pmu.disable(hwc, idx); | 1119 | x86_pmu_stop(event); |
1126 | } | 1120 | } |
1127 | 1121 | ||
1128 | if (handled) | 1122 | if (handled) |
@@ -1309,7 +1303,7 @@ int hw_perf_group_sched_in(struct perf_event *leader, | |||
1309 | memcpy(cpuc->assign, assign, n0*sizeof(int)); | 1303 | memcpy(cpuc->assign, assign, n0*sizeof(int)); |
1310 | 1304 | ||
1311 | cpuc->n_events = n0; | 1305 | cpuc->n_events = n0; |
1312 | cpuc->n_added = n1; | 1306 | cpuc->n_added += n1; |
1313 | ctx->nr_active += n1; | 1307 | ctx->nr_active += n1; |
1314 | 1308 | ||
1315 | /* | 1309 | /* |
@@ -1337,6 +1331,41 @@ undo: | |||
1337 | #include "perf_event_p6.c" | 1331 | #include "perf_event_p6.c" |
1338 | #include "perf_event_intel.c" | 1332 | #include "perf_event_intel.c" |
1339 | 1333 | ||
1334 | static int __cpuinit | ||
1335 | x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) | ||
1336 | { | ||
1337 | unsigned int cpu = (long)hcpu; | ||
1338 | int ret = NOTIFY_OK; | ||
1339 | |||
1340 | switch (action & ~CPU_TASKS_FROZEN) { | ||
1341 | case CPU_UP_PREPARE: | ||
1342 | if (x86_pmu.cpu_prepare) | ||
1343 | ret = x86_pmu.cpu_prepare(cpu); | ||
1344 | break; | ||
1345 | |||
1346 | case CPU_STARTING: | ||
1347 | if (x86_pmu.cpu_starting) | ||
1348 | x86_pmu.cpu_starting(cpu); | ||
1349 | break; | ||
1350 | |||
1351 | case CPU_DYING: | ||
1352 | if (x86_pmu.cpu_dying) | ||
1353 | x86_pmu.cpu_dying(cpu); | ||
1354 | break; | ||
1355 | |||
1356 | case CPU_UP_CANCELED: | ||
1357 | case CPU_DEAD: | ||
1358 | if (x86_pmu.cpu_dead) | ||
1359 | x86_pmu.cpu_dead(cpu); | ||
1360 | break; | ||
1361 | |||
1362 | default: | ||
1363 | break; | ||
1364 | } | ||
1365 | |||
1366 | return ret; | ||
1367 | } | ||
1368 | |||
1340 | static void __init pmu_check_apic(void) | 1369 | static void __init pmu_check_apic(void) |
1341 | { | 1370 | { |
1342 | if (cpu_has_apic) | 1371 | if (cpu_has_apic) |
@@ -1415,11 +1444,13 @@ void __init init_hw_perf_events(void) | |||
1415 | pr_info("... max period: %016Lx\n", x86_pmu.max_period); | 1444 | pr_info("... max period: %016Lx\n", x86_pmu.max_period); |
1416 | pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed); | 1445 | pr_info("... fixed-purpose events: %d\n", x86_pmu.num_events_fixed); |
1417 | pr_info("... event mask: %016Lx\n", perf_event_mask); | 1446 | pr_info("... event mask: %016Lx\n", perf_event_mask); |
1447 | |||
1448 | perf_cpu_notifier(x86_pmu_notifier); | ||
1418 | } | 1449 | } |
1419 | 1450 | ||
1420 | static inline void x86_pmu_read(struct perf_event *event) | 1451 | static inline void x86_pmu_read(struct perf_event *event) |
1421 | { | 1452 | { |
1422 | x86_perf_event_update(event, &event->hw, event->hw.idx); | 1453 | x86_perf_event_update(event); |
1423 | } | 1454 | } |
1424 | 1455 | ||
1425 | static const struct pmu pmu = { | 1456 | static const struct pmu pmu = { |
@@ -1601,14 +1632,42 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) | |||
1601 | return len; | 1632 | return len; |
1602 | } | 1633 | } |
1603 | 1634 | ||
1604 | static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) | 1635 | #ifdef CONFIG_COMPAT |
1636 | static inline int | ||
1637 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
1605 | { | 1638 | { |
1606 | unsigned long bytes; | 1639 | /* 32-bit process in 64-bit kernel. */ |
1640 | struct stack_frame_ia32 frame; | ||
1641 | const void __user *fp; | ||
1607 | 1642 | ||
1608 | bytes = copy_from_user_nmi(frame, fp, sizeof(*frame)); | 1643 | if (!test_thread_flag(TIF_IA32)) |
1644 | return 0; | ||
1645 | |||
1646 | fp = compat_ptr(regs->bp); | ||
1647 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | ||
1648 | unsigned long bytes; | ||
1649 | frame.next_frame = 0; | ||
1650 | frame.return_address = 0; | ||
1651 | |||
1652 | bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); | ||
1653 | if (bytes != sizeof(frame)) | ||
1654 | break; | ||
1609 | 1655 | ||
1610 | return bytes == sizeof(*frame); | 1656 | if (fp < compat_ptr(regs->sp)) |
1657 | break; | ||
1658 | |||
1659 | callchain_store(entry, frame.return_address); | ||
1660 | fp = compat_ptr(frame.next_frame); | ||
1661 | } | ||
1662 | return 1; | ||
1611 | } | 1663 | } |
1664 | #else | ||
1665 | static inline int | ||
1666 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | ||
1667 | { | ||
1668 | return 0; | ||
1669 | } | ||
1670 | #endif | ||
1612 | 1671 | ||
1613 | static void | 1672 | static void |
1614 | perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1673 | perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) |
@@ -1624,11 +1683,16 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1624 | callchain_store(entry, PERF_CONTEXT_USER); | 1683 | callchain_store(entry, PERF_CONTEXT_USER); |
1625 | callchain_store(entry, regs->ip); | 1684 | callchain_store(entry, regs->ip); |
1626 | 1685 | ||
1686 | if (perf_callchain_user32(regs, entry)) | ||
1687 | return; | ||
1688 | |||
1627 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | 1689 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
1690 | unsigned long bytes; | ||
1628 | frame.next_frame = NULL; | 1691 | frame.next_frame = NULL; |
1629 | frame.return_address = 0; | 1692 | frame.return_address = 0; |
1630 | 1693 | ||
1631 | if (!copy_stack_frame(fp, &frame)) | 1694 | bytes = copy_from_user_nmi(&frame, fp, sizeof(frame)); |
1695 | if (bytes != sizeof(frame)) | ||
1632 | break; | 1696 | break; |
1633 | 1697 | ||
1634 | if ((unsigned long)fp < regs->sp) | 1698 | if ((unsigned long)fp < regs->sp) |
@@ -1675,28 +1739,14 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
1675 | return entry; | 1739 | return entry; |
1676 | } | 1740 | } |
1677 | 1741 | ||
1678 | void hw_perf_event_setup_online(int cpu) | 1742 | void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) |
1679 | { | ||
1680 | init_debug_store_on_cpu(cpu); | ||
1681 | |||
1682 | switch (boot_cpu_data.x86_vendor) { | ||
1683 | case X86_VENDOR_AMD: | ||
1684 | amd_pmu_cpu_online(cpu); | ||
1685 | break; | ||
1686 | default: | ||
1687 | return; | ||
1688 | } | ||
1689 | } | ||
1690 | |||
1691 | void hw_perf_event_setup_offline(int cpu) | ||
1692 | { | 1743 | { |
1693 | init_debug_store_on_cpu(cpu); | 1744 | regs->ip = ip; |
1694 | 1745 | /* | |
1695 | switch (boot_cpu_data.x86_vendor) { | 1746 | * perf_arch_fetch_caller_regs adds another call, we need to increment |
1696 | case X86_VENDOR_AMD: | 1747 | * the skip level |
1697 | amd_pmu_cpu_offline(cpu); | 1748 | */ |
1698 | break; | 1749 | regs->bp = rewind_frame_pointer(skip + 1); |
1699 | default: | 1750 | regs->cs = __KERNEL_CS; |
1700 | return; | 1751 | local_save_flags(regs->flags); |
1701 | } | ||
1702 | } | 1752 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 8f3dbfda3c4f..db6f7d4056e1 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
@@ -137,6 +137,13 @@ static inline int amd_is_nb_event(struct hw_perf_event *hwc) | |||
137 | return (hwc->config & 0xe0) == 0xe0; | 137 | return (hwc->config & 0xe0) == 0xe0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static inline int amd_has_nb(struct cpu_hw_events *cpuc) | ||
141 | { | ||
142 | struct amd_nb *nb = cpuc->amd_nb; | ||
143 | |||
144 | return nb && nb->nb_id != -1; | ||
145 | } | ||
146 | |||
140 | static void amd_put_event_constraints(struct cpu_hw_events *cpuc, | 147 | static void amd_put_event_constraints(struct cpu_hw_events *cpuc, |
141 | struct perf_event *event) | 148 | struct perf_event *event) |
142 | { | 149 | { |
@@ -147,7 +154,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc, | |||
147 | /* | 154 | /* |
148 | * only care about NB events | 155 | * only care about NB events |
149 | */ | 156 | */ |
150 | if (!(nb && amd_is_nb_event(hwc))) | 157 | if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc))) |
151 | return; | 158 | return; |
152 | 159 | ||
153 | /* | 160 | /* |
@@ -214,7 +221,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) | |||
214 | /* | 221 | /* |
215 | * if not NB event or no NB, then no constraints | 222 | * if not NB event or no NB, then no constraints |
216 | */ | 223 | */ |
217 | if (!(nb && amd_is_nb_event(hwc))) | 224 | if (!(amd_has_nb(cpuc) && amd_is_nb_event(hwc))) |
218 | return &unconstrained; | 225 | return &unconstrained; |
219 | 226 | ||
220 | /* | 227 | /* |
@@ -271,28 +278,6 @@ done: | |||
271 | return &emptyconstraint; | 278 | return &emptyconstraint; |
272 | } | 279 | } |
273 | 280 | ||
274 | static __initconst struct x86_pmu amd_pmu = { | ||
275 | .name = "AMD", | ||
276 | .handle_irq = x86_pmu_handle_irq, | ||
277 | .disable_all = x86_pmu_disable_all, | ||
278 | .enable_all = x86_pmu_enable_all, | ||
279 | .enable = x86_pmu_enable_event, | ||
280 | .disable = x86_pmu_disable_event, | ||
281 | .eventsel = MSR_K7_EVNTSEL0, | ||
282 | .perfctr = MSR_K7_PERFCTR0, | ||
283 | .event_map = amd_pmu_event_map, | ||
284 | .raw_event = amd_pmu_raw_event, | ||
285 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), | ||
286 | .num_events = 4, | ||
287 | .event_bits = 48, | ||
288 | .event_mask = (1ULL << 48) - 1, | ||
289 | .apic = 1, | ||
290 | /* use highest bit to detect overflow */ | ||
291 | .max_period = (1ULL << 47) - 1, | ||
292 | .get_event_constraints = amd_get_event_constraints, | ||
293 | .put_event_constraints = amd_put_event_constraints | ||
294 | }; | ||
295 | |||
296 | static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) | 281 | static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) |
297 | { | 282 | { |
298 | struct amd_nb *nb; | 283 | struct amd_nb *nb; |
@@ -309,57 +294,61 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id) | |||
309 | * initialize all possible NB constraints | 294 | * initialize all possible NB constraints |
310 | */ | 295 | */ |
311 | for (i = 0; i < x86_pmu.num_events; i++) { | 296 | for (i = 0; i < x86_pmu.num_events; i++) { |
312 | set_bit(i, nb->event_constraints[i].idxmsk); | 297 | __set_bit(i, nb->event_constraints[i].idxmsk); |
313 | nb->event_constraints[i].weight = 1; | 298 | nb->event_constraints[i].weight = 1; |
314 | } | 299 | } |
315 | return nb; | 300 | return nb; |
316 | } | 301 | } |
317 | 302 | ||
318 | static void amd_pmu_cpu_online(int cpu) | 303 | static int amd_pmu_cpu_prepare(int cpu) |
319 | { | 304 | { |
320 | struct cpu_hw_events *cpu1, *cpu2; | 305 | struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); |
321 | struct amd_nb *nb = NULL; | 306 | |
307 | WARN_ON_ONCE(cpuc->amd_nb); | ||
308 | |||
309 | if (boot_cpu_data.x86_max_cores < 2) | ||
310 | return NOTIFY_OK; | ||
311 | |||
312 | cpuc->amd_nb = amd_alloc_nb(cpu, -1); | ||
313 | if (!cpuc->amd_nb) | ||
314 | return NOTIFY_BAD; | ||
315 | |||
316 | return NOTIFY_OK; | ||
317 | } | ||
318 | |||
319 | static void amd_pmu_cpu_starting(int cpu) | ||
320 | { | ||
321 | struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); | ||
322 | struct amd_nb *nb; | ||
322 | int i, nb_id; | 323 | int i, nb_id; |
323 | 324 | ||
324 | if (boot_cpu_data.x86_max_cores < 2) | 325 | if (boot_cpu_data.x86_max_cores < 2) |
325 | return; | 326 | return; |
326 | 327 | ||
327 | /* | ||
328 | * function may be called too early in the | ||
329 | * boot process, in which case nb_id is bogus | ||
330 | */ | ||
331 | nb_id = amd_get_nb_id(cpu); | 328 | nb_id = amd_get_nb_id(cpu); |
332 | if (nb_id == BAD_APICID) | 329 | WARN_ON_ONCE(nb_id == BAD_APICID); |
333 | return; | ||
334 | |||
335 | cpu1 = &per_cpu(cpu_hw_events, cpu); | ||
336 | cpu1->amd_nb = NULL; | ||
337 | 330 | ||
338 | raw_spin_lock(&amd_nb_lock); | 331 | raw_spin_lock(&amd_nb_lock); |
339 | 332 | ||
340 | for_each_online_cpu(i) { | 333 | for_each_online_cpu(i) { |
341 | cpu2 = &per_cpu(cpu_hw_events, i); | 334 | nb = per_cpu(cpu_hw_events, i).amd_nb; |
342 | nb = cpu2->amd_nb; | 335 | if (WARN_ON_ONCE(!nb)) |
343 | if (!nb) | ||
344 | continue; | 336 | continue; |
345 | if (nb->nb_id == nb_id) | ||
346 | goto found; | ||
347 | } | ||
348 | 337 | ||
349 | nb = amd_alloc_nb(cpu, nb_id); | 338 | if (nb->nb_id == nb_id) { |
350 | if (!nb) { | 339 | kfree(cpuc->amd_nb); |
351 | pr_err("perf_events: failed NB allocation for CPU%d\n", cpu); | 340 | cpuc->amd_nb = nb; |
352 | raw_spin_unlock(&amd_nb_lock); | 341 | break; |
353 | return; | 342 | } |
354 | } | 343 | } |
355 | found: | 344 | |
356 | nb->refcnt++; | 345 | cpuc->amd_nb->nb_id = nb_id; |
357 | cpu1->amd_nb = nb; | 346 | cpuc->amd_nb->refcnt++; |
358 | 347 | ||
359 | raw_spin_unlock(&amd_nb_lock); | 348 | raw_spin_unlock(&amd_nb_lock); |
360 | } | 349 | } |
361 | 350 | ||
362 | static void amd_pmu_cpu_offline(int cpu) | 351 | static void amd_pmu_cpu_dead(int cpu) |
363 | { | 352 | { |
364 | struct cpu_hw_events *cpuhw; | 353 | struct cpu_hw_events *cpuhw; |
365 | 354 | ||
@@ -370,14 +359,44 @@ static void amd_pmu_cpu_offline(int cpu) | |||
370 | 359 | ||
371 | raw_spin_lock(&amd_nb_lock); | 360 | raw_spin_lock(&amd_nb_lock); |
372 | 361 | ||
373 | if (--cpuhw->amd_nb->refcnt == 0) | 362 | if (cpuhw->amd_nb) { |
374 | kfree(cpuhw->amd_nb); | 363 | struct amd_nb *nb = cpuhw->amd_nb; |
364 | |||
365 | if (nb->nb_id == -1 || --nb->refcnt == 0) | ||
366 | kfree(nb); | ||
375 | 367 | ||
376 | cpuhw->amd_nb = NULL; | 368 | cpuhw->amd_nb = NULL; |
369 | } | ||
377 | 370 | ||
378 | raw_spin_unlock(&amd_nb_lock); | 371 | raw_spin_unlock(&amd_nb_lock); |
379 | } | 372 | } |
380 | 373 | ||
374 | static __initconst struct x86_pmu amd_pmu = { | ||
375 | .name = "AMD", | ||
376 | .handle_irq = x86_pmu_handle_irq, | ||
377 | .disable_all = x86_pmu_disable_all, | ||
378 | .enable_all = x86_pmu_enable_all, | ||
379 | .enable = x86_pmu_enable_event, | ||
380 | .disable = x86_pmu_disable_event, | ||
381 | .eventsel = MSR_K7_EVNTSEL0, | ||
382 | .perfctr = MSR_K7_PERFCTR0, | ||
383 | .event_map = amd_pmu_event_map, | ||
384 | .raw_event = amd_pmu_raw_event, | ||
385 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), | ||
386 | .num_events = 4, | ||
387 | .event_bits = 48, | ||
388 | .event_mask = (1ULL << 48) - 1, | ||
389 | .apic = 1, | ||
390 | /* use highest bit to detect overflow */ | ||
391 | .max_period = (1ULL << 47) - 1, | ||
392 | .get_event_constraints = amd_get_event_constraints, | ||
393 | .put_event_constraints = amd_put_event_constraints, | ||
394 | |||
395 | .cpu_prepare = amd_pmu_cpu_prepare, | ||
396 | .cpu_starting = amd_pmu_cpu_starting, | ||
397 | .cpu_dead = amd_pmu_cpu_dead, | ||
398 | }; | ||
399 | |||
381 | static __init int amd_pmu_init(void) | 400 | static __init int amd_pmu_init(void) |
382 | { | 401 | { |
383 | /* Performance-monitoring supported from K7 and later: */ | 402 | /* Performance-monitoring supported from K7 and later: */ |
@@ -390,11 +409,6 @@ static __init int amd_pmu_init(void) | |||
390 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, | 409 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, |
391 | sizeof(hw_cache_event_ids)); | 410 | sizeof(hw_cache_event_ids)); |
392 | 411 | ||
393 | /* | ||
394 | * explicitly initialize the boot cpu, other cpus will get | ||
395 | * the cpu hotplug callbacks from smp_init() | ||
396 | */ | ||
397 | amd_pmu_cpu_online(smp_processor_id()); | ||
398 | return 0; | 412 | return 0; |
399 | } | 413 | } |
400 | 414 | ||
@@ -405,12 +419,4 @@ static int amd_pmu_init(void) | |||
405 | return 0; | 419 | return 0; |
406 | } | 420 | } |
407 | 421 | ||
408 | static void amd_pmu_cpu_online(int cpu) | ||
409 | { | ||
410 | } | ||
411 | |||
412 | static void amd_pmu_cpu_offline(int cpu) | ||
413 | { | ||
414 | } | ||
415 | |||
416 | #endif | 422 | #endif |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 44b60c852107..9c794ac87837 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -548,9 +548,9 @@ static inline void intel_pmu_ack_status(u64 ack) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | static inline void | 550 | static inline void |
551 | intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx) | 551 | intel_pmu_disable_fixed(struct hw_perf_event *hwc) |
552 | { | 552 | { |
553 | int idx = __idx - X86_PMC_IDX_FIXED; | 553 | int idx = hwc->idx - X86_PMC_IDX_FIXED; |
554 | u64 ctrl_val, mask; | 554 | u64 ctrl_val, mask; |
555 | 555 | ||
556 | mask = 0xfULL << (idx * 4); | 556 | mask = 0xfULL << (idx * 4); |
@@ -621,26 +621,28 @@ static void intel_pmu_drain_bts_buffer(void) | |||
621 | } | 621 | } |
622 | 622 | ||
623 | static inline void | 623 | static inline void |
624 | intel_pmu_disable_event(struct hw_perf_event *hwc, int idx) | 624 | intel_pmu_disable_event(struct perf_event *event) |
625 | { | 625 | { |
626 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | 626 | struct hw_perf_event *hwc = &event->hw; |
627 | |||
628 | if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { | ||
627 | intel_pmu_disable_bts(); | 629 | intel_pmu_disable_bts(); |
628 | intel_pmu_drain_bts_buffer(); | 630 | intel_pmu_drain_bts_buffer(); |
629 | return; | 631 | return; |
630 | } | 632 | } |
631 | 633 | ||
632 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { | 634 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
633 | intel_pmu_disable_fixed(hwc, idx); | 635 | intel_pmu_disable_fixed(hwc); |
634 | return; | 636 | return; |
635 | } | 637 | } |
636 | 638 | ||
637 | x86_pmu_disable_event(hwc, idx); | 639 | x86_pmu_disable_event(event); |
638 | } | 640 | } |
639 | 641 | ||
640 | static inline void | 642 | static inline void |
641 | intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx) | 643 | intel_pmu_enable_fixed(struct hw_perf_event *hwc) |
642 | { | 644 | { |
643 | int idx = __idx - X86_PMC_IDX_FIXED; | 645 | int idx = hwc->idx - X86_PMC_IDX_FIXED; |
644 | u64 ctrl_val, bits, mask; | 646 | u64 ctrl_val, bits, mask; |
645 | int err; | 647 | int err; |
646 | 648 | ||
@@ -670,9 +672,11 @@ intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx) | |||
670 | err = checking_wrmsrl(hwc->config_base, ctrl_val); | 672 | err = checking_wrmsrl(hwc->config_base, ctrl_val); |
671 | } | 673 | } |
672 | 674 | ||
673 | static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) | 675 | static void intel_pmu_enable_event(struct perf_event *event) |
674 | { | 676 | { |
675 | if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) { | 677 | struct hw_perf_event *hwc = &event->hw; |
678 | |||
679 | if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { | ||
676 | if (!__get_cpu_var(cpu_hw_events).enabled) | 680 | if (!__get_cpu_var(cpu_hw_events).enabled) |
677 | return; | 681 | return; |
678 | 682 | ||
@@ -681,11 +685,11 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
681 | } | 685 | } |
682 | 686 | ||
683 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { | 687 | if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { |
684 | intel_pmu_enable_fixed(hwc, idx); | 688 | intel_pmu_enable_fixed(hwc); |
685 | return; | 689 | return; |
686 | } | 690 | } |
687 | 691 | ||
688 | __x86_pmu_enable_event(hwc, idx); | 692 | __x86_pmu_enable_event(hwc); |
689 | } | 693 | } |
690 | 694 | ||
691 | /* | 695 | /* |
@@ -694,14 +698,8 @@ static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx) | |||
694 | */ | 698 | */ |
695 | static int intel_pmu_save_and_restart(struct perf_event *event) | 699 | static int intel_pmu_save_and_restart(struct perf_event *event) |
696 | { | 700 | { |
697 | struct hw_perf_event *hwc = &event->hw; | 701 | x86_perf_event_update(event); |
698 | int idx = hwc->idx; | 702 | return x86_perf_event_set_period(event); |
699 | int ret; | ||
700 | |||
701 | x86_perf_event_update(event, hwc, idx); | ||
702 | ret = x86_perf_event_set_period(event, hwc, idx); | ||
703 | |||
704 | return ret; | ||
705 | } | 703 | } |
706 | 704 | ||
707 | static void intel_pmu_reset(void) | 705 | static void intel_pmu_reset(void) |
@@ -745,11 +743,11 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) | |||
745 | 743 | ||
746 | cpuc = &__get_cpu_var(cpu_hw_events); | 744 | cpuc = &__get_cpu_var(cpu_hw_events); |
747 | 745 | ||
748 | perf_disable(); | 746 | intel_pmu_disable_all(); |
749 | intel_pmu_drain_bts_buffer(); | 747 | intel_pmu_drain_bts_buffer(); |
750 | status = intel_pmu_get_status(); | 748 | status = intel_pmu_get_status(); |
751 | if (!status) { | 749 | if (!status) { |
752 | perf_enable(); | 750 | intel_pmu_enable_all(); |
753 | return 0; | 751 | return 0; |
754 | } | 752 | } |
755 | 753 | ||
@@ -759,8 +757,7 @@ again: | |||
759 | WARN_ONCE(1, "perfevents: irq loop stuck!\n"); | 757 | WARN_ONCE(1, "perfevents: irq loop stuck!\n"); |
760 | perf_event_print_debug(); | 758 | perf_event_print_debug(); |
761 | intel_pmu_reset(); | 759 | intel_pmu_reset(); |
762 | perf_enable(); | 760 | goto done; |
763 | return 1; | ||
764 | } | 761 | } |
765 | 762 | ||
766 | inc_irq_stat(apic_perf_irqs); | 763 | inc_irq_stat(apic_perf_irqs); |
@@ -768,7 +765,6 @@ again: | |||
768 | for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { | 765 | for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { |
769 | struct perf_event *event = cpuc->events[bit]; | 766 | struct perf_event *event = cpuc->events[bit]; |
770 | 767 | ||
771 | clear_bit(bit, (unsigned long *) &status); | ||
772 | if (!test_bit(bit, cpuc->active_mask)) | 768 | if (!test_bit(bit, cpuc->active_mask)) |
773 | continue; | 769 | continue; |
774 | 770 | ||
@@ -778,7 +774,7 @@ again: | |||
778 | data.period = event->hw.last_period; | 774 | data.period = event->hw.last_period; |
779 | 775 | ||
780 | if (perf_event_overflow(event, 1, &data, regs)) | 776 | if (perf_event_overflow(event, 1, &data, regs)) |
781 | intel_pmu_disable_event(&event->hw, bit); | 777 | x86_pmu_stop(event); |
782 | } | 778 | } |
783 | 779 | ||
784 | intel_pmu_ack_status(ack); | 780 | intel_pmu_ack_status(ack); |
@@ -790,8 +786,8 @@ again: | |||
790 | if (status) | 786 | if (status) |
791 | goto again; | 787 | goto again; |
792 | 788 | ||
793 | perf_enable(); | 789 | done: |
794 | 790 | intel_pmu_enable_all(); | |
795 | return 1; | 791 | return 1; |
796 | } | 792 | } |
797 | 793 | ||
@@ -870,7 +866,10 @@ static __initconst struct x86_pmu intel_pmu = { | |||
870 | .max_period = (1ULL << 31) - 1, | 866 | .max_period = (1ULL << 31) - 1, |
871 | .enable_bts = intel_pmu_enable_bts, | 867 | .enable_bts = intel_pmu_enable_bts, |
872 | .disable_bts = intel_pmu_disable_bts, | 868 | .disable_bts = intel_pmu_disable_bts, |
873 | .get_event_constraints = intel_get_event_constraints | 869 | .get_event_constraints = intel_get_event_constraints, |
870 | |||
871 | .cpu_starting = init_debug_store_on_cpu, | ||
872 | .cpu_dying = fini_debug_store_on_cpu, | ||
874 | }; | 873 | }; |
875 | 874 | ||
876 | static __init int intel_pmu_init(void) | 875 | static __init int intel_pmu_init(void) |
@@ -937,6 +936,7 @@ static __init int intel_pmu_init(void) | |||
937 | 936 | ||
938 | case 26: /* 45 nm nehalem, "Bloomfield" */ | 937 | case 26: /* 45 nm nehalem, "Bloomfield" */ |
939 | case 30: /* 45 nm nehalem, "Lynnfield" */ | 938 | case 30: /* 45 nm nehalem, "Lynnfield" */ |
939 | case 46: /* 45 nm nehalem-ex, "Beckton" */ | ||
940 | memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, | 940 | memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, |
941 | sizeof(hw_cache_event_ids)); | 941 | sizeof(hw_cache_event_ids)); |
942 | 942 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index a4e67b99d91c..a330485d14da 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -77,27 +77,29 @@ static void p6_pmu_enable_all(void) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static inline void | 79 | static inline void |
80 | p6_pmu_disable_event(struct hw_perf_event *hwc, int idx) | 80 | p6_pmu_disable_event(struct perf_event *event) |
81 | { | 81 | { |
82 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 82 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
83 | struct hw_perf_event *hwc = &event->hw; | ||
83 | u64 val = P6_NOP_EVENT; | 84 | u64 val = P6_NOP_EVENT; |
84 | 85 | ||
85 | if (cpuc->enabled) | 86 | if (cpuc->enabled) |
86 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 87 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
87 | 88 | ||
88 | (void)checking_wrmsrl(hwc->config_base + idx, val); | 89 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); |
89 | } | 90 | } |
90 | 91 | ||
91 | static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx) | 92 | static void p6_pmu_enable_event(struct perf_event *event) |
92 | { | 93 | { |
93 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 94 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
95 | struct hw_perf_event *hwc = &event->hw; | ||
94 | u64 val; | 96 | u64 val; |
95 | 97 | ||
96 | val = hwc->config; | 98 | val = hwc->config; |
97 | if (cpuc->enabled) | 99 | if (cpuc->enabled) |
98 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 100 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
99 | 101 | ||
100 | (void)checking_wrmsrl(hwc->config_base + idx, val); | 102 | (void)checking_wrmsrl(hwc->config_base + hwc->idx, val); |
101 | } | 103 | } |
102 | 104 | ||
103 | static __initconst struct x86_pmu p6_pmu = { | 105 | static __initconst struct x86_pmu p6_pmu = { |
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c index 1cbed97b59cf..dfdb4dba2320 100644 --- a/arch/x86/kernel/cpu/vmware.c +++ b/arch/x86/kernel/cpu/vmware.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/module.h> | ||
25 | #include <asm/div64.h> | 26 | #include <asm/div64.h> |
26 | #include <asm/vmware.h> | 27 | #include <asm/vmware.h> |
27 | #include <asm/x86_init.h> | 28 | #include <asm/x86_init.h> |
@@ -101,6 +102,7 @@ int vmware_platform(void) | |||
101 | 102 | ||
102 | return 0; | 103 | return 0; |
103 | } | 104 | } |
105 | EXPORT_SYMBOL(vmware_platform); | ||
104 | 106 | ||
105 | /* | 107 | /* |
106 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. | 108 | * VMware hypervisor takes care of exporting a reliable TSC to the guest. |
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 83e5e628de73..8b862d5900fe 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/cpu.h> | 40 | #include <linux/cpu.h> |
41 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/gfp.h> | ||
43 | 44 | ||
44 | #include <asm/processor.h> | 45 | #include <asm/processor.h> |
45 | #include <asm/msr.h> | 46 | #include <asm/msr.h> |
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a4849c10a77e..ebd4c51d096a 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
28 | #include <asm/reboot.h> | 28 | #include <asm/reboot.h> |
29 | #include <asm/virtext.h> | 29 | #include <asm/virtext.h> |
30 | #include <asm/x86_init.h> | ||
31 | 30 | ||
32 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) | 31 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) |
33 | 32 | ||
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs) | |||
103 | #ifdef CONFIG_HPET_TIMER | 102 | #ifdef CONFIG_HPET_TIMER |
104 | hpet_disable(); | 103 | hpet_disable(); |
105 | #endif | 104 | #endif |
106 | |||
107 | #ifdef CONFIG_X86_64 | ||
108 | x86_platform.iommu_shutdown(); | ||
109 | #endif | ||
110 | |||
111 | crash_save_cpu(regs, safe_smp_processor_id()); | 105 | crash_save_cpu(regs, safe_smp_processor_id()); |
112 | } | 106 | } |
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index cd97ce18c29d..67414550c3cc 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (C) IBM Corporation, 2004. All rights reserved | 5 | * Copyright (C) IBM Corporation, 2004. All rights reserved |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/slab.h> | ||
8 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
9 | #include <linux/highmem.h> | 10 | #include <linux/highmem.h> |
10 | #include <linux/crash_dump.h> | 11 | #include <linux/crash_dump.h> |
diff --git a/arch/x86/kernel/dumpstack.h b/arch/x86/kernel/dumpstack.h index 4fd1420faffa..e1a93be4fd44 100644 --- a/arch/x86/kernel/dumpstack.h +++ b/arch/x86/kernel/dumpstack.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) | 14 | #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | #include <linux/uaccess.h> | ||
18 | |||
17 | extern void | 19 | extern void |
18 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, | 20 | show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, |
19 | unsigned long *stack, unsigned long bp, char *log_lvl); | 21 | unsigned long *stack, unsigned long bp, char *log_lvl); |
@@ -29,4 +31,26 @@ struct stack_frame { | |||
29 | struct stack_frame *next_frame; | 31 | struct stack_frame *next_frame; |
30 | unsigned long return_address; | 32 | unsigned long return_address; |
31 | }; | 33 | }; |
34 | |||
35 | struct stack_frame_ia32 { | ||
36 | u32 next_frame; | ||
37 | u32 return_address; | ||
38 | }; | ||
39 | |||
40 | static inline unsigned long rewind_frame_pointer(int n) | ||
41 | { | ||
42 | struct stack_frame *frame; | ||
43 | |||
44 | get_bp(frame); | ||
45 | |||
46 | #ifdef CONFIG_FRAME_POINTER | ||
47 | while (n--) { | ||
48 | if (probe_kernel_address(&frame->next_frame, frame)) | ||
49 | break; | ||
50 | } | ||
32 | #endif | 51 | #endif |
52 | |||
53 | return (unsigned long)frame; | ||
54 | } | ||
55 | |||
56 | #endif /* DUMPSTACK_H */ | ||
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index d5e2a2ebb627..272c9f1f05f3 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -208,7 +208,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
208 | if (in_irq_stack(stack, irq_stack, irq_stack_end)) { | 208 | if (in_irq_stack(stack, irq_stack, irq_stack_end)) { |
209 | if (ops->stack(data, "IRQ") < 0) | 209 | if (ops->stack(data, "IRQ") < 0) |
210 | break; | 210 | break; |
211 | bp = print_context_stack(tinfo, stack, bp, | 211 | bp = ops->walk_stack(tinfo, stack, bp, |
212 | ops, data, irq_stack_end, &graph); | 212 | ops, data, irq_stack_end, &graph); |
213 | /* | 213 | /* |
214 | * We link to the next stack (which would be | 214 | * We link to the next stack (which would be |
@@ -229,7 +229,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
229 | /* | 229 | /* |
230 | * This handles the process stack: | 230 | * This handles the process stack: |
231 | */ | 231 | */ |
232 | bp = print_context_stack(tinfo, stack, bp, ops, data, NULL, &graph); | 232 | bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph); |
233 | put_cpu(); | 233 | put_cpu(); |
234 | } | 234 | } |
235 | EXPORT_SYMBOL(dump_trace); | 235 | EXPORT_SYMBOL(dump_trace); |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 740b440fbd73..7bca3c6a02fb 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -519,29 +519,45 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, | |||
519 | printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ", | 519 | printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ", |
520 | (unsigned long long) start, | 520 | (unsigned long long) start, |
521 | (unsigned long long) end); | 521 | (unsigned long long) end); |
522 | e820_print_type(old_type); | 522 | if (checktype) |
523 | e820_print_type(old_type); | ||
523 | printk(KERN_CONT "\n"); | 524 | printk(KERN_CONT "\n"); |
524 | 525 | ||
525 | for (i = 0; i < e820.nr_map; i++) { | 526 | for (i = 0; i < e820.nr_map; i++) { |
526 | struct e820entry *ei = &e820.map[i]; | 527 | struct e820entry *ei = &e820.map[i]; |
527 | u64 final_start, final_end; | 528 | u64 final_start, final_end; |
529 | u64 ei_end; | ||
528 | 530 | ||
529 | if (checktype && ei->type != old_type) | 531 | if (checktype && ei->type != old_type) |
530 | continue; | 532 | continue; |
533 | |||
534 | ei_end = ei->addr + ei->size; | ||
531 | /* totally covered? */ | 535 | /* totally covered? */ |
532 | if (ei->addr >= start && | 536 | if (ei->addr >= start && ei_end <= end) { |
533 | (ei->addr + ei->size) <= (start + size)) { | ||
534 | real_removed_size += ei->size; | 537 | real_removed_size += ei->size; |
535 | memset(ei, 0, sizeof(struct e820entry)); | 538 | memset(ei, 0, sizeof(struct e820entry)); |
536 | continue; | 539 | continue; |
537 | } | 540 | } |
541 | |||
542 | /* new range is totally covered? */ | ||
543 | if (ei->addr < start && ei_end > end) { | ||
544 | e820_add_region(end, ei_end - end, ei->type); | ||
545 | ei->size = start - ei->addr; | ||
546 | real_removed_size += size; | ||
547 | continue; | ||
548 | } | ||
549 | |||
538 | /* partially covered */ | 550 | /* partially covered */ |
539 | final_start = max(start, ei->addr); | 551 | final_start = max(start, ei->addr); |
540 | final_end = min(start + size, ei->addr + ei->size); | 552 | final_end = min(end, ei_end); |
541 | if (final_start >= final_end) | 553 | if (final_start >= final_end) |
542 | continue; | 554 | continue; |
543 | real_removed_size += final_end - final_start; | 555 | real_removed_size += final_end - final_start; |
544 | 556 | ||
557 | /* | ||
558 | * left range could be head or tail, so need to update | ||
559 | * size at first. | ||
560 | */ | ||
545 | ei->size -= final_end - final_start; | 561 | ei->size -= final_end - final_start; |
546 | if (ei->addr < final_start) | 562 | if (ei->addr < final_start) |
547 | continue; | 563 | continue; |
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index adedeef1dedc..b2e246037392 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/start_kernel.h> | 9 | #include <linux/start_kernel.h> |
10 | #include <linux/mm.h> | ||
10 | 11 | ||
11 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
12 | #include <asm/sections.h> | 13 | #include <asm/sections.h> |
@@ -44,9 +45,10 @@ void __init i386_start_kernel(void) | |||
44 | #ifdef CONFIG_BLK_DEV_INITRD | 45 | #ifdef CONFIG_BLK_DEV_INITRD |
45 | /* Reserve INITRD */ | 46 | /* Reserve INITRD */ |
46 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | 47 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { |
48 | /* Assume only end is not page aligned */ | ||
47 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 49 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
48 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 50 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
49 | u64 ramdisk_end = ramdisk_image + ramdisk_size; | 51 | u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); |
50 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | 52 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); |
51 | } | 53 | } |
52 | #endif | 54 | #endif |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b5a9896ca1e7..7147143fd614 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data) | |||
103 | #ifdef CONFIG_BLK_DEV_INITRD | 103 | #ifdef CONFIG_BLK_DEV_INITRD |
104 | /* Reserve INITRD */ | 104 | /* Reserve INITRD */ |
105 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | 105 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { |
106 | /* Assume only end is not page aligned */ | ||
106 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | 107 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; |
107 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | 108 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; |
108 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; | 109 | unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); |
109 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | 110 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); |
110 | } | 111 | } |
111 | #endif | 112 | #endif |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ee4fa1bfcb33..23b4ecdffa9b 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/sysdev.h> | 4 | #include <linux/sysdev.h> |
5 | #include <linux/delay.h> | 5 | #include <linux/delay.h> |
6 | #include <linux/errno.h> | 6 | #include <linux/errno.h> |
7 | #include <linux/slab.h> | ||
7 | #include <linux/hpet.h> | 8 | #include <linux/hpet.h> |
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
9 | #include <linux/cpu.h> | 10 | #include <linux/cpu.h> |
@@ -399,9 +400,15 @@ static int hpet_next_event(unsigned long delta, | |||
399 | * then we might have a real hardware problem. We can not do | 400 | * then we might have a real hardware problem. We can not do |
400 | * much about it here, but at least alert the user/admin with | 401 | * much about it here, but at least alert the user/admin with |
401 | * a prominent warning. | 402 | * a prominent warning. |
403 | * An erratum on some chipsets (ICH9,..), results in comparator read | ||
404 | * immediately following a write returning old value. Workaround | ||
405 | * for this is to read this value second time, when first | ||
406 | * read returns old value. | ||
402 | */ | 407 | */ |
403 | WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt, | 408 | if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { |
409 | WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt, | ||
404 | KERN_WARNING "hpet: compare register read back failed.\n"); | 410 | KERN_WARNING "hpet: compare register read back failed.\n"); |
411 | } | ||
405 | 412 | ||
406 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; | 413 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; |
407 | } | 414 | } |
@@ -1143,6 +1150,7 @@ int hpet_set_periodic_freq(unsigned long freq) | |||
1143 | do_div(clc, freq); | 1150 | do_div(clc, freq); |
1144 | clc >>= hpet_clockevent.shift; | 1151 | clc >>= hpet_clockevent.shift; |
1145 | hpet_pie_delta = clc; | 1152 | hpet_pie_delta = clc; |
1153 | hpet_pie_limit = 0; | ||
1146 | } | 1154 | } |
1147 | return 1; | 1155 | return 1; |
1148 | } | 1156 | } |
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index c01a2b846d47..54c31c285488 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/regset.h> | 9 | #include <linux/regset.h> |
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | ||
11 | 12 | ||
12 | #include <asm/sigcontext.h> | 13 | #include <asm/sigcontext.h> |
13 | #include <asm/processor.h> | 14 | #include <asm/processor.h> |
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index fb725ee15f55..7c9f02c130f3 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/ioport.h> | 5 | #include <linux/ioport.h> |
6 | #include <linux/interrupt.h> | 6 | #include <linux/interrupt.h> |
7 | #include <linux/timex.h> | 7 | #include <linux/timex.h> |
8 | #include <linux/slab.h> | ||
9 | #include <linux/random.h> | 8 | #include <linux/random.h> |
10 | #include <linux/init.h> | 9 | #include <linux/init.h> |
11 | #include <linux/kernel_stat.h> | 10 | #include <linux/kernel_stat.h> |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index ef257fc2921b..0ed2d300cd46 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/ioport.h> | 5 | #include <linux/ioport.h> |
6 | #include <linux/interrupt.h> | 6 | #include <linux/interrupt.h> |
7 | #include <linux/timex.h> | 7 | #include <linux/timex.h> |
8 | #include <linux/slab.h> | ||
9 | #include <linux/random.h> | 8 | #include <linux/random.h> |
10 | #include <linux/kprobes.h> | 9 | #include <linux/kprobes.h> |
11 | #include <linux/init.h> | 10 | #include <linux/init.h> |
@@ -141,6 +140,28 @@ void __init init_IRQ(void) | |||
141 | x86_init.irqs.intr_init(); | 140 | x86_init.irqs.intr_init(); |
142 | } | 141 | } |
143 | 142 | ||
143 | /* | ||
144 | * Setup the vector to irq mappings. | ||
145 | */ | ||
146 | void setup_vector_irq(int cpu) | ||
147 | { | ||
148 | #ifndef CONFIG_X86_IO_APIC | ||
149 | int irq; | ||
150 | |||
151 | /* | ||
152 | * On most of the platforms, legacy PIC delivers the interrupts on the | ||
153 | * boot cpu. But there are certain platforms where PIC interrupts are | ||
154 | * delivered to multiple cpu's. If the legacy IRQ is handled by the | ||
155 | * legacy PIC, for the new cpu that is coming online, setup the static | ||
156 | * legacy vector to irq mapping: | ||
157 | */ | ||
158 | for (irq = 0; irq < legacy_pic->nr_legacy_irqs; irq++) | ||
159 | per_cpu(vector_irq, cpu)[IRQ0_VECTOR + irq] = irq; | ||
160 | #endif | ||
161 | |||
162 | __setup_vector_irq(cpu); | ||
163 | } | ||
164 | |||
144 | static void __init smp_intr_init(void) | 165 | static void __init smp_intr_init(void) |
145 | { | 166 | { |
146 | #ifdef CONFIG_SMP | 167 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/kernel/k8.c b/arch/x86/kernel/k8.c index 9b895464dd03..0f7bc20cfcde 100644 --- a/arch/x86/kernel/k8.c +++ b/arch/x86/kernel/k8.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * Shared support code for AMD K8 northbridges and derivates. | 2 | * Shared support code for AMD K8 northbridges and derivates. |
3 | * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. | 3 | * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. |
4 | */ | 4 | */ |
5 | #include <linux/gfp.h> | ||
6 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/slab.h> | ||
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index e444357375ce..8afd9f321f10 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/debugfs.h> | 9 | #include <linux/debugfs.h> |
10 | #include <linux/uaccess.h> | 10 | #include <linux/uaccess.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/slab.h> | ||
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
14 | #include <linux/io.h> | 15 | #include <linux/io.h> |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index bfba6019d762..b2258ca91003 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -618,8 +618,8 @@ int kgdb_arch_init(void) | |||
618 | * portion of kgdb because this operation requires mutexs to | 618 | * portion of kgdb because this operation requires mutexs to |
619 | * complete. | 619 | * complete. |
620 | */ | 620 | */ |
621 | hw_breakpoint_init(&attr); | ||
621 | attr.bp_addr = (unsigned long)kgdb_arch_init; | 622 | attr.bp_addr = (unsigned long)kgdb_arch_init; |
622 | attr.type = PERF_TYPE_BREAKPOINT; | ||
623 | attr.bp_len = HW_BREAKPOINT_LEN_1; | 623 | attr.bp_len = HW_BREAKPOINT_LEN_1; |
624 | attr.bp_type = HW_BREAKPOINT_W; | 624 | attr.bp_type = HW_BREAKPOINT_W; |
625 | attr.disabled = 1; | 625 | attr.disabled = 1; |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index b43bbaebe2c0..1658efdfb4e5 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -534,20 +534,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
534 | struct kprobe_ctlblk *kcb; | 534 | struct kprobe_ctlblk *kcb; |
535 | 535 | ||
536 | addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); | 536 | addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t)); |
537 | if (*addr != BREAKPOINT_INSTRUCTION) { | ||
538 | /* | ||
539 | * The breakpoint instruction was removed right | ||
540 | * after we hit it. Another cpu has removed | ||
541 | * either a probepoint or a debugger breakpoint | ||
542 | * at this address. In either case, no further | ||
543 | * handling of this interrupt is appropriate. | ||
544 | * Back up over the (now missing) int3 and run | ||
545 | * the original instruction. | ||
546 | */ | ||
547 | regs->ip = (unsigned long)addr; | ||
548 | return 1; | ||
549 | } | ||
550 | |||
551 | /* | 537 | /* |
552 | * We don't want to be preempted for the entire | 538 | * We don't want to be preempted for the entire |
553 | * duration of kprobe processing. We conditionally | 539 | * duration of kprobe processing. We conditionally |
@@ -579,6 +565,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
579 | setup_singlestep(p, regs, kcb, 0); | 565 | setup_singlestep(p, regs, kcb, 0); |
580 | return 1; | 566 | return 1; |
581 | } | 567 | } |
568 | } else if (*addr != BREAKPOINT_INSTRUCTION) { | ||
569 | /* | ||
570 | * The breakpoint instruction was removed right | ||
571 | * after we hit it. Another cpu has removed | ||
572 | * either a probepoint or a debugger breakpoint | ||
573 | * at this address. In either case, no further | ||
574 | * handling of this interrupt is appropriate. | ||
575 | * Back up over the (now missing) int3 and run | ||
576 | * the original instruction. | ||
577 | */ | ||
578 | regs->ip = (unsigned long)addr; | ||
579 | preempt_enable_no_resched(); | ||
580 | return 1; | ||
582 | } else if (kprobe_running()) { | 581 | } else if (kprobe_running()) { |
583 | p = __get_cpu_var(current_kprobe); | 582 | p = __get_cpu_var(current_kprobe); |
584 | if (p->break_handler && p->break_handler(p, regs)) { | 583 | if (p->break_handler && p->break_handler(p, regs)) { |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index ec6ef60cbd17..ea697263b373 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/gfp.h> | ||
10 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
12 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 4a8bb82248ae..035c8c529181 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/kexec.h> | 10 | #include <linux/kexec.h> |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/gfp.h> | ||
12 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
13 | #include <linux/numa.h> | 14 | #include <linux/numa.h> |
14 | #include <linux/ftrace.h> | 15 | #include <linux/ftrace.h> |
diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c index 845d80ce1ef1..63eaf6596233 100644 --- a/arch/x86/kernel/mca_32.c +++ b/arch/x86/kernel/mca_32.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
43 | #include <linux/mca.h> | 43 | #include <linux/mca.h> |
44 | #include <linux/kprobes.h> | 44 | #include <linux/kprobes.h> |
45 | #include <linux/slab.h> | ||
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <linux/proc_fs.h> | 48 | #include <linux/proc_fs.h> |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 89f386f044e4..e0bc186d7501 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/bug.h> | 24 | #include <linux/bug.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/gfp.h> | ||
26 | 27 | ||
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
28 | #include <asm/page.h> | 29 | #include <asm/page.h> |
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index a2c1edd2d3ac..e81030f71a8f 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c | |||
@@ -664,7 +664,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf) | |||
664 | { | 664 | { |
665 | unsigned long size = get_mpc_size(mpf->physptr); | 665 | unsigned long size = get_mpc_size(mpf->physptr); |
666 | 666 | ||
667 | reserve_early(mpf->physptr, mpf->physptr+size, "MP-table mpc"); | 667 | reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc"); |
668 | } | 668 | } |
669 | 669 | ||
670 | static int __init smp_scan_config(unsigned long base, unsigned long length) | 670 | static int __init smp_scan_config(unsigned long base, unsigned long length) |
@@ -693,7 +693,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) | |||
693 | mpf, (u64)virt_to_phys(mpf)); | 693 | mpf, (u64)virt_to_phys(mpf)); |
694 | 694 | ||
695 | mem = virt_to_phys(mpf); | 695 | mem = virt_to_phys(mpf); |
696 | reserve_early(mem, mem + sizeof(*mpf), "MP-table mpf"); | 696 | reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf"); |
697 | if (mpf->physptr) | 697 | if (mpf->physptr) |
698 | smp_reserve_memory(mpf); | 698 | smp_reserve_memory(mpf); |
699 | 699 | ||
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 206735ac8cbd..4d4468e9f47c 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/cpu.h> | 37 | #include <linux/cpu.h> |
38 | #include <linux/notifier.h> | 38 | #include <linux/notifier.h> |
39 | #include <linux/uaccess.h> | 39 | #include <linux/uaccess.h> |
40 | #include <linux/gfp.h> | ||
40 | 41 | ||
41 | #include <asm/processor.h> | 42 | #include <asm/processor.h> |
42 | #include <asm/msr.h> | 43 | #include <asm/msr.h> |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index a4ac764a6880..4b7e3d8b01dd 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/dma-debug.h> | 2 | #include <linux/dma-debug.h> |
3 | #include <linux/dmar.h> | 3 | #include <linux/dmar.h> |
4 | #include <linux/bootmem.h> | 4 | #include <linux/bootmem.h> |
5 | #include <linux/gfp.h> | ||
5 | #include <linux/pci.h> | 6 | #include <linux/pci.h> |
6 | #include <linux/kmemleak.h> | 7 | #include <linux/kmemleak.h> |
7 | 8 | ||
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index f3af115a573a..0f7f130caa67 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/iommu-helper.h> | 29 | #include <linux/iommu-helper.h> |
30 | #include <linux/sysdev.h> | 30 | #include <linux/sysdev.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/gfp.h> | ||
32 | #include <asm/atomic.h> | 33 | #include <asm/atomic.h> |
33 | #include <asm/mtrr.h> | 34 | #include <asm/mtrr.h> |
34 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
@@ -564,6 +565,9 @@ static void enable_gart_translations(void) | |||
564 | 565 | ||
565 | enable_gart_translation(dev, __pa(agp_gatt_table)); | 566 | enable_gart_translation(dev, __pa(agp_gatt_table)); |
566 | } | 567 | } |
568 | |||
569 | /* Flush the GART-TLB to remove stale entries */ | ||
570 | k8_flush_garts(); | ||
567 | } | 571 | } |
568 | 572 | ||
569 | /* | 573 | /* |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 22be12b60a8f..3af4af810c07 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/scatterlist.h> | 4 | #include <linux/scatterlist.h> |
5 | #include <linux/string.h> | 5 | #include <linux/string.h> |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/gfp.h> | ||
7 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
8 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
9 | 10 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ad9540676fcc..0415c3ef91b5 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -526,21 +526,39 @@ static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) | |||
526 | } | 526 | } |
527 | 527 | ||
528 | /* | 528 | /* |
529 | * Check for AMD CPUs, which have potentially C1E support | 529 | * Check for AMD CPUs, where APIC timer interrupt does not wake up CPU from C1e. |
530 | * For more information see | ||
531 | * - Erratum #400 for NPT family 0xf and family 0x10 CPUs | ||
532 | * - Erratum #365 for family 0x11 (not affected because C1e not in use) | ||
530 | */ | 533 | */ |
531 | static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | 534 | static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) |
532 | { | 535 | { |
536 | u64 val; | ||
533 | if (c->x86_vendor != X86_VENDOR_AMD) | 537 | if (c->x86_vendor != X86_VENDOR_AMD) |
534 | return 0; | 538 | goto no_c1e_idle; |
535 | |||
536 | if (c->x86 < 0x0F) | ||
537 | return 0; | ||
538 | 539 | ||
539 | /* Family 0x0f models < rev F do not have C1E */ | 540 | /* Family 0x0f models < rev F do not have C1E */ |
540 | if (c->x86 == 0x0f && c->x86_model < 0x40) | 541 | if (c->x86 == 0x0F && c->x86_model >= 0x40) |
541 | return 0; | 542 | return 1; |
542 | 543 | ||
543 | return 1; | 544 | if (c->x86 == 0x10) { |
545 | /* | ||
546 | * check OSVW bit for CPUs that are not affected | ||
547 | * by erratum #400 | ||
548 | */ | ||
549 | if (cpu_has(c, X86_FEATURE_OSVW)) { | ||
550 | rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val); | ||
551 | if (val >= 2) { | ||
552 | rdmsrl(MSR_AMD64_OSVW_STATUS, val); | ||
553 | if (!(val & BIT(1))) | ||
554 | goto no_c1e_idle; | ||
555 | } | ||
556 | } | ||
557 | return 1; | ||
558 | } | ||
559 | |||
560 | no_c1e_idle: | ||
561 | return 0; | ||
544 | } | 562 | } |
545 | 563 | ||
546 | static cpumask_var_t c1e_mask; | 564 | static cpumask_var_t c1e_mask; |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index dc9690b4c4cc..17cb3295cbf7 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -276,12 +276,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
276 | 276 | ||
277 | set_tsk_thread_flag(p, TIF_FORK); | 277 | set_tsk_thread_flag(p, TIF_FORK); |
278 | 278 | ||
279 | p->thread.fs = me->thread.fs; | ||
280 | p->thread.gs = me->thread.gs; | ||
281 | p->thread.io_bitmap_ptr = NULL; | 279 | p->thread.io_bitmap_ptr = NULL; |
282 | 280 | ||
283 | savesegment(gs, p->thread.gsindex); | 281 | savesegment(gs, p->thread.gsindex); |
282 | p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs; | ||
284 | savesegment(fs, p->thread.fsindex); | 283 | savesegment(fs, p->thread.fsindex); |
284 | p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs; | ||
285 | savesegment(es, p->thread.es); | 285 | savesegment(es, p->thread.es); |
286 | savesegment(ds, p->thread.ds); | 286 | savesegment(ds, p->thread.ds); |
287 | 287 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index a503b1fd04e5..2e9b55027b7e 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/slab.h> | ||
15 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
16 | #include <linux/regset.h> | 17 | #include <linux/regset.h> |
17 | #include <linux/tracehook.h> | 18 | #include <linux/tracehook.h> |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5d7ba1a449bd..c4851eff57b3 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -55,7 +55,6 @@ | |||
55 | #include <linux/stddef.h> | 55 | #include <linux/stddef.h> |
56 | #include <linux/unistd.h> | 56 | #include <linux/unistd.h> |
57 | #include <linux/ptrace.h> | 57 | #include <linux/ptrace.h> |
58 | #include <linux/slab.h> | ||
59 | #include <linux/user.h> | 58 | #include <linux/user.h> |
60 | #include <linux/delay.h> | 59 | #include <linux/delay.h> |
61 | 60 | ||
@@ -314,16 +313,17 @@ static void __init reserve_brk(void) | |||
314 | #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) | 313 | #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) |
315 | static void __init relocate_initrd(void) | 314 | static void __init relocate_initrd(void) |
316 | { | 315 | { |
317 | 316 | /* Assume only end is not page aligned */ | |
318 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 317 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
319 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 318 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
319 | u64 area_size = PAGE_ALIGN(ramdisk_size); | ||
320 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; | 320 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; |
321 | u64 ramdisk_here; | 321 | u64 ramdisk_here; |
322 | unsigned long slop, clen, mapaddr; | 322 | unsigned long slop, clen, mapaddr; |
323 | char *p, *q; | 323 | char *p, *q; |
324 | 324 | ||
325 | /* We need to move the initrd down into lowmem */ | 325 | /* We need to move the initrd down into lowmem */ |
326 | ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, | 326 | ramdisk_here = find_e820_area(0, end_of_lowmem, area_size, |
327 | PAGE_SIZE); | 327 | PAGE_SIZE); |
328 | 328 | ||
329 | if (ramdisk_here == -1ULL) | 329 | if (ramdisk_here == -1ULL) |
@@ -332,7 +332,7 @@ static void __init relocate_initrd(void) | |||
332 | 332 | ||
333 | /* Note: this includes all the lowmem currently occupied by | 333 | /* Note: this includes all the lowmem currently occupied by |
334 | the initrd, we rely on that fact to keep the data intact. */ | 334 | the initrd, we rely on that fact to keep the data intact. */ |
335 | reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, | 335 | reserve_early(ramdisk_here, ramdisk_here + area_size, |
336 | "NEW RAMDISK"); | 336 | "NEW RAMDISK"); |
337 | initrd_start = ramdisk_here + PAGE_OFFSET; | 337 | initrd_start = ramdisk_here + PAGE_OFFSET; |
338 | initrd_end = initrd_start + ramdisk_size; | 338 | initrd_end = initrd_start + ramdisk_size; |
@@ -376,9 +376,10 @@ static void __init relocate_initrd(void) | |||
376 | 376 | ||
377 | static void __init reserve_initrd(void) | 377 | static void __init reserve_initrd(void) |
378 | { | 378 | { |
379 | /* Assume only end is not page aligned */ | ||
379 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 380 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
380 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 381 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
381 | u64 ramdisk_end = ramdisk_image + ramdisk_size; | 382 | u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); |
382 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; | 383 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; |
383 | 384 | ||
384 | if (!boot_params.hdr.type_of_loader || | 385 | if (!boot_params.hdr.type_of_loader || |
@@ -606,6 +607,16 @@ static int __init setup_elfcorehdr(char *arg) | |||
606 | early_param("elfcorehdr", setup_elfcorehdr); | 607 | early_param("elfcorehdr", setup_elfcorehdr); |
607 | #endif | 608 | #endif |
608 | 609 | ||
610 | static __init void reserve_ibft_region(void) | ||
611 | { | ||
612 | unsigned long addr, size = 0; | ||
613 | |||
614 | addr = find_ibft_region(&size); | ||
615 | |||
616 | if (size) | ||
617 | reserve_early_overlap_ok(addr, addr + size, "ibft"); | ||
618 | } | ||
619 | |||
609 | #ifdef CONFIG_X86_RESERVE_LOW_64K | 620 | #ifdef CONFIG_X86_RESERVE_LOW_64K |
610 | static int __init dmi_low_memory_corruption(const struct dmi_system_id *d) | 621 | static int __init dmi_low_memory_corruption(const struct dmi_system_id *d) |
611 | { | 622 | { |
@@ -908,6 +919,8 @@ void __init setup_arch(char **cmdline_p) | |||
908 | */ | 919 | */ |
909 | find_smp_config(); | 920 | find_smp_config(); |
910 | 921 | ||
922 | reserve_ibft_region(); | ||
923 | |||
911 | reserve_trampoline_memory(); | 924 | reserve_trampoline_memory(); |
912 | 925 | ||
913 | #ifdef CONFIG_ACPI_SLEEP | 926 | #ifdef CONFIG_ACPI_SLEEP |
@@ -975,8 +988,6 @@ void __init setup_arch(char **cmdline_p) | |||
975 | 988 | ||
976 | dma32_reserve_bootmem(); | 989 | dma32_reserve_bootmem(); |
977 | 990 | ||
978 | reserve_ibft_region(); | ||
979 | |||
980 | #ifdef CONFIG_KVM_CLOCK | 991 | #ifdef CONFIG_KVM_CLOCK |
981 | kvmclock_init(); | 992 | kvmclock_init(); |
982 | #endif | 993 | #endif |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index ec1de97600e7..d801210945d6 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/cache.h> | 21 | #include <linux/cache.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/cpu.h> | 23 | #include <linux/cpu.h> |
24 | #include <linux/gfp.h> | ||
24 | 25 | ||
25 | #include <asm/mtrr.h> | 26 | #include <asm/mtrr.h> |
26 | #include <asm/tlbflush.h> | 27 | #include <asm/tlbflush.h> |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a02e80c3c54b..763d815e27a0 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/nmi.h> | 49 | #include <linux/nmi.h> |
50 | #include <linux/tboot.h> | 50 | #include <linux/tboot.h> |
51 | #include <linux/stackprotector.h> | 51 | #include <linux/stackprotector.h> |
52 | #include <linux/gfp.h> | ||
52 | 53 | ||
53 | #include <asm/acpi.h> | 54 | #include <asm/acpi.h> |
54 | #include <asm/desc.h> | 55 | #include <asm/desc.h> |
@@ -242,12 +243,10 @@ static void __cpuinit smp_callin(void) | |||
242 | end_local_APIC_setup(); | 243 | end_local_APIC_setup(); |
243 | map_cpu_to_logical_apicid(); | 244 | map_cpu_to_logical_apicid(); |
244 | 245 | ||
245 | notify_cpu_starting(cpuid); | ||
246 | |||
247 | /* | 246 | /* |
248 | * Need to setup vector mappings before we enable interrupts. | 247 | * Need to setup vector mappings before we enable interrupts. |
249 | */ | 248 | */ |
250 | __setup_vector_irq(smp_processor_id()); | 249 | setup_vector_irq(smp_processor_id()); |
251 | /* | 250 | /* |
252 | * Get our bogomips. | 251 | * Get our bogomips. |
253 | * | 252 | * |
@@ -264,6 +263,8 @@ static void __cpuinit smp_callin(void) | |||
264 | */ | 263 | */ |
265 | smp_store_cpu_info(cpuid); | 264 | smp_store_cpu_info(cpuid); |
266 | 265 | ||
266 | notify_cpu_starting(cpuid); | ||
267 | |||
267 | /* | 268 | /* |
268 | * Allow the master to continue. | 269 | * Allow the master to continue. |
269 | */ | 270 | */ |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 364d015efebc..17b03dd3a6b5 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/proc_fs.h> | 10 | #include <linux/proc_fs.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | ||
12 | 13 | ||
13 | #include <asm/mmu_context.h> | 14 | #include <asm/mmu_context.h> |
14 | #include <asm/uv/uv.h> | 15 | #include <asm/uv/uv.h> |
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c index ece73d8e3240..1d40336b030a 100644 --- a/arch/x86/kernel/uv_irq.c +++ b/arch/x86/kernel/uv_irq.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/rbtree.h> | 12 | #include <linux/rbtree.h> |
13 | #include <linux/slab.h> | ||
13 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
14 | 15 | ||
15 | #include <asm/apic.h> | 16 | #include <asm/apic.h> |
diff --git a/arch/x86/kernel/uv_time.c b/arch/x86/kernel/uv_time.c index 2b75ef638dbc..56e421bc379b 100644 --- a/arch/x86/kernel/uv_time.c +++ b/arch/x86/kernel/uv_time.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Copyright (c) Dimitri Sivanich | 19 | * Copyright (c) Dimitri Sivanich |
20 | */ | 20 | */ |
21 | #include <linux/clockchips.h> | 21 | #include <linux/clockchips.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | #include <asm/uv/uv_mmrs.h> | 24 | #include <asm/uv/uv_mmrs.h> |
24 | #include <asm/uv/uv_hub.h> | 25 | #include <asm/uv/uv_hub.h> |
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c index 7dd599deca4a..ce9fbacb7526 100644 --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/gfp.h> | ||
31 | #include <asm/vmi.h> | 32 | #include <asm/vmi.h> |
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | #include <asm/fixmap.h> | 34 | #include <asm/fixmap.h> |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 44879df55696..2cc249718c46 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -291,8 +291,8 @@ SECTIONS | |||
291 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { | 291 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
292 | __smp_locks = .; | 292 | __smp_locks = .; |
293 | *(.smp_locks) | 293 | *(.smp_locks) |
294 | __smp_locks_end = .; | ||
295 | . = ALIGN(PAGE_SIZE); | 294 | . = ALIGN(PAGE_SIZE); |
295 | __smp_locks_end = .; | ||
296 | } | 296 | } |
297 | 297 | ||
298 | #ifdef CONFIG_X86_64 | 298 | #ifdef CONFIG_X86_64 |