Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/pseries: warn if recursing into the hcall tracing code

The hcall tracing code has a recursion check built in, which skips
tracing if we are already tracing an hcall.

However if the tracing code has problems with recursion, this check
may not catch all cases because the tracing code could be invoked from
a different tracepoint first, then make an hcall that gets traced,
then recurse.

Add an explicit warning if recursion is detected here, which might help
to notice tracing code making hcalls. Really the core trace code should
have its own recursion checking and warnings though.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210508101455.1578318-5-npiggin@gmail.com

authored by

Nicholas Piggin and committed by
Michael Ellerman
4f242fc5 7058f4b1

+10 -4
+10 -4
arch/powerpc/platforms/pseries/lpar.c
··· 1829 1829 #endif 1830 1830 1831 1831 /* 1832 - * Since the tracing code might execute hcalls we need to guard against 1833 - * recursion. 1832 + * Keep track of hcall tracing depth and prevent recursion. Warn if any is 1833 + * detected because it may indicate a problem. This will not catch all 1834 + * problems with tracing code making hcalls, because the tracing might have 1835 + * been invoked from a non-hcall, so the first hcall could recurse into it 1836 + * without warning here, but this better than nothing. 1837 + * 1838 + * Hcalls with specific problems being traced should use the _notrace 1839 + * plpar_hcall variants. 1834 1840 */ 1835 1841 static DEFINE_PER_CPU(unsigned int, hcall_trace_depth); 1836 1842 ··· 1850 1844 1851 1845 depth = this_cpu_ptr(&hcall_trace_depth); 1852 1846 1853 - if (*depth) 1847 + if (WARN_ON_ONCE(*depth)) 1854 1848 goto out; 1855 1849 1856 1850 (*depth)++; ··· 1871 1865 1872 1866 depth = this_cpu_ptr(&hcall_trace_depth); 1873 1867 1874 - if (*depth) 1868 + if (*depth) /* Don't warn again on the way out */ 1875 1869 goto out; 1876 1870 1877 1871 (*depth)++;