aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-28 15:55:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-28 15:55:55 -0400
commitc4a227d89f758e582fd167bb15245f2704de99ef (patch)
treef5b6e0091e6543c14d1cd7cf1f93e097a96bbd64 /arch
parent87367a0b71a5188e34a913c05673b5078f71a64d (diff)
parentf506b3dc0ec454a16d40cab9ee5d75435b39dc50 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (25 commits) perf: Fix SIGIO handling perf top: Don't stop if no kernel symtab is found perf top: Handle kptr_restrict perf top: Remove unused macro perf events: initialize fd array to -1 instead of 0 perf tools: Make sure kptr_restrict warnings fit 80 col terms perf tools: Fix build on older systems perf symbols: Handle /proc/sys/kernel/kptr_restrict perf: Remove duplicate headers ftrace: Add internal recursive checks tracing: Update btrfs's tracepoints to use u64 interface tracing: Add __print_symbolic_u64 to avoid warnings on 32bit machine ftrace: Set ops->flag to enabled even on static function tracing tracing: Have event with function tracer check error return ftrace: Have ftrace_startup() return failure code jump_label: Check entries limit in __jump_label_update ftrace/recordmcount: Avoid STT_FUNC symbols as base on ARM scripts/tags.sh: Add magic for trace-events for etags too scripts/tags.sh: Fix ctags for DEFINE_EVENT() x86/ftrace: Fix compiler warning in ftrace.c ...
Diffstat (limited to 'arch')
-rw-r--r--arch/blackfin/mm/maccess.c4
-rw-r--r--arch/s390/mm/maccess.c4
-rw-r--r--arch/x86/kernel/ftrace.c12
-rw-r--r--arch/x86/oprofile/op_model_amd.c95
4 files changed, 64 insertions, 51 deletions
diff --git a/arch/blackfin/mm/maccess.c b/arch/blackfin/mm/maccess.c
index b71cebc1f8a3..e2532114c5fd 100644
--- a/arch/blackfin/mm/maccess.c
+++ b/arch/blackfin/mm/maccess.c
@@ -16,7 +16,7 @@ static int validate_memory_access_address(unsigned long addr, int size)
16 return bfin_mem_access_type(addr, size); 16 return bfin_mem_access_type(addr, size);
17} 17}
18 18
19long probe_kernel_read(void *dst, void *src, size_t size) 19long probe_kernel_read(void *dst, const void *src, size_t size)
20{ 20{
21 unsigned long lsrc = (unsigned long)src; 21 unsigned long lsrc = (unsigned long)src;
22 int mem_type; 22 int mem_type;
@@ -55,7 +55,7 @@ long probe_kernel_read(void *dst, void *src, size_t size)
55 return -EFAULT; 55 return -EFAULT;
56} 56}
57 57
58long probe_kernel_write(void *dst, void *src, size_t size) 58long probe_kernel_write(void *dst, const void *src, size_t size)
59{ 59{
60 unsigned long ldst = (unsigned long)dst; 60 unsigned long ldst = (unsigned long)dst;
61 int mem_type; 61 int mem_type;
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 71a4b0d34be0..51e5cd9b906a 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -19,7 +19,7 @@
19 * using the stura instruction. 19 * using the stura instruction.
20 * Returns the number of bytes copied or -EFAULT. 20 * Returns the number of bytes copied or -EFAULT.
21 */ 21 */
22static long probe_kernel_write_odd(void *dst, void *src, size_t size) 22static long probe_kernel_write_odd(void *dst, const void *src, size_t size)
23{ 23{
24 unsigned long count, aligned; 24 unsigned long count, aligned;
25 int offset, mask; 25 int offset, mask;
@@ -45,7 +45,7 @@ static long probe_kernel_write_odd(void *dst, void *src, size_t size)
45 return rc ? rc : count; 45 return rc ? rc : count;
46} 46}
47 47
48long probe_kernel_write(void *dst, void *src, size_t size) 48long probe_kernel_write(void *dst, const void *src, size_t size)
49{ 49{
50 long copied = 0; 50 long copied = 0;
51 51
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 0ba15a6cc57e..c9a281f272fd 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -123,7 +123,7 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
123static atomic_t nmi_running = ATOMIC_INIT(0); 123static atomic_t nmi_running = ATOMIC_INIT(0);
124static int mod_code_status; /* holds return value of text write */ 124static int mod_code_status; /* holds return value of text write */
125static void *mod_code_ip; /* holds the IP to write to */ 125static void *mod_code_ip; /* holds the IP to write to */
126static void *mod_code_newcode; /* holds the text to write to the IP */ 126static const void *mod_code_newcode; /* holds the text to write to the IP */
127 127
128static unsigned nmi_wait_count; 128static unsigned nmi_wait_count;
129static atomic_t nmi_update_count = ATOMIC_INIT(0); 129static atomic_t nmi_update_count = ATOMIC_INIT(0);
@@ -225,7 +225,7 @@ within(unsigned long addr, unsigned long start, unsigned long end)
225} 225}
226 226
227static int 227static int
228do_ftrace_mod_code(unsigned long ip, void *new_code) 228do_ftrace_mod_code(unsigned long ip, const void *new_code)
229{ 229{
230 /* 230 /*
231 * On x86_64, kernel text mappings are mapped read-only with 231 * On x86_64, kernel text mappings are mapped read-only with
@@ -266,8 +266,8 @@ static const unsigned char *ftrace_nop_replace(void)
266} 266}
267 267
268static int 268static int
269ftrace_modify_code(unsigned long ip, unsigned char *old_code, 269ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
270 unsigned char *new_code) 270 unsigned const char *new_code)
271{ 271{
272 unsigned char replaced[MCOUNT_INSN_SIZE]; 272 unsigned char replaced[MCOUNT_INSN_SIZE];
273 273
@@ -301,7 +301,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
301int ftrace_make_nop(struct module *mod, 301int ftrace_make_nop(struct module *mod,
302 struct dyn_ftrace *rec, unsigned long addr) 302 struct dyn_ftrace *rec, unsigned long addr)
303{ 303{
304 unsigned char *new, *old; 304 unsigned const char *new, *old;
305 unsigned long ip = rec->ip; 305 unsigned long ip = rec->ip;
306 306
307 old = ftrace_call_replace(ip, addr); 307 old = ftrace_call_replace(ip, addr);
@@ -312,7 +312,7 @@ int ftrace_make_nop(struct module *mod,
312 312
313int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 313int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
314{ 314{
315 unsigned char *new, *old; 315 unsigned const char *new, *old;
316 unsigned long ip = rec->ip; 316 unsigned long ip = rec->ip;
317 317
318 old = ftrace_nop_replace(); 318 old = ftrace_nop_replace();
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index c3b8e24f2b16..9fd8a567fe1e 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -316,16 +316,23 @@ static void op_amd_stop_ibs(void)
316 wrmsrl(MSR_AMD64_IBSOPCTL, 0); 316 wrmsrl(MSR_AMD64_IBSOPCTL, 0);
317} 317}
318 318
319static inline int eilvt_is_available(int offset) 319static inline int get_eilvt(int offset)
320{ 320{
321 /* check if we may assign a vector */
322 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); 321 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
323} 322}
324 323
324static inline int put_eilvt(int offset)
325{
326 return !setup_APIC_eilvt(offset, 0, 0, 1);
327}
328
325static inline int ibs_eilvt_valid(void) 329static inline int ibs_eilvt_valid(void)
326{ 330{
327 int offset; 331 int offset;
328 u64 val; 332 u64 val;
333 int valid = 0;
334
335 preempt_disable();
329 336
330 rdmsrl(MSR_AMD64_IBSCTL, val); 337 rdmsrl(MSR_AMD64_IBSCTL, val);
331 offset = val & IBSCTL_LVT_OFFSET_MASK; 338 offset = val & IBSCTL_LVT_OFFSET_MASK;
@@ -333,16 +340,20 @@ static inline int ibs_eilvt_valid(void)
333 if (!(val & IBSCTL_LVT_OFFSET_VALID)) { 340 if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
334 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", 341 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
335 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 342 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
336 return 0; 343 goto out;
337 } 344 }
338 345
339 if (!eilvt_is_available(offset)) { 346 if (!get_eilvt(offset)) {
340 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", 347 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
341 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 348 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
342 return 0; 349 goto out;
343 } 350 }
344 351
345 return 1; 352 valid = 1;
353out:
354 preempt_enable();
355
356 return valid;
346} 357}
347 358
348static inline int get_ibs_offset(void) 359static inline int get_ibs_offset(void)
@@ -600,67 +611,69 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
600 611
601static int force_ibs_eilvt_setup(void) 612static int force_ibs_eilvt_setup(void)
602{ 613{
603 int i; 614 int offset;
604 int ret; 615 int ret;
605 616
606 /* find the next free available EILVT entry */ 617 /*
607 for (i = 1; i < 4; i++) { 618 * find the next free available EILVT entry, skip offset 0,
608 if (!eilvt_is_available(i)) 619 * pin search to this cpu
609 continue; 620 */
610 ret = setup_ibs_ctl(i); 621 preempt_disable();
611 if (ret) 622 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
612 return ret; 623 if (get_eilvt(offset))
613 pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); 624 break;
614 return 0;
615 } 625 }
626 preempt_enable();
616 627
617 printk(KERN_DEBUG "No EILVT entry available\n"); 628 if (offset == APIC_EILVT_NR_MAX) {
618 629 printk(KERN_DEBUG "No EILVT entry available\n");
619 return -EBUSY; 630 return -EBUSY;
620} 631 }
621
622static int __init_ibs_nmi(void)
623{
624 int ret;
625
626 if (ibs_eilvt_valid())
627 return 0;
628 632
629 ret = force_ibs_eilvt_setup(); 633 ret = setup_ibs_ctl(offset);
630 if (ret) 634 if (ret)
631 return ret; 635 goto out;
632 636
633 if (!ibs_eilvt_valid()) 637 if (!ibs_eilvt_valid()) {
634 return -EFAULT; 638 ret = -EFAULT;
639 goto out;
640 }
635 641
642 pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
636 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); 643 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
637 644
638 return 0; 645 return 0;
646out:
647 preempt_disable();
648 put_eilvt(offset);
649 preempt_enable();
650 return ret;
639} 651}
640 652
641/* 653/*
642 * check and reserve APIC extended interrupt LVT offset for IBS if 654 * check and reserve APIC extended interrupt LVT offset for IBS if
643 * available 655 * available
644 *
645 * init_ibs() preforms implicitly cpu-local operations, so pin this
646 * thread to its current CPU
647 */ 656 */
648 657
649static void init_ibs(void) 658static void init_ibs(void)
650{ 659{
651 preempt_disable();
652
653 ibs_caps = get_ibs_caps(); 660 ibs_caps = get_ibs_caps();
661
654 if (!ibs_caps) 662 if (!ibs_caps)
663 return;
664
665 if (ibs_eilvt_valid())
655 goto out; 666 goto out;
656 667
657 if (__init_ibs_nmi() < 0) 668 if (!force_ibs_eilvt_setup())
658 ibs_caps = 0; 669 goto out;
659 else 670
660 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 671 /* Failed to setup ibs */
672 ibs_caps = 0;
673 return;
661 674
662out: 675out:
663 preempt_enable(); 676 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
664} 677}
665 678
666static int (*create_arch_files)(struct super_block *sb, struct dentry *root); 679static int (*create_arch_files)(struct super_block *sb, struct dentry *root);