Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
random: Fix handing of arch_get_random_long in get_random_bytes()
x86: Call stop_machine_text_poke() on all CPUs
x86, ioapic: Only print ioapic debug information for IRQs belonging to an ioapic chip
x86/mrst: Avoid reporting wrong nmi status
x86/mrst: Add support for Penwell clock calibration
x86/apic: Allow use of lapic timer early calibration result
x86/apic: Do not clear nr_irqs_gsi if no legacy irqs
x86/platform: Add a wallclock_init func to x86_platforms ops
x86/mce: Make mce_chrdev_ops 'static const'

+120 -22
+1
arch/x86/include/asm/apic.h
··· 49 49 extern int local_apic_timer_c2_ok; 50 50 51 51 extern int disable_apic; 52 + extern unsigned int lapic_timer_frequency; 52 53 53 54 #ifdef CONFIG_SMP 54 55 extern void __inquire_remote_apic(int apicid);
+1 -1
arch/x86/include/asm/mach_traps.h
··· 17 17 #define NMI_REASON_CLEAR_IOCHK 0x08 18 18 #define NMI_REASON_CLEAR_MASK 0x0f 19 19 20 - static inline unsigned char get_nmi_reason(void) 20 + static inline unsigned char default_get_nmi_reason(void) 21 21 { 22 22 return inb(NMI_REASON_PORT); 23 23 }
+4 -1
arch/x86/include/asm/mce.h
··· 201 201 void mce_notify_process(void); 202 202 203 203 DECLARE_PER_CPU(struct mce, injectm); 204 - extern struct file_operations mce_chrdev_ops; 204 + 205 + extern void register_mce_write_callback(ssize_t (*)(struct file *filp, 206 + const char __user *ubuf, 207 + size_t usize, loff_t *off)); 205 208 206 209 /* 207 210 * Exception handler
+7
arch/x86/include/asm/mrst.h
··· 44 44 45 45 extern enum mrst_timer_options mrst_timer_options; 46 46 47 + /* 48 + * Penwell uses spread spectrum clock, so the freq number is not exactly 49 + * the same as reported by MSR based on SDM. 50 + */ 51 + #define PENWELL_FSB_FREQ_83SKU 83200 52 + #define PENWELL_FSB_FREQ_100SKU 99840 53 + 47 54 #define SFI_MTMR_MAX_NUM 8 48 55 #define SFI_MRTC_MAX 8 49 56
+3
arch/x86/include/asm/x86_init.h
··· 152 152 /** 153 153 * struct x86_platform_ops - platform specific runtime functions 154 154 * @calibrate_tsc: calibrate TSC 155 + * @wallclock_init: init the wallclock device 155 156 * @get_wallclock: get time from HW clock like RTC etc. 156 157 * @set_wallclock: set time back to HW clock 157 158 * @is_untracked_pat_range exclude from PAT logic ··· 161 160 */ 162 161 struct x86_platform_ops { 163 162 unsigned long (*calibrate_tsc)(void); 163 + void (*wallclock_init)(void); 164 164 unsigned long (*get_wallclock)(void); 165 165 int (*set_wallclock)(unsigned long nowtime); 166 166 void (*iommu_shutdown)(void); 167 167 bool (*is_untracked_pat_range)(u64 start, u64 end); 168 168 void (*nmi_init)(void); 169 + unsigned char (*get_nmi_reason)(void); 169 170 int (*i8042_detect)(void); 170 171 }; 171 172
+1 -1
arch/x86/kernel/alternative.c
··· 738 738 739 739 atomic_set(&stop_machine_first, 1); 740 740 wrote_text = 0; 741 - __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); 741 + __stop_machine(stop_machine_text_poke, (void *)&tpp, cpu_online_mask); 742 742 }
+26 -7
arch/x86/kernel/apic/apic.c
··· 186 186 .flags = IORESOURCE_MEM | IORESOURCE_BUSY, 187 187 }; 188 188 189 - static unsigned int calibration_result; 189 + unsigned int lapic_timer_frequency = 0; 190 190 191 191 static void apic_pm_activate(void); 192 192 ··· 454 454 switch (mode) { 455 455 case CLOCK_EVT_MODE_PERIODIC: 456 456 case CLOCK_EVT_MODE_ONESHOT: 457 - __setup_APIC_LVTT(calibration_result, 457 + __setup_APIC_LVTT(lapic_timer_frequency, 458 458 mode != CLOCK_EVT_MODE_PERIODIC, 1); 459 459 break; 460 460 case CLOCK_EVT_MODE_UNUSED: ··· 638 638 long delta, deltatsc; 639 639 int pm_referenced = 0; 640 640 641 + /** 642 + * check if lapic timer has already been calibrated by platform 643 + * specific routine, such as tsc calibration code. if so, we just fill 644 + * in the clockevent structure and return. 645 + */ 646 + 647 + if (lapic_timer_frequency) { 648 + apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n", 649 + lapic_timer_frequency); 650 + lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR, 651 + TICK_NSEC, lapic_clockevent.shift); 652 + lapic_clockevent.max_delta_ns = 653 + clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); 654 + lapic_clockevent.min_delta_ns = 655 + clockevent_delta2ns(0xF, &lapic_clockevent); 656 + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; 657 + return 0; 658 + } 659 + 641 660 local_irq_disable(); 642 661 643 662 /* Replace the global interrupt handler */ ··· 698 679 lapic_clockevent.min_delta_ns = 699 680 clockevent_delta2ns(0xF, &lapic_clockevent); 700 681 701 - calibration_result = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; 682 + lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; 702 683 703 684 apic_printk(APIC_VERBOSE, "..... delta %ld\n", delta); 704 685 apic_printk(APIC_VERBOSE, "..... mult: %u\n", lapic_clockevent.mult); 705 686 apic_printk(APIC_VERBOSE, "..... calibration result: %u\n", 706 - calibration_result); 687 + lapic_timer_frequency); 707 688 708 689 if (cpu_has_tsc) { 709 690 apic_printk(APIC_VERBOSE, "..... CPU clock speed is " ··· 714 695 715 696 apic_printk(APIC_VERBOSE, "..... host bus clock speed is " 716 697 "%u.%04u MHz.\n", 717 - calibration_result / (1000000 / HZ), 718 - calibration_result % (1000000 / HZ)); 698 + lapic_timer_frequency / (1000000 / HZ), 699 + lapic_timer_frequency % (1000000 / HZ)); 719 700 720 701 /* 721 702 * Do a sanity check on the APIC calibration result 722 703 */ 723 - if (calibration_result < (1000000 / HZ)) { 704 + if (lapic_timer_frequency < (1000000 / HZ)) { 724 705 local_irq_enable(); 725 706 pr_warning("APIC frequency too slow, disabling apic timer\n"); 726 707 return -1;
+6 -3
arch/x86/kernel/apic/io_apic.c
··· 193 193 struct irq_cfg *cfg; 194 194 int count, node, i; 195 195 196 - if (!legacy_pic->nr_legacy_irqs) { 197 - nr_irqs_gsi = 0; 196 + if (!legacy_pic->nr_legacy_irqs) 198 197 io_apic_irqs = ~0UL; 199 - } 200 198 201 199 for (i = 0; i < nr_ioapics; i++) { 202 200 ioapics[i].saved_registers = ··· 1694 1696 int ioapic_idx; 1695 1697 struct irq_cfg *cfg; 1696 1698 unsigned int irq; 1699 + struct irq_chip *chip; 1697 1700 1698 1701 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); 1699 1702 for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) ··· 1714 1715 printk(KERN_DEBUG "IRQ to pin mappings:\n"); 1715 1716 for_each_active_irq(irq) { 1716 1717 struct irq_pin_list *entry; 1718 + 1719 + chip = irq_get_chip(irq); 1720 + if (chip != &ioapic_chip) 1721 + continue; 1717 1722 1718 1723 cfg = irq_get_chip_data(irq); 1719 1724 if (!cfg)
+1 -1
arch/x86/kernel/cpu/mcheck/mce-inject.c
··· 208 208 if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) 209 209 return -ENOMEM; 210 210 printk(KERN_INFO "Machine check injector initialized\n"); 211 - mce_chrdev_ops.write = mce_write; 211 + register_mce_write_callback(mce_write); 212 212 register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, 213 213 "mce_notify"); 214 214 return 0;
+22 -3
arch/x86/kernel/cpu/mcheck/mce.c
··· 1634 1634 } 1635 1635 } 1636 1636 1637 - /* Modified in mce-inject.c, so not static or const */ 1638 - struct file_operations mce_chrdev_ops = { 1637 + static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, 1638 + size_t usize, loff_t *off); 1639 + 1640 + void register_mce_write_callback(ssize_t (*fn)(struct file *filp, 1641 + const char __user *ubuf, 1642 + size_t usize, loff_t *off)) 1643 + { 1644 + mce_write = fn; 1645 + } 1646 + EXPORT_SYMBOL_GPL(register_mce_write_callback); 1647 + 1648 + ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, 1649 + size_t usize, loff_t *off) 1650 + { 1651 + if (mce_write) 1652 + return mce_write(filp, ubuf, usize, off); 1653 + else 1654 + return -EINVAL; 1655 + } 1656 + 1657 + static const struct file_operations mce_chrdev_ops = { 1639 1658 .open = mce_chrdev_open, 1640 1659 .release = mce_chrdev_release, 1641 1660 .read = mce_chrdev_read, 1661 + .write = mce_chrdev_write, 1642 1662 .poll = mce_chrdev_poll, 1643 1663 .unlocked_ioctl = mce_chrdev_ioctl, 1644 1664 .llseek = no_llseek, 1645 1665 }; 1646 - EXPORT_SYMBOL_GPL(mce_chrdev_ops); 1647 1666 1648 1667 static struct miscdevice mce_chrdev_device = { 1649 1668 MISC_MCELOG_MINOR,
+2 -1
arch/x86/kernel/nmi.c
··· 29 29 #include <asm/traps.h> 30 30 #include <asm/mach_traps.h> 31 31 #include <asm/nmi.h> 32 + #include <asm/x86_init.h> 32 33 33 34 #define NMI_MAX_NAMELEN 16 34 35 struct nmiaction { ··· 349 348 350 349 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */ 351 350 raw_spin_lock(&nmi_reason_lock); 352 - reason = get_nmi_reason(); 351 + reason = x86_platform.get_nmi_reason(); 353 352 354 353 if (reason & NMI_REASON_MASK) { 355 354 if (reason & NMI_REASON_SERR)
+2
arch/x86/kernel/setup.c
··· 1045 1045 1046 1046 x86_init.timers.wallclock_init(); 1047 1047 1048 + x86_platform.wallclock_init(); 1049 + 1048 1050 mcheck_init(); 1049 1051 1050 1052 arch_init_ideal_nops();
+4
arch/x86/kernel/x86_init.c
··· 21 21 #include <asm/pat.h> 22 22 #include <asm/tsc.h> 23 23 #include <asm/iommu.h> 24 + #include <asm/mach_traps.h> 24 25 25 26 void __cpuinit x86_init_noop(void) { } 26 27 void __init x86_init_uint_noop(unsigned int unused) { } 27 28 void __init x86_init_pgd_noop(pgd_t *unused) { } 28 29 int __init iommu_init_noop(void) { return 0; } 29 30 void iommu_shutdown_noop(void) { } 31 + void wallclock_init_noop(void) { } 30 32 31 33 /* 32 34 * The platform setup functions are preset with the default functions ··· 99 97 100 98 struct x86_platform_ops x86_platform = { 101 99 .calibrate_tsc = native_calibrate_tsc, 100 + .wallclock_init = wallclock_init_noop, 102 101 .get_wallclock = mach_get_cmos_time, 103 102 .set_wallclock = mach_set_rtc_mmss, 104 103 .iommu_shutdown = iommu_shutdown_noop, 105 104 .is_untracked_pat_range = is_ISA_range, 106 105 .nmi_init = default_nmi_init, 106 + .get_nmi_reason = default_get_nmi_reason, 107 107 .i8042_detect = default_i8042_detect 108 108 }; 109 109
+40 -4
arch/x86/platform/mrst/mrst.c
··· 187 187 static unsigned long __init mrst_calibrate_tsc(void) 188 188 { 189 189 unsigned long flags, fast_calibrate; 190 + if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) { 191 + u32 lo, hi, ratio, fsb; 190 192 191 - local_irq_save(flags); 192 - fast_calibrate = apbt_quick_calibrate(); 193 - local_irq_restore(flags); 194 - 193 + rdmsr(MSR_IA32_PERF_STATUS, lo, hi); 194 + pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi); 195 + ratio = (hi >> 8) & 0x1f; 196 + pr_debug("ratio is %d\n", ratio); 197 + if (!ratio) { 198 + pr_err("read a zero ratio, should be incorrect!\n"); 199 + pr_err("force tsc ratio to 16 ...\n"); 200 + ratio = 16; 201 + } 202 + rdmsr(MSR_FSB_FREQ, lo, hi); 203 + if ((lo & 0x7) == 0x7) 204 + fsb = PENWELL_FSB_FREQ_83SKU; 205 + else 206 + fsb = PENWELL_FSB_FREQ_100SKU; 207 + fast_calibrate = ratio * fsb; 208 + pr_debug("read penwell tsc %lu khz\n", fast_calibrate); 209 + lapic_timer_frequency = fsb * 1000 / HZ; 210 + /* mark tsc clocksource as reliable */ 211 + set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE); 212 + } else { 213 + local_irq_save(flags); 214 + fast_calibrate = apbt_quick_calibrate(); 215 + local_irq_restore(flags); 216 + } 217 + 195 218 if (fast_calibrate) 196 219 return fast_calibrate; 197 220 ··· 277 254 } 278 255 279 256 /* 257 + * Moorestown does not have external NMI source nor port 0x61 to report 258 + * NMI status. The possible NMI sources are from pmu as a result of NMI 259 + * watchdog or lock debug. Reading io port 0x61 results in 0xff which 260 + * misled NMI handler. 261 + */ 262 + static unsigned char mrst_get_nmi_reason(void) 263 + { 264 + return 0; 265 + } 266 + 267 + /* 280 268 * Moorestown specific x86_init function overrides and early setup 281 269 * calls. 282 270 */ ··· 308 274 x86_platform.calibrate_tsc = mrst_calibrate_tsc; 309 275 x86_platform.i8042_detect = mrst_i8042_detect; 310 276 x86_init.timers.wallclock_init = mrst_rtc_init; 277 + x86_platform.get_nmi_reason = mrst_get_nmi_reason; 278 + 311 279 x86_init.pci.init = pci_mrst_init; 312 280 x86_init.pci.fixup_irqs = x86_init_noop; 313 281