diff options
| -rw-r--r-- | arch/ia64/kernel/mca.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 23d54413c006..4f8464ead634 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
| @@ -630,6 +630,32 @@ copy_reg(const u64 *fr, u64 fnat, u64 *tr, u64 *tnat) | |||
| 630 | *tnat |= (nat << tslot); | 630 | *tnat |= (nat << tslot); |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | /* Change the comm field on the MCA/INT task to include the pid that | ||
| 634 | * was interrupted, it makes for easier debugging. If that pid was 0 | ||
| 635 | * (swapper or nested MCA/INIT) then use the start of the previous comm | ||
| 636 | * field suffixed with its cpu. | ||
| 637 | */ | ||
| 638 | |||
| 639 | static void | ||
| 640 | ia64_mca_modify_comm(const task_t *previous_current) | ||
| 641 | { | ||
| 642 | char *p, comm[sizeof(current->comm)]; | ||
| 643 | if (previous_current->pid) | ||
| 644 | snprintf(comm, sizeof(comm), "%s %d", | ||
| 645 | current->comm, previous_current->pid); | ||
| 646 | else { | ||
| 647 | int l; | ||
| 648 | if ((p = strchr(previous_current->comm, ' '))) | ||
| 649 | l = p - previous_current->comm; | ||
| 650 | else | ||
| 651 | l = strlen(previous_current->comm); | ||
| 652 | snprintf(comm, sizeof(comm), "%s %*s %d", | ||
| 653 | current->comm, l, previous_current->comm, | ||
| 654 | task_thread_info(previous_current)->cpu); | ||
| 655 | } | ||
| 656 | memcpy(current->comm, comm, sizeof(current->comm)); | ||
| 657 | } | ||
| 658 | |||
| 633 | /* On entry to this routine, we are running on the per cpu stack, see | 659 | /* On entry to this routine, we are running on the per cpu stack, see |
| 634 | * mca_asm.h. The original stack has not been touched by this event. Some of | 660 | * mca_asm.h. The original stack has not been touched by this event. Some of |
| 635 | * the original stack's registers will be in the RBS on this stack. This stack | 661 | * the original stack's registers will be in the RBS on this stack. This stack |
| @@ -648,7 +674,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
| 648 | struct ia64_sal_os_state *sos, | 674 | struct ia64_sal_os_state *sos, |
| 649 | const char *type) | 675 | const char *type) |
| 650 | { | 676 | { |
| 651 | char *p, comm[sizeof(current->comm)]; | 677 | char *p; |
| 652 | ia64_va va; | 678 | ia64_va va; |
| 653 | extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */ | 679 | extern char ia64_leave_kernel[]; /* Need asm address, not function descriptor */ |
| 654 | const pal_min_state_area_t *ms = sos->pal_min_state; | 680 | const pal_min_state_area_t *ms = sos->pal_min_state; |
| @@ -721,6 +747,10 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
| 721 | /* Verify the previous stack state before we change it */ | 747 | /* Verify the previous stack state before we change it */ |
| 722 | if (user_mode(regs)) { | 748 | if (user_mode(regs)) { |
| 723 | msg = "occurred in user space"; | 749 | msg = "occurred in user space"; |
| 750 | /* previous_current is guaranteed to be valid when the task was | ||
| 751 | * in user space, so ... | ||
| 752 | */ | ||
| 753 | ia64_mca_modify_comm(previous_current); | ||
| 724 | goto no_mod; | 754 | goto no_mod; |
| 725 | } | 755 | } |
| 726 | if (r13 != sos->prev_IA64_KR_CURRENT) { | 756 | if (r13 != sos->prev_IA64_KR_CURRENT) { |
| @@ -750,25 +780,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, | |||
| 750 | goto no_mod; | 780 | goto no_mod; |
| 751 | } | 781 | } |
| 752 | 782 | ||
| 753 | /* Change the comm field on the MCA/INT task to include the pid that | 783 | ia64_mca_modify_comm(previous_current); |
| 754 | * was interrupted, it makes for easier debugging. If that pid was 0 | ||
| 755 | * (swapper or nested MCA/INIT) then use the start of the previous comm | ||
| 756 | * field suffixed with its cpu. | ||
| 757 | */ | ||
| 758 | if (previous_current->pid) | ||
| 759 | snprintf(comm, sizeof(comm), "%s %d", | ||
| 760 | current->comm, previous_current->pid); | ||
| 761 | else { | ||
| 762 | int l; | ||
| 763 | if ((p = strchr(previous_current->comm, ' '))) | ||
| 764 | l = p - previous_current->comm; | ||
| 765 | else | ||
| 766 | l = strlen(previous_current->comm); | ||
| 767 | snprintf(comm, sizeof(comm), "%s %*s %d", | ||
| 768 | current->comm, l, previous_current->comm, | ||
| 769 | task_thread_info(previous_current)->cpu); | ||
| 770 | } | ||
| 771 | memcpy(current->comm, comm, sizeof(current->comm)); | ||
| 772 | 784 | ||
| 773 | /* Make the original task look blocked. First stack a struct pt_regs, | 785 | /* Make the original task look blocked. First stack a struct pt_regs, |
| 774 | * describing the state at the time of interrupt. mca_asm.S built a | 786 | * describing the state at the time of interrupt. mca_asm.S built a |
