diff options
Diffstat (limited to 'arch/ia64')
| -rw-r--r-- | arch/ia64/Kconfig | 14 | ||||
| -rw-r--r-- | arch/ia64/Kconfig.debug | 11 | ||||
| -rw-r--r-- | arch/ia64/hp/sim/simserial.c | 6 | ||||
| -rw-r--r-- | arch/ia64/ia32/ia32_ioctl.c | 4 | ||||
| -rw-r--r-- | arch/ia64/kernel/kprobes.c | 126 | ||||
| -rw-r--r-- | arch/ia64/kernel/mca_drv.c | 3 | ||||
| -rw-r--r-- | arch/ia64/kernel/perfmon.c | 2 | ||||
| -rw-r--r-- | arch/ia64/kernel/process.c | 34 | ||||
| -rw-r--r-- | arch/ia64/kernel/setup.c | 7 | ||||
| -rw-r--r-- | arch/ia64/kernel/smpboot.c | 1 | ||||
| -rw-r--r-- | arch/ia64/oprofile/Kconfig | 6 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 4 | ||||
| -rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_reg.c | 2 |
13 files changed, 119 insertions, 101 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 3b4248cff9a7..d4de8a4814be 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -191,6 +191,7 @@ config IOSAPIC | |||
| 191 | 191 | ||
| 192 | config IA64_SGI_SN_XP | 192 | config IA64_SGI_SN_XP |
| 193 | tristate "Support communication between SGI SSIs" | 193 | tristate "Support communication between SGI SSIs" |
| 194 | depends on IA64_GENERIC || IA64_SGI_SN2 | ||
| 194 | select IA64_UNCACHED_ALLOCATOR | 195 | select IA64_UNCACHED_ALLOCATOR |
| 195 | help | 196 | help |
| 196 | An SGI machine can be divided into multiple Single System | 197 | An SGI machine can be divided into multiple Single System |
| @@ -426,8 +427,21 @@ config GENERIC_PENDING_IRQ | |||
| 426 | 427 | ||
| 427 | source "arch/ia64/hp/sim/Kconfig" | 428 | source "arch/ia64/hp/sim/Kconfig" |
| 428 | 429 | ||
| 430 | menu "Instrumentation Support" | ||
| 431 | depends on EXPERIMENTAL | ||
| 432 | |||
| 429 | source "arch/ia64/oprofile/Kconfig" | 433 | source "arch/ia64/oprofile/Kconfig" |
| 430 | 434 | ||
| 435 | config KPROBES | ||
| 436 | bool "Kprobes (EXPERIMENTAL)" | ||
| 437 | help | ||
| 438 | Kprobes allows you to trap at almost any kernel address and | ||
| 439 | execute a callback function. register_kprobe() establishes | ||
| 440 | a probepoint and specifies the callback. Kprobes is useful | ||
| 441 | for kernel debugging, non-intrusive instrumentation and testing. | ||
| 442 | If in doubt, say "N". | ||
| 443 | endmenu | ||
| 444 | |||
| 431 | source "arch/ia64/Kconfig.debug" | 445 | source "arch/ia64/Kconfig.debug" |
| 432 | 446 | ||
| 433 | source "security/Kconfig" | 447 | source "security/Kconfig" |
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug index fda67ac993d7..de9d507ba0fd 100644 --- a/arch/ia64/Kconfig.debug +++ b/arch/ia64/Kconfig.debug | |||
| @@ -2,17 +2,6 @@ menu "Kernel hacking" | |||
| 2 | 2 | ||
| 3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
| 4 | 4 | ||
| 5 | config KPROBES | ||
| 6 | bool "Kprobes" | ||
| 7 | depends on DEBUG_KERNEL | ||
| 8 | help | ||
| 9 | Kprobes allows you to trap at almost any kernel address and | ||
| 10 | execute a callback function. register_kprobe() establishes | ||
| 11 | a probepoint and specifies the callback. Kprobes is useful | ||
| 12 | for kernel debugging, non-intrusive instrumentation and testing. | ||
| 13 | If in doubt, say "N". | ||
| 14 | |||
| 15 | |||
| 16 | choice | 5 | choice |
| 17 | prompt "Physical memory granularity" | 6 | prompt "Physical memory granularity" |
| 18 | default IA64_GRANULE_64MB | 7 | default IA64_GRANULE_64MB |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index b42ec37be51c..19ee635eeb70 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
| @@ -642,10 +642,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
| 642 | info->event = 0; | 642 | info->event = 0; |
| 643 | info->tty = 0; | 643 | info->tty = 0; |
| 644 | if (info->blocked_open) { | 644 | if (info->blocked_open) { |
| 645 | if (info->close_delay) { | 645 | if (info->close_delay) |
| 646 | current->state = TASK_INTERRUPTIBLE; | 646 | schedule_timeout_interruptible(info->close_delay); |
| 647 | schedule_timeout(info->close_delay); | ||
| 648 | } | ||
| 649 | wake_up_interruptible(&info->open_wait); | 647 | wake_up_interruptible(&info->open_wait); |
| 650 | } | 648 | } |
| 651 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 649 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c index 164b211f4174..88739394f6df 100644 --- a/arch/ia64/ia32/ia32_ioctl.c +++ b/arch/ia64/ia32/ia32_ioctl.c | |||
| @@ -29,10 +29,8 @@ | |||
| 29 | #define CODE | 29 | #define CODE |
| 30 | #include "compat_ioctl.c" | 30 | #include "compat_ioctl.c" |
| 31 | 31 | ||
| 32 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); | ||
| 33 | |||
| 34 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) | 32 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) |
| 35 | #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, | 33 | #define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL }, |
| 36 | #define IOCTL_TABLE_START \ | 34 | #define IOCTL_TABLE_START \ |
| 37 | struct ioctl_trans ioctl_start[] = { | 35 | struct ioctl_trans ioctl_start[] = { |
| 38 | #define IOCTL_TABLE_END \ | 36 | #define IOCTL_TABLE_END \ |
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 471086b808a4..96736a119c91 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
| 27 | #include <linux/kprobes.h> | 27 | #include <linux/kprobes.h> |
| 28 | #include <linux/ptrace.h> | 28 | #include <linux/ptrace.h> |
| 29 | #include <linux/spinlock.h> | ||
| 30 | #include <linux/string.h> | 29 | #include <linux/string.h> |
| 31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 32 | #include <linux/preempt.h> | 31 | #include <linux/preempt.h> |
| @@ -38,13 +37,8 @@ | |||
| 38 | 37 | ||
| 39 | extern void jprobe_inst_return(void); | 38 | extern void jprobe_inst_return(void); |
| 40 | 39 | ||
| 41 | /* kprobe_status settings */ | 40 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
| 42 | #define KPROBE_HIT_ACTIVE 0x00000001 | 41 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
| 43 | #define KPROBE_HIT_SS 0x00000002 | ||
| 44 | |||
| 45 | static struct kprobe *current_kprobe, *kprobe_prev; | ||
| 46 | static unsigned long kprobe_status, kprobe_status_prev; | ||
| 47 | static struct pt_regs jprobe_saved_regs; | ||
| 48 | 42 | ||
| 49 | enum instruction_type {A, I, M, F, B, L, X, u}; | 43 | enum instruction_type {A, I, M, F, B, L, X, u}; |
| 50 | static enum instruction_type bundle_encoding[32][3] = { | 44 | static enum instruction_type bundle_encoding[32][3] = { |
| @@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot, | |||
| 313 | return 0; | 307 | return 0; |
| 314 | } | 308 | } |
| 315 | 309 | ||
| 316 | static inline void save_previous_kprobe(void) | 310 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) |
| 317 | { | 311 | { |
| 318 | kprobe_prev = current_kprobe; | 312 | kcb->prev_kprobe.kp = kprobe_running(); |
| 319 | kprobe_status_prev = kprobe_status; | 313 | kcb->prev_kprobe.status = kcb->kprobe_status; |
| 320 | } | 314 | } |
| 321 | 315 | ||
| 322 | static inline void restore_previous_kprobe(void) | 316 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
| 323 | { | 317 | { |
| 324 | current_kprobe = kprobe_prev; | 318 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
| 325 | kprobe_status = kprobe_status_prev; | 319 | kcb->kprobe_status = kcb->prev_kprobe.status; |
| 326 | } | 320 | } |
| 327 | 321 | ||
| 328 | static inline void set_current_kprobe(struct kprobe *p) | 322 | static inline void set_current_kprobe(struct kprobe *p, |
| 323 | struct kprobe_ctlblk *kcb) | ||
| 329 | { | 324 | { |
| 330 | current_kprobe = p; | 325 | __get_cpu_var(current_kprobe) = p; |
| 331 | } | 326 | } |
| 332 | 327 | ||
| 333 | static void kretprobe_trampoline(void) | 328 | static void kretprobe_trampoline(void) |
| @@ -347,10 +342,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 347 | struct kretprobe_instance *ri = NULL; | 342 | struct kretprobe_instance *ri = NULL; |
| 348 | struct hlist_head *head; | 343 | struct hlist_head *head; |
| 349 | struct hlist_node *node, *tmp; | 344 | struct hlist_node *node, *tmp; |
| 350 | unsigned long orig_ret_address = 0; | 345 | unsigned long flags, orig_ret_address = 0; |
| 351 | unsigned long trampoline_address = | 346 | unsigned long trampoline_address = |
| 352 | ((struct fnptr *)kretprobe_trampoline)->ip; | 347 | ((struct fnptr *)kretprobe_trampoline)->ip; |
| 353 | 348 | ||
| 349 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
| 354 | head = kretprobe_inst_table_head(current); | 350 | head = kretprobe_inst_table_head(current); |
| 355 | 351 | ||
| 356 | /* | 352 | /* |
| @@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 389 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | 385 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); |
| 390 | regs->cr_iip = orig_ret_address; | 386 | regs->cr_iip = orig_ret_address; |
| 391 | 387 | ||
| 392 | unlock_kprobes(); | 388 | reset_current_kprobe(); |
| 389 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
| 393 | preempt_enable_no_resched(); | 390 | preempt_enable_no_resched(); |
| 394 | 391 | ||
| 395 | /* | 392 | /* |
| 396 | * By returning a non-zero value, we are telling | 393 | * By returning a non-zero value, we are telling |
| 397 | * kprobe_handler() that we have handled unlocking | 394 | * kprobe_handler() that we don't want the post_handler |
| 398 | * and re-enabling preemption. | 395 | * to run (and have re-enabled preemption) |
| 399 | */ | 396 | */ |
| 400 | return 1; | 397 | return 1; |
| 401 | } | 398 | } |
| 402 | 399 | ||
| 400 | /* Called with kretprobe_lock held */ | ||
| 403 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | 401 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, |
| 404 | struct pt_regs *regs) | 402 | struct pt_regs *regs) |
| 405 | { | 403 | { |
| @@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
| 606 | int ret = 0; | 604 | int ret = 0; |
| 607 | struct pt_regs *regs = args->regs; | 605 | struct pt_regs *regs = args->regs; |
| 608 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); | 606 | kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); |
| 607 | struct kprobe_ctlblk *kcb; | ||
| 609 | 608 | ||
| 609 | /* | ||
| 610 | * We don't want to be preempted for the entire | ||
| 611 | * duration of kprobe processing | ||
| 612 | */ | ||
| 610 | preempt_disable(); | 613 | preempt_disable(); |
| 614 | kcb = get_kprobe_ctlblk(); | ||
| 611 | 615 | ||
| 612 | /* Handle recursion cases */ | 616 | /* Handle recursion cases */ |
| 613 | if (kprobe_running()) { | 617 | if (kprobe_running()) { |
| 614 | p = get_kprobe(addr); | 618 | p = get_kprobe(addr); |
| 615 | if (p) { | 619 | if (p) { |
| 616 | if ( (kprobe_status == KPROBE_HIT_SS) && | 620 | if ((kcb->kprobe_status == KPROBE_HIT_SS) && |
| 617 | (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { | 621 | (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { |
| 618 | ia64_psr(regs)->ss = 0; | 622 | ia64_psr(regs)->ss = 0; |
| 619 | unlock_kprobes(); | ||
| 620 | goto no_kprobe; | 623 | goto no_kprobe; |
| 621 | } | 624 | } |
| 622 | /* We have reentered the pre_kprobe_handler(), since | 625 | /* We have reentered the pre_kprobe_handler(), since |
| @@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
| 625 | * just single step on the instruction of the new probe | 628 | * just single step on the instruction of the new probe |
| 626 | * without calling any user handlers. | 629 | * without calling any user handlers. |
| 627 | */ | 630 | */ |
| 628 | save_previous_kprobe(); | 631 | save_previous_kprobe(kcb); |
| 629 | set_current_kprobe(p); | 632 | set_current_kprobe(p, kcb); |
| 630 | p->nmissed++; | 633 | p->nmissed++; |
| 631 | prepare_ss(p, regs); | 634 | prepare_ss(p, regs); |
| 632 | kprobe_status = KPROBE_REENTER; | 635 | kcb->kprobe_status = KPROBE_REENTER; |
| 633 | return 1; | 636 | return 1; |
| 634 | } else if (args->err == __IA64_BREAK_JPROBE) { | 637 | } else if (args->err == __IA64_BREAK_JPROBE) { |
| 635 | /* | 638 | /* |
| 636 | * jprobe instrumented function just completed | 639 | * jprobe instrumented function just completed |
| 637 | */ | 640 | */ |
| 638 | p = current_kprobe; | 641 | p = __get_cpu_var(current_kprobe); |
| 639 | if (p->break_handler && p->break_handler(p, regs)) { | 642 | if (p->break_handler && p->break_handler(p, regs)) { |
| 640 | goto ss_probe; | 643 | goto ss_probe; |
| 641 | } | 644 | } |
| @@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
| 645 | } | 648 | } |
| 646 | } | 649 | } |
| 647 | 650 | ||
| 648 | lock_kprobes(); | ||
| 649 | p = get_kprobe(addr); | 651 | p = get_kprobe(addr); |
| 650 | if (!p) { | 652 | if (!p) { |
| 651 | unlock_kprobes(); | ||
| 652 | if (!is_ia64_break_inst(regs)) { | 653 | if (!is_ia64_break_inst(regs)) { |
| 653 | /* | 654 | /* |
| 654 | * The breakpoint instruction was removed right | 655 | * The breakpoint instruction was removed right |
| @@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
| 665 | goto no_kprobe; | 666 | goto no_kprobe; |
| 666 | } | 667 | } |
| 667 | 668 | ||
| 668 | kprobe_status = KPROBE_HIT_ACTIVE; | 669 | set_current_kprobe(p, kcb); |
| 669 | set_current_kprobe(p); | 670 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
| 670 | 671 | ||
| 671 | if (p->pre_handler && p->pre_handler(p, regs)) | 672 | if (p->pre_handler && p->pre_handler(p, regs)) |
| 672 | /* | 673 | /* |
| @@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) | |||
| 678 | 679 | ||
| 679 | ss_probe: | 680 | ss_probe: |
| 680 | prepare_ss(p, regs); | 681 | prepare_ss(p, regs); |
| 681 | kprobe_status = KPROBE_HIT_SS; | 682 | kcb->kprobe_status = KPROBE_HIT_SS; |
| 682 | return 1; | 683 | return 1; |
| 683 | 684 | ||
| 684 | no_kprobe: | 685 | no_kprobe: |
| @@ -688,23 +689,25 @@ no_kprobe: | |||
| 688 | 689 | ||
| 689 | static int __kprobes post_kprobes_handler(struct pt_regs *regs) | 690 | static int __kprobes post_kprobes_handler(struct pt_regs *regs) |
| 690 | { | 691 | { |
| 691 | if (!kprobe_running()) | 692 | struct kprobe *cur = kprobe_running(); |
| 693 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
| 694 | |||
| 695 | if (!cur) | ||
| 692 | return 0; | 696 | return 0; |
| 693 | 697 | ||
| 694 | if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { | 698 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { |
| 695 | kprobe_status = KPROBE_HIT_SSDONE; | 699 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
| 696 | current_kprobe->post_handler(current_kprobe, regs, 0); | 700 | cur->post_handler(cur, regs, 0); |
| 697 | } | 701 | } |
| 698 | 702 | ||
| 699 | resume_execution(current_kprobe, regs); | 703 | resume_execution(cur, regs); |
| 700 | 704 | ||
| 701 | /*Restore back the original saved kprobes variables and continue. */ | 705 | /*Restore back the original saved kprobes variables and continue. */ |
| 702 | if (kprobe_status == KPROBE_REENTER) { | 706 | if (kcb->kprobe_status == KPROBE_REENTER) { |
| 703 | restore_previous_kprobe(); | 707 | restore_previous_kprobe(kcb); |
| 704 | goto out; | 708 | goto out; |
| 705 | } | 709 | } |
| 706 | 710 | reset_current_kprobe(); | |
| 707 | unlock_kprobes(); | ||
| 708 | 711 | ||
| 709 | out: | 712 | out: |
| 710 | preempt_enable_no_resched(); | 713 | preempt_enable_no_resched(); |
| @@ -713,16 +716,15 @@ out: | |||
| 713 | 716 | ||
| 714 | static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) | 717 | static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) |
| 715 | { | 718 | { |
| 716 | if (!kprobe_running()) | 719 | struct kprobe *cur = kprobe_running(); |
| 717 | return 0; | 720 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 718 | 721 | ||
| 719 | if (current_kprobe->fault_handler && | 722 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) |
| 720 | current_kprobe->fault_handler(current_kprobe, regs, trapnr)) | ||
| 721 | return 1; | 723 | return 1; |
| 722 | 724 | ||
| 723 | if (kprobe_status & KPROBE_HIT_SS) { | 725 | if (kcb->kprobe_status & KPROBE_HIT_SS) { |
| 724 | resume_execution(current_kprobe, regs); | 726 | resume_execution(cur, regs); |
| 725 | unlock_kprobes(); | 727 | reset_current_kprobe(); |
| 726 | preempt_enable_no_resched(); | 728 | preempt_enable_no_resched(); |
| 727 | } | 729 | } |
| 728 | 730 | ||
| @@ -733,31 +735,38 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
| 733 | unsigned long val, void *data) | 735 | unsigned long val, void *data) |
| 734 | { | 736 | { |
| 735 | struct die_args *args = (struct die_args *)data; | 737 | struct die_args *args = (struct die_args *)data; |
| 738 | int ret = NOTIFY_DONE; | ||
| 739 | |||
| 736 | switch(val) { | 740 | switch(val) { |
| 737 | case DIE_BREAK: | 741 | case DIE_BREAK: |
| 738 | if (pre_kprobes_handler(args)) | 742 | if (pre_kprobes_handler(args)) |
| 739 | return NOTIFY_STOP; | 743 | ret = NOTIFY_STOP; |
| 740 | break; | 744 | break; |
| 741 | case DIE_SS: | 745 | case DIE_SS: |
| 742 | if (post_kprobes_handler(args->regs)) | 746 | if (post_kprobes_handler(args->regs)) |
| 743 | return NOTIFY_STOP; | 747 | ret = NOTIFY_STOP; |
| 744 | break; | 748 | break; |
| 745 | case DIE_PAGE_FAULT: | 749 | case DIE_PAGE_FAULT: |
| 746 | if (kprobes_fault_handler(args->regs, args->trapnr)) | 750 | /* kprobe_running() needs smp_processor_id() */ |
| 747 | return NOTIFY_STOP; | 751 | preempt_disable(); |
| 752 | if (kprobe_running() && | ||
| 753 | kprobes_fault_handler(args->regs, args->trapnr)) | ||
| 754 | ret = NOTIFY_STOP; | ||
| 755 | preempt_enable(); | ||
| 748 | default: | 756 | default: |
| 749 | break; | 757 | break; |
| 750 | } | 758 | } |
| 751 | return NOTIFY_DONE; | 759 | return ret; |
| 752 | } | 760 | } |
| 753 | 761 | ||
| 754 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 762 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
| 755 | { | 763 | { |
| 756 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 764 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
| 757 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; | 765 | unsigned long addr = ((struct fnptr *)(jp->entry))->ip; |
| 766 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
| 758 | 767 | ||
| 759 | /* save architectural state */ | 768 | /* save architectural state */ |
| 760 | jprobe_saved_regs = *regs; | 769 | kcb->jprobe_saved_regs = *regs; |
| 761 | 770 | ||
| 762 | /* after rfi, execute the jprobe instrumented function */ | 771 | /* after rfi, execute the jprobe instrumented function */ |
| 763 | regs->cr_iip = addr & ~0xFULL; | 772 | regs->cr_iip = addr & ~0xFULL; |
| @@ -775,7 +784,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 775 | 784 | ||
| 776 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 785 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
| 777 | { | 786 | { |
| 778 | *regs = jprobe_saved_regs; | 787 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 788 | |||
| 789 | *regs = kcb->jprobe_saved_regs; | ||
| 790 | preempt_enable_no_resched(); | ||
| 779 | return 1; | 791 | return 1; |
| 780 | } | 792 | } |
| 781 | 793 | ||
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index f081c60ab206..eb39bc9c133b 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
| @@ -88,7 +88,7 @@ mca_page_isolate(unsigned long paddr) | |||
| 88 | if (!ia64_phys_addr_valid(paddr)) | 88 | if (!ia64_phys_addr_valid(paddr)) |
| 89 | return ISOLATE_NONE; | 89 | return ISOLATE_NONE; |
| 90 | 90 | ||
| 91 | if (!pfn_valid(paddr)) | 91 | if (!pfn_valid(paddr >> PAGE_SHIFT)) |
| 92 | return ISOLATE_NONE; | 92 | return ISOLATE_NONE; |
| 93 | 93 | ||
| 94 | /* convert physical address to physical page number */ | 94 | /* convert physical address to physical page number */ |
| @@ -108,6 +108,7 @@ mca_page_isolate(unsigned long paddr) | |||
| 108 | return ISOLATE_NG; | 108 | return ISOLATE_NG; |
| 109 | 109 | ||
| 110 | /* add attribute 'Reserved' and register the page */ | 110 | /* add attribute 'Reserved' and register the page */ |
| 111 | get_page(p); | ||
| 111 | SetPageReserved(p); | 112 | SetPageReserved(p); |
| 112 | page_isolate[num_page_isolate++] = p; | 113 | page_isolate[num_page_isolate++] = p; |
| 113 | 114 | ||
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index f7dfc107cb7b..410d4804fa6e 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
| @@ -4940,7 +4940,7 @@ abort_locked: | |||
| 4940 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; | 4940 | if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT; |
| 4941 | 4941 | ||
| 4942 | error_args: | 4942 | error_args: |
| 4943 | if (args_k) kfree(args_k); | 4943 | kfree(args_k); |
| 4944 | 4944 | ||
| 4945 | DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); | 4945 | DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret)); |
| 4946 | 4946 | ||
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 051e050359e4..640d6908f8ec 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
| @@ -197,11 +197,15 @@ void | |||
| 197 | default_idle (void) | 197 | default_idle (void) |
| 198 | { | 198 | { |
| 199 | local_irq_enable(); | 199 | local_irq_enable(); |
| 200 | while (!need_resched()) | 200 | while (!need_resched()) { |
| 201 | if (can_do_pal_halt) | 201 | if (can_do_pal_halt) { |
| 202 | safe_halt(); | 202 | local_irq_disable(); |
| 203 | else | 203 | if (!need_resched()) |
| 204 | safe_halt(); | ||
| 205 | local_irq_enable(); | ||
| 206 | } else | ||
| 204 | cpu_relax(); | 207 | cpu_relax(); |
| 208 | } | ||
| 205 | } | 209 | } |
| 206 | 210 | ||
| 207 | #ifdef CONFIG_HOTPLUG_CPU | 211 | #ifdef CONFIG_HOTPLUG_CPU |
| @@ -263,16 +267,16 @@ void __attribute__((noreturn)) | |||
| 263 | cpu_idle (void) | 267 | cpu_idle (void) |
| 264 | { | 268 | { |
| 265 | void (*mark_idle)(int) = ia64_mark_idle; | 269 | void (*mark_idle)(int) = ia64_mark_idle; |
| 270 | int cpu = smp_processor_id(); | ||
| 271 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 266 | 272 | ||
| 267 | /* endless idle loop with no priority at all */ | 273 | /* endless idle loop with no priority at all */ |
| 268 | while (1) { | 274 | while (1) { |
| 275 | if (!need_resched()) { | ||
| 276 | void (*idle)(void); | ||
| 269 | #ifdef CONFIG_SMP | 277 | #ifdef CONFIG_SMP |
| 270 | if (!need_resched()) | ||
| 271 | min_xtp(); | 278 | min_xtp(); |
| 272 | #endif | 279 | #endif |
| 273 | while (!need_resched()) { | ||
| 274 | void (*idle)(void); | ||
| 275 | |||
| 276 | if (__get_cpu_var(cpu_idle_state)) | 280 | if (__get_cpu_var(cpu_idle_state)) |
| 277 | __get_cpu_var(cpu_idle_state) = 0; | 281 | __get_cpu_var(cpu_idle_state) = 0; |
| 278 | 282 | ||
| @@ -284,17 +288,17 @@ cpu_idle (void) | |||
| 284 | if (!idle) | 288 | if (!idle) |
| 285 | idle = default_idle; | 289 | idle = default_idle; |
| 286 | (*idle)(); | 290 | (*idle)(); |
| 287 | } | 291 | if (mark_idle) |
| 288 | 292 | (*mark_idle)(0); | |
| 289 | if (mark_idle) | ||
| 290 | (*mark_idle)(0); | ||
| 291 | |||
| 292 | #ifdef CONFIG_SMP | 293 | #ifdef CONFIG_SMP |
| 293 | normal_xtp(); | 294 | normal_xtp(); |
| 294 | #endif | 295 | #endif |
| 296 | } | ||
| 297 | preempt_enable_no_resched(); | ||
| 295 | schedule(); | 298 | schedule(); |
| 299 | preempt_disable(); | ||
| 296 | check_pgt_cache(); | 300 | check_pgt_cache(); |
| 297 | if (cpu_is_offline(smp_processor_id())) | 301 | if (cpu_is_offline(cpu)) |
| 298 | play_dead(); | 302 | play_dead(); |
| 299 | } | 303 | } |
| 300 | } | 304 | } |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index fc56ca2da358..3af6de36a482 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
| @@ -92,6 +92,13 @@ extern void efi_initialize_iomem_resources(struct resource *, | |||
| 92 | extern char _text[], _end[], _etext[]; | 92 | extern char _text[], _end[], _etext[]; |
| 93 | 93 | ||
| 94 | unsigned long ia64_max_cacheline_size; | 94 | unsigned long ia64_max_cacheline_size; |
| 95 | |||
| 96 | int dma_get_cache_alignment(void) | ||
| 97 | { | ||
| 98 | return ia64_max_cacheline_size; | ||
| 99 | } | ||
| 100 | EXPORT_SYMBOL(dma_get_cache_alignment); | ||
| 101 | |||
| 95 | unsigned long ia64_iobase; /* virtual address for I/O accesses */ | 102 | unsigned long ia64_iobase; /* virtual address for I/O accesses */ |
| 96 | EXPORT_SYMBOL(ia64_iobase); | 103 | EXPORT_SYMBOL(ia64_iobase); |
| 97 | struct io_space io_space[MAX_IO_SPACES]; | 104 | struct io_space io_space[MAX_IO_SPACES]; |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 400a48987124..8f44e7d2df66 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
| @@ -399,6 +399,7 @@ start_secondary (void *unused) | |||
| 399 | Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); | 399 | Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id()); |
| 400 | efi_map_pal_code(); | 400 | efi_map_pal_code(); |
| 401 | cpu_init(); | 401 | cpu_init(); |
| 402 | preempt_disable(); | ||
| 402 | smp_callin(); | 403 | smp_callin(); |
| 403 | 404 | ||
| 404 | cpu_idle(); | 405 | cpu_idle(); |
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig index 56e6f614b04a..97271ab484dc 100644 --- a/arch/ia64/oprofile/Kconfig +++ b/arch/ia64/oprofile/Kconfig | |||
| @@ -1,7 +1,3 @@ | |||
| 1 | |||
| 2 | menu "Profiling support" | ||
| 3 | depends on EXPERIMENTAL | ||
| 4 | |||
| 5 | config PROFILING | 1 | config PROFILING |
| 6 | bool "Profiling support (EXPERIMENTAL)" | 2 | bool "Profiling support (EXPERIMENTAL)" |
| 7 | help | 3 | help |
| @@ -22,5 +18,3 @@ config OPROFILE | |||
| 22 | 18 | ||
| 23 | If unsure, say N. | 19 | If unsure, say N. |
| 24 | 20 | ||
| 25 | endmenu | ||
| 26 | |||
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 7b03b8084ffc..1f500c81002c 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
| @@ -212,13 +212,13 @@ void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info) | |||
| 212 | pdi_pcibus_info; | 212 | pdi_pcibus_info; |
| 213 | 213 | ||
| 214 | /* Disable the device's IRQ */ | 214 | /* Disable the device's IRQ */ |
| 215 | pcireg_intr_enable_bit_clr(pcibus_info, bit); | 215 | pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit)); |
| 216 | 216 | ||
| 217 | /* Change the device's IRQ */ | 217 | /* Change the device's IRQ */ |
| 218 | pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); | 218 | pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr); |
| 219 | 219 | ||
| 220 | /* Re-enable the device's IRQ */ | 220 | /* Re-enable the device's IRQ */ |
| 221 | pcireg_intr_enable_bit_set(pcibus_info, bit); | 221 | pcireg_intr_enable_bit_set(pcibus_info, (1 << bit)); |
| 222 | 222 | ||
| 223 | pcibr_force_interrupt(sn_irq_info); | 223 | pcibr_force_interrupt(sn_irq_info); |
| 224 | } | 224 | } |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c index 4f718c3e93d3..5d534091262c 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c | |||
| @@ -131,7 +131,7 @@ void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits) | |||
| 131 | __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); | 131 | __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); |
| 132 | break; | 132 | break; |
| 133 | case PCIBR_BRIDGETYPE_PIC: | 133 | case PCIBR_BRIDGETYPE_PIC: |
| 134 | __sn_clrq_relaxed(&ptr->pic.p_int_enable, ~bits); | 134 | __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits); |
| 135 | break; | 135 | break; |
| 136 | default: | 136 | default: |
| 137 | panic | 137 | panic |
