diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 23:47:59 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 23:47:59 -0500 |
| commit | 756300983f11a1c6f9457d6d8f57354e0f0fe8d4 (patch) | |
| tree | 9f9b791b4af64b4db7dc4a1b6f900ff91fec5206 | |
| parent | df7147b3c37cb203f968119f3b6a1cd648c535a1 (diff) | |
| parent | 9cf7826743e5c78dcfcfdc99d17f79ce6d3a2942 (diff) | |
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86/amd-iommu: Fix PCI hotplug with passthrough mode
x86/amd-iommu: Fix passthrough mode
x86: mmio-mod.c: Use pr_fmt
x86: kmmio.c: Add and use pr_fmt(fmt)
x86: i8254.c: Add pr_fmt(fmt)
x86: setup_percpu.c: Use pr_<level> and add pr_fmt(fmt)
x86: es7000_32.c: Use pr_<level> and add pr_fmt(fmt)
x86: Print DMI_BOARD_NAME as well as DMI_PRODUCT_NAME from __show_regs()
x86: Factor duplicated code out of __show_regs() into show_regs_common()
arch/x86/kernel/microcode*: Use pr_fmt() and remove duplicated KERN_ERR prefix
x86, mce: fix confusion between bank attributes and mce attributes
x86/mce: Set up timer unconditionally
x86: Fix bogus warning in apic_noop.apic_write()
x86: Fix typo in arch/x86/mm/kmmio.c
x86: ASUS P4S800 reboot=bios quirk
| -rw-r--r-- | arch/x86/include/asm/amd_iommu_proto.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/system.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/amd_iommu.c | 46 | ||||
| -rw-r--r-- | arch/x86/kernel/amd_iommu_init.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/apic_noop.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/es7000_32.c | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/microcode_amd.c | 40 | ||||
| -rw-r--r-- | arch/x86/kernel/microcode_core.c | 26 | ||||
| -rw-r--r-- | arch/x86/kernel/microcode_intel.c | 47 | ||||
| -rw-r--r-- | arch/x86/kernel/process.c | 21 | ||||
| -rw-r--r-- | arch/x86/kernel/process_32.c | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/process_64.c | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/reboot.c | 8 | ||||
| -rw-r--r-- | arch/x86/kernel/setup_percpu.c | 13 | ||||
| -rw-r--r-- | arch/x86/kvm/i8254.c | 12 | ||||
| -rw-r--r-- | arch/x86/mm/kmmio.c | 42 | ||||
| -rw-r--r-- | arch/x86/mm/mmio-mod.c | 71 |
18 files changed, 221 insertions, 168 deletions
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index 84786fb9a23b..4d817f9e6e77 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
| @@ -28,7 +28,9 @@ extern void amd_iommu_flush_all_domains(void); | |||
| 28 | extern void amd_iommu_flush_all_devices(void); | 28 | extern void amd_iommu_flush_all_devices(void); |
| 29 | extern void amd_iommu_apply_erratum_63(u16 devid); | 29 | extern void amd_iommu_apply_erratum_63(u16 devid); |
| 30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); | 30 | extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); |
| 31 | 31 | extern int amd_iommu_init_devices(void); | |
| 32 | extern void amd_iommu_uninit_devices(void); | ||
| 33 | extern void amd_iommu_init_notifier(void); | ||
| 32 | #ifndef CONFIG_AMD_IOMMU_STATS | 34 | #ifndef CONFIG_AMD_IOMMU_STATS |
| 33 | 35 | ||
| 34 | static inline void amd_iommu_stats_init(void) { } | 36 | static inline void amd_iommu_stats_init(void) { } |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index 022a84386de8..ecb544e65382 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
| @@ -23,6 +23,7 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
| 23 | struct tss_struct; | 23 | struct tss_struct; |
| 24 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 24 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
| 25 | struct tss_struct *tss); | 25 | struct tss_struct *tss); |
| 26 | extern void show_regs_common(void); | ||
| 26 | 27 | ||
| 27 | #ifdef CONFIG_X86_32 | 28 | #ifdef CONFIG_X86_32 |
| 28 | 29 | ||
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 1c0fb4d4ad55..b990b5cc9541 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -166,6 +166,43 @@ static void iommu_uninit_device(struct device *dev) | |||
| 166 | { | 166 | { |
| 167 | kfree(dev->archdata.iommu); | 167 | kfree(dev->archdata.iommu); |
| 168 | } | 168 | } |
| 169 | |||
| 170 | void __init amd_iommu_uninit_devices(void) | ||
| 171 | { | ||
| 172 | struct pci_dev *pdev = NULL; | ||
| 173 | |||
| 174 | for_each_pci_dev(pdev) { | ||
| 175 | |||
| 176 | if (!check_device(&pdev->dev)) | ||
| 177 | continue; | ||
| 178 | |||
| 179 | iommu_uninit_device(&pdev->dev); | ||
| 180 | } | ||
| 181 | } | ||
| 182 | |||
| 183 | int __init amd_iommu_init_devices(void) | ||
| 184 | { | ||
| 185 | struct pci_dev *pdev = NULL; | ||
| 186 | int ret = 0; | ||
| 187 | |||
| 188 | for_each_pci_dev(pdev) { | ||
| 189 | |||
| 190 | if (!check_device(&pdev->dev)) | ||
| 191 | continue; | ||
| 192 | |||
| 193 | ret = iommu_init_device(&pdev->dev); | ||
| 194 | if (ret) | ||
| 195 | goto out_free; | ||
| 196 | } | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | |||
| 200 | out_free: | ||
| 201 | |||
| 202 | amd_iommu_uninit_devices(); | ||
| 203 | |||
| 204 | return ret; | ||
| 205 | } | ||
| 169 | #ifdef CONFIG_AMD_IOMMU_STATS | 206 | #ifdef CONFIG_AMD_IOMMU_STATS |
| 170 | 207 | ||
| 171 | /* | 208 | /* |
| @@ -1587,6 +1624,11 @@ static struct notifier_block device_nb = { | |||
| 1587 | .notifier_call = device_change_notifier, | 1624 | .notifier_call = device_change_notifier, |
| 1588 | }; | 1625 | }; |
| 1589 | 1626 | ||
| 1627 | void amd_iommu_init_notifier(void) | ||
| 1628 | { | ||
| 1629 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
| 1630 | } | ||
| 1631 | |||
| 1590 | /***************************************************************************** | 1632 | /***************************************************************************** |
| 1591 | * | 1633 | * |
| 1592 | * The next functions belong to the dma_ops mapping/unmapping code. | 1634 | * The next functions belong to the dma_ops mapping/unmapping code. |
| @@ -2145,8 +2187,6 @@ static void prealloc_protection_domains(void) | |||
| 2145 | if (!check_device(&dev->dev)) | 2187 | if (!check_device(&dev->dev)) |
| 2146 | continue; | 2188 | continue; |
| 2147 | 2189 | ||
| 2148 | iommu_init_device(&dev->dev); | ||
| 2149 | |||
| 2150 | /* Is there already any domain for it? */ | 2190 | /* Is there already any domain for it? */ |
| 2151 | if (domain_for_device(&dev->dev)) | 2191 | if (domain_for_device(&dev->dev)) |
| 2152 | continue; | 2192 | continue; |
| @@ -2215,8 +2255,6 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 2215 | 2255 | ||
| 2216 | register_iommu(&amd_iommu_ops); | 2256 | register_iommu(&amd_iommu_ops); |
| 2217 | 2257 | ||
| 2218 | bus_register_notifier(&pci_bus_type, &device_nb); | ||
| 2219 | |||
| 2220 | amd_iommu_stats_init(); | 2258 | amd_iommu_stats_init(); |
| 2221 | 2259 | ||
| 2222 | return 0; | 2260 | return 0; |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 9c4a6f747552..1dca9c34eaeb 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
| @@ -1274,6 +1274,10 @@ static int __init amd_iommu_init(void) | |||
| 1274 | if (ret) | 1274 | if (ret) |
| 1275 | goto free; | 1275 | goto free; |
| 1276 | 1276 | ||
| 1277 | ret = amd_iommu_init_devices(); | ||
| 1278 | if (ret) | ||
| 1279 | goto free; | ||
| 1280 | |||
| 1277 | if (iommu_pass_through) | 1281 | if (iommu_pass_through) |
| 1278 | ret = amd_iommu_init_passthrough(); | 1282 | ret = amd_iommu_init_passthrough(); |
| 1279 | else | 1283 | else |
| @@ -1281,6 +1285,8 @@ static int __init amd_iommu_init(void) | |||
| 1281 | if (ret) | 1285 | if (ret) |
| 1282 | goto free; | 1286 | goto free; |
| 1283 | 1287 | ||
| 1288 | amd_iommu_init_notifier(); | ||
| 1289 | |||
| 1284 | enable_iommus(); | 1290 | enable_iommus(); |
| 1285 | 1291 | ||
| 1286 | if (iommu_pass_through) | 1292 | if (iommu_pass_through) |
| @@ -1296,6 +1302,9 @@ out: | |||
| 1296 | return ret; | 1302 | return ret; |
| 1297 | 1303 | ||
| 1298 | free: | 1304 | free: |
| 1305 | |||
| 1306 | amd_iommu_uninit_devices(); | ||
| 1307 | |||
| 1299 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, | 1308 | free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, |
| 1300 | get_order(MAX_DOMAIN_ID/8)); | 1309 | get_order(MAX_DOMAIN_ID/8)); |
| 1301 | 1310 | ||
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index d9acc3bee0f4..e31b9ffe25f5 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
| @@ -127,7 +127,7 @@ static u32 noop_apic_read(u32 reg) | |||
| 127 | 127 | ||
| 128 | static void noop_apic_write(u32 reg, u32 v) | 128 | static void noop_apic_write(u32 reg, u32 v) |
| 129 | { | 129 | { |
| 130 | WARN_ON_ONCE((cpu_has_apic || !disable_apic)); | 130 | WARN_ON_ONCE(cpu_has_apic && !disable_apic); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | struct apic apic_noop = { | 133 | struct apic apic_noop = { |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index e85f8fb7f8e7..dd2b5f264643 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
| @@ -27,6 +27,9 @@ | |||
| 27 | * | 27 | * |
| 28 | * http://www.unisys.com | 28 | * http://www.unisys.com |
| 29 | */ | 29 | */ |
| 30 | |||
| 31 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 32 | |||
| 30 | #include <linux/notifier.h> | 33 | #include <linux/notifier.h> |
| 31 | #include <linux/spinlock.h> | 34 | #include <linux/spinlock.h> |
| 32 | #include <linux/cpumask.h> | 35 | #include <linux/cpumask.h> |
| @@ -223,9 +226,9 @@ static int parse_unisys_oem(char *oemptr) | |||
| 223 | mip_addr = val; | 226 | mip_addr = val; |
| 224 | mip = (struct mip_reg *)val; | 227 | mip = (struct mip_reg *)val; |
| 225 | mip_reg = __va(mip); | 228 | mip_reg = __va(mip); |
| 226 | pr_debug("es7000_mipcfg: host_reg = 0x%lx \n", | 229 | pr_debug("host_reg = 0x%lx\n", |
| 227 | (unsigned long)host_reg); | 230 | (unsigned long)host_reg); |
| 228 | pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n", | 231 | pr_debug("mip_reg = 0x%lx\n", |
| 229 | (unsigned long)mip_reg); | 232 | (unsigned long)mip_reg); |
| 230 | success++; | 233 | success++; |
| 231 | break; | 234 | break; |
| @@ -401,7 +404,7 @@ static void es7000_enable_apic_mode(void) | |||
| 401 | if (!es7000_plat) | 404 | if (!es7000_plat) |
| 402 | return; | 405 | return; |
| 403 | 406 | ||
| 404 | printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); | 407 | pr_info("Enabling APIC mode.\n"); |
| 405 | memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); | 408 | memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); |
| 406 | es7000_mip_reg.off_0x00 = MIP_SW_APIC; | 409 | es7000_mip_reg.off_0x00 = MIP_SW_APIC; |
| 407 | es7000_mip_reg.off_0x38 = MIP_VALID; | 410 | es7000_mip_reg.off_0x38 = MIP_VALID; |
| @@ -514,8 +517,7 @@ static void es7000_setup_apic_routing(void) | |||
| 514 | { | 517 | { |
| 515 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); | 518 | int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); |
| 516 | 519 | ||
| 517 | printk(KERN_INFO | 520 | pr_info("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", |
| 518 | "Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n", | ||
| 519 | (apic_version[apic] == 0x14) ? | 521 | (apic_version[apic] == 0x14) ? |
| 520 | "Physical Cluster" : "Logical Cluster", | 522 | "Physical Cluster" : "Logical Cluster", |
| 521 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); | 523 | nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index d7ebf25d10ed..a8aacd4b513c 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -1388,13 +1388,14 @@ static void __mcheck_cpu_init_timer(void) | |||
| 1388 | struct timer_list *t = &__get_cpu_var(mce_timer); | 1388 | struct timer_list *t = &__get_cpu_var(mce_timer); |
| 1389 | int *n = &__get_cpu_var(mce_next_interval); | 1389 | int *n = &__get_cpu_var(mce_next_interval); |
| 1390 | 1390 | ||
| 1391 | setup_timer(t, mce_start_timer, smp_processor_id()); | ||
| 1392 | |||
| 1391 | if (mce_ignore_ce) | 1393 | if (mce_ignore_ce) |
| 1392 | return; | 1394 | return; |
| 1393 | 1395 | ||
| 1394 | *n = check_interval * HZ; | 1396 | *n = check_interval * HZ; |
| 1395 | if (!*n) | 1397 | if (!*n) |
| 1396 | return; | 1398 | return; |
| 1397 | setup_timer(t, mce_start_timer, smp_processor_id()); | ||
| 1398 | t->expires = round_jiffies(jiffies + *n); | 1399 | t->expires = round_jiffies(jiffies + *n); |
| 1399 | add_timer_on(t, smp_processor_id()); | 1400 | add_timer_on(t, smp_processor_id()); |
| 1400 | } | 1401 | } |
| @@ -1928,7 +1929,7 @@ error2: | |||
| 1928 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr); | 1929 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr); |
| 1929 | error: | 1930 | error: |
| 1930 | while (--i >= 0) | 1931 | while (--i >= 0) |
| 1931 | sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr); | 1932 | sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]); |
| 1932 | 1933 | ||
| 1933 | sysdev_unregister(&per_cpu(mce_dev, cpu)); | 1934 | sysdev_unregister(&per_cpu(mce_dev, cpu)); |
| 1934 | 1935 | ||
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 63123d902103..37542b67c57e 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c | |||
| @@ -13,6 +13,9 @@ | |||
| 13 | * Licensed under the terms of the GNU General Public | 13 | * Licensed under the terms of the GNU General Public |
| 14 | * License version 2. See file COPYING for details. | 14 | * License version 2. See file COPYING for details. |
| 15 | */ | 15 | */ |
| 16 | |||
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 18 | |||
| 16 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
| 17 | #include <linux/pci_ids.h> | 20 | #include <linux/pci_ids.h> |
| 18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| @@ -81,7 +84,7 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) | |||
| 81 | 84 | ||
| 82 | memset(csig, 0, sizeof(*csig)); | 85 | memset(csig, 0, sizeof(*csig)); |
| 83 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); | 86 | rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); |
| 84 | pr_info("microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev); | 87 | pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev); |
| 85 | return 0; | 88 | return 0; |
| 86 | } | 89 | } |
| 87 | 90 | ||
| @@ -111,8 +114,8 @@ static int get_matching_microcode(int cpu, void *mc, int rev) | |||
| 111 | 114 | ||
| 112 | /* ucode might be chipset specific -- currently we don't support this */ | 115 | /* ucode might be chipset specific -- currently we don't support this */ |
| 113 | if (mc_header->nb_dev_id || mc_header->sb_dev_id) { | 116 | if (mc_header->nb_dev_id || mc_header->sb_dev_id) { |
| 114 | pr_err(KERN_ERR "microcode: CPU%d: loading of chipset " | 117 | pr_err("CPU%d: loading of chipset specific code not yet supported\n", |
| 115 | "specific code not yet supported\n", cpu); | 118 | cpu); |
| 116 | return 0; | 119 | return 0; |
| 117 | } | 120 | } |
| 118 | 121 | ||
| @@ -141,12 +144,12 @@ static int apply_microcode_amd(int cpu) | |||
| 141 | 144 | ||
| 142 | /* check current patch id and patch's id for match */ | 145 | /* check current patch id and patch's id for match */ |
| 143 | if (rev != mc_amd->hdr.patch_id) { | 146 | if (rev != mc_amd->hdr.patch_id) { |
| 144 | pr_err("microcode: CPU%d: update failed " | 147 | pr_err("CPU%d: update failed (for patch_level=0x%x)\n", |
| 145 | "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id); | 148 | cpu, mc_amd->hdr.patch_id); |
| 146 | return -1; | 149 | return -1; |
| 147 | } | 150 | } |
| 148 | 151 | ||
| 149 | pr_info("microcode: CPU%d: updated (new patch_level=0x%x)\n", cpu, rev); | 152 | pr_info("CPU%d: updated (new patch_level=0x%x)\n", cpu, rev); |
| 150 | uci->cpu_sig.rev = rev; | 153 | uci->cpu_sig.rev = rev; |
| 151 | 154 | ||
| 152 | return 0; | 155 | return 0; |
| @@ -169,15 +172,14 @@ get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) | |||
| 169 | return NULL; | 172 | return NULL; |
| 170 | 173 | ||
| 171 | if (section_hdr[0] != UCODE_UCODE_TYPE) { | 174 | if (section_hdr[0] != UCODE_UCODE_TYPE) { |
| 172 | pr_err("microcode: error: invalid type field in " | 175 | pr_err("error: invalid type field in container file section header\n"); |
| 173 | "container file section header\n"); | ||
| 174 | return NULL; | 176 | return NULL; |
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); | 179 | total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); |
| 178 | 180 | ||
| 179 | if (total_size > size || total_size > UCODE_MAX_SIZE) { | 181 | if (total_size > size || total_size > UCODE_MAX_SIZE) { |
| 180 | pr_err("microcode: error: size mismatch\n"); | 182 | pr_err("error: size mismatch\n"); |
| 181 | return NULL; | 183 | return NULL; |
| 182 | } | 184 | } |
| 183 | 185 | ||
| @@ -206,14 +208,13 @@ static int install_equiv_cpu_table(const u8 *buf) | |||
| 206 | size = buf_pos[2]; | 208 | size = buf_pos[2]; |
| 207 | 209 | ||
| 208 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { | 210 | if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { |
| 209 | pr_err("microcode: error: invalid type field in " | 211 | pr_err("error: invalid type field in container file section header\n"); |
| 210 | "container file section header\n"); | ||
| 211 | return 0; | 212 | return 0; |
| 212 | } | 213 | } |
| 213 | 214 | ||
| 214 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); | 215 | equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); |
| 215 | if (!equiv_cpu_table) { | 216 | if (!equiv_cpu_table) { |
| 216 | pr_err("microcode: failed to allocate equivalent CPU table\n"); | 217 | pr_err("failed to allocate equivalent CPU table\n"); |
| 217 | return 0; | 218 | return 0; |
| 218 | } | 219 | } |
| 219 | 220 | ||
| @@ -246,7 +247,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) | |||
| 246 | 247 | ||
| 247 | offset = install_equiv_cpu_table(ucode_ptr); | 248 | offset = install_equiv_cpu_table(ucode_ptr); |
| 248 | if (!offset) { | 249 | if (!offset) { |
| 249 | pr_err("microcode: failed to create equivalent cpu table\n"); | 250 | pr_err("failed to create equivalent cpu table\n"); |
| 250 | return UCODE_ERROR; | 251 | return UCODE_ERROR; |
| 251 | } | 252 | } |
| 252 | 253 | ||
| @@ -277,8 +278,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) | |||
| 277 | if (!leftover) { | 278 | if (!leftover) { |
| 278 | vfree(uci->mc); | 279 | vfree(uci->mc); |
| 279 | uci->mc = new_mc; | 280 | uci->mc = new_mc; |
| 280 | pr_debug("microcode: CPU%d found a matching microcode " | 281 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
| 281 | "update with version 0x%x (current=0x%x)\n", | ||
| 282 | cpu, new_rev, uci->cpu_sig.rev); | 282 | cpu, new_rev, uci->cpu_sig.rev); |
| 283 | } else { | 283 | } else { |
| 284 | vfree(new_mc); | 284 | vfree(new_mc); |
| @@ -300,7 +300,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 300 | return UCODE_NFOUND; | 300 | return UCODE_NFOUND; |
| 301 | 301 | ||
| 302 | if (*(u32 *)firmware->data != UCODE_MAGIC) { | 302 | if (*(u32 *)firmware->data != UCODE_MAGIC) { |
| 303 | pr_err("microcode: invalid UCODE_MAGIC (0x%08x)\n", | 303 | pr_err("invalid UCODE_MAGIC (0x%08x)\n", |
| 304 | *(u32 *)firmware->data); | 304 | *(u32 *)firmware->data); |
| 305 | return UCODE_ERROR; | 305 | return UCODE_ERROR; |
| 306 | } | 306 | } |
| @@ -313,8 +313,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 313 | static enum ucode_state | 313 | static enum ucode_state |
| 314 | request_microcode_user(int cpu, const void __user *buf, size_t size) | 314 | request_microcode_user(int cpu, const void __user *buf, size_t size) |
| 315 | { | 315 | { |
| 316 | pr_info("microcode: AMD microcode update via " | 316 | pr_info("AMD microcode update via /dev/cpu/microcode not supported\n"); |
| 317 | "/dev/cpu/microcode not supported\n"); | ||
| 318 | return UCODE_ERROR; | 317 | return UCODE_ERROR; |
| 319 | } | 318 | } |
| 320 | 319 | ||
| @@ -334,14 +333,13 @@ void init_microcode_amd(struct device *device) | |||
| 334 | WARN_ON(c->x86_vendor != X86_VENDOR_AMD); | 333 | WARN_ON(c->x86_vendor != X86_VENDOR_AMD); |
| 335 | 334 | ||
| 336 | if (c->x86 < 0x10) { | 335 | if (c->x86 < 0x10) { |
| 337 | pr_warning("microcode: AMD CPU family 0x%x not supported\n", | 336 | pr_warning("AMD CPU family 0x%x not supported\n", c->x86); |
| 338 | c->x86); | ||
| 339 | return; | 337 | return; |
| 340 | } | 338 | } |
| 341 | supported_cpu = 1; | 339 | supported_cpu = 1; |
| 342 | 340 | ||
| 343 | if (request_firmware(&firmware, fw_name, device)) | 341 | if (request_firmware(&firmware, fw_name, device)) |
| 344 | pr_err("microcode: failed to load file %s\n", fw_name); | 342 | pr_err("failed to load file %s\n", fw_name); |
| 345 | } | 343 | } |
| 346 | 344 | ||
| 347 | void fini_microcode_amd(void) | 345 | void fini_microcode_amd(void) |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index e68aae397869..844c02c65fcb 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
| @@ -70,6 +70,9 @@ | |||
| 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
| 71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
| 72 | */ | 72 | */ |
| 73 | |||
| 74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 75 | |||
| 73 | #include <linux/platform_device.h> | 76 | #include <linux/platform_device.h> |
| 74 | #include <linux/miscdevice.h> | 77 | #include <linux/miscdevice.h> |
| 75 | #include <linux/capability.h> | 78 | #include <linux/capability.h> |
| @@ -209,7 +212,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, | |||
| 209 | ssize_t ret = -EINVAL; | 212 | ssize_t ret = -EINVAL; |
| 210 | 213 | ||
| 211 | if ((len >> PAGE_SHIFT) > totalram_pages) { | 214 | if ((len >> PAGE_SHIFT) > totalram_pages) { |
| 212 | pr_err("microcode: too much data (max %ld pages)\n", totalram_pages); | 215 | pr_err("too much data (max %ld pages)\n", totalram_pages); |
| 213 | return ret; | 216 | return ret; |
| 214 | } | 217 | } |
| 215 | 218 | ||
| @@ -244,7 +247,7 @@ static int __init microcode_dev_init(void) | |||
| 244 | 247 | ||
| 245 | error = misc_register(µcode_dev); | 248 | error = misc_register(µcode_dev); |
| 246 | if (error) { | 249 | if (error) { |
| 247 | pr_err("microcode: can't misc_register on minor=%d\n", MICROCODE_MINOR); | 250 | pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR); |
| 248 | return error; | 251 | return error; |
| 249 | } | 252 | } |
| 250 | 253 | ||
| @@ -359,7 +362,7 @@ static enum ucode_state microcode_resume_cpu(int cpu) | |||
| 359 | if (!uci->mc) | 362 | if (!uci->mc) |
| 360 | return UCODE_NFOUND; | 363 | return UCODE_NFOUND; |
| 361 | 364 | ||
| 362 | pr_debug("microcode: CPU%d updated upon resume\n", cpu); | 365 | pr_debug("CPU%d updated upon resume\n", cpu); |
| 363 | apply_microcode_on_target(cpu); | 366 | apply_microcode_on_target(cpu); |
| 364 | 367 | ||
| 365 | return UCODE_OK; | 368 | return UCODE_OK; |
| @@ -379,7 +382,7 @@ static enum ucode_state microcode_init_cpu(int cpu) | |||
| 379 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev); | 382 | ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev); |
| 380 | 383 | ||
| 381 | if (ustate == UCODE_OK) { | 384 | if (ustate == UCODE_OK) { |
| 382 | pr_debug("microcode: CPU%d updated upon init\n", cpu); | 385 | pr_debug("CPU%d updated upon init\n", cpu); |
| 383 | apply_microcode_on_target(cpu); | 386 | apply_microcode_on_target(cpu); |
| 384 | } | 387 | } |
| 385 | 388 | ||
| @@ -406,7 +409,7 @@ static int mc_sysdev_add(struct sys_device *sys_dev) | |||
| 406 | if (!cpu_online(cpu)) | 409 | if (!cpu_online(cpu)) |
| 407 | return 0; | 410 | return 0; |
| 408 | 411 | ||
| 409 | pr_debug("microcode: CPU%d added\n", cpu); | 412 | pr_debug("CPU%d added\n", cpu); |
| 410 | 413 | ||
| 411 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); | 414 | err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); |
| 412 | if (err) | 415 | if (err) |
| @@ -425,7 +428,7 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) | |||
| 425 | if (!cpu_online(cpu)) | 428 | if (!cpu_online(cpu)) |
| 426 | return 0; | 429 | return 0; |
| 427 | 430 | ||
| 428 | pr_debug("microcode: CPU%d removed\n", cpu); | 431 | pr_debug("CPU%d removed\n", cpu); |
| 429 | microcode_fini_cpu(cpu); | 432 | microcode_fini_cpu(cpu); |
| 430 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 433 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
| 431 | return 0; | 434 | return 0; |
| @@ -473,15 +476,15 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | |||
| 473 | microcode_update_cpu(cpu); | 476 | microcode_update_cpu(cpu); |
| 474 | case CPU_DOWN_FAILED: | 477 | case CPU_DOWN_FAILED: |
| 475 | case CPU_DOWN_FAILED_FROZEN: | 478 | case CPU_DOWN_FAILED_FROZEN: |
| 476 | pr_debug("microcode: CPU%d added\n", cpu); | 479 | pr_debug("CPU%d added\n", cpu); |
| 477 | if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) | 480 | if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) |
| 478 | pr_err("microcode: Failed to create group for CPU%d\n", cpu); | 481 | pr_err("Failed to create group for CPU%d\n", cpu); |
| 479 | break; | 482 | break; |
| 480 | case CPU_DOWN_PREPARE: | 483 | case CPU_DOWN_PREPARE: |
| 481 | case CPU_DOWN_PREPARE_FROZEN: | 484 | case CPU_DOWN_PREPARE_FROZEN: |
| 482 | /* Suspend is in progress, only remove the interface */ | 485 | /* Suspend is in progress, only remove the interface */ |
| 483 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); | 486 | sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); |
| 484 | pr_debug("microcode: CPU%d removed\n", cpu); | 487 | pr_debug("CPU%d removed\n", cpu); |
| 485 | break; | 488 | break; |
| 486 | case CPU_DEAD: | 489 | case CPU_DEAD: |
| 487 | case CPU_UP_CANCELED_FROZEN: | 490 | case CPU_UP_CANCELED_FROZEN: |
| @@ -507,7 +510,7 @@ static int __init microcode_init(void) | |||
| 507 | microcode_ops = init_amd_microcode(); | 510 | microcode_ops = init_amd_microcode(); |
| 508 | 511 | ||
| 509 | if (!microcode_ops) { | 512 | if (!microcode_ops) { |
| 510 | pr_err("microcode: no support for this CPU vendor\n"); | 513 | pr_err("no support for this CPU vendor\n"); |
| 511 | return -ENODEV; | 514 | return -ENODEV; |
| 512 | } | 515 | } |
| 513 | 516 | ||
| @@ -541,8 +544,7 @@ static int __init microcode_init(void) | |||
| 541 | register_hotcpu_notifier(&mc_cpu_notifier); | 544 | register_hotcpu_notifier(&mc_cpu_notifier); |
| 542 | 545 | ||
| 543 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION | 546 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION |
| 544 | " <tigran@aivazian.fsnet.co.uk>," | 547 | " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); |
| 545 | " Peter Oruba\n"); | ||
| 546 | 548 | ||
| 547 | return 0; | 549 | return 0; |
| 548 | } | 550 | } |
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index 0d334ddd0a96..ebd193e476ca 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
| @@ -70,6 +70,9 @@ | |||
| 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. | 70 | * Fix sigmatch() macro to handle old CPUs with pf == 0. |
| 71 | * Thanks to Stuart Swales for pointing out this bug. | 71 | * Thanks to Stuart Swales for pointing out this bug. |
| 72 | */ | 72 | */ |
| 73 | |||
| 74 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 75 | |||
| 73 | #include <linux/firmware.h> | 76 | #include <linux/firmware.h> |
| 74 | #include <linux/uaccess.h> | 77 | #include <linux/uaccess.h> |
| 75 | #include <linux/kernel.h> | 78 | #include <linux/kernel.h> |
| @@ -146,8 +149,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
| 146 | 149 | ||
| 147 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || | 150 | if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || |
| 148 | cpu_has(c, X86_FEATURE_IA64)) { | 151 | cpu_has(c, X86_FEATURE_IA64)) { |
| 149 | printk(KERN_ERR "microcode: CPU%d not a capable Intel " | 152 | pr_err("CPU%d not a capable Intel processor\n", cpu_num); |
| 150 | "processor\n", cpu_num); | ||
| 151 | return -1; | 153 | return -1; |
| 152 | } | 154 | } |
| 153 | 155 | ||
| @@ -165,8 +167,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) | |||
| 165 | /* get the current revision from MSR 0x8B */ | 167 | /* get the current revision from MSR 0x8B */ |
| 166 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); | 168 | rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); |
| 167 | 169 | ||
| 168 | printk(KERN_INFO "microcode: CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", | 170 | pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", |
| 169 | cpu_num, csig->sig, csig->pf, csig->rev); | 171 | cpu_num, csig->sig, csig->pf, csig->rev); |
| 170 | 172 | ||
| 171 | return 0; | 173 | return 0; |
| 172 | } | 174 | } |
| @@ -194,28 +196,24 @@ static int microcode_sanity_check(void *mc) | |||
| 194 | data_size = get_datasize(mc_header); | 196 | data_size = get_datasize(mc_header); |
| 195 | 197 | ||
| 196 | if (data_size + MC_HEADER_SIZE > total_size) { | 198 | if (data_size + MC_HEADER_SIZE > total_size) { |
| 197 | printk(KERN_ERR "microcode: error! " | 199 | pr_err("error! Bad data size in microcode data file\n"); |
| 198 | "Bad data size in microcode data file\n"); | ||
| 199 | return -EINVAL; | 200 | return -EINVAL; |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 202 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { | 203 | if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { |
| 203 | printk(KERN_ERR "microcode: error! " | 204 | pr_err("error! Unknown microcode update format\n"); |
| 204 | "Unknown microcode update format\n"); | ||
| 205 | return -EINVAL; | 205 | return -EINVAL; |
| 206 | } | 206 | } |
| 207 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); | 207 | ext_table_size = total_size - (MC_HEADER_SIZE + data_size); |
| 208 | if (ext_table_size) { | 208 | if (ext_table_size) { |
| 209 | if ((ext_table_size < EXT_HEADER_SIZE) | 209 | if ((ext_table_size < EXT_HEADER_SIZE) |
| 210 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { | 210 | || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { |
| 211 | printk(KERN_ERR "microcode: error! " | 211 | pr_err("error! Small exttable size in microcode data file\n"); |
| 212 | "Small exttable size in microcode data file\n"); | ||
| 213 | return -EINVAL; | 212 | return -EINVAL; |
| 214 | } | 213 | } |
| 215 | ext_header = mc + MC_HEADER_SIZE + data_size; | 214 | ext_header = mc + MC_HEADER_SIZE + data_size; |
| 216 | if (ext_table_size != exttable_size(ext_header)) { | 215 | if (ext_table_size != exttable_size(ext_header)) { |
| 217 | printk(KERN_ERR "microcode: error! " | 216 | pr_err("error! Bad exttable size in microcode data file\n"); |
| 218 | "Bad exttable size in microcode data file\n"); | ||
| 219 | return -EFAULT; | 217 | return -EFAULT; |
| 220 | } | 218 | } |
| 221 | ext_sigcount = ext_header->count; | 219 | ext_sigcount = ext_header->count; |
| @@ -230,8 +228,7 @@ static int microcode_sanity_check(void *mc) | |||
| 230 | while (i--) | 228 | while (i--) |
| 231 | ext_table_sum += ext_tablep[i]; | 229 | ext_table_sum += ext_tablep[i]; |
| 232 | if (ext_table_sum) { | 230 | if (ext_table_sum) { |
| 233 | printk(KERN_WARNING "microcode: aborting, " | 231 | pr_warning("aborting, bad extended signature table checksum\n"); |
| 234 | "bad extended signature table checksum\n"); | ||
| 235 | return -EINVAL; | 232 | return -EINVAL; |
| 236 | } | 233 | } |
| 237 | } | 234 | } |
| @@ -242,7 +239,7 @@ static int microcode_sanity_check(void *mc) | |||
| 242 | while (i--) | 239 | while (i--) |
| 243 | orig_sum += ((int *)mc)[i]; | 240 | orig_sum += ((int *)mc)[i]; |
| 244 | if (orig_sum) { | 241 | if (orig_sum) { |
| 245 | printk(KERN_ERR "microcode: aborting, bad checksum\n"); | 242 | pr_err("aborting, bad checksum\n"); |
| 246 | return -EINVAL; | 243 | return -EINVAL; |
| 247 | } | 244 | } |
| 248 | if (!ext_table_size) | 245 | if (!ext_table_size) |
| @@ -255,7 +252,7 @@ static int microcode_sanity_check(void *mc) | |||
| 255 | - (mc_header->sig + mc_header->pf + mc_header->cksum) | 252 | - (mc_header->sig + mc_header->pf + mc_header->cksum) |
| 256 | + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); | 253 | + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); |
| 257 | if (sum) { | 254 | if (sum) { |
| 258 | printk(KERN_ERR "microcode: aborting, bad checksum\n"); | 255 | pr_err("aborting, bad checksum\n"); |
| 259 | return -EINVAL; | 256 | return -EINVAL; |
| 260 | } | 257 | } |
| 261 | } | 258 | } |
| @@ -327,13 +324,11 @@ static int apply_microcode(int cpu) | |||
| 327 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); | 324 | rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); |
| 328 | 325 | ||
| 329 | if (val[1] != mc_intel->hdr.rev) { | 326 | if (val[1] != mc_intel->hdr.rev) { |
| 330 | printk(KERN_ERR "microcode: CPU%d update " | 327 | pr_err("CPU%d update to revision 0x%x failed\n", |
| 331 | "to revision 0x%x failed\n", | 328 | cpu_num, mc_intel->hdr.rev); |
| 332 | cpu_num, mc_intel->hdr.rev); | ||
| 333 | return -1; | 329 | return -1; |
| 334 | } | 330 | } |
| 335 | printk(KERN_INFO "microcode: CPU%d updated to revision " | 331 | pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x \n", |
| 336 | "0x%x, date = %04x-%02x-%02x \n", | ||
| 337 | cpu_num, val[1], | 332 | cpu_num, val[1], |
| 338 | mc_intel->hdr.date & 0xffff, | 333 | mc_intel->hdr.date & 0xffff, |
| 339 | mc_intel->hdr.date >> 24, | 334 | mc_intel->hdr.date >> 24, |
| @@ -362,8 +357,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
| 362 | 357 | ||
| 363 | mc_size = get_totalsize(&mc_header); | 358 | mc_size = get_totalsize(&mc_header); |
| 364 | if (!mc_size || mc_size > leftover) { | 359 | if (!mc_size || mc_size > leftover) { |
| 365 | printk(KERN_ERR "microcode: error!" | 360 | pr_err("error! Bad data in microcode data file\n"); |
| 366 | "Bad data in microcode data file\n"); | ||
| 367 | break; | 361 | break; |
| 368 | } | 362 | } |
| 369 | 363 | ||
| @@ -405,9 +399,8 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
| 405 | vfree(uci->mc); | 399 | vfree(uci->mc); |
| 406 | uci->mc = (struct microcode_intel *)new_mc; | 400 | uci->mc = (struct microcode_intel *)new_mc; |
| 407 | 401 | ||
| 408 | pr_debug("microcode: CPU%d found a matching microcode update with" | 402 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
| 409 | " version 0x%x (current=0x%x)\n", | 403 | cpu, new_rev, uci->cpu_sig.rev); |
| 410 | cpu, new_rev, uci->cpu_sig.rev); | ||
| 411 | out: | 404 | out: |
| 412 | return state; | 405 | return state; |
| 413 | } | 406 | } |
| @@ -429,7 +422,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) | |||
| 429 | c->x86, c->x86_model, c->x86_mask); | 422 | c->x86, c->x86_model, c->x86_mask); |
| 430 | 423 | ||
| 431 | if (request_firmware(&firmware, name, device)) { | 424 | if (request_firmware(&firmware, name, device)) { |
| 432 | pr_debug("microcode: data file %s load failed\n", name); | 425 | pr_debug("data file %s load failed\n", name); |
| 433 | return UCODE_NFOUND; | 426 | return UCODE_NFOUND; |
| 434 | } | 427 | } |
| 435 | 428 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 5e2ba634ea15..7a7bd4e3ec49 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
| 11 | #include <linux/random.h> | 11 | #include <linux/random.h> |
| 12 | #include <linux/user-return-notifier.h> | 12 | #include <linux/user-return-notifier.h> |
| 13 | #include <linux/dmi.h> | ||
| 14 | #include <linux/utsname.h> | ||
| 13 | #include <trace/events/power.h> | 15 | #include <trace/events/power.h> |
| 14 | #include <linux/hw_breakpoint.h> | 16 | #include <linux/hw_breakpoint.h> |
| 15 | #include <asm/system.h> | 17 | #include <asm/system.h> |
| @@ -90,6 +92,25 @@ void exit_thread(void) | |||
| 90 | } | 92 | } |
| 91 | } | 93 | } |
| 92 | 94 | ||
| 95 | void show_regs_common(void) | ||
| 96 | { | ||
| 97 | const char *board, *product; | ||
| 98 | |||
| 99 | board = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 100 | if (!board) | ||
| 101 | board = ""; | ||
| 102 | product = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 103 | if (!product) | ||
| 104 | product = ""; | ||
| 105 | |||
| 106 | printk("\n"); | ||
| 107 | printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", | ||
| 108 | current->pid, current->comm, print_tainted(), | ||
| 109 | init_utsname()->release, | ||
| 110 | (int)strcspn(init_utsname()->version, " "), | ||
| 111 | init_utsname()->version, board, product); | ||
| 112 | } | ||
| 113 | |||
| 93 | void flush_thread(void) | 114 | void flush_thread(void) |
| 94 | { | 115 | { |
| 95 | struct task_struct *tsk = current; | 116 | struct task_struct *tsk = current; |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 075580b35682..120b88797a75 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
| 24 | #include <linux/user.h> | 24 | #include <linux/user.h> |
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/utsname.h> | ||
| 27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 28 | #include <linux/reboot.h> | 27 | #include <linux/reboot.h> |
| 29 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| @@ -35,7 +34,6 @@ | |||
| 35 | #include <linux/tick.h> | 34 | #include <linux/tick.h> |
| 36 | #include <linux/percpu.h> | 35 | #include <linux/percpu.h> |
| 37 | #include <linux/prctl.h> | 36 | #include <linux/prctl.h> |
| 38 | #include <linux/dmi.h> | ||
| 39 | #include <linux/ftrace.h> | 37 | #include <linux/ftrace.h> |
| 40 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
| 41 | #include <linux/io.h> | 39 | #include <linux/io.h> |
| @@ -128,7 +126,6 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 128 | unsigned long d0, d1, d2, d3, d6, d7; | 126 | unsigned long d0, d1, d2, d3, d6, d7; |
| 129 | unsigned long sp; | 127 | unsigned long sp; |
| 130 | unsigned short ss, gs; | 128 | unsigned short ss, gs; |
| 131 | const char *board; | ||
| 132 | 129 | ||
| 133 | if (user_mode_vm(regs)) { | 130 | if (user_mode_vm(regs)) { |
| 134 | sp = regs->sp; | 131 | sp = regs->sp; |
| @@ -140,16 +137,7 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 140 | savesegment(gs, gs); | 137 | savesegment(gs, gs); |
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | printk("\n"); | 140 | show_regs_common(); |
| 144 | |||
| 145 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 146 | if (!board) | ||
| 147 | board = ""; | ||
| 148 | printk("Pid: %d, comm: %s %s (%s %.*s) %s\n", | ||
| 149 | task_pid_nr(current), current->comm, | ||
| 150 | print_tainted(), init_utsname()->release, | ||
| 151 | (int)strcspn(init_utsname()->version, " "), | ||
| 152 | init_utsname()->version, board); | ||
| 153 | 141 | ||
| 154 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", | 142 | printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", |
| 155 | (u16)regs->cs, regs->ip, regs->flags, | 143 | (u16)regs->cs, regs->ip, regs->flags, |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c95c8f4e790a..e5ab0cd0ef36 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/user.h> | 27 | #include <linux/user.h> |
| 28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 29 | #include <linux/utsname.h> | ||
| 30 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 31 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 32 | #include <linux/ptrace.h> | 31 | #include <linux/ptrace.h> |
| @@ -38,7 +37,6 @@ | |||
| 38 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
| 39 | #include <linux/io.h> | 38 | #include <linux/io.h> |
| 40 | #include <linux/ftrace.h> | 39 | #include <linux/ftrace.h> |
| 41 | #include <linux/dmi.h> | ||
| 42 | 40 | ||
| 43 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
| 44 | #include <asm/system.h> | 42 | #include <asm/system.h> |
| @@ -163,18 +161,8 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 163 | unsigned long d0, d1, d2, d3, d6, d7; | 161 | unsigned long d0, d1, d2, d3, d6, d7; |
| 164 | unsigned int fsindex, gsindex; | 162 | unsigned int fsindex, gsindex; |
| 165 | unsigned int ds, cs, es; | 163 | unsigned int ds, cs, es; |
| 166 | const char *board; | 164 | |
| 167 | 165 | show_regs_common(); | |
| 168 | printk("\n"); | ||
| 169 | print_modules(); | ||
| 170 | board = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
| 171 | if (!board) | ||
| 172 | board = ""; | ||
| 173 | printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n", | ||
| 174 | current->pid, current->comm, print_tainted(), | ||
| 175 | init_utsname()->release, | ||
| 176 | (int)strcspn(init_utsname()->version, " "), | ||
| 177 | init_utsname()->version, board); | ||
| 178 | printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); | 166 | printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); |
| 179 | printk_address(regs->ip, 1); | 167 | printk_address(regs->ip, 1); |
| 180 | printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, | 168 | printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 2b97fc5b124e..1545bc0c9845 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
| @@ -259,6 +259,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
| 259 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), | 259 | DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), |
| 260 | }, | 260 | }, |
| 261 | }, | 261 | }, |
| 262 | { /* Handle problems with rebooting on ASUS P4S800 */ | ||
| 263 | .callback = set_bios_reboot, | ||
| 264 | .ident = "ASUS P4S800", | ||
| 265 | .matches = { | ||
| 266 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
| 267 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), | ||
| 268 | }, | ||
| 269 | }, | ||
| 262 | { } | 270 | { } |
| 263 | }; | 271 | }; |
| 264 | 272 | ||
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index d559af913e1f..35abcb8b00e9 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 2 | |||
| 1 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 2 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 3 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| @@ -20,9 +22,9 @@ | |||
| 20 | #include <asm/stackprotector.h> | 22 | #include <asm/stackprotector.h> |
| 21 | 23 | ||
| 22 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | 24 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
| 23 | # define DBG(x...) printk(KERN_DEBUG x) | 25 | # define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__) |
| 24 | #else | 26 | #else |
| 25 | # define DBG(x...) | 27 | # define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0) |
| 26 | #endif | 28 | #endif |
| 27 | 29 | ||
| 28 | DEFINE_PER_CPU(int, cpu_number); | 30 | DEFINE_PER_CPU(int, cpu_number); |
| @@ -116,8 +118,8 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
| 116 | } else { | 118 | } else { |
| 117 | ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), | 119 | ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), |
| 118 | size, align, goal); | 120 | size, align, goal); |
| 119 | pr_debug("per cpu data for cpu%d %lu bytes on node%d at " | 121 | pr_debug("per cpu data for cpu%d %lu bytes on node%d at %016lx\n", |
| 120 | "%016lx\n", cpu, size, node, __pa(ptr)); | 122 | cpu, size, node, __pa(ptr)); |
| 121 | } | 123 | } |
| 122 | return ptr; | 124 | return ptr; |
| 123 | #else | 125 | #else |
| @@ -198,8 +200,7 @@ void __init setup_per_cpu_areas(void) | |||
| 198 | pcpu_cpu_distance, | 200 | pcpu_cpu_distance, |
| 199 | pcpu_fc_alloc, pcpu_fc_free); | 201 | pcpu_fc_alloc, pcpu_fc_free); |
| 200 | if (rc < 0) | 202 | if (rc < 0) |
| 201 | pr_warning("PERCPU: %s allocator failed (%d), " | 203 | pr_warning("%s allocator failed (%d), falling back to page size\n", |
| 202 | "falling back to page size\n", | ||
| 203 | pcpu_fc_names[pcpu_chosen_fc], rc); | 204 | pcpu_fc_names[pcpu_chosen_fc], rc); |
| 204 | } | 205 | } |
| 205 | if (rc < 0) | 206 | if (rc < 0) |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index fab7440c9bb2..296aba49472a 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | * Based on QEMU and Xen. | 29 | * Based on QEMU and Xen. |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #define pr_fmt(fmt) "pit: " fmt | ||
| 33 | |||
| 32 | #include <linux/kvm_host.h> | 34 | #include <linux/kvm_host.h> |
| 33 | 35 | ||
| 34 | #include "irq.h" | 36 | #include "irq.h" |
| @@ -262,7 +264,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | |||
| 262 | 264 | ||
| 263 | static void destroy_pit_timer(struct kvm_timer *pt) | 265 | static void destroy_pit_timer(struct kvm_timer *pt) |
| 264 | { | 266 | { |
| 265 | pr_debug("pit: execute del timer!\n"); | 267 | pr_debug("execute del timer!\n"); |
| 266 | hrtimer_cancel(&pt->timer); | 268 | hrtimer_cancel(&pt->timer); |
| 267 | } | 269 | } |
| 268 | 270 | ||
| @@ -284,7 +286,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) | |||
| 284 | 286 | ||
| 285 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); | 287 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); |
| 286 | 288 | ||
| 287 | pr_debug("pit: create pit timer, interval is %llu nsec\n", interval); | 289 | pr_debug("create pit timer, interval is %llu nsec\n", interval); |
| 288 | 290 | ||
| 289 | /* TODO The new value only affected after the retriggered */ | 291 | /* TODO The new value only affected after the retriggered */ |
| 290 | hrtimer_cancel(&pt->timer); | 292 | hrtimer_cancel(&pt->timer); |
| @@ -309,7 +311,7 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) | |||
| 309 | 311 | ||
| 310 | WARN_ON(!mutex_is_locked(&ps->lock)); | 312 | WARN_ON(!mutex_is_locked(&ps->lock)); |
| 311 | 313 | ||
| 312 | pr_debug("pit: load_count val is %d, channel is %d\n", val, channel); | 314 | pr_debug("load_count val is %d, channel is %d\n", val, channel); |
| 313 | 315 | ||
| 314 | /* | 316 | /* |
| 315 | * The largest possible initial count is 0; this is equivalent | 317 | * The largest possible initial count is 0; this is equivalent |
| @@ -395,8 +397,8 @@ static int pit_ioport_write(struct kvm_io_device *this, | |||
| 395 | mutex_lock(&pit_state->lock); | 397 | mutex_lock(&pit_state->lock); |
| 396 | 398 | ||
| 397 | if (val != 0) | 399 | if (val != 0) |
| 398 | pr_debug("pit: write addr is 0x%x, len is %d, val is 0x%x\n", | 400 | pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n", |
| 399 | (unsigned int)addr, len, val); | 401 | (unsigned int)addr, len, val); |
| 400 | 402 | ||
| 401 | if (addr == 3) { | 403 | if (addr == 3) { |
| 402 | channel = val >> 6; | 404 | channel = val >> 6; |
diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 07bcc309cfda..c0f6198565eb 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * 2008 Pekka Paalanen <pq@iki.fi> | 5 | * 2008 Pekka Paalanen <pq@iki.fi> |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 9 | |||
| 8 | #include <linux/list.h> | 10 | #include <linux/list.h> |
| 9 | #include <linux/rculist.h> | 11 | #include <linux/rculist.h> |
| 10 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| @@ -136,7 +138,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 136 | pte_t *pte = lookup_address(f->page, &level); | 138 | pte_t *pte = lookup_address(f->page, &level); |
| 137 | 139 | ||
| 138 | if (!pte) { | 140 | if (!pte) { |
| 139 | pr_err("kmmio: no pte for page 0x%08lx\n", f->page); | 141 | pr_err("no pte for page 0x%08lx\n", f->page); |
| 140 | return -1; | 142 | return -1; |
| 141 | } | 143 | } |
| 142 | 144 | ||
| @@ -148,7 +150,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 148 | clear_pte_presence(pte, clear, &f->old_presence); | 150 | clear_pte_presence(pte, clear, &f->old_presence); |
| 149 | break; | 151 | break; |
| 150 | default: | 152 | default: |
| 151 | pr_err("kmmio: unexpected page level 0x%x.\n", level); | 153 | pr_err("unexpected page level 0x%x.\n", level); |
| 152 | return -1; | 154 | return -1; |
| 153 | } | 155 | } |
| 154 | 156 | ||
| @@ -170,13 +172,14 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) | |||
| 170 | static int arm_kmmio_fault_page(struct kmmio_fault_page *f) | 172 | static int arm_kmmio_fault_page(struct kmmio_fault_page *f) |
| 171 | { | 173 | { |
| 172 | int ret; | 174 | int ret; |
| 173 | WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n"); | 175 | WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n")); |
| 174 | if (f->armed) { | 176 | if (f->armed) { |
| 175 | pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n", | 177 | pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n", |
| 176 | f->page, f->count, !!f->old_presence); | 178 | f->page, f->count, !!f->old_presence); |
| 177 | } | 179 | } |
| 178 | ret = clear_page_presence(f, true); | 180 | ret = clear_page_presence(f, true); |
| 179 | WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page); | 181 | WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"), |
| 182 | f->page); | ||
| 180 | f->armed = true; | 183 | f->armed = true; |
| 181 | return ret; | 184 | return ret; |
| 182 | } | 185 | } |
| @@ -240,24 +243,21 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) | |||
| 240 | * condition needs handling by do_page_fault(), the | 243 | * condition needs handling by do_page_fault(), the |
| 241 | * page really not being present is the most common. | 244 | * page really not being present is the most common. |
| 242 | */ | 245 | */ |
| 243 | pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n", | 246 | pr_debug("secondary hit for 0x%08lx CPU %d.\n", |
| 244 | addr, smp_processor_id()); | 247 | addr, smp_processor_id()); |
| 245 | 248 | ||
| 246 | if (!faultpage->old_presence) | 249 | if (!faultpage->old_presence) |
| 247 | pr_info("kmmio: unexpected secondary hit for " | 250 | pr_info("unexpected secondary hit for address 0x%08lx on CPU %d.\n", |
| 248 | "address 0x%08lx on CPU %d.\n", addr, | 251 | addr, smp_processor_id()); |
| 249 | smp_processor_id()); | ||
| 250 | } else { | 252 | } else { |
| 251 | /* | 253 | /* |
| 252 | * Prevent overwriting already in-flight context. | 254 | * Prevent overwriting already in-flight context. |
| 253 | * This should not happen, let's hope disarming at | 255 | * This should not happen, let's hope disarming at |
| 254 | * least prevents a panic. | 256 | * least prevents a panic. |
| 255 | */ | 257 | */ |
| 256 | pr_emerg("kmmio: recursive probe hit on CPU %d, " | 258 | pr_emerg("recursive probe hit on CPU %d, for address 0x%08lx. Ignoring.\n", |
| 257 | "for address 0x%08lx. Ignoring.\n", | 259 | smp_processor_id(), addr); |
| 258 | smp_processor_id(), addr); | 260 | pr_emerg("previous hit was at 0x%08lx.\n", ctx->addr); |
| 259 | pr_emerg("kmmio: previous hit was at 0x%08lx.\n", | ||
| 260 | ctx->addr); | ||
| 261 | disarm_kmmio_fault_page(faultpage); | 261 | disarm_kmmio_fault_page(faultpage); |
| 262 | } | 262 | } |
| 263 | goto no_kmmio_ctx; | 263 | goto no_kmmio_ctx; |
| @@ -316,8 +316,8 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) | |||
| 316 | * something external causing them (f.e. using a debugger while | 316 | * something external causing them (f.e. using a debugger while |
| 317 | * mmio tracing enabled), or erroneous behaviour | 317 | * mmio tracing enabled), or erroneous behaviour |
| 318 | */ | 318 | */ |
| 319 | pr_warning("kmmio: unexpected debug trap on CPU %d.\n", | 319 | pr_warning("unexpected debug trap on CPU %d.\n", |
| 320 | smp_processor_id()); | 320 | smp_processor_id()); |
| 321 | goto out; | 321 | goto out; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| @@ -425,7 +425,7 @@ int register_kmmio_probe(struct kmmio_probe *p) | |||
| 425 | list_add_rcu(&p->list, &kmmio_probes); | 425 | list_add_rcu(&p->list, &kmmio_probes); |
| 426 | while (size < size_lim) { | 426 | while (size < size_lim) { |
| 427 | if (add_kmmio_fault_page(p->addr + size)) | 427 | if (add_kmmio_fault_page(p->addr + size)) |
| 428 | pr_err("kmmio: Unable to set page fault.\n"); | 428 | pr_err("Unable to set page fault.\n"); |
| 429 | size += PAGE_SIZE; | 429 | size += PAGE_SIZE; |
| 430 | } | 430 | } |
| 431 | out: | 431 | out: |
| @@ -490,7 +490,7 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) | |||
| 490 | * 2. remove_kmmio_fault_pages() | 490 | * 2. remove_kmmio_fault_pages() |
| 491 | * Remove the pages from kmmio_page_table. | 491 | * Remove the pages from kmmio_page_table. |
| 492 | * 3. rcu_free_kmmio_fault_pages() | 492 | * 3. rcu_free_kmmio_fault_pages() |
| 493 | * Actally free the kmmio_fault_page structs as with RCU. | 493 | * Actually free the kmmio_fault_page structs as with RCU. |
| 494 | */ | 494 | */ |
| 495 | void unregister_kmmio_probe(struct kmmio_probe *p) | 495 | void unregister_kmmio_probe(struct kmmio_probe *p) |
| 496 | { | 496 | { |
| @@ -511,7 +511,7 @@ void unregister_kmmio_probe(struct kmmio_probe *p) | |||
| 511 | 511 | ||
| 512 | drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); | 512 | drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); |
| 513 | if (!drelease) { | 513 | if (!drelease) { |
| 514 | pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); | 514 | pr_crit("leaking kmmio_fault_page objects.\n"); |
| 515 | return; | 515 | return; |
| 516 | } | 516 | } |
| 517 | drelease->release_list = release_list; | 517 | drelease->release_list = release_list; |
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index 132772a8ec57..4c765e9c4664 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c | |||
| @@ -19,6 +19,9 @@ | |||
| 19 | * | 19 | * |
| 20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. | 20 | * Derived from the read-mod example from relay-examples by Tom Zanussi. |
| 21 | */ | 21 | */ |
| 22 | |||
| 23 | #define pr_fmt(fmt) "mmiotrace: " | ||
| 24 | |||
| 22 | #define DEBUG 1 | 25 | #define DEBUG 1 |
| 23 | 26 | ||
| 24 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| @@ -36,8 +39,6 @@ | |||
| 36 | 39 | ||
| 37 | #include "pf_in.h" | 40 | #include "pf_in.h" |
| 38 | 41 | ||
| 39 | #define NAME "mmiotrace: " | ||
| 40 | |||
| 41 | struct trap_reason { | 42 | struct trap_reason { |
| 42 | unsigned long addr; | 43 | unsigned long addr; |
| 43 | unsigned long ip; | 44 | unsigned long ip; |
| @@ -96,17 +97,18 @@ static void print_pte(unsigned long address) | |||
| 96 | pte_t *pte = lookup_address(address, &level); | 97 | pte_t *pte = lookup_address(address, &level); |
| 97 | 98 | ||
| 98 | if (!pte) { | 99 | if (!pte) { |
| 99 | pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", | 100 | pr_err("Error in %s: no pte for page 0x%08lx\n", |
| 100 | __func__, address); | 101 | __func__, address); |
| 101 | return; | 102 | return; |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | if (level == PG_LEVEL_2M) { | 105 | if (level == PG_LEVEL_2M) { |
| 105 | pr_emerg(NAME "4MB pages are not currently supported: " | 106 | pr_emerg("4MB pages are not currently supported: 0x%08lx\n", |
| 106 | "0x%08lx\n", address); | 107 | address); |
| 107 | BUG(); | 108 | BUG(); |
| 108 | } | 109 | } |
| 109 | pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address, | 110 | pr_info("pte for 0x%lx: 0x%llx 0x%llx\n", |
| 111 | address, | ||
| 110 | (unsigned long long)pte_val(*pte), | 112 | (unsigned long long)pte_val(*pte), |
| 111 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); | 113 | (unsigned long long)pte_val(*pte) & _PAGE_PRESENT); |
| 112 | } | 114 | } |
| @@ -118,22 +120,21 @@ static void print_pte(unsigned long address) | |||
| 118 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) | 120 | static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) |
| 119 | { | 121 | { |
| 120 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); | 122 | const struct trap_reason *my_reason = &get_cpu_var(pf_reason); |
| 121 | pr_emerg(NAME "unexpected fault for address: 0x%08lx, " | 123 | pr_emerg("unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n", |
| 122 | "last fault for address: 0x%08lx\n", | 124 | addr, my_reason->addr); |
| 123 | addr, my_reason->addr); | ||
| 124 | print_pte(addr); | 125 | print_pte(addr); |
| 125 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); | 126 | print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); |
| 126 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); | 127 | print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); |
| 127 | #ifdef __i386__ | 128 | #ifdef __i386__ |
| 128 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | 129 | pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", |
| 129 | regs->ax, regs->bx, regs->cx, regs->dx); | 130 | regs->ax, regs->bx, regs->cx, regs->dx); |
| 130 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", | 131 | pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", |
| 131 | regs->si, regs->di, regs->bp, regs->sp); | 132 | regs->si, regs->di, regs->bp, regs->sp); |
| 132 | #else | 133 | #else |
| 133 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", | 134 | pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", |
| 134 | regs->ax, regs->cx, regs->dx); | 135 | regs->ax, regs->cx, regs->dx); |
| 135 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", | 136 | pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", |
| 136 | regs->si, regs->di, regs->bp, regs->sp); | 137 | regs->si, regs->di, regs->bp, regs->sp); |
| 137 | #endif | 138 | #endif |
| 138 | put_cpu_var(pf_reason); | 139 | put_cpu_var(pf_reason); |
| 139 | BUG(); | 140 | BUG(); |
| @@ -213,7 +214,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, | |||
| 213 | /* this should always return the active_trace count to 0 */ | 214 | /* this should always return the active_trace count to 0 */ |
| 214 | my_reason->active_traces--; | 215 | my_reason->active_traces--; |
| 215 | if (my_reason->active_traces) { | 216 | if (my_reason->active_traces) { |
| 216 | pr_emerg(NAME "unexpected post handler"); | 217 | pr_emerg("unexpected post handler"); |
| 217 | BUG(); | 218 | BUG(); |
| 218 | } | 219 | } |
| 219 | 220 | ||
| @@ -244,7 +245,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, | |||
| 244 | }; | 245 | }; |
| 245 | 246 | ||
| 246 | if (!trace) { | 247 | if (!trace) { |
| 247 | pr_err(NAME "kmalloc failed in ioremap\n"); | 248 | pr_err("kmalloc failed in ioremap\n"); |
| 248 | return; | 249 | return; |
| 249 | } | 250 | } |
| 250 | 251 | ||
| @@ -282,8 +283,8 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long size, | |||
| 282 | if (!is_enabled()) /* recheck and proper locking in *_core() */ | 283 | if (!is_enabled()) /* recheck and proper locking in *_core() */ |
| 283 | return; | 284 | return; |
| 284 | 285 | ||
| 285 | pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n", | 286 | pr_debug("ioremap_*(0x%llx, 0x%lx) = %p\n", |
| 286 | (unsigned long long)offset, size, addr); | 287 | (unsigned long long)offset, size, addr); |
| 287 | if ((filter_offset) && (offset != filter_offset)) | 288 | if ((filter_offset) && (offset != filter_offset)) |
| 288 | return; | 289 | return; |
| 289 | ioremap_trace_core(offset, size, addr); | 290 | ioremap_trace_core(offset, size, addr); |
| @@ -301,7 +302,7 @@ static void iounmap_trace_core(volatile void __iomem *addr) | |||
| 301 | struct remap_trace *tmp; | 302 | struct remap_trace *tmp; |
| 302 | struct remap_trace *found_trace = NULL; | 303 | struct remap_trace *found_trace = NULL; |
| 303 | 304 | ||
| 304 | pr_debug(NAME "Unmapping %p.\n", addr); | 305 | pr_debug("Unmapping %p.\n", addr); |
| 305 | 306 | ||
| 306 | spin_lock_irq(&trace_lock); | 307 | spin_lock_irq(&trace_lock); |
| 307 | if (!is_enabled()) | 308 | if (!is_enabled()) |
| @@ -363,9 +364,8 @@ static void clear_trace_list(void) | |||
| 363 | * Caller also ensures is_enabled() cannot change. | 364 | * Caller also ensures is_enabled() cannot change. |
| 364 | */ | 365 | */ |
| 365 | list_for_each_entry(trace, &trace_list, list) { | 366 | list_for_each_entry(trace, &trace_list, list) { |
| 366 | pr_notice(NAME "purging non-iounmapped " | 367 | pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n", |
| 367 | "trace @0x%08lx, size 0x%lx.\n", | 368 | trace->probe.addr, trace->probe.len); |
| 368 | trace->probe.addr, trace->probe.len); | ||
| 369 | if (!nommiotrace) | 369 | if (!nommiotrace) |
| 370 | unregister_kmmio_probe(&trace->probe); | 370 | unregister_kmmio_probe(&trace->probe); |
| 371 | } | 371 | } |
| @@ -387,7 +387,7 @@ static void enter_uniprocessor(void) | |||
| 387 | 387 | ||
| 388 | if (downed_cpus == NULL && | 388 | if (downed_cpus == NULL && |
| 389 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { | 389 | !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { |
| 390 | pr_notice(NAME "Failed to allocate mask\n"); | 390 | pr_notice("Failed to allocate mask\n"); |
| 391 | goto out; | 391 | goto out; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| @@ -395,20 +395,19 @@ static void enter_uniprocessor(void) | |||
| 395 | cpumask_copy(downed_cpus, cpu_online_mask); | 395 | cpumask_copy(downed_cpus, cpu_online_mask); |
| 396 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); | 396 | cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); |
| 397 | if (num_online_cpus() > 1) | 397 | if (num_online_cpus() > 1) |
| 398 | pr_notice(NAME "Disabling non-boot CPUs...\n"); | 398 | pr_notice("Disabling non-boot CPUs...\n"); |
| 399 | put_online_cpus(); | 399 | put_online_cpus(); |
| 400 | 400 | ||
| 401 | for_each_cpu(cpu, downed_cpus) { | 401 | for_each_cpu(cpu, downed_cpus) { |
| 402 | err = cpu_down(cpu); | 402 | err = cpu_down(cpu); |
| 403 | if (!err) | 403 | if (!err) |
| 404 | pr_info(NAME "CPU%d is down.\n", cpu); | 404 | pr_info("CPU%d is down.\n", cpu); |
| 405 | else | 405 | else |
| 406 | pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); | 406 | pr_err("Error taking CPU%d down: %d\n", cpu, err); |
| 407 | } | 407 | } |
| 408 | out: | 408 | out: |
| 409 | if (num_online_cpus() > 1) | 409 | if (num_online_cpus() > 1) |
| 410 | pr_warning(NAME "multiple CPUs still online, " | 410 | pr_warning("multiple CPUs still online, may miss events.\n"); |
| 411 | "may miss events.\n"); | ||
| 412 | } | 411 | } |
| 413 | 412 | ||
| 414 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, | 413 | /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, |
| @@ -420,13 +419,13 @@ static void __ref leave_uniprocessor(void) | |||
| 420 | 419 | ||
| 421 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) | 420 | if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) |
| 422 | return; | 421 | return; |
| 423 | pr_notice(NAME "Re-enabling CPUs...\n"); | 422 | pr_notice("Re-enabling CPUs...\n"); |
| 424 | for_each_cpu(cpu, downed_cpus) { | 423 | for_each_cpu(cpu, downed_cpus) { |
| 425 | err = cpu_up(cpu); | 424 | err = cpu_up(cpu); |
| 426 | if (!err) | 425 | if (!err) |
| 427 | pr_info(NAME "enabled CPU%d.\n", cpu); | 426 | pr_info("enabled CPU%d.\n", cpu); |
| 428 | else | 427 | else |
| 429 | pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err); | 428 | pr_err("cannot re-enable CPU%d: %d\n", cpu, err); |
| 430 | } | 429 | } |
| 431 | } | 430 | } |
| 432 | 431 | ||
| @@ -434,8 +433,8 @@ static void __ref leave_uniprocessor(void) | |||
| 434 | static void enter_uniprocessor(void) | 433 | static void enter_uniprocessor(void) |
| 435 | { | 434 | { |
| 436 | if (num_online_cpus() > 1) | 435 | if (num_online_cpus() > 1) |
| 437 | pr_warning(NAME "multiple CPUs are online, may miss events. " | 436 | pr_warning("multiple CPUs are online, may miss events. " |
| 438 | "Suggest booting with maxcpus=1 kernel argument.\n"); | 437 | "Suggest booting with maxcpus=1 kernel argument.\n"); |
| 439 | } | 438 | } |
| 440 | 439 | ||
| 441 | static void leave_uniprocessor(void) | 440 | static void leave_uniprocessor(void) |
| @@ -450,13 +449,13 @@ void enable_mmiotrace(void) | |||
| 450 | goto out; | 449 | goto out; |
| 451 | 450 | ||
| 452 | if (nommiotrace) | 451 | if (nommiotrace) |
| 453 | pr_info(NAME "MMIO tracing disabled.\n"); | 452 | pr_info("MMIO tracing disabled.\n"); |
| 454 | kmmio_init(); | 453 | kmmio_init(); |
| 455 | enter_uniprocessor(); | 454 | enter_uniprocessor(); |
| 456 | spin_lock_irq(&trace_lock); | 455 | spin_lock_irq(&trace_lock); |
| 457 | atomic_inc(&mmiotrace_enabled); | 456 | atomic_inc(&mmiotrace_enabled); |
| 458 | spin_unlock_irq(&trace_lock); | 457 | spin_unlock_irq(&trace_lock); |
| 459 | pr_info(NAME "enabled.\n"); | 458 | pr_info("enabled.\n"); |
| 460 | out: | 459 | out: |
| 461 | mutex_unlock(&mmiotrace_mutex); | 460 | mutex_unlock(&mmiotrace_mutex); |
| 462 | } | 461 | } |
| @@ -475,7 +474,7 @@ void disable_mmiotrace(void) | |||
| 475 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ | 474 | clear_trace_list(); /* guarantees: no more kmmio callbacks */ |
| 476 | leave_uniprocessor(); | 475 | leave_uniprocessor(); |
| 477 | kmmio_cleanup(); | 476 | kmmio_cleanup(); |
| 478 | pr_info(NAME "disabled.\n"); | 477 | pr_info("disabled.\n"); |
| 479 | out: | 478 | out: |
| 480 | mutex_unlock(&mmiotrace_mutex); | 479 | mutex_unlock(&mmiotrace_mutex); |
| 481 | } | 480 | } |
