Commit 95fc76c8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Michael Ellerman:

 - On 32-bit fix overread/overwrite of thread_struct via ptrace
   PEEK/POKE.

 - Fix softirqs not switching to the softirq stack since we moved
   irq_exit().

 - Force thread size increase when KASAN is enabled to avoid stack
   overflows.

 - On Book3s 64 mark more code as not to be instrumented by KASAN to
   avoid crashes.

 - Exempt __get_wchan() from KASAN checking, as it's inherently racy.

 - Fix a recently introduced crash in the papr_scm driver in some
   configurations.

 - Remove include of <generated/compile.h> which is forbidden.

Thanks to Ariel Miculas, Chen Jingwen, Christophe Leroy, Erhard Furtner,
He Ying, Kees Cook, Masahiro Yamada, Nageswara R Sastry, Paul Mackerras,
Sachin Sant, Vaibhav Jain, and Wanming Hu.

* tag 'powerpc-5.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/32: Fix overread/overwrite of thread_struct via ptrace
  powerpc/book3e: get rid of #include <generated/compile.h>
  powerpc/kasan: Force thread size increase with KASAN
  powerpc/papr_scm: don't requests stats with '0' sized stats buffer
  powerpc: Don't select HAVE_IRQ_EXIT_ON_IRQ_STACK
  powerpc/kasan: Silence KASAN warnings in __get_wchan()
  powerpc/kasan: Mark more real-mode code as not to be instrumented
parents 825464e7 8e127844
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -223,7 +223,6 @@ config PPC
	select HAVE_HARDLOCKUP_DETECTOR_PERF	if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
	select HAVE_HW_BREAKPOINT		if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
	select HAVE_IOREMAP_PROT
	select HAVE_IRQ_EXIT_ON_IRQ_STACK
	select HAVE_IRQ_TIME_ACCOUNTING
	select HAVE_KERNEL_GZIP
	select HAVE_KERNEL_LZMA			if DEFAULT_UIMAGE
@@ -786,7 +785,6 @@ config THREAD_SHIFT
	range 13 15
	default "15" if PPC_256K_PAGES
	default "14" if PPC64
	default "14" if KASAN
	default "13"
	help
	  Used to define the stack size. The default is almost always what you
+8 −2
Original line number Diff line number Diff line
@@ -14,10 +14,16 @@

#ifdef __KERNEL__

#if defined(CONFIG_VMAP_STACK) && CONFIG_THREAD_SHIFT < PAGE_SHIFT
#ifdef CONFIG_KASAN
#define MIN_THREAD_SHIFT	(CONFIG_THREAD_SHIFT + 1)
#else
#define MIN_THREAD_SHIFT	CONFIG_THREAD_SHIFT
#endif

#if defined(CONFIG_VMAP_STACK) && MIN_THREAD_SHIFT < PAGE_SHIFT
#define THREAD_SHIFT		PAGE_SHIFT
#else
#define THREAD_SHIFT		CONFIG_THREAD_SHIFT
#define THREAD_SHIFT		MIN_THREAD_SHIFT
#endif

#define THREAD_SIZE		(1 << THREAD_SHIFT)
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ KASAN_SANITIZE_paca.o := n
KASAN_SANITIZE_setup_64.o := n
KASAN_SANITIZE_mce.o := n
KASAN_SANITIZE_mce_power.o := n
KASAN_SANITIZE_udbg.o := n
KASAN_SANITIZE_udbg_16550.o := n

# we have to be particularly careful in ppc64 to exclude code that
# runs with translations off, as we cannot access the shadow with
+2 −2
Original line number Diff line number Diff line
@@ -2158,12 +2158,12 @@ static unsigned long ___get_wchan(struct task_struct *p)
		return 0;

	do {
		sp = *(unsigned long *)sp;
		sp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
		if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD) ||
		    task_is_running(p))
			return 0;
		if (count > 0) {
			ip = ((unsigned long *)sp)[STACK_FRAME_LR_SAVE];
			ip = READ_ONCE_NOCHECK(((unsigned long *)sp)[STACK_FRAME_LR_SAVE]);
			if (!in_sched_functions(ip))
				return ip;
		}
+14 −6
Original line number Diff line number Diff line
@@ -17,9 +17,13 @@ int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)

#ifdef CONFIG_PPC_FPU_REGS
	flush_fp_to_thread(child);
	if (fpidx < (PT_FPSCR - PT_FPR0))
		memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
	if (fpidx < (PT_FPSCR - PT_FPR0)) {
		if (IS_ENABLED(CONFIG_PPC32))
			// On 32-bit the index we are passed refers to 32-bit words
			*data = ((u32 *)child->thread.fp_state.fpr)[fpidx];
		else
			memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
	} else
		*data = child->thread.fp_state.fpscr;
#else
	*data = 0;
@@ -39,9 +43,13 @@ int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)

#ifdef CONFIG_PPC_FPU_REGS
	flush_fp_to_thread(child);
	if (fpidx < (PT_FPSCR - PT_FPR0))
		memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
	if (fpidx < (PT_FPSCR - PT_FPR0)) {
		if (IS_ENABLED(CONFIG_PPC32))
			// On 32-bit the index we are passed refers to 32-bit words
			((u32 *)child->thread.fp_state.fpr)[fpidx] = data;
		else
			memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
	} else
		child->thread.fp_state.fpscr = data;
#endif

Loading