diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:47:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:47:41 -0400 |
| commit | e225ca27057e70e7cbb14ae4c1e5f758973af645 (patch) | |
| tree | 80a2de6cddda12d11b5379dca312e3fae507e225 | |
| parent | 54f7fc25e5736c39050454fe6b5a2bed027fbfab (diff) | |
| parent | 55c2770e413e96871147b9406a9c41fe9bc5209c (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull Sparc updates from David Miller:
1) Updated syscall tracing fix from Al Viro.
2) SUN4V error reporting was deficient in several areas.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: fix ptrace interaction with force_successful_syscall_return()
sparc64: Fix deficiencies in sun4v error reporting.
| -rw-r--r-- | arch/sparc/include/asm/uaccess_64.h | 5 | ||||
| -rw-r--r-- | arch/sparc/kernel/syscalls.S | 32 | ||||
| -rw-r--r-- | arch/sparc/kernel/traps_64.c | 263 | ||||
| -rw-r--r-- | arch/sparc/mm/fault_64.c | 2 |
4 files changed, 221 insertions, 81 deletions
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 7c831d848b4e..73083e1d38d9 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h | |||
| @@ -265,6 +265,11 @@ extern __must_check long strnlen_user(const char __user *str, long n); | |||
| 265 | #define __copy_to_user_inatomic ___copy_to_user | 265 | #define __copy_to_user_inatomic ___copy_to_user |
| 266 | #define __copy_from_user_inatomic ___copy_from_user | 266 | #define __copy_from_user_inatomic ___copy_from_user |
| 267 | 267 | ||
| 268 | struct pt_regs; | ||
| 269 | extern unsigned long compute_effective_address(struct pt_regs *, | ||
| 270 | unsigned int insn, | ||
| 271 | unsigned int rd); | ||
| 272 | |||
| 268 | #endif /* __ASSEMBLY__ */ | 273 | #endif /* __ASSEMBLY__ */ |
| 269 | 274 | ||
| 270 | #endif /* _ASM_UACCESS_H */ | 275 | #endif /* _ASM_UACCESS_H */ |
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 1d7e274f3f2b..7f5f65d0b3fd 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
| @@ -212,24 +212,20 @@ linux_sparc_syscall: | |||
| 212 | 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 212 | 3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
| 213 | ret_sys_call: | 213 | ret_sys_call: |
| 214 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 | 214 | ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3 |
| 215 | ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc | ||
| 216 | sra %o0, 0, %o0 | 215 | sra %o0, 0, %o0 |
| 217 | mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 | 216 | mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 |
| 218 | sllx %g2, 32, %g2 | 217 | sllx %g2, 32, %g2 |
| 219 | 218 | ||
| 220 | /* Check if force_successful_syscall_return() | ||
| 221 | * was invoked. | ||
| 222 | */ | ||
| 223 | ldub [%g6 + TI_SYS_NOERROR], %l2 | ||
| 224 | brnz,a,pn %l2, 80f | ||
| 225 | stb %g0, [%g6 + TI_SYS_NOERROR] | ||
| 226 | |||
| 227 | cmp %o0, -ERESTART_RESTARTBLOCK | 219 | cmp %o0, -ERESTART_RESTARTBLOCK |
| 228 | bgeu,pn %xcc, 1f | 220 | bgeu,pn %xcc, 1f |
| 229 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 | 221 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0 |
| 230 | 80: | 222 | ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc |
| 223 | |||
| 224 | 2: | ||
| 225 | stb %g0, [%g6 + TI_SYS_NOERROR] | ||
| 231 | /* System call success, clear Carry condition code. */ | 226 | /* System call success, clear Carry condition code. */ |
| 232 | andn %g3, %g2, %g3 | 227 | andn %g3, %g2, %g3 |
| 228 | 3: | ||
| 233 | stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] | 229 | stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] |
| 234 | bne,pn %icc, linux_syscall_trace2 | 230 | bne,pn %icc, linux_syscall_trace2 |
| 235 | add %l1, 0x4, %l2 ! npc = npc+4 | 231 | add %l1, 0x4, %l2 ! npc = npc+4 |
| @@ -238,20 +234,20 @@ ret_sys_call: | |||
| 238 | stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] | 234 | stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] |
| 239 | 235 | ||
| 240 | 1: | 236 | 1: |
| 237 | /* Check if force_successful_syscall_return() | ||
| 238 | * was invoked. | ||
| 239 | */ | ||
| 240 | ldub [%g6 + TI_SYS_NOERROR], %l2 | ||
| 241 | brnz,pn %l2, 2b | ||
| 242 | ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc | ||
| 241 | /* System call failure, set Carry condition code. | 243 | /* System call failure, set Carry condition code. |
| 242 | * Also, get abs(errno) to return to the process. | 244 | * Also, get abs(errno) to return to the process. |
| 243 | */ | 245 | */ |
| 244 | andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6 | ||
| 245 | sub %g0, %o0, %o0 | 246 | sub %g0, %o0, %o0 |
| 246 | or %g3, %g2, %g3 | ||
| 247 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] | 247 | stx %o0, [%sp + PTREGS_OFF + PT_V9_I0] |
| 248 | stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE] | 248 | ba,pt %xcc, 3b |
| 249 | bne,pn %icc, linux_syscall_trace2 | 249 | or %g3, %g2, %g3 |
| 250 | add %l1, 0x4, %l2 ! npc = npc+4 | ||
| 251 | stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] | ||
| 252 | 250 | ||
| 253 | b,pt %xcc, rtrap | ||
| 254 | stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] | ||
| 255 | linux_syscall_trace2: | 251 | linux_syscall_trace2: |
| 256 | call syscall_trace_leave | 252 | call syscall_trace_leave |
| 257 | add %sp, PTREGS_OFF, %o0 | 253 | add %sp, PTREGS_OFF, %o0 |
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index fa1f1d375ffc..b66a77968f35 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* arch/sparc64/kernel/traps.c | 1 | /* arch/sparc64/kernel/traps.c |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 1995,1997,2008,2009 David S. Miller (davem@davemloft.net) | 3 | * Copyright (C) 1995,1997,2008,2009,2012 David S. Miller (davem@davemloft.net) |
| 4 | * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) | 4 | * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/kdebug.h> | 19 | #include <linux/kdebug.h> |
| 20 | #include <linux/ftrace.h> | 20 | #include <linux/ftrace.h> |
| 21 | #include <linux/reboot.h> | ||
| 21 | #include <linux/gfp.h> | 22 | #include <linux/gfp.h> |
| 22 | 23 | ||
| 23 | #include <asm/smp.h> | 24 | #include <asm/smp.h> |
| @@ -1760,85 +1761,223 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs) | |||
| 1760 | } | 1761 | } |
| 1761 | 1762 | ||
| 1762 | struct sun4v_error_entry { | 1763 | struct sun4v_error_entry { |
| 1763 | u64 err_handle; | 1764 | /* Unique error handle */ |
| 1764 | u64 err_stick; | 1765 | /*0x00*/u64 err_handle; |
| 1765 | 1766 | ||
| 1766 | u32 err_type; | 1767 | /* %stick value at the time of the error */ |
| 1768 | /*0x08*/u64 err_stick; | ||
| 1769 | |||
| 1770 | /*0x10*/u8 reserved_1[3]; | ||
| 1771 | |||
| 1772 | /* Error type */ | ||
| 1773 | /*0x13*/u8 err_type; | ||
| 1767 | #define SUN4V_ERR_TYPE_UNDEFINED 0 | 1774 | #define SUN4V_ERR_TYPE_UNDEFINED 0 |
| 1768 | #define SUN4V_ERR_TYPE_UNCORRECTED_RES 1 | 1775 | #define SUN4V_ERR_TYPE_UNCORRECTED_RES 1 |
| 1769 | #define SUN4V_ERR_TYPE_PRECISE_NONRES 2 | 1776 | #define SUN4V_ERR_TYPE_PRECISE_NONRES 2 |
| 1770 | #define SUN4V_ERR_TYPE_DEFERRED_NONRES 3 | 1777 | #define SUN4V_ERR_TYPE_DEFERRED_NONRES 3 |
| 1771 | #define SUN4V_ERR_TYPE_WARNING_RES 4 | 1778 | #define SUN4V_ERR_TYPE_SHUTDOWN_RQST 4 |
| 1779 | #define SUN4V_ERR_TYPE_DUMP_CORE 5 | ||
| 1780 | #define SUN4V_ERR_TYPE_SP_STATE_CHANGE 6 | ||
| 1781 | #define SUN4V_ERR_TYPE_NUM 7 | ||
| 1772 | 1782 | ||
| 1773 | u32 err_attrs; | 1783 | /* Error attributes */ |
| 1784 | /*0x14*/u32 err_attrs; | ||
| 1774 | #define SUN4V_ERR_ATTRS_PROCESSOR 0x00000001 | 1785 | #define SUN4V_ERR_ATTRS_PROCESSOR 0x00000001 |
| 1775 | #define SUN4V_ERR_ATTRS_MEMORY 0x00000002 | 1786 | #define SUN4V_ERR_ATTRS_MEMORY 0x00000002 |
| 1776 | #define SUN4V_ERR_ATTRS_PIO 0x00000004 | 1787 | #define SUN4V_ERR_ATTRS_PIO 0x00000004 |
| 1777 | #define SUN4V_ERR_ATTRS_INT_REGISTERS 0x00000008 | 1788 | #define SUN4V_ERR_ATTRS_INT_REGISTERS 0x00000008 |
| 1778 | #define SUN4V_ERR_ATTRS_FPU_REGISTERS 0x00000010 | 1789 | #define SUN4V_ERR_ATTRS_FPU_REGISTERS 0x00000010 |
| 1779 | #define SUN4V_ERR_ATTRS_USER_MODE 0x01000000 | 1790 | #define SUN4V_ERR_ATTRS_SHUTDOWN_RQST 0x00000020 |
| 1780 | #define SUN4V_ERR_ATTRS_PRIV_MODE 0x02000000 | 1791 | #define SUN4V_ERR_ATTRS_ASR 0x00000040 |
| 1792 | #define SUN4V_ERR_ATTRS_ASI 0x00000080 | ||
| 1793 | #define SUN4V_ERR_ATTRS_PRIV_REG 0x00000100 | ||
| 1794 | #define SUN4V_ERR_ATTRS_SPSTATE_MSK 0x00000600 | ||
| 1795 | #define SUN4V_ERR_ATTRS_SPSTATE_SHFT 9 | ||
| 1796 | #define SUN4V_ERR_ATTRS_MODE_MSK 0x03000000 | ||
| 1797 | #define SUN4V_ERR_ATTRS_MODE_SHFT 24 | ||
| 1781 | #define SUN4V_ERR_ATTRS_RES_QUEUE_FULL 0x80000000 | 1798 | #define SUN4V_ERR_ATTRS_RES_QUEUE_FULL 0x80000000 |
| 1782 | 1799 | ||
| 1783 | u64 err_raddr; | 1800 | #define SUN4V_ERR_SPSTATE_FAULTED 0 |
| 1784 | u32 err_size; | 1801 | #define SUN4V_ERR_SPSTATE_AVAILABLE 1 |
| 1785 | u16 err_cpu; | 1802 | #define SUN4V_ERR_SPSTATE_NOT_PRESENT 2 |
| 1786 | u16 err_pad; | 1803 | |
| 1804 | #define SUN4V_ERR_MODE_USER 1 | ||
| 1805 | #define SUN4V_ERR_MODE_PRIV 2 | ||
| 1806 | |||
| 1807 | /* Real address of the memory region or PIO transaction */ | ||
| 1808 | /*0x18*/u64 err_raddr; | ||
| 1809 | |||
| 1810 | /* Size of the operation triggering the error, in bytes */ | ||
| 1811 | /*0x20*/u32 err_size; | ||
| 1812 | |||
| 1813 | /* ID of the CPU */ | ||
| 1814 | /*0x24*/u16 err_cpu; | ||
| 1815 | |||
| 1816 | /* Grace periof for shutdown, in seconds */ | ||
| 1817 | /*0x26*/u16 err_secs; | ||
| 1818 | |||
| 1819 | /* Value of the %asi register */ | ||
| 1820 | /*0x28*/u8 err_asi; | ||
| 1821 | |||
| 1822 | /*0x29*/u8 reserved_2; | ||
| 1823 | |||
| 1824 | /* Value of the ASR register number */ | ||
| 1825 | /*0x2a*/u16 err_asr; | ||
| 1826 | #define SUN4V_ERR_ASR_VALID 0x8000 | ||
| 1827 | |||
| 1828 | /*0x2c*/u32 reserved_3; | ||
| 1829 | /*0x30*/u64 reserved_4; | ||
| 1830 | /*0x38*/u64 reserved_5; | ||
| 1787 | }; | 1831 | }; |
| 1788 | 1832 | ||
| 1789 | static atomic_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0); | 1833 | static atomic_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0); |
| 1790 | static atomic_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0); | 1834 | static atomic_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0); |
| 1791 | 1835 | ||
| 1792 | static const char *sun4v_err_type_to_str(u32 type) | 1836 | static const char *sun4v_err_type_to_str(u8 type) |
| 1793 | { | 1837 | { |
| 1794 | switch (type) { | 1838 | static const char *types[SUN4V_ERR_TYPE_NUM] = { |
| 1795 | case SUN4V_ERR_TYPE_UNDEFINED: | 1839 | "undefined", |
| 1796 | return "undefined"; | 1840 | "uncorrected resumable", |
| 1797 | case SUN4V_ERR_TYPE_UNCORRECTED_RES: | 1841 | "precise nonresumable", |
| 1798 | return "uncorrected resumable"; | 1842 | "deferred nonresumable", |
| 1799 | case SUN4V_ERR_TYPE_PRECISE_NONRES: | 1843 | "shutdown request", |
| 1800 | return "precise nonresumable"; | 1844 | "dump core", |
| 1801 | case SUN4V_ERR_TYPE_DEFERRED_NONRES: | 1845 | "SP state change", |
| 1802 | return "deferred nonresumable"; | 1846 | }; |
| 1803 | case SUN4V_ERR_TYPE_WARNING_RES: | 1847 | |
| 1804 | return "warning resumable"; | 1848 | if (type < SUN4V_ERR_TYPE_NUM) |
| 1805 | default: | 1849 | return types[type]; |
| 1806 | return "unknown"; | 1850 | |
| 1851 | return "unknown"; | ||
| 1852 | } | ||
| 1853 | |||
| 1854 | static void sun4v_emit_err_attr_strings(u32 attrs) | ||
| 1855 | { | ||
| 1856 | static const char *attr_names[] = { | ||
| 1857 | "processor", | ||
| 1858 | "memory", | ||
| 1859 | "PIO", | ||
| 1860 | "int-registers", | ||
| 1861 | "fpu-registers", | ||
| 1862 | "shutdown-request", | ||
| 1863 | "ASR", | ||
| 1864 | "ASI", | ||
| 1865 | "priv-reg", | ||
| 1866 | }; | ||
| 1867 | static const char *sp_states[] = { | ||
| 1868 | "sp-faulted", | ||
| 1869 | "sp-available", | ||
| 1870 | "sp-not-present", | ||
| 1871 | "sp-state-reserved", | ||
| 1872 | }; | ||
| 1873 | static const char *modes[] = { | ||
| 1874 | "mode-reserved0", | ||
| 1875 | "user", | ||
| 1876 | "priv", | ||
| 1877 | "mode-reserved1", | ||
| 1878 | }; | ||
| 1879 | u32 sp_state, mode; | ||
| 1880 | int i; | ||
| 1881 | |||
| 1882 | for (i = 0; i < ARRAY_SIZE(attr_names); i++) { | ||
| 1883 | if (attrs & (1U << i)) { | ||
| 1884 | const char *s = attr_names[i]; | ||
| 1885 | |||
| 1886 | pr_cont("%s ", s); | ||
| 1887 | } | ||
| 1807 | } | 1888 | } |
| 1889 | |||
| 1890 | sp_state = ((attrs & SUN4V_ERR_ATTRS_SPSTATE_MSK) >> | ||
| 1891 | SUN4V_ERR_ATTRS_SPSTATE_SHFT); | ||
| 1892 | pr_cont("%s ", sp_states[sp_state]); | ||
| 1893 | |||
| 1894 | mode = ((attrs & SUN4V_ERR_ATTRS_MODE_MSK) >> | ||
| 1895 | SUN4V_ERR_ATTRS_MODE_SHFT); | ||
| 1896 | pr_cont("%s ", modes[mode]); | ||
| 1897 | |||
| 1898 | if (attrs & SUN4V_ERR_ATTRS_RES_QUEUE_FULL) | ||
| 1899 | pr_cont("res-queue-full "); | ||
| 1808 | } | 1900 | } |
| 1809 | 1901 | ||
| 1810 | static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) | 1902 | /* When the report contains a real-address of "-1" it means that the |
| 1903 | * hardware did not provide the address. So we compute the effective | ||
| 1904 | * address of the load or store instruction at regs->tpc and report | ||
| 1905 | * that. Usually when this happens it's a PIO and in such a case we | ||
| 1906 | * are using physical addresses with bypass ASIs anyways, so what we | ||
| 1907 | * report here is exactly what we want. | ||
| 1908 | */ | ||
| 1909 | static void sun4v_report_real_raddr(const char *pfx, struct pt_regs *regs) | ||
| 1811 | { | 1910 | { |
| 1911 | unsigned int insn; | ||
| 1912 | u64 addr; | ||
| 1913 | |||
| 1914 | if (!(regs->tstate & TSTATE_PRIV)) | ||
| 1915 | return; | ||
| 1916 | |||
| 1917 | insn = *(unsigned int *) regs->tpc; | ||
| 1918 | |||
| 1919 | addr = compute_effective_address(regs, insn, 0); | ||
| 1920 | |||
| 1921 | printk("%s: insn effective address [0x%016llx]\n", | ||
| 1922 | pfx, addr); | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, | ||
| 1926 | int cpu, const char *pfx, atomic_t *ocnt) | ||
| 1927 | { | ||
| 1928 | u64 *raw_ptr = (u64 *) ent; | ||
| 1929 | u32 attrs; | ||
| 1812 | int cnt; | 1930 | int cnt; |
| 1813 | 1931 | ||
| 1814 | printk("%s: Reporting on cpu %d\n", pfx, cpu); | 1932 | printk("%s: Reporting on cpu %d\n", pfx, cpu); |
| 1815 | printk("%s: err_handle[%llx] err_stick[%llx] err_type[%08x:%s]\n", | 1933 | printk("%s: TPC [0x%016lx] <%pS>\n", |
| 1816 | pfx, | 1934 | pfx, regs->tpc, (void *) regs->tpc); |
| 1817 | ent->err_handle, ent->err_stick, | 1935 | |
| 1818 | ent->err_type, | 1936 | printk("%s: RAW [%016llx:%016llx:%016llx:%016llx\n", |
| 1819 | sun4v_err_type_to_str(ent->err_type)); | 1937 | pfx, raw_ptr[0], raw_ptr[1], raw_ptr[2], raw_ptr[3]); |
| 1820 | printk("%s: err_attrs[%08x:%s %s %s %s %s %s %s %s]\n", | 1938 | printk("%s: %016llx:%016llx:%016llx:%016llx]\n", |
| 1821 | pfx, | 1939 | pfx, raw_ptr[4], raw_ptr[5], raw_ptr[6], raw_ptr[7]); |
| 1822 | ent->err_attrs, | 1940 | |
| 1823 | ((ent->err_attrs & SUN4V_ERR_ATTRS_PROCESSOR) ? | 1941 | printk("%s: handle [0x%016llx] stick [0x%016llx]\n", |
| 1824 | "processor" : ""), | 1942 | pfx, ent->err_handle, ent->err_stick); |
| 1825 | ((ent->err_attrs & SUN4V_ERR_ATTRS_MEMORY) ? | 1943 | |
| 1826 | "memory" : ""), | 1944 | printk("%s: type [%s]\n", pfx, sun4v_err_type_to_str(ent->err_type)); |
| 1827 | ((ent->err_attrs & SUN4V_ERR_ATTRS_PIO) ? | 1945 | |
| 1828 | "pio" : ""), | 1946 | attrs = ent->err_attrs; |
| 1829 | ((ent->err_attrs & SUN4V_ERR_ATTRS_INT_REGISTERS) ? | 1947 | printk("%s: attrs [0x%08x] < ", pfx, attrs); |
| 1830 | "integer-regs" : ""), | 1948 | sun4v_emit_err_attr_strings(attrs); |
| 1831 | ((ent->err_attrs & SUN4V_ERR_ATTRS_FPU_REGISTERS) ? | 1949 | pr_cont(">\n"); |
| 1832 | "fpu-regs" : ""), | 1950 | |
| 1833 | ((ent->err_attrs & SUN4V_ERR_ATTRS_USER_MODE) ? | 1951 | /* Various fields in the error report are only valid if |
| 1834 | "user" : ""), | 1952 | * certain attribute bits are set. |
| 1835 | ((ent->err_attrs & SUN4V_ERR_ATTRS_PRIV_MODE) ? | 1953 | */ |
| 1836 | "privileged" : ""), | 1954 | if (attrs & (SUN4V_ERR_ATTRS_MEMORY | |
| 1837 | ((ent->err_attrs & SUN4V_ERR_ATTRS_RES_QUEUE_FULL) ? | 1955 | SUN4V_ERR_ATTRS_PIO | |
| 1838 | "queue-full" : "")); | 1956 | SUN4V_ERR_ATTRS_ASI)) { |
| 1839 | printk("%s: err_raddr[%016llx] err_size[%u] err_cpu[%u]\n", | 1957 | printk("%s: raddr [0x%016llx]\n", pfx, ent->err_raddr); |
| 1840 | pfx, | 1958 | |
| 1841 | ent->err_raddr, ent->err_size, ent->err_cpu); | 1959 | if (ent->err_raddr == ~(u64)0) |
| 1960 | sun4v_report_real_raddr(pfx, regs); | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | if (attrs & (SUN4V_ERR_ATTRS_MEMORY | SUN4V_ERR_ATTRS_ASI)) | ||
| 1964 | printk("%s: size [0x%x]\n", pfx, ent->err_size); | ||
| 1965 | |||
| 1966 | if (attrs & (SUN4V_ERR_ATTRS_PROCESSOR | | ||
| 1967 | SUN4V_ERR_ATTRS_INT_REGISTERS | | ||
| 1968 | SUN4V_ERR_ATTRS_FPU_REGISTERS | | ||
| 1969 | SUN4V_ERR_ATTRS_PRIV_REG)) | ||
| 1970 | printk("%s: cpu[%u]\n", pfx, ent->err_cpu); | ||
| 1971 | |||
| 1972 | if (attrs & SUN4V_ERR_ATTRS_ASI) | ||
| 1973 | printk("%s: asi [0x%02x]\n", pfx, ent->err_asi); | ||
| 1974 | |||
| 1975 | if ((attrs & (SUN4V_ERR_ATTRS_INT_REGISTERS | | ||
| 1976 | SUN4V_ERR_ATTRS_FPU_REGISTERS | | ||
| 1977 | SUN4V_ERR_ATTRS_PRIV_REG)) && | ||
| 1978 | (ent->err_asr & SUN4V_ERR_ASR_VALID) != 0) | ||
| 1979 | printk("%s: reg [0x%04x]\n", | ||
| 1980 | pfx, ent->err_asr & ~SUN4V_ERR_ASR_VALID); | ||
| 1842 | 1981 | ||
| 1843 | show_regs(regs); | 1982 | show_regs(regs); |
| 1844 | 1983 | ||
| @@ -1874,13 +2013,15 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) | |||
| 1874 | 2013 | ||
| 1875 | put_cpu(); | 2014 | put_cpu(); |
| 1876 | 2015 | ||
| 1877 | if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) { | 2016 | if (local_copy.err_type == SUN4V_ERR_TYPE_SHUTDOWN_RQST) { |
| 1878 | /* If err_type is 0x4, it's a powerdown request. Do | 2017 | /* We should really take the seconds field of |
| 1879 | * not do the usual resumable error log because that | 2018 | * the error report and use it for the shutdown |
| 1880 | * makes it look like some abnormal error. | 2019 | * invocation, but for now do the same thing we |
| 2020 | * do for a DS shutdown request. | ||
| 1881 | */ | 2021 | */ |
| 1882 | printk(KERN_INFO "Power down request...\n"); | 2022 | pr_info("Shutdown request, %u seconds...\n", |
| 1883 | kill_cad_pid(SIGINT, 1); | 2023 | local_copy.err_secs); |
| 2024 | orderly_poweroff(true); | ||
| 1884 | return; | 2025 | return; |
| 1885 | } | 2026 | } |
| 1886 | 2027 | ||
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 2976dba1ebaf..097aee763af3 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
| @@ -151,8 +151,6 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, | |||
| 151 | printk(KERN_CONT "\n"); | 151 | printk(KERN_CONT "\n"); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); | ||
| 155 | |||
| 156 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | 154 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, |
| 157 | unsigned int insn, int fault_code) | 155 | unsigned int insn, int fault_code) |
| 158 | { | 156 | { |
