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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull perf fixes from Ingo Molnar:

- an s2ram related fix on AMD systems

- a perf fault handling bug that is relatively old but which has become
much easier to trigger in v3.13 after commit e00b12e64be9 ("perf/x86:
Further optimize copy_from_user_nmi()")

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/amd/ibs: Fix waking up from S3 for AMD family 10h
x86, mm, perf: Allow recursive faults from interrupts

+63 -8
+45 -8
arch/x86/kernel/cpu/perf_event_amd_ibs.c
··· 10 10 #include <linux/module.h> 11 11 #include <linux/pci.h> 12 12 #include <linux/ptrace.h> 13 + #include <linux/syscore_ops.h> 13 14 14 15 #include <asm/apic.h> 15 16 ··· 817 816 return ret; 818 817 } 819 818 819 + static void ibs_eilvt_setup(void) 820 + { 821 + /* 822 + * Force LVT offset assignment for family 10h: The offsets are 823 + * not assigned by the BIOS for this family, so the OS is 824 + * responsible for doing it. If the OS assignment fails, fall 825 + * back to BIOS settings and try to setup this. 826 + */ 827 + if (boot_cpu_data.x86 == 0x10) 828 + force_ibs_eilvt_setup(); 829 + } 830 + 820 831 static inline int get_ibs_lvt_offset(void) 821 832 { 822 833 u64 val; ··· 864 851 setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1); 865 852 } 866 853 854 + #ifdef CONFIG_PM 855 + 856 + static int perf_ibs_suspend(void) 857 + { 858 + clear_APIC_ibs(NULL); 859 + return 0; 860 + } 861 + 862 + static void perf_ibs_resume(void) 863 + { 864 + ibs_eilvt_setup(); 865 + setup_APIC_ibs(NULL); 866 + } 867 + 868 + static struct syscore_ops perf_ibs_syscore_ops = { 869 + .resume = perf_ibs_resume, 870 + .suspend = perf_ibs_suspend, 871 + }; 872 + 873 + static void perf_ibs_pm_init(void) 874 + { 875 + register_syscore_ops(&perf_ibs_syscore_ops); 876 + } 877 + 878 + #else 879 + 880 + static inline void perf_ibs_pm_init(void) { } 881 + 882 + #endif 883 + 867 884 static int 868 885 perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) 869 886 { ··· 920 877 if (!caps) 921 878 return -ENODEV; /* ibs not supported by the cpu */ 922 879 923 - /* 924 - * Force LVT offset assignment for family 10h: The offsets are 925 - * not assigned by the BIOS for this family, so the OS is 926 - * responsible for doing it. If the OS assignment fails, fall 927 - * back to BIOS settings and try to setup this. 928 - */ 929 - if (boot_cpu_data.x86 == 0x10) 930 - force_ibs_eilvt_setup(); 880 + ibs_eilvt_setup(); 931 881 932 882 if (!ibs_eilvt_valid()) 933 883 goto out; 934 884 885 + perf_ibs_pm_init(); 935 886 get_online_cpus(); 936 887 ibs_caps = caps; 937 888 /* make ibs_caps visible to other cpus: */
+18
arch/x86/mm/fault.c
··· 641 641 642 642 /* Are we prepared to handle this kernel fault? */ 643 643 if (fixup_exception(regs)) { 644 + /* 645 + * Any interrupt that takes a fault gets the fixup. This makes 646 + * the below recursive fault logic only apply to a faults from 647 + * task context. 648 + */ 649 + if (in_interrupt()) 650 + return; 651 + 652 + /* 653 + * Per the above we're !in_interrupt(), aka. task context. 654 + * 655 + * In this case we need to make sure we're not recursively 656 + * faulting through the emulate_vsyscall() logic. 657 + */ 644 658 if (current_thread_info()->sig_on_uaccess_error && signal) { 645 659 tsk->thread.trap_nr = X86_TRAP_PF; 646 660 tsk->thread.error_code = error_code | PF_USER; ··· 663 649 /* XXX: hwpoison faults will set the wrong code. */ 664 650 force_sig_info_fault(signal, si_code, address, tsk, 0); 665 651 } 652 + 653 + /* 654 + * Barring that, we can do the fixup and be happy. 655 + */ 666 656 return; 667 657 } 668 658