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 |