Commit 75630098 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'x86-fixes-for-linus' of...

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
parents df7147b3 9cf78267
...@@ -28,7 +28,9 @@ extern void amd_iommu_flush_all_domains(void); ...@@ -28,7 +28,9 @@ extern void amd_iommu_flush_all_domains(void);
extern void amd_iommu_flush_all_devices(void); extern void amd_iommu_flush_all_devices(void);
extern void amd_iommu_apply_erratum_63(u16 devid); extern void amd_iommu_apply_erratum_63(u16 devid);
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu); extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
extern int amd_iommu_init_devices(void);
extern void amd_iommu_uninit_devices(void);
extern void amd_iommu_init_notifier(void);
#ifndef CONFIG_AMD_IOMMU_STATS #ifndef CONFIG_AMD_IOMMU_STATS
static inline void amd_iommu_stats_init(void) { } static inline void amd_iommu_stats_init(void) { }
......
...@@ -23,6 +23,7 @@ struct task_struct *__switch_to(struct task_struct *prev, ...@@ -23,6 +23,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
struct tss_struct; struct tss_struct;
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
struct tss_struct *tss); struct tss_struct *tss);
extern void show_regs_common(void);
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
...@@ -166,6 +166,43 @@ static void iommu_uninit_device(struct device *dev) ...@@ -166,6 +166,43 @@ static void iommu_uninit_device(struct device *dev)
{ {
kfree(dev->archdata.iommu); kfree(dev->archdata.iommu);
} }
void __init amd_iommu_uninit_devices(void)
{
struct pci_dev *pdev = NULL;
for_each_pci_dev(pdev) {
if (!check_device(&pdev->dev))
continue;
iommu_uninit_device(&pdev->dev);
}
}
int __init amd_iommu_init_devices(void)
{
struct pci_dev *pdev = NULL;
int ret = 0;
for_each_pci_dev(pdev) {
if (!check_device(&pdev->dev))
continue;
ret = iommu_init_device(&pdev->dev);
if (ret)
goto out_free;
}
return 0;
out_free:
amd_iommu_uninit_devices();
return ret;
}
#ifdef CONFIG_AMD_IOMMU_STATS #ifdef CONFIG_AMD_IOMMU_STATS
/* /*
...@@ -1587,6 +1624,11 @@ static struct notifier_block device_nb = { ...@@ -1587,6 +1624,11 @@ static struct notifier_block device_nb = {
.notifier_call = device_change_notifier, .notifier_call = device_change_notifier,
}; };
void amd_iommu_init_notifier(void)
{
bus_register_notifier(&pci_bus_type, &device_nb);
}
/***************************************************************************** /*****************************************************************************
* *
* The next functions belong to the dma_ops mapping/unmapping code. * The next functions belong to the dma_ops mapping/unmapping code.
...@@ -2145,8 +2187,6 @@ static void prealloc_protection_domains(void) ...@@ -2145,8 +2187,6 @@ static void prealloc_protection_domains(void)
if (!check_device(&dev->dev)) if (!check_device(&dev->dev))
continue; continue;
iommu_init_device(&dev->dev);
/* Is there already any domain for it? */ /* Is there already any domain for it? */
if (domain_for_device(&dev->dev)) if (domain_for_device(&dev->dev))
continue; continue;
...@@ -2215,8 +2255,6 @@ int __init amd_iommu_init_dma_ops(void) ...@@ -2215,8 +2255,6 @@ int __init amd_iommu_init_dma_ops(void)
register_iommu(&amd_iommu_ops); register_iommu(&amd_iommu_ops);
bus_register_notifier(&pci_bus_type, &device_nb);
amd_iommu_stats_init(); amd_iommu_stats_init();
return 0; return 0;
......
...@@ -1274,6 +1274,10 @@ static int __init amd_iommu_init(void) ...@@ -1274,6 +1274,10 @@ static int __init amd_iommu_init(void)
if (ret) if (ret)
goto free; goto free;
ret = amd_iommu_init_devices();
if (ret)
goto free;
if (iommu_pass_through) if (iommu_pass_through)
ret = amd_iommu_init_passthrough(); ret = amd_iommu_init_passthrough();
else else
...@@ -1281,6 +1285,8 @@ static int __init amd_iommu_init(void) ...@@ -1281,6 +1285,8 @@ static int __init amd_iommu_init(void)
if (ret) if (ret)
goto free; goto free;
amd_iommu_init_notifier();
enable_iommus(); enable_iommus();
if (iommu_pass_through) if (iommu_pass_through)
...@@ -1296,6 +1302,9 @@ static int __init amd_iommu_init(void) ...@@ -1296,6 +1302,9 @@ static int __init amd_iommu_init(void)
return ret; return ret;
free: free:
amd_iommu_uninit_devices();
free_pages((unsigned long)amd_iommu_pd_alloc_bitmap, free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
get_order(MAX_DOMAIN_ID/8)); get_order(MAX_DOMAIN_ID/8));
......
...@@ -127,7 +127,7 @@ static u32 noop_apic_read(u32 reg) ...@@ -127,7 +127,7 @@ static u32 noop_apic_read(u32 reg)
static void noop_apic_write(u32 reg, u32 v) static void noop_apic_write(u32 reg, u32 v)
{ {
WARN_ON_ONCE((cpu_has_apic || !disable_apic)); WARN_ON_ONCE(cpu_has_apic && !disable_apic);
} }
struct apic apic_noop = { struct apic apic_noop = {
......
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
* *
* http://www.unisys.com * http://www.unisys.com
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
...@@ -223,9 +226,9 @@ static int parse_unisys_oem(char *oemptr) ...@@ -223,9 +226,9 @@ static int parse_unisys_oem(char *oemptr)
mip_addr = val; mip_addr = val;
mip = (struct mip_reg *)val; mip = (struct mip_reg *)val;
mip_reg = __va(mip); mip_reg = __va(mip);
pr_debug("es7000_mipcfg: host_reg = 0x%lx \n", pr_debug("host_reg = 0x%lx\n",
(unsigned long)host_reg); (unsigned long)host_reg);
pr_debug("es7000_mipcfg: mip_reg = 0x%lx \n", pr_debug("mip_reg = 0x%lx\n",
(unsigned long)mip_reg); (unsigned long)mip_reg);
success++; success++;
break; break;
...@@ -401,7 +404,7 @@ static void es7000_enable_apic_mode(void) ...@@ -401,7 +404,7 @@ static void es7000_enable_apic_mode(void)
if (!es7000_plat) if (!es7000_plat)
return; return;
printk(KERN_INFO "ES7000: Enabling APIC mode.\n"); pr_info("Enabling APIC mode.\n");
memset(&es7000_mip_reg, 0, sizeof(struct mip_reg)); memset(&es7000_mip_reg, 0, sizeof(struct mip_reg));
es7000_mip_reg.off_0x00 = MIP_SW_APIC; es7000_mip_reg.off_0x00 = MIP_SW_APIC;
es7000_mip_reg.off_0x38 = MIP_VALID; es7000_mip_reg.off_0x38 = MIP_VALID;
...@@ -514,8 +517,7 @@ static void es7000_setup_apic_routing(void) ...@@ -514,8 +517,7 @@ static void es7000_setup_apic_routing(void)
{ {
int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id()); int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
printk(KERN_INFO pr_info("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
"Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
(apic_version[apic] == 0x14) ? (apic_version[apic] == 0x14) ?
"Physical Cluster" : "Logical Cluster", "Physical Cluster" : "Logical Cluster",
nr_ioapics, cpumask_bits(es7000_target_cpus())[0]); nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
......
...@@ -1388,13 +1388,14 @@ static void __mcheck_cpu_init_timer(void) ...@@ -1388,13 +1388,14 @@ static void __mcheck_cpu_init_timer(void)
struct timer_list *t = &__get_cpu_var(mce_timer); struct timer_list *t = &__get_cpu_var(mce_timer);
int *n = &__get_cpu_var(mce_next_interval); int *n = &__get_cpu_var(mce_next_interval);
setup_timer(t, mce_start_timer, smp_processor_id());
if (mce_ignore_ce) if (mce_ignore_ce)
return; return;
*n = check_interval * HZ; *n = check_interval * HZ;
if (!*n) if (!*n)
return; return;
setup_timer(t, mce_start_timer, smp_processor_id());
t->expires = round_jiffies(jiffies + *n); t->expires = round_jiffies(jiffies + *n);
add_timer_on(t, smp_processor_id()); add_timer_on(t, smp_processor_id());
} }
...@@ -1928,7 +1929,7 @@ static __cpuinit int mce_create_device(unsigned int cpu) ...@@ -1928,7 +1929,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr); sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr);
error: error:
while (--i >= 0) while (--i >= 0)
sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr); sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
sysdev_unregister(&per_cpu(mce_dev, cpu)); sysdev_unregister(&per_cpu(mce_dev, cpu));
......
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
* Licensed under the terms of the GNU General Public * Licensed under the terms of the GNU General Public
* License version 2. See file COPYING for details. * License version 2. See file COPYING for details.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -81,7 +84,7 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) ...@@ -81,7 +84,7 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
memset(csig, 0, sizeof(*csig)); memset(csig, 0, sizeof(*csig));
rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
pr_info("microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev); pr_info("CPU%d: patch_level=0x%x\n", cpu, csig->rev);
return 0; return 0;
} }
...@@ -111,8 +114,8 @@ static int get_matching_microcode(int cpu, void *mc, int rev) ...@@ -111,8 +114,8 @@ static int get_matching_microcode(int cpu, void *mc, int rev)
/* ucode might be chipset specific -- currently we don't support this */ /* ucode might be chipset specific -- currently we don't support this */
if (mc_header->nb_dev_id || mc_header->sb_dev_id) { if (mc_header->nb_dev_id || mc_header->sb_dev_id) {
pr_err(KERN_ERR "microcode: CPU%d: loading of chipset " pr_err("CPU%d: loading of chipset specific code not yet supported\n",
"specific code not yet supported\n", cpu); cpu);
return 0; return 0;
} }
...@@ -141,12 +144,12 @@ static int apply_microcode_amd(int cpu) ...@@ -141,12 +144,12 @@ static int apply_microcode_amd(int cpu)
/* check current patch id and patch's id for match */ /* check current patch id and patch's id for match */
if (rev != mc_amd->hdr.patch_id) { if (rev != mc_amd->hdr.patch_id) {
pr_err("microcode: CPU%d: update failed " pr_err("CPU%d: update failed (for patch_level=0x%x)\n",
"(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id); cpu, mc_amd->hdr.patch_id);
return -1; return -1;
} }
pr_info("microcode: CPU%d: updated (new patch_level=0x%x)\n", cpu, rev); pr_info("CPU%d: updated (new patch_level=0x%x)\n", cpu, rev);
uci->cpu_sig.rev = rev; uci->cpu_sig.rev = rev;
return 0; return 0;
...@@ -169,15 +172,14 @@ get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size) ...@@ -169,15 +172,14 @@ get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
return NULL; return NULL;
if (section_hdr[0] != UCODE_UCODE_TYPE) { if (section_hdr[0] != UCODE_UCODE_TYPE) {
pr_err("microcode: error: invalid type field in " pr_err("error: invalid type field in container file section header\n");
"container file section header\n");
return NULL; return NULL;
} }
total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
if (total_size > size || total_size > UCODE_MAX_SIZE) { if (total_size > size || total_size > UCODE_MAX_SIZE) {
pr_err("microcode: error: size mismatch\n"); pr_err("error: size mismatch\n");
return NULL; return NULL;
} }
...@@ -206,14 +208,13 @@ static int install_equiv_cpu_table(const u8 *buf) ...@@ -206,14 +208,13 @@ static int install_equiv_cpu_table(const u8 *buf)
size = buf_pos[2]; size = buf_pos[2];
if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {
pr_err("microcode: error: invalid type field in " pr_err("error: invalid type field in container file section header\n");
"container file section header\n");
return 0; return 0;
} }
equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
if (!equiv_cpu_table) { if (!equiv_cpu_table) {
pr_err("microcode: failed to allocate equivalent CPU table\n"); pr_err("failed to allocate equivalent CPU table\n");
return 0; return 0;
} }
...@@ -246,7 +247,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) ...@@ -246,7 +247,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size)
offset = install_equiv_cpu_table(ucode_ptr); offset = install_equiv_cpu_table(ucode_ptr);
if (!offset) { if (!offset) {
pr_err("microcode: failed to create equivalent cpu table\n"); pr_err("failed to create equivalent cpu table\n");
return UCODE_ERROR; return UCODE_ERROR;
} }
...@@ -277,8 +278,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size) ...@@ -277,8 +278,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size)
if (!leftover) { if (!leftover) {
vfree(uci->mc); vfree(uci->mc);
uci->mc = new_mc; uci->mc = new_mc;
pr_debug("microcode: CPU%d found a matching microcode " pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
"update with version 0x%x (current=0x%x)\n",
cpu, new_rev, uci->cpu_sig.rev); cpu, new_rev, uci->cpu_sig.rev);
} else { } else {
vfree(new_mc); vfree(new_mc);
...@@ -300,7 +300,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) ...@@ -300,7 +300,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device)
return UCODE_NFOUND; return UCODE_NFOUND;
if (*(u32 *)firmware->data != UCODE_MAGIC) { if (*(u32 *)firmware->data != UCODE_MAGIC) {
pr_err("microcode: invalid UCODE_MAGIC (0x%08x)\n", pr_err("invalid UCODE_MAGIC (0x%08x)\n",
*(u32 *)firmware->data); *(u32 *)firmware->data);
return UCODE_ERROR; return UCODE_ERROR;
} }
...@@ -313,8 +313,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) ...@@ -313,8 +313,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device)
static enum ucode_state static enum ucode_state
request_microcode_user(int cpu, const void __user *buf, size_t size) request_microcode_user(int cpu, const void __user *buf, size_t size)
{ {
pr_info("microcode: AMD microcode update via " pr_info("AMD microcode update via /dev/cpu/microcode not supported\n");
"/dev/cpu/microcode not supported\n");
return UCODE_ERROR; return UCODE_ERROR;
} }
...@@ -334,14 +333,13 @@ void init_microcode_amd(struct device *device) ...@@ -334,14 +333,13 @@ void init_microcode_amd(struct device *device)
WARN_ON(c->x86_vendor != X86_VENDOR_AMD); WARN_ON(c->x86_vendor != X86_VENDOR_AMD);
if (c->x86 < 0x10) { if (c->x86 < 0x10) {
pr_warning("microcode: AMD CPU family 0x%x not supported\n", pr_warning("AMD CPU family 0x%x not supported\n", c->x86);
c->x86);
return; return;
} }
supported_cpu = 1; supported_cpu = 1;
if (request_firmware(&firmware, fw_name, device)) if (request_firmware(&firmware, fw_name, device))
pr_err("microcode: failed to load file %s\n", fw_name); pr_err("failed to load file %s\n", fw_name);
} }
void fini_microcode_amd(void) void fini_microcode_amd(void)
......
...@@ -70,6 +70,9 @@ ...@@ -70,6 +70,9 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0. * Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug. * Thanks to Stuart Swales for pointing out this bug.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/capability.h> #include <linux/capability.h>
...@@ -209,7 +212,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf, ...@@ -209,7 +212,7 @@ static ssize_t microcode_write(struct file *file, const char __user *buf,
ssize_t ret = -EINVAL; ssize_t ret = -EINVAL;
if ((len >> PAGE_SHIFT) > totalram_pages) { if ((len >> PAGE_SHIFT) > totalram_pages) {
pr_err("microcode: too much data (max %ld pages)\n", totalram_pages); pr_err("too much data (max %ld pages)\n", totalram_pages);
return ret; return ret;
} }
...@@ -244,7 +247,7 @@ static int __init microcode_dev_init(void) ...@@ -244,7 +247,7 @@ static int __init microcode_dev_init(void)
error = misc_register(&microcode_dev); error = misc_register(&microcode_dev);
if (error) { if (error) {
pr_err("microcode: can't misc_register on minor=%d\n", MICROCODE_MINOR); pr_err("can't misc_register on minor=%d\n", MICROCODE_MINOR);
return error; return error;
} }
...@@ -359,7 +362,7 @@ static enum ucode_state microcode_resume_cpu(int cpu) ...@@ -359,7 +362,7 @@ static enum ucode_state microcode_resume_cpu(int cpu)
if (!uci->mc) if (!uci->mc)
return UCODE_NFOUND; return UCODE_NFOUND;
pr_debug("microcode: CPU%d updated upon resume\n", cpu); pr_debug("CPU%d updated upon resume\n", cpu);
apply_microcode_on_target(cpu); apply_microcode_on_target(cpu);
return UCODE_OK; return UCODE_OK;
...@@ -379,7 +382,7 @@ static enum ucode_state microcode_init_cpu(int cpu) ...@@ -379,7 +382,7 @@ static enum ucode_state microcode_init_cpu(int cpu)
ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev); ustate = microcode_ops->request_microcode_fw(cpu, &microcode_pdev->dev);
if (ustate == UCODE_OK) { if (ustate == UCODE_OK) {
pr_debug("microcode: CPU%d updated upon init\n", cpu); pr_debug("CPU%d updated upon init\n", cpu);
apply_microcode_on_target(cpu); apply_microcode_on_target(cpu);
} }
...@@ -406,7 +409,7 @@ static int mc_sysdev_add(struct sys_device *sys_dev) ...@@ -406,7 +409,7 @@ static int mc_sysdev_add(struct sys_device *sys_dev)
if (!cpu_online(cpu)) if (!cpu_online(cpu))
return 0; return 0;
pr_debug("microcode: CPU%d added\n", cpu); pr_debug("CPU%d added\n", cpu);
err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
if (err) if (err)
...@@ -425,7 +428,7 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) ...@@ -425,7 +428,7 @@ static int mc_sysdev_remove(struct sys_device *sys_dev)
if (!cpu_online(cpu)) if (!cpu_online(cpu))
return 0; return 0;
pr_debug("microcode: CPU%d removed\n", cpu); pr_debug("CPU%d removed\n", cpu);
microcode_fini_cpu(cpu); microcode_fini_cpu(cpu);
sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
return 0; return 0;
...@@ -473,15 +476,15 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) ...@@ -473,15 +476,15 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
microcode_update_cpu(cpu); microcode_update_cpu(cpu);
case CPU_DOWN_FAILED: case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN: case CPU_DOWN_FAILED_FROZEN:
pr_debug("microcode: CPU%d added\n", cpu); pr_debug("CPU%d added\n", cpu);
if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
pr_err("microcode: Failed to create group for CPU%d\n", cpu); pr_err("Failed to create group for CPU%d\n", cpu);
break; break;
case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN: case CPU_DOWN_PREPARE_FROZEN:
/* Suspend is in progress, only remove the interface */ /* Suspend is in progress, only remove the interface */
sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
pr_debug("microcode: CPU%d removed\n", cpu); pr_debug("CPU%d removed\n", cpu);
break; break;
case CPU_DEAD: case CPU_DEAD:
case CPU_UP_CANCELED_FROZEN: case CPU_UP_CANCELED_FROZEN:
...@@ -507,7 +510,7 @@ static int __init microcode_init(void) ...@@ -507,7 +510,7 @@ static int __init microcode_init(void)
microcode_ops = init_amd_microcode(); microcode_ops = init_amd_microcode();
if (!microcode_ops) { if (!microcode_ops) {
pr_err("microcode: no support for this CPU vendor\n"); pr_err("no support for this CPU vendor\n");
return -ENODEV; return -ENODEV;
} }
...@@ -541,8 +544,7 @@ static int __init microcode_init(void) ...@@ -541,8 +544,7 @@ static int __init microcode_init(void)
register_hotcpu_notifier(&mc_cpu_notifier); register_hotcpu_notifier(&mc_cpu_notifier);
pr_info("Microcode Update Driver: v" MICROCODE_VERSION pr_info("Microcode Update Driver: v" MICROCODE_VERSION
" <tigran@aivazian.fsnet.co.uk>," " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n");
" Peter Oruba\n");
return 0; return 0;
} }
......
...@@ -70,6 +70,9 @@ ...@@ -70,6 +70,9 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0. * Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug. * Thanks to Stuart Swales for pointing out this bug.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -146,8 +149,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) ...@@ -146,8 +149,7 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
cpu_has(c, X86_FEATURE_IA64)) { cpu_has(c, X86_FEATURE_IA64)) {
printk(KERN_ERR "microcode: CPU%d not a capable Intel " pr_err("CPU%d not a capable Intel processor\n", cpu_num);
"processor\n", cpu_num);
return -1; return -1;
} }
...@@ -165,8 +167,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) ...@@ -165,8 +167,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
/* get the current revision from MSR 0x8B */ /* get the current revision from MSR 0x8B */
rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
printk(KERN_INFO "microcode: CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n", pr_info("CPU%d sig=0x%x, pf=0x%x, revision=0x%x\n",
cpu_num, csig->sig, csig->pf, csig->rev); cpu_num, csig->sig, csig->pf, csig->rev);
return 0; return 0;
} }
...@@ -194,28 +196,24 @@ static int microcode_sanity_check(void *mc) ...@@ -194,28 +196,24 @@ static int microcode_sanity_check(void *mc)
data_size = get_datasize(mc_header); data_size = get_datasize(mc_header);
if (data_size + MC_HEADER_SIZE > total_size) { if (data_size + MC_HEADER_SIZE > total_size) {
printk(KERN_ERR "microcode: error! " pr_err("error! Bad data size in microcode data file\n");
"Bad data size in microcode data file\n");
return -EINVAL; return -EINVAL;
} }
if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
printk(KERN_ERR "microcode: error! " pr_err("error! Unknown microcode update format\n");
"Unknown microcode update format\n");
return -EINVAL; return -EINVAL;
} }
ext_table_size = total_size - (MC_HEADER_SIZE + data_size); ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
if (ext_table_size) { if (ext_table_size) {
if ((ext_table_size < EXT_HEADER_SIZE) if ((ext_table_size < EXT_HEADER_SIZE)
|| ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
printk(KERN_ERR "microcode: error! " pr_err("error! Small exttable size in microcode data file\n");
"Small exttable size in microcode data file\n");
return -EINVAL; return -EINVAL;
} }
ext_header = mc + MC_HEADER_SIZE + data_size; ext_header = mc + MC_HEADER_SIZE + data_size;
if (ext_table_size != exttable_size(ext_header)) { if (ext_table_size != exttable_size(ext_header)) {
printk(KERN_ERR "microcode: error! " pr_err("error! Bad exttable size in microcode data file\n");
"Bad exttable size in microcode data file\n");
return -EFAULT; return -EFAULT;
} }
ext_sigcount = ext_header->count; ext_sigcount = ext_header->count;
...@@ -230,8 +228,7 @@ static int microcode_sanity_check(void *mc) ...@@ -230,8 +228,7 @@ static int microcode_sanity_check(void *mc)
while (i--) while (i--)
ext_table_sum += ext_tablep[i]; ext_table_sum += ext_tablep[i];
if (ext_table_sum) { if (ext_table_sum) {
printk(KERN_WARNING "microcode: aborting, " pr_warning("aborting, bad extended signature table checksum\n");
"bad extended signature table checksum\n");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -242,7 +239,7 @@ static int microcode_sanity_check(void *mc) ...@@ -242,7 +239,7 @@ static int microcode_sanity_check(void *mc)
while (i--) while (i--)
orig_sum += ((int *)mc)[i]; orig_sum += ((int *)mc)[i];
if (orig_sum) { if (orig_sum) {
printk(KERN_ERR "microcode: aborting, bad checksum\n"); pr_err("aborting, bad checksum\n");
return -EINVAL; return -EINVAL;
} }
if (!ext_table_size) if (!ext_table_size)
...@@ -255,7 +252,7 @@ static int microcode_sanity_check(void *mc) ...@@ -255,7 +252,7 @@ static int microcode_sanity_check(void *mc)
- (mc_header->sig + mc_header->pf + mc_header->cksum) - (mc_header->sig + mc_header->pf + mc_header->cksum)
+ (ext_sig->sig + ext_sig->pf + ext_sig->cksum); + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
if (sum) { if (sum) {
printk(KERN_ERR "microcode: aborting, bad checksum\n"); pr_err("aborting, bad checksum\n");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -327,13 +324,11 @@ static int apply_microcode(int cpu) ...@@ -327,13 +324,11 @@ static int apply_microcode(int cpu)
rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
if (val[1] != mc_intel->hdr.rev) { if (val[1] != mc_intel->hdr.rev) {
printk(KERN_ERR "microcode: CPU%d update " pr_err("CPU%d update to revision 0x%x failed\n",
"to revision 0x%x failed\n", cpu_num, mc_intel->hdr.rev);
cpu_num, mc_intel->hdr.rev);
return -1; return -1;
} }
printk(KERN_INFO "microcode: CPU%d updated to revision " pr_info("CPU%d updated to revision 0x%x, date = %04x-%02x-%02x \n",
"0x%x, date = %04x-%02x-%02x \n",
cpu_num, val[1], cpu_num, val[1],
mc_intel->hdr.date & 0xffff, mc_intel->hdr.date & 0xffff,
mc_intel->hdr.date >> 24, mc_intel->hdr.date >> 24,
...@@ -362,8 +357,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, ...@@ -362,8 +357,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
mc_size = get_totalsize(&mc_header); mc_size = get_totalsize(&mc_header);
if (!mc_size || mc_size > leftover) { if (!mc_size || mc_size > leftover) {
printk(KERN_ERR "microcode: error!" pr_err("error! Bad data in microcode data file\n");
"Bad data in microcode data file\n");
break; break;
} }
...@@ -405,9 +399,8 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, ...@@ -405,9 +399,8 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
vfree(uci->mc); vfree(uci->mc);
uci->mc = (struct microcode_intel *)new_mc; uci->mc = (struct microcode_intel *)new_mc;
pr_debug("microcode: CPU%d found a matching microcode update with" pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
" version 0x%x (current=0x%x)\n", cpu, new_rev, uci->cpu_sig.rev);
cpu, new_rev, uci->cpu_sig.rev);
out: out:
return state; return state;
} }
...@@ -429,7 +422,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device) ...@@ -429,7 +422,7 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device)
c->x86, c->x86_model, c->x86_mask); c->x86, c->x86_model, c->x86_mask);
if (request_firmware(&firmware, name, device)) { if (request_firmware(&firmware, name, device)) {
pr_debug("microcode: data file %s load failed\n", name); pr_debug("data file %s load failed\n", name);
return UCODE_NFOUND; return UCODE_NFOUND;
} }
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/user-return-notifier.h> #include <linux/user-return-notifier.h>
#include <linux/dmi.h>
#include <linux/utsname.h>
#include <trace/events/power.h> #include <trace/events/power.h>
#include <linux/hw_breakpoint.h> #include <linux/hw_breakpoint.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -90,6 +92,25 @@ void exit_thread(void) ...@@ -90,6 +92,25 @@ void exit_thread(void)
} }
} }
void show_regs_common(void)
{
const char *board, *product;
board = dmi_get_system_info(DMI_BOARD_NAME);
if (!board)
board = "";
product = dmi_get_system_info(DMI_PRODUCT_NAME);
if (!product)
product = "";
printk("\n");
printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
current->pid, current->comm, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
init_utsname()->version, board, product);
}
void flush_thread(void) void flush_thread(void)
{ {
struct task_struct *tsk = current; struct task_struct *tsk = current;
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/utsname.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -35,7 +34,6 @@ ...@@ -35,7 +34,6 @@
#include <linux/tick.h> #include <linux/tick.h>
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/prctl.h> #include <linux/prctl.h>
#include <linux/dmi.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -128,7 +126,6 @@ void __show_regs(struct pt_regs *regs, int all) ...@@ -128,7 +126,6 @@ void __show_regs(struct pt_regs *regs, int all)
unsigned long d0, d1, d2, d3, d6, d7; unsigned long d0, d1, d2, d3, d6, d7;
unsigned long sp; unsigned long sp;
unsigned short ss, gs; unsigned short ss, gs;
const char *board;
if (user_mode_vm(regs)) { if (user_mode_vm(regs)) {
sp = regs->sp; sp = regs->sp;
...@@ -140,16 +137,7 @@ void __show_regs(struct pt_regs *regs, int all) ...@@ -140,16 +137,7 @@ void __show_regs(struct pt_regs *regs, int all)
savesegment(gs, gs); savesegment(gs, gs);
} }
printk("\n"); show_regs_common();
board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (!board)
board = "";
printk("Pid: %d, comm: %s %s (%s %.*s) %s\n",
task_pid_nr(current), current->comm,
print_tainted(), init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
init_utsname()->version, board);
printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n", printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
(u16)regs->cs, regs->ip, regs->flags, (u16)regs->cs, regs->ip, regs->flags,
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/utsname.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
...@@ -38,7 +37,6 @@ ...@@ -38,7 +37,6 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/dmi.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -163,18 +161,8 @@ void __show_regs(struct pt_regs *regs, int all) ...@@ -163,18 +161,8 @@ void __show_regs(struct pt_regs *regs, int all)
unsigned long d0, d1, d2, d3, d6, d7; unsigned long d0, d1, d2, d3, d6, d7;
unsigned int fsindex, gsindex; unsigned int fsindex, gsindex;
unsigned int ds, cs, es; unsigned int ds, cs, es;
const char *board;
show_regs_common();
printk("\n");
print_modules();
board = dmi_get_system_info(DMI_PRODUCT_NAME);
if (!board)
board = "";
printk(KERN_INFO "Pid: %d, comm: %.20s %s %s %.*s %s\n",
current->pid, current->comm, print_tainted(),
init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
init_utsname()->version, board);
printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip); printk(KERN_INFO "RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
printk_address(regs->ip, 1); printk_address(regs->ip, 1);
printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, printk(KERN_INFO "RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss,
......
...@@ -259,6 +259,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { ...@@ -259,6 +259,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"), DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
}, },
}, },
{ /* Handle problems with rebooting on ASUS P4S800 */
.callback = set_bios_reboot,
.ident = "ASUS P4S800",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
},
},
{ } { }
}; };
......
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -20,9 +22,9 @@ ...@@ -20,9 +22,9 @@
#include <asm/stackprotector.h> #include <asm/stackprotector.h>
#ifdef CONFIG_DEBUG_PER_CPU_MAPS #ifdef CONFIG_DEBUG_PER_CPU_MAPS
# define DBG(x...) printk(KERN_DEBUG x) # define DBG(fmt, ...) pr_dbg(fmt, ##__VA_ARGS__)
#else #else
# define DBG(x...) # define DBG(fmt, ...) do { if (0) pr_dbg(fmt, ##__VA_ARGS__); } while (0)
#endif #endif
DEFINE_PER_CPU(int, cpu_number); DEFINE_PER_CPU(int, cpu_number);
...@@ -116,8 +118,8 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, ...@@ -116,8 +118,8 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
} else { } else {
ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node), ptr = __alloc_bootmem_node_nopanic(NODE_DATA(node),
size, align, goal); size, align, goal);
pr_debug("per cpu data for cpu%d %lu bytes on node%d at " pr_debug("per cpu data for cpu%d %lu bytes on node%d at %016lx\n",
"%016lx\n", cpu, size, node, __pa(ptr)); cpu, size, node, __pa(ptr));
} }
return ptr; return ptr;
#else #else
...@@ -198,8 +200,7 @@ void __init setup_per_cpu_areas(void) ...@@ -198,8 +200,7 @@ void __init setup_per_cpu_areas(void)
pcpu_cpu_distance, pcpu_cpu_distance,
pcpu_fc_alloc, pcpu_fc_free); pcpu_fc_alloc, pcpu_fc_free);
if (rc < 0) if (rc < 0)
pr_warning("PERCPU: %s allocator failed (%d), " pr_warning("%s allocator failed (%d), falling back to page size\n",
"falling back to page size\n",
pcpu_fc_names[pcpu_chosen_fc], rc); pcpu_fc_names[pcpu_chosen_fc], rc);
} }
if (rc < 0) if (rc < 0)
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
* Based on QEMU and Xen. * Based on QEMU and Xen.
*/ */
#define pr_fmt(fmt) "pit: " fmt
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
#include "irq.h" #include "irq.h"
...@@ -262,7 +264,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) ...@@ -262,7 +264,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
static void destroy_pit_timer(struct kvm_timer *pt) static void destroy_pit_timer(struct kvm_timer *pt)
{ {
pr_debug("pit: execute del timer!\n"); pr_debug("execute del timer!\n");
hrtimer_cancel(&pt->timer); hrtimer_cancel(&pt->timer);
} }
...@@ -284,7 +286,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) ...@@ -284,7 +286,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
pr_debug("pit: create pit timer, interval is %llu nsec\n", interval); pr_debug("create pit timer, interval is %llu nsec\n", interval);
/* TODO The new value only affected after the retriggered */ /* TODO The new value only affected after the retriggered */
hrtimer_cancel(&pt->timer); hrtimer_cancel(&pt->timer);
...@@ -309,7 +311,7 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val) ...@@ -309,7 +311,7 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
WARN_ON(!mutex_is_locked(&ps->lock)); WARN_ON(!mutex_is_locked(&ps->lock));
pr_debug("pit: load_count val is %d, channel is %d\n", val, channel); pr_debug("load_count val is %d, channel is %d\n", val, channel);
/* /*
* The largest possible initial count is 0; this is equivalent * 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,8 +397,8 @@ static int pit_ioport_write(struct kvm_io_device *this,
mutex_lock(&pit_state->lock); mutex_lock(&pit_state->lock);
if (val != 0) if (val != 0)
pr_debug("pit: write addr is 0x%x, len is %d, val is 0x%x\n", pr_debug("write addr is 0x%x, len is %d, val is 0x%x\n",
(unsigned int)addr, len, val); (unsigned int)addr, len, val);
if (addr == 3) { if (addr == 3) {
channel = val >> 6; channel = val >> 6;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* 2008 Pekka Paalanen <pq@iki.fi> * 2008 Pekka Paalanen <pq@iki.fi>
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/list.h> #include <linux/list.h>
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -136,7 +138,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) ...@@ -136,7 +138,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
pte_t *pte = lookup_address(f->page, &level); pte_t *pte = lookup_address(f->page, &level);
if (!pte) { if (!pte) {
pr_err("kmmio: no pte for page 0x%08lx\n", f->page); pr_err("no pte for page 0x%08lx\n", f->page);
return -1; return -1;
} }
...@@ -148,7 +150,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) ...@@ -148,7 +150,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
clear_pte_presence(pte, clear, &f->old_presence); clear_pte_presence(pte, clear, &f->old_presence);
break; break;
default: default:
pr_err("kmmio: unexpected page level 0x%x.\n", level); pr_err("unexpected page level 0x%x.\n", level);
return -1; return -1;
} }
...@@ -170,13 +172,14 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear) ...@@ -170,13 +172,14 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
static int arm_kmmio_fault_page(struct kmmio_fault_page *f) static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
{ {
int ret; int ret;
WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n"); WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n"));
if (f->armed) { if (f->armed) {
pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n", pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n",
f->page, f->count, !!f->old_presence); f->page, f->count, !!f->old_presence);
} }
ret = clear_page_presence(f, true); ret = clear_page_presence(f, true);
WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page); WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"),
f->page);
f->armed = true; f->armed = true;
return ret; return ret;
} }
...@@ -240,24 +243,21 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr) ...@@ -240,24 +243,21 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
* condition needs handling by do_page_fault(), the * condition needs handling by do_page_fault(), the
* page really not being present is the most common. * page really not being present is the most common.
*/ */
pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n", pr_debug("secondary hit for 0x%08lx CPU %d.\n",
addr, smp_processor_id()); addr, smp_processor_id());
if (!faultpage->old_presence) if (!faultpage->old_presence)
pr_info("kmmio: unexpected secondary hit for " pr_info("unexpected secondary hit for address 0x%08lx on CPU %d.\n",
"address 0x%08lx on CPU %d.\n", addr, addr, smp_processor_id());
smp_processor_id());
} else { } else {
/* /*
* Prevent overwriting already in-flight context. * Prevent overwriting already in-flight context.
* This should not happen, let's hope disarming at * This should not happen, let's hope disarming at
* least prevents a panic. * least prevents a panic.
*/ */
pr_emerg("kmmio: recursive probe hit on CPU %d, " pr_emerg("recursive probe hit on CPU %d, for address 0x%08lx. Ignoring.\n",
"for address 0x%08lx. Ignoring.\n", smp_processor_id(), addr);
smp_processor_id(), addr); pr_emerg("previous hit was at 0x%08lx.\n", ctx->addr);
pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
ctx->addr);
disarm_kmmio_fault_page(faultpage); disarm_kmmio_fault_page(faultpage);
} }
goto no_kmmio_ctx; goto no_kmmio_ctx;
...@@ -316,8 +316,8 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs) ...@@ -316,8 +316,8 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
* something external causing them (f.e. using a debugger while * something external causing them (f.e. using a debugger while
* mmio tracing enabled), or erroneous behaviour * mmio tracing enabled), or erroneous behaviour
*/ */
pr_warning("kmmio: unexpected debug trap on CPU %d.\n", pr_warning("unexpected debug trap on CPU %d.\n",
smp_processor_id()); smp_processor_id());
goto out; goto out;
} }
...@@ -425,7 +425,7 @@ int register_kmmio_probe(struct kmmio_probe *p) ...@@ -425,7 +425,7 @@ int register_kmmio_probe(struct kmmio_probe *p)
list_add_rcu(&p->list, &kmmio_probes); list_add_rcu(&p->list, &kmmio_probes);
while (size < size_lim) { while (size < size_lim) {
if (add_kmmio_fault_page(p->addr + size)) if (add_kmmio_fault_page(p->addr + size))
pr_err("kmmio: Unable to set page fault.\n"); pr_err("Unable to set page fault.\n");
size += PAGE_SIZE; size += PAGE_SIZE;
} }
out: out:
...@@ -490,7 +490,7 @@ static void remove_kmmio_fault_pages(struct rcu_head *head) ...@@ -490,7 +490,7 @@ static void remove_kmmio_fault_pages(struct rcu_head *head)
* 2. remove_kmmio_fault_pages() * 2. remove_kmmio_fault_pages()
* Remove the pages from kmmio_page_table. * Remove the pages from kmmio_page_table.
* 3. rcu_free_kmmio_fault_pages() * 3. rcu_free_kmmio_fault_pages()
* Actally free the kmmio_fault_page structs as with RCU. * Actually free the kmmio_fault_page structs as with RCU.
*/ */
void unregister_kmmio_probe(struct kmmio_probe *p) void unregister_kmmio_probe(struct kmmio_probe *p)
{ {
...@@ -511,7 +511,7 @@ void unregister_kmmio_probe(struct kmmio_probe *p) ...@@ -511,7 +511,7 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC);
if (!drelease) { if (!drelease) {
pr_crit("kmmio: leaking kmmio_fault_page objects.\n"); pr_crit("leaking kmmio_fault_page objects.\n");
return; return;
} }
drelease->release_list = release_list; drelease->release_list = release_list;
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
* *
* Derived from the read-mod example from relay-examples by Tom Zanussi. * Derived from the read-mod example from relay-examples by Tom Zanussi.
*/ */
#define pr_fmt(fmt) "mmiotrace: "
#define DEBUG 1 #define DEBUG 1
#include <linux/module.h> #include <linux/module.h>
...@@ -36,8 +39,6 @@ ...@@ -36,8 +39,6 @@
#include "pf_in.h" #include "pf_in.h"
#define NAME "mmiotrace: "
struct trap_reason { struct trap_reason {
unsigned long addr; unsigned long addr;
unsigned long ip; unsigned long ip;
...@@ -96,17 +97,18 @@ static void print_pte(unsigned long address) ...@@ -96,17 +97,18 @@ static void print_pte(unsigned long address)
pte_t *pte = lookup_address(address, &level); pte_t *pte = lookup_address(address, &level);
if (!pte) { if (!pte) {
pr_err(NAME "Error in %s: no pte for page 0x%08lx\n", pr_err("Error in %s: no pte for page 0x%08lx\n",
__func__, address); __func__, address);
return; return;
} }
if (level == PG_LEVEL_2M) { if (level == PG_LEVEL_2M) {
pr_emerg(NAME "4MB pages are not currently supported: " pr_emerg("4MB pages are not currently supported: 0x%08lx\n",
"0x%08lx\n", address); address);
BUG(); BUG();
} }
pr_info(NAME "pte for 0x%lx: 0x%llx 0x%llx\n", address, pr_info("pte for 0x%lx: 0x%llx 0x%llx\n",
address,
(unsigned long long)pte_val(*pte), (unsigned long long)pte_val(*pte),
(unsigned long long)pte_val(*pte) & _PAGE_PRESENT); (unsigned long long)pte_val(*pte) & _PAGE_PRESENT);
} }
...@@ -118,22 +120,21 @@ static void print_pte(unsigned long address) ...@@ -118,22 +120,21 @@ static void print_pte(unsigned long address)
static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr) static void die_kmmio_nesting_error(struct pt_regs *regs, unsigned long addr)
{ {
const struct trap_reason *my_reason = &get_cpu_var(pf_reason); const struct trap_reason *my_reason = &get_cpu_var(pf_reason);
pr_emerg(NAME "unexpected fault for address: 0x%08lx, " pr_emerg("unexpected fault for address: 0x%08lx, last fault for address: 0x%08lx\n",
"last fault for address: 0x%08lx\n", addr, my_reason->addr);
addr, my_reason->addr);
print_pte(addr); print_pte(addr);
print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip); print_symbol(KERN_EMERG "faulting IP is at %s\n", regs->ip);
print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip); print_symbol(KERN_EMERG "last faulting IP was at %s\n", my_reason->ip);
#ifdef __i386__ #ifdef __i386__
pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", pr_emerg("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->ax, regs->bx, regs->cx, regs->dx); regs->ax, regs->bx, regs->cx, regs->dx);
pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", pr_emerg("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
regs->si, regs->di, regs->bp, regs->sp); regs->si, regs->di, regs->bp, regs->sp);
#else #else
pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n", pr_emerg("rax: %016lx rcx: %016lx rdx: %016lx\n",
regs->ax, regs->cx, regs->dx); regs->ax, regs->cx, regs->dx);
pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n", pr_emerg("rsi: %016lx rdi: %016lx rbp: %016lx rsp: %016lx\n",
regs->si, regs->di, regs->bp, regs->sp); regs->si, regs->di, regs->bp, regs->sp);
#endif #endif
put_cpu_var(pf_reason); put_cpu_var(pf_reason);
BUG(); BUG();
...@@ -213,7 +214,7 @@ static void post(struct kmmio_probe *p, unsigned long condition, ...@@ -213,7 +214,7 @@ static void post(struct kmmio_probe *p, unsigned long condition,
/* this should always return the active_trace count to 0 */ /* this should always return the active_trace count to 0 */
my_reason->active_traces--; my_reason->active_traces--;
if (my_reason->active_traces) { if (my_reason->active_traces) {
pr_emerg(NAME "unexpected post handler"); pr_emerg("unexpected post handler");
BUG(); BUG();
} }
...@@ -244,7 +245,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, ...@@ -244,7 +245,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size,
}; };
if (!trace) { if (!trace) {
pr_err(NAME "kmalloc failed in ioremap\n"); pr_err("kmalloc failed in ioremap\n");
return; return;
} }
...@@ -282,8 +283,8 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long size, ...@@ -282,8 +283,8 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
if (!is_enabled()) /* recheck and proper locking in *_core() */ if (!is_enabled()) /* recheck and proper locking in *_core() */
return; return;
pr_debug(NAME "ioremap_*(0x%llx, 0x%lx) = %p\n", pr_debug("ioremap_*(0x%llx, 0x%lx) = %p\n",
(unsigned long long)offset, size, addr); (unsigned long long)offset, size, addr);
if ((filter_offset) && (offset != filter_offset)) if ((filter_offset) && (offset != filter_offset))
return; return;
ioremap_trace_core(offset, size, addr); ioremap_trace_core(offset, size, addr);
...@@ -301,7 +302,7 @@ static void iounmap_trace_core(volatile void __iomem *addr) ...@@ -301,7 +302,7 @@ static void iounmap_trace_core(volatile void __iomem *addr)
struct remap_trace *tmp; struct remap_trace *tmp;
struct remap_trace *found_trace = NULL; struct remap_trace *found_trace = NULL;
pr_debug(NAME "Unmapping %p.\n", addr); pr_debug("Unmapping %p.\n", addr);
spin_lock_irq(&trace_lock); spin_lock_irq(&trace_lock);
if (!is_enabled()) if (!is_enabled())
...@@ -363,9 +364,8 @@ static void clear_trace_list(void) ...@@ -363,9 +364,8 @@ static void clear_trace_list(void)
* Caller also ensures is_enabled() cannot change. * Caller also ensures is_enabled() cannot change.
*/ */
list_for_each_entry(trace, &trace_list, list) { list_for_each_entry(trace, &trace_list, list) {
pr_notice(NAME "purging non-iounmapped " pr_notice("purging non-iounmapped trace @0x%08lx, size 0x%lx.\n",
"trace @0x%08lx, size 0x%lx.\n", trace->probe.addr, trace->probe.len);
trace->probe.addr, trace->probe.len);
if (!nommiotrace) if (!nommiotrace)
unregister_kmmio_probe(&trace->probe); unregister_kmmio_probe(&trace->probe);
} }
...@@ -387,7 +387,7 @@ static void enter_uniprocessor(void) ...@@ -387,7 +387,7 @@ static void enter_uniprocessor(void)
if (downed_cpus == NULL && if (downed_cpus == NULL &&
!alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) { !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
pr_notice(NAME "Failed to allocate mask\n"); pr_notice("Failed to allocate mask\n");
goto out; goto out;
} }
...@@ -395,20 +395,19 @@ static void enter_uniprocessor(void) ...@@ -395,20 +395,19 @@ static void enter_uniprocessor(void)
cpumask_copy(downed_cpus, cpu_online_mask); cpumask_copy(downed_cpus, cpu_online_mask);
cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus); cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
pr_notice(NAME "Disabling non-boot CPUs...\n"); pr_notice("Disabling non-boot CPUs...\n");
put_online_cpus(); put_online_cpus();
for_each_cpu(cpu, downed_cpus) { for_each_cpu(cpu, downed_cpus) {
err = cpu_down(cpu); err = cpu_down(cpu);
if (!err) if (!err)
pr_info(NAME "CPU%d is down.\n", cpu); pr_info("CPU%d is down.\n", cpu);
else else
pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err); pr_err("Error taking CPU%d down: %d\n", cpu, err);
} }
out: out:
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
pr_warning(NAME "multiple CPUs still online, " pr_warning("multiple CPUs still online, may miss events.\n");
"may miss events.\n");
} }
/* __ref because leave_uniprocessor calls cpu_up which is __cpuinit, /* __ref because leave_uniprocessor calls cpu_up which is __cpuinit,
...@@ -420,13 +419,13 @@ static void __ref leave_uniprocessor(void) ...@@ -420,13 +419,13 @@ static void __ref leave_uniprocessor(void)
if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0) if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
return; return;
pr_notice(NAME "Re-enabling CPUs...\n"); pr_notice("Re-enabling CPUs...\n");
for_each_cpu(cpu, downed_cpus) { for_each_cpu(cpu, downed_cpus) {
err = cpu_up(cpu); err = cpu_up(cpu);
if (!err) if (!err)
pr_info(NAME "enabled CPU%d.\n", cpu); pr_info("enabled CPU%d.\n", cpu);
else else
pr_err(NAME "cannot re-enable CPU%d: %d\n", cpu, err); pr_err("cannot re-enable CPU%d: %d\n", cpu, err);
} }
} }
...@@ -434,8 +433,8 @@ static void __ref leave_uniprocessor(void) ...@@ -434,8 +433,8 @@ static void __ref leave_uniprocessor(void)
static void enter_uniprocessor(void) static void enter_uniprocessor(void)
{ {
if (num_online_cpus() > 1) if (num_online_cpus() > 1)
pr_warning(NAME "multiple CPUs are online, may miss events. " pr_warning("multiple CPUs are online, may miss events. "
"Suggest booting with maxcpus=1 kernel argument.\n"); "Suggest booting with maxcpus=1 kernel argument.\n");
} }
static void leave_uniprocessor(void) static void leave_uniprocessor(void)
...@@ -450,13 +449,13 @@ void enable_mmiotrace(void) ...@@ -450,13 +449,13 @@ void enable_mmiotrace(void)
goto out; goto out;
if (nommiotrace) if (nommiotrace)
pr_info(NAME "MMIO tracing disabled.\n"); pr_info("MMIO tracing disabled.\n");
kmmio_init(); kmmio_init();
enter_uniprocessor(); enter_uniprocessor();
spin_lock_irq(&trace_lock); spin_lock_irq(&trace_lock);
atomic_inc(&mmiotrace_enabled); atomic_inc(&mmiotrace_enabled);
spin_unlock_irq(&trace_lock); spin_unlock_irq(&trace_lock);
pr_info(NAME "enabled.\n"); pr_info("enabled.\n");
out: out:
mutex_unlock(&mmiotrace_mutex); mutex_unlock(&mmiotrace_mutex);
} }
...@@ -475,7 +474,7 @@ void disable_mmiotrace(void) ...@@ -475,7 +474,7 @@ void disable_mmiotrace(void)
clear_trace_list(); /* guarantees: no more kmmio callbacks */ clear_trace_list(); /* guarantees: no more kmmio callbacks */
leave_uniprocessor(); leave_uniprocessor();
kmmio_cleanup(); kmmio_cleanup();
pr_info(NAME "disabled.\n"); pr_info("disabled.\n");
out: out:
mutex_unlock(&mmiotrace_mutex); mutex_unlock(&mmiotrace_mutex);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment