Skip to content

Commit e225ca2

Browse files
committed
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.
2 parents 54f7fc2 + 55c2770 commit e225ca2

File tree

4 files changed

+221
-81
lines changed

4 files changed

+221
-81
lines changed

arch/sparc/include/asm/uaccess_64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ extern __must_check long strnlen_user(const char __user *str, long n);
265265
#define __copy_to_user_inatomic ___copy_to_user
266266
#define __copy_from_user_inatomic ___copy_from_user
267267

268+
struct pt_regs;
269+
extern unsigned long compute_effective_address(struct pt_regs *,
270+
unsigned int insn,
271+
unsigned int rd);
272+
268273
#endif /* __ASSEMBLY__ */
269274

270275
#endif /* _ASM_UACCESS_H */

arch/sparc/kernel/syscalls.S

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,24 +212,20 @@ linux_sparc_syscall:
212212
3: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
213213
ret_sys_call:
214214
ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
215-
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
216215
sra %o0, 0, %o0
217216
mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
218217
sllx %g2, 32, %g2
219218

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-
227219
cmp %o0, -ERESTART_RESTARTBLOCK
228220
bgeu,pn %xcc, 1f
229-
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
230-
80:
221+
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %g0
222+
ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
223+
224+
2:
225+
stb %g0, [%g6 + TI_SYS_NOERROR]
231226
/* System call success, clear Carry condition code. */
232227
andn %g3, %g2, %g3
228+
3:
233229
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
234230
bne,pn %icc, linux_syscall_trace2
235231
add %l1, 0x4, %l2 ! npc = npc+4
@@ -238,20 +234,20 @@ ret_sys_call:
238234
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
239235

240236
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
241243
/* System call failure, set Carry condition code.
242244
* Also, get abs(errno) to return to the process.
243245
*/
244-
andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT), %l6
245246
sub %g0, %o0, %o0
246-
or %g3, %g2, %g3
247247
stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
248-
stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
249-
bne,pn %icc, linux_syscall_trace2
250-
add %l1, 0x4, %l2 ! npc = npc+4
251-
stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
248+
ba,pt %xcc, 3b
249+
or %g3, %g2, %g3
252250

253-
b,pt %xcc, rtrap
254-
stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
255251
linux_syscall_trace2:
256252
call syscall_trace_leave
257253
add %sp, PTREGS_OFF, %o0

arch/sparc/kernel/traps_64.c

Lines changed: 202 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* arch/sparc64/kernel/traps.c
22
*
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)
44
* Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
55
*/
66

@@ -18,6 +18,7 @@
1818
#include <linux/init.h>
1919
#include <linux/kdebug.h>
2020
#include <linux/ftrace.h>
21+
#include <linux/reboot.h>
2122
#include <linux/gfp.h>
2223

2324
#include <asm/smp.h>
@@ -1760,85 +1761,223 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
17601761
}
17611762

17621763
struct sun4v_error_entry {
1763-
u64 err_handle;
1764-
u64 err_stick;
1764+
/* Unique error handle */
1765+
/*0x00*/u64 err_handle;
17651766

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;
17671774
#define SUN4V_ERR_TYPE_UNDEFINED 0
17681775
#define SUN4V_ERR_TYPE_UNCORRECTED_RES 1
17691776
#define SUN4V_ERR_TYPE_PRECISE_NONRES 2
17701777
#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
17721782

1773-
u32 err_attrs;
1783+
/* Error attributes */
1784+
/*0x14*/u32 err_attrs;
17741785
#define SUN4V_ERR_ATTRS_PROCESSOR 0x00000001
17751786
#define SUN4V_ERR_ATTRS_MEMORY 0x00000002
17761787
#define SUN4V_ERR_ATTRS_PIO 0x00000004
17771788
#define SUN4V_ERR_ATTRS_INT_REGISTERS 0x00000008
17781789
#define SUN4V_ERR_ATTRS_FPU_REGISTERS 0x00000010
1779-
#define SUN4V_ERR_ATTRS_USER_MODE 0x01000000
1780-
#define SUN4V_ERR_ATTRS_PRIV_MODE 0x02000000
1790+
#define SUN4V_ERR_ATTRS_SHUTDOWN_RQST 0x00000020
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
17811798
#define SUN4V_ERR_ATTRS_RES_QUEUE_FULL 0x80000000
17821799

1783-
u64 err_raddr;
1784-
u32 err_size;
1785-
u16 err_cpu;
1786-
u16 err_pad;
1800+
#define SUN4V_ERR_SPSTATE_FAULTED 0
1801+
#define SUN4V_ERR_SPSTATE_AVAILABLE 1
1802+
#define SUN4V_ERR_SPSTATE_NOT_PRESENT 2
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;
17871831
};
17881832

17891833
static atomic_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0);
17901834
static atomic_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0);
17911835

1792-
static const char *sun4v_err_type_to_str(u32 type)
1793-
{
1794-
switch (type) {
1795-
case SUN4V_ERR_TYPE_UNDEFINED:
1796-
return "undefined";
1797-
case SUN4V_ERR_TYPE_UNCORRECTED_RES:
1798-
return "uncorrected resumable";
1799-
case SUN4V_ERR_TYPE_PRECISE_NONRES:
1800-
return "precise nonresumable";
1801-
case SUN4V_ERR_TYPE_DEFERRED_NONRES:
1802-
return "deferred nonresumable";
1803-
case SUN4V_ERR_TYPE_WARNING_RES:
1804-
return "warning resumable";
1805-
default:
1806-
return "unknown";
1836+
static const char *sun4v_err_type_to_str(u8 type)
1837+
{
1838+
static const char *types[SUN4V_ERR_TYPE_NUM] = {
1839+
"undefined",
1840+
"uncorrected resumable",
1841+
"precise nonresumable",
1842+
"deferred nonresumable",
1843+
"shutdown request",
1844+
"dump core",
1845+
"SP state change",
1846+
};
1847+
1848+
if (type < SUN4V_ERR_TYPE_NUM)
1849+
return types[type];
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+
}
18071888
}
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 ");
18081900
}
18091901

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)
18111910
{
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;
18121930
int cnt;
18131931

18141932
printk("%s: Reporting on cpu %d\n", pfx, cpu);
1815-
printk("%s: err_handle[%llx] err_stick[%llx] err_type[%08x:%s]\n",
1816-
pfx,
1817-
ent->err_handle, ent->err_stick,
1818-
ent->err_type,
1819-
sun4v_err_type_to_str(ent->err_type));
1820-
printk("%s: err_attrs[%08x:%s %s %s %s %s %s %s %s]\n",
1821-
pfx,
1822-
ent->err_attrs,
1823-
((ent->err_attrs & SUN4V_ERR_ATTRS_PROCESSOR) ?
1824-
"processor" : ""),
1825-
((ent->err_attrs & SUN4V_ERR_ATTRS_MEMORY) ?
1826-
"memory" : ""),
1827-
((ent->err_attrs & SUN4V_ERR_ATTRS_PIO) ?
1828-
"pio" : ""),
1829-
((ent->err_attrs & SUN4V_ERR_ATTRS_INT_REGISTERS) ?
1830-
"integer-regs" : ""),
1831-
((ent->err_attrs & SUN4V_ERR_ATTRS_FPU_REGISTERS) ?
1832-
"fpu-regs" : ""),
1833-
((ent->err_attrs & SUN4V_ERR_ATTRS_USER_MODE) ?
1834-
"user" : ""),
1835-
((ent->err_attrs & SUN4V_ERR_ATTRS_PRIV_MODE) ?
1836-
"privileged" : ""),
1837-
((ent->err_attrs & SUN4V_ERR_ATTRS_RES_QUEUE_FULL) ?
1838-
"queue-full" : ""));
1839-
printk("%s: err_raddr[%016llx] err_size[%u] err_cpu[%u]\n",
1840-
pfx,
1841-
ent->err_raddr, ent->err_size, ent->err_cpu);
1933+
printk("%s: TPC [0x%016lx] <%pS>\n",
1934+
pfx, regs->tpc, (void *) regs->tpc);
1935+
1936+
printk("%s: RAW [%016llx:%016llx:%016llx:%016llx\n",
1937+
pfx, raw_ptr[0], raw_ptr[1], raw_ptr[2], raw_ptr[3]);
1938+
printk("%s: %016llx:%016llx:%016llx:%016llx]\n",
1939+
pfx, raw_ptr[4], raw_ptr[5], raw_ptr[6], raw_ptr[7]);
1940+
1941+
printk("%s: handle [0x%016llx] stick [0x%016llx]\n",
1942+
pfx, ent->err_handle, ent->err_stick);
1943+
1944+
printk("%s: type [%s]\n", pfx, sun4v_err_type_to_str(ent->err_type));
1945+
1946+
attrs = ent->err_attrs;
1947+
printk("%s: attrs [0x%08x] < ", pfx, attrs);
1948+
sun4v_emit_err_attr_strings(attrs);
1949+
pr_cont(">\n");
1950+
1951+
/* Various fields in the error report are only valid if
1952+
* certain attribute bits are set.
1953+
*/
1954+
if (attrs & (SUN4V_ERR_ATTRS_MEMORY |
1955+
SUN4V_ERR_ATTRS_PIO |
1956+
SUN4V_ERR_ATTRS_ASI)) {
1957+
printk("%s: raddr [0x%016llx]\n", pfx, ent->err_raddr);
1958+
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);
18421981

18431982
show_regs(regs);
18441983

@@ -1874,13 +2013,15 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset)
18742013

18752014
put_cpu();
18762015

1877-
if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) {
1878-
/* If err_type is 0x4, it's a powerdown request. Do
1879-
* not do the usual resumable error log because that
1880-
* makes it look like some abnormal error.
2016+
if (local_copy.err_type == SUN4V_ERR_TYPE_SHUTDOWN_RQST) {
2017+
/* We should really take the seconds field of
2018+
* the error report and use it for the shutdown
2019+
* invocation, but for now do the same thing we
2020+
* do for a DS shutdown request.
18812021
*/
1882-
printk(KERN_INFO "Power down request...\n");
1883-
kill_cad_pid(SIGINT, 1);
2022+
pr_info("Shutdown request, %u seconds...\n",
2023+
local_copy.err_secs);
2024+
orderly_poweroff(true);
18842025
return;
18852026
}
18862027

arch/sparc/mm/fault_64.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
151151
printk(KERN_CONT "\n");
152152
}
153153

154-
extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
155-
156154
static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
157155
unsigned int insn, int fault_code)
158156
{

0 commit comments

Comments
 (0)