diff mbox series

ARM: iwmmxt: Remove support for PJ4/PJ4B cores

Message ID 20240209110901.4032939-2-ardb+git@google.com (mailing list archive)
State New, archived
Headers show
Series ARM: iwmmxt: Remove support for PJ4/PJ4B cores | expand

Commit Message

Ard Biesheuvel Feb. 9, 2024, 11:09 a.m. UTC
From: Ard Biesheuvel <ardb@kernel.org>

PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
does not support this combination (its iWMMXt configuration always
implies v5te), and so there is no v6/v7 user space that actually makes
use of this, beyond generic support for things like setjmp() that
preserve/restore the iWMMXt register file using generic LDC/STC
instructions emitted in assembler. As [0] appears to imply, this logic
is triggered for the init process at boot, and so most processes will
have a iWMMXt register context associated with it, even though it is
never used.

This means that advertising iWMMXt support on these cores results in
context switch overhead without any associated benefit, and so it is
better to simply ignore the iWMMXt unit on these systems. So rip out the
support. Doing so also fixes the issue reported in [0] related to UNDEF
handling of co-processor #0/#1 instructions issued from user space
running in Thumb2 mode.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Nicolas Pitre <nico@fluxnic.net>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Linus Walleij <linus.walleij@linaro.org>
Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/arm/Kconfig          |   4 +-
 arch/arm/kernel/Makefile  |   2 -
 arch/arm/kernel/iwmmxt.S  |  51 ++++----------
 arch/arm/kernel/pj4-cp0.c | 135 --------------------------------------
 4 files changed, 15 insertions(+), 177 deletions(-)
 delete mode 100644 arch/arm/kernel/pj4-cp0.c

Comments

Linus Walleij Feb. 9, 2024, 1:54 p.m. UTC | #1
On Fri, Feb 9, 2024 at 12:09 PM Ard Biesheuvel <ardb+git@google.com> wrote:

> From: Ard Biesheuvel <ardb@kernel.org>
>
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
>
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

I would probably say in the commit message that the window for enabling
this in GCC and userspace was when the core was introduced and it
has long since passed; whoever was supposed to do this didn't exist
or care and thus the job never got done.

I was worried about some assembly in userspace making use of this,
so I checked libavcodec and it does not seem to have any iWMMX
optimizations at all. (Don't know what else to check.)

CC to Lubomir who made the Dell WYSE port which use MMP3 with PJ4
so he can check that he doesn't have userspace using this either and
can ACK this commit.

Yours,
Linus Walleij
Arnd Bergmann Feb. 9, 2024, 2:27 p.m. UTC | #2
On Fri, Feb 9, 2024, at 12:09, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
>
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
>
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Acked-by: Arnd Bergmann <arnd@arndb.de>

Maybe add a bit about which cores are actually affected by this:

The PJ4 cores are used in four platforms: armada 370/xp, dove
(cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
Out of these, only the first is still widely used, but that
one actually doesn't have iwmmxt but instead has only
vfpv3-d16.

I've also added the maintainers of those platforms to Cc,
in case anyone has objections after all.

      Arnd
Nicolas Pitre Feb. 9, 2024, 5:15 p.m. UTC | #3
On Fri, 9 Feb 2024, Ard Biesheuvel wrote:

> From: Ard Biesheuvel <ardb@kernel.org>
> 
> PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> does not support this combination (its iWMMXt configuration always
> implies v5te), and so there is no v6/v7 user space that actually makes
> use of this, beyond generic support for things like setjmp() that
> preserve/restore the iWMMXt register file using generic LDC/STC
> instructions emitted in assembler. As [0] appears to imply, this logic
> is triggered for the init process at boot, and so most processes will
> have a iWMMXt register context associated with it, even though it is
> never used.
> 
> This means that advertising iWMMXt support on these cores results in
> context switch overhead without any associated benefit, and so it is
> better to simply ignore the iWMMXt unit on these systems. So rip out the
> support. Doing so also fixes the issue reported in [0] related to UNDEF
> handling of co-processor #0/#1 instructions issued from user space
> running in Thumb2 mode.
> 
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Nicolas Pitre <nico@fluxnic.net>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Acked-by: Nicolas Pitre <nico@fluxnic.net>

I think Arnd is right suggesting you augment the commit message with the 
list of affected targets so to make this commit easier to find if ever a 
revert is needed.


> ---
>  arch/arm/Kconfig          |   4 +-
>  arch/arm/kernel/Makefile  |   2 -
>  arch/arm/kernel/iwmmxt.S  |  51 ++++----------
>  arch/arm/kernel/pj4-cp0.c | 135 --------------------------------------
>  4 files changed, 15 insertions(+), 177 deletions(-)
>  delete mode 100644 arch/arm/kernel/pj4-cp0.c
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0af6709570d1..0d4e316a389e 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -503,8 +503,8 @@ source "arch/arm/mm/Kconfig"
>  
>  config IWMMXT
>  	bool "Enable iWMMXt support"
> -	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
> -	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
> +	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
> +	default y if PXA27x || PXA3xx || ARCH_MMP
>  	help
>  	  Enable support for iWMMXt context switching at run time if
>  	  running on a CPU that supports it.
> diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
> index 771264d4726a..ae2f2b2b4e5a 100644
> --- a/arch/arm/kernel/Makefile
> +++ b/arch/arm/kernel/Makefile
> @@ -75,8 +75,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
>  obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
>  obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
>  obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
> -obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
> -obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
>  obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
>  obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
>  obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
> diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
> index a0218c4867b9..4a335d3c5969 100644
> --- a/arch/arm/kernel/iwmmxt.S
> +++ b/arch/arm/kernel/iwmmxt.S
> @@ -18,18 +18,6 @@
>  #include <asm/assembler.h>
>  #include "iwmmxt.h"
>  
> -#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
> -#define PJ4(code...)		code
> -#define XSC(code...)
> -#elif defined(CONFIG_CPU_MOHAWK) || \
> -	defined(CONFIG_CPU_XSC3) || \
> -	defined(CONFIG_CPU_XSCALE)
> -#define PJ4(code...)
> -#define XSC(code...)		code
> -#else
> -#error "Unsupported iWMMXt architecture"
> -#endif
> -
>  #define MMX_WR0		 	(0x00)
>  #define MMX_WR1		 	(0x08)
>  #define MMX_WR2		 	(0x10)
> @@ -81,17 +69,13 @@ ENDPROC(iwmmxt_undef_handler)
>  ENTRY(iwmmxt_task_enable)
>  	inc_preempt_count r10, r3
>  
> -	XSC(mrc	p15, 0, r2, c15, c1, 0)
> -	PJ4(mrc p15, 0, r2, c1, c0, 2)
> +	mrc	p15, 0, r2, c15, c1, 0
>  	@ CP0 and CP1 accessible?
> -	XSC(tst	r2, #0x3)
> -	PJ4(tst	r2, #0xf)
> +	tst	r2, #0x3
>  	bne	4f				@ if so no business here
>  	@ enable access to CP0 and CP1
> -	XSC(orr	r2, r2, #0x3)
> -	XSC(mcr	p15, 0, r2, c15, c1, 0)
> -	PJ4(orr	r2, r2, #0xf)
> -	PJ4(mcr	p15, 0, r2, c1, c0, 2)
> +	orr	r2, r2, #0x3
> +	mcr	p15, 0, r2, c15, c1, 0
>  
>  	ldr	r3, =concan_owner
>  	ldr	r2, [r0, #S_PC]			@ current task pc value
> @@ -218,12 +202,9 @@ ENTRY(iwmmxt_task_disable)
>  	bne	1f				@ no: quit
>  
>  	@ enable access to CP0 and CP1
> -	XSC(mrc	p15, 0, r4, c15, c1, 0)
> -	XSC(orr	r4, r4, #0x3)
> -	XSC(mcr	p15, 0, r4, c15, c1, 0)
> -	PJ4(mrc p15, 0, r4, c1, c0, 2)
> -	PJ4(orr	r4, r4, #0xf)
> -	PJ4(mcr	p15, 0, r4, c1, c0, 2)
> +	mrc	p15, 0, r4, c15, c1, 0
> +	orr	r4, r4, #0x3
> +	mcr	p15, 0, r4, c15, c1, 0
>  
>  	mov	r0, #0				@ nothing to load
>  	str	r0, [r3]			@ no more current owner
> @@ -232,10 +213,8 @@ ENTRY(iwmmxt_task_disable)
>  	bl	concan_save
>  
>  	@ disable access to CP0 and CP1
> -	XSC(bic	r4, r4, #0x3)
> -	XSC(mcr	p15, 0, r4, c15, c1, 0)
> -	PJ4(bic	r4, r4, #0xf)
> -	PJ4(mcr	p15, 0, r4, c1, c0, 2)
> +	bic	r4, r4, #0x3
> +	mcr	p15, 0, r4, c15, c1, 0
>  
>  	mrc	p15, 0, r2, c2, c0, 0
>  	mov	r2, r2				@ cpwait
> @@ -330,11 +309,9 @@ ENDPROC(iwmmxt_task_restore)
>   */
>  ENTRY(iwmmxt_task_switch)
>  
> -	XSC(mrc	p15, 0, r1, c15, c1, 0)
> -	PJ4(mrc	p15, 0, r1, c1, c0, 2)
> +	mrc	p15, 0, r1, c15, c1, 0
>  	@ CP0 and CP1 accessible?
> -	XSC(tst	r1, #0x3)
> -	PJ4(tst	r1, #0xf)
> +	tst	r1, #0x3
>  	bne	1f				@ yes: block them for next task
>  
>  	ldr	r2, =concan_owner
> @@ -344,10 +321,8 @@ ENTRY(iwmmxt_task_switch)
>  	retne	lr				@ no: leave Concan disabled
>  
>  1:	@ flip Concan access
> -	XSC(eor	r1, r1, #0x3)
> -	XSC(mcr	p15, 0, r1, c15, c1, 0)
> -	PJ4(eor r1, r1, #0xf)
> -	PJ4(mcr	p15, 0, r1, c1, c0, 2)
> +	eor	r1, r1, #0x3
> +	mcr	p15, 0, r1, c15, c1, 0
>  
>  	mrc	p15, 0, r1, c2, c0, 0
>  	sub	pc, lr, r1, lsr #32		@ cpwait and return
> diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
> deleted file mode 100644
> index 4bca8098c4ff..000000000000
> --- a/arch/arm/kernel/pj4-cp0.c
> +++ /dev/null
> @@ -1,135 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * linux/arch/arm/kernel/pj4-cp0.c
> - *
> - * PJ4 iWMMXt coprocessor context switching and handling
> - *
> - * Copyright (c) 2010 Marvell International Inc.
> - */
> -
> -#include <linux/types.h>
> -#include <linux/kernel.h>
> -#include <linux/signal.h>
> -#include <linux/sched.h>
> -#include <linux/init.h>
> -#include <linux/io.h>
> -#include <asm/thread_notify.h>
> -#include <asm/cputype.h>
> -
> -static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
> -{
> -	struct thread_info *thread = t;
> -
> -	switch (cmd) {
> -	case THREAD_NOTIFY_FLUSH:
> -		/*
> -		 * flush_thread() zeroes thread->fpstate, so no need
> -		 * to do anything here.
> -		 *
> -		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
> -		 * initialised state information on the first fault.
> -		 */
> -
> -	case THREAD_NOTIFY_EXIT:
> -		iwmmxt_task_release(thread);
> -		break;
> -
> -	case THREAD_NOTIFY_SWITCH:
> -		iwmmxt_task_switch(thread);
> -		break;
> -	}
> -
> -	return NOTIFY_DONE;
> -}
> -
> -static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
> -	.notifier_call	= iwmmxt_do,
> -};
> -
> -
> -static u32 __init pj4_cp_access_read(void)
> -{
> -	u32 value;
> -
> -	__asm__ __volatile__ (
> -		"mrc	p15, 0, %0, c1, c0, 2\n\t"
> -		: "=r" (value));
> -	return value;
> -}
> -
> -static void __init pj4_cp_access_write(u32 value)
> -{
> -	u32 temp;
> -
> -	__asm__ __volatile__ (
> -		"mcr	p15, 0, %1, c1, c0, 2\n\t"
> -#ifdef CONFIG_THUMB2_KERNEL
> -		"isb\n\t"
> -#else
> -		"mrc	p15, 0, %0, c1, c0, 2\n\t"
> -		"mov	%0, %0\n\t"
> -		"sub	pc, pc, #4\n\t"
> -#endif
> -		: "=r" (temp) : "r" (value));
> -}
> -
> -static int __init pj4_get_iwmmxt_version(void)
> -{
> -	u32 cp_access, wcid;
> -
> -	cp_access = pj4_cp_access_read();
> -	pj4_cp_access_write(cp_access | 0xf);
> -
> -	/* check if coprocessor 0 and 1 are available */
> -	if ((pj4_cp_access_read() & 0xf) != 0xf) {
> -		pj4_cp_access_write(cp_access);
> -		return -ENODEV;
> -	}
> -
> -	/* read iWMMXt coprocessor id register p1, c0 */
> -	__asm__ __volatile__ ("mrc    p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
> -
> -	pj4_cp_access_write(cp_access);
> -
> -	/* iWMMXt v1 */
> -	if ((wcid & 0xffffff00) == 0x56051000)
> -		return 1;
> -	/* iWMMXt v2 */
> -	if ((wcid & 0xffffff00) == 0x56052000)
> -		return 2;
> -
> -	return -EINVAL;
> -}
> -
> -/*
> - * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
> - * switch code handle iWMMXt context switching.
> - */
> -static int __init pj4_cp0_init(void)
> -{
> -	u32 __maybe_unused cp_access;
> -	int vers;
> -
> -	if (!cpu_is_pj4())
> -		return 0;
> -
> -	vers = pj4_get_iwmmxt_version();
> -	if (vers < 0)
> -		return 0;
> -
> -#ifndef CONFIG_IWMMXT
> -	pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
> -#else
> -	cp_access = pj4_cp_access_read() & ~0xf;
> -	pj4_cp_access_write(cp_access);
> -
> -	pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
> -	elf_hwcap |= HWCAP_IWMMXT;
> -	thread_register_notifier(&iwmmxt_notifier_block);
> -	register_iwmmxt_undef_handler();
> -#endif
> -
> -	return 0;
> -}
> -
> -late_initcall(pj4_cp0_init);
> -- 
> 2.43.0.687.g38aa6559b0-goog
> 
>
Jisheng Zhang Feb. 11, 2024, 7:01 a.m. UTC | #4
On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
> On Fri, Feb 9, 2024, at 12:09, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> >
> > PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
> > does not support this combination (its iWMMXt configuration always
> > implies v5te), and so there is no v6/v7 user space that actually makes
> > use of this, beyond generic support for things like setjmp() that
> > preserve/restore the iWMMXt register file using generic LDC/STC
> > instructions emitted in assembler. As [0] appears to imply, this logic
> > is triggered for the init process at boot, and so most processes will
> > have a iWMMXt register context associated with it, even though it is
> > never used.
> >
> > This means that advertising iWMMXt support on these cores results in
> > context switch overhead without any associated benefit, and so it is
> > better to simply ignore the iWMMXt unit on these systems. So rip out the
> > support. Doing so also fixes the issue reported in [0] related to UNDEF
> > handling of co-processor #0/#1 instructions issued from user space
> > running in Thumb2 mode.
> >
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Nicolas Pitre <nico@fluxnic.net>
> > Cc: Russell King <linux@armlinux.org.uk>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> > Fixes: 8bcba70cb5c22 ("ARM: entry: Disregard Thumb undef exception ...")
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=218427 [0]
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>

For berlin SoC

Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
> 
> Maybe add a bit about which cores are actually affected by this:
> 
> The PJ4 cores are used in four platforms: armada 370/xp, dove
> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).

Per berlin2cd.dtsi, chromecast is powered by CA9 ;)

> Out of these, only the first is still widely used, but that
> one actually doesn't have iwmmxt but instead has only
> vfpv3-d16.
> 
> I've also added the maintainers of those platforms to Cc,
> in case anyone has objections after all.
> 
>       Arnd
Arnd Bergmann Feb. 11, 2024, 10:21 a.m. UTC | #5
On Sun, Feb 11, 2024, at 08:01, Jisheng Zhang wrote:
> On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
>>
>> Maybe add a bit about which cores are actually affected by this:
>> 
>> The PJ4 cores are used in four platforms: armada 370/xp, dove
>> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
>
> Per berlin2cd.dtsi, chromecast is powered by CA9 ;)

Right, I confused it with the one in the Google TV, had
not realized these were actually different variants of that
chip.

     Arnd
Ard Biesheuvel Feb. 13, 2024, 2:42 p.m. UTC | #6
On Sun, 11 Feb 2024 at 11:22, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Sun, Feb 11, 2024, at 08:01, Jisheng Zhang wrote:
> > On Fri, Feb 09, 2024 at 03:27:02PM +0100, Arnd Bergmann wrote:
> >>
> >> Maybe add a bit about which cores are actually affected by this:
> >>
> >> The PJ4 cores are used in four platforms: armada 370/xp, dove
> >> (cubox, d2plug), mmp2 (xo-1.75) and berlin (chromecast 1).
> >
> > Per berlin2cd.dtsi, chromecast is powered by CA9 ;)
>
> Right, I confused it with the one in the Google TV, had
> not realized these were actually different variants of that
> chip.
>

Thanks all. I'll respin and resend.
Matt Turner Aug. 15, 2024, 6:41 p.m. UTC | #7
On 02/09, Ard Biesheuvel wrote:
>From: Ard Biesheuvel <ardb@kernel.org>
>
>PJ4 is a v7 core that incorporates a iWMMXt coprocessor. However, GCC
>does not support this combination (its iWMMXt configuration always
>implies v5te), and so there is no v6/v7 user space that actually makes
>use of this, beyond generic support for things like setjmp() that
>preserve/restore the iWMMXt register file using generic LDC/STC
>instructions emitted in assembler. As [0] appears to imply, this logic
>is triggered for the init process at boot, and so most processes will
>have a iWMMXt register context associated with it, even though it is
>never used.
>
>This means that advertising iWMMXt support on these cores results in
>context switch overhead without any associated benefit, and so it is
>better to simply ignore the iWMMXt unit on these systems. So rip out the
>support. Doing so also fixes the issue reported in [0] related to UNDEF
>handling of co-processor #0/#1 instructions issued from user space
>running in Thumb2 mode.

For what it's worth, there was usage of iwMMXt on ARM v7 cores.

pixman had [1][2] iwMMXt paths that I optimized for the XO 1.75 and
would occasionally test on a CuBox over the years.

I'm surprised to see that this landed with the claim that "there is
no v6/v7 user space that actually makes use of this". A quick Google
search reveals evidence of usage [3]. It doesn't seem like this should
have been backported to the stable branches in any case.

I know that ffmpeg used to have iwMMXt paths as well, but I believe they
were removed a few years ago.

Anyway, I guess it's totally dead now.

[1] https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests/108
[2] https://mattst88.com/blog/2012/07/06/My_time_optimizing_graphics_performance_on_the_OLPC_XO_1.75_laptop/
[3] https://www.phoronix.com/news/MTEzNDQ
diff mbox series

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..0d4e316a389e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -503,8 +503,8 @@  source "arch/arm/mm/Kconfig"
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
-	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+	default y if PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 771264d4726a..ae2f2b2b4e5a 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -75,8 +75,6 @@  obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
-obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
-obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index a0218c4867b9..4a335d3c5969 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -18,18 +18,6 @@ 
 #include <asm/assembler.h>
 #include "iwmmxt.h"
 
-#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
-#define PJ4(code...)		code
-#define XSC(code...)
-#elif defined(CONFIG_CPU_MOHAWK) || \
-	defined(CONFIG_CPU_XSC3) || \
-	defined(CONFIG_CPU_XSCALE)
-#define PJ4(code...)
-#define XSC(code...)		code
-#else
-#error "Unsupported iWMMXt architecture"
-#endif
-
 #define MMX_WR0		 	(0x00)
 #define MMX_WR1		 	(0x08)
 #define MMX_WR2		 	(0x10)
@@ -81,17 +69,13 @@  ENDPROC(iwmmxt_undef_handler)
 ENTRY(iwmmxt_task_enable)
 	inc_preempt_count r10, r3
 
-	XSC(mrc	p15, 0, r2, c15, c1, 0)
-	PJ4(mrc p15, 0, r2, c1, c0, 2)
+	mrc	p15, 0, r2, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r2, #0x3)
-	PJ4(tst	r2, #0xf)
+	tst	r2, #0x3
 	bne	4f				@ if so no business here
 	@ enable access to CP0 and CP1
-	XSC(orr	r2, r2, #0x3)
-	XSC(mcr	p15, 0, r2, c15, c1, 0)
-	PJ4(orr	r2, r2, #0xf)
-	PJ4(mcr	p15, 0, r2, c1, c0, 2)
+	orr	r2, r2, #0x3
+	mcr	p15, 0, r2, c15, c1, 0
 
 	ldr	r3, =concan_owner
 	ldr	r2, [r0, #S_PC]			@ current task pc value
@@ -218,12 +202,9 @@  ENTRY(iwmmxt_task_disable)
 	bne	1f				@ no: quit
 
 	@ enable access to CP0 and CP1
-	XSC(mrc	p15, 0, r4, c15, c1, 0)
-	XSC(orr	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(mrc p15, 0, r4, c1, c0, 2)
-	PJ4(orr	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	mrc	p15, 0, r4, c15, c1, 0
+	orr	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mov	r0, #0				@ nothing to load
 	str	r0, [r3]			@ no more current owner
@@ -232,10 +213,8 @@  ENTRY(iwmmxt_task_disable)
 	bl	concan_save
 
 	@ disable access to CP0 and CP1
-	XSC(bic	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(bic	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	bic	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mrc	p15, 0, r2, c2, c0, 0
 	mov	r2, r2				@ cpwait
@@ -330,11 +309,9 @@  ENDPROC(iwmmxt_task_restore)
  */
 ENTRY(iwmmxt_task_switch)
 
-	XSC(mrc	p15, 0, r1, c15, c1, 0)
-	PJ4(mrc	p15, 0, r1, c1, c0, 2)
+	mrc	p15, 0, r1, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r1, #0x3)
-	PJ4(tst	r1, #0xf)
+	tst	r1, #0x3
 	bne	1f				@ yes: block them for next task
 
 	ldr	r2, =concan_owner
@@ -344,10 +321,8 @@  ENTRY(iwmmxt_task_switch)
 	retne	lr				@ no: leave Concan disabled
 
 1:	@ flip Concan access
-	XSC(eor	r1, r1, #0x3)
-	XSC(mcr	p15, 0, r1, c15, c1, 0)
-	PJ4(eor r1, r1, #0xf)
-	PJ4(mcr	p15, 0, r1, c1, c0, 2)
+	eor	r1, r1, #0x3
+	mcr	p15, 0, r1, c15, c1, 0
 
 	mrc	p15, 0, r1, c2, c0, 0
 	sub	pc, lr, r1, lsr #32		@ cpwait and return
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
deleted file mode 100644
index 4bca8098c4ff..000000000000
--- a/arch/arm/kernel/pj4-cp0.c
+++ /dev/null
@@ -1,135 +0,0 @@ 
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/kernel/pj4-cp0.c
- *
- * PJ4 iWMMXt coprocessor context switching and handling
- *
- * Copyright (c) 2010 Marvell International Inc.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <asm/thread_notify.h>
-#include <asm/cputype.h>
-
-static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
-{
-	struct thread_info *thread = t;
-
-	switch (cmd) {
-	case THREAD_NOTIFY_FLUSH:
-		/*
-		 * flush_thread() zeroes thread->fpstate, so no need
-		 * to do anything here.
-		 *
-		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
-		 * initialised state information on the first fault.
-		 */
-
-	case THREAD_NOTIFY_EXIT:
-		iwmmxt_task_release(thread);
-		break;
-
-	case THREAD_NOTIFY_SWITCH:
-		iwmmxt_task_switch(thread);
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
-	.notifier_call	= iwmmxt_do,
-};
-
-
-static u32 __init pj4_cp_access_read(void)
-{
-	u32 value;
-
-	__asm__ __volatile__ (
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		: "=r" (value));
-	return value;
-}
-
-static void __init pj4_cp_access_write(u32 value)
-{
-	u32 temp;
-
-	__asm__ __volatile__ (
-		"mcr	p15, 0, %1, c1, c0, 2\n\t"
-#ifdef CONFIG_THUMB2_KERNEL
-		"isb\n\t"
-#else
-		"mrc	p15, 0, %0, c1, c0, 2\n\t"
-		"mov	%0, %0\n\t"
-		"sub	pc, pc, #4\n\t"
-#endif
-		: "=r" (temp) : "r" (value));
-}
-
-static int __init pj4_get_iwmmxt_version(void)
-{
-	u32 cp_access, wcid;
-
-	cp_access = pj4_cp_access_read();
-	pj4_cp_access_write(cp_access | 0xf);
-
-	/* check if coprocessor 0 and 1 are available */
-	if ((pj4_cp_access_read() & 0xf) != 0xf) {
-		pj4_cp_access_write(cp_access);
-		return -ENODEV;
-	}
-
-	/* read iWMMXt coprocessor id register p1, c0 */
-	__asm__ __volatile__ ("mrc    p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
-
-	pj4_cp_access_write(cp_access);
-
-	/* iWMMXt v1 */
-	if ((wcid & 0xffffff00) == 0x56051000)
-		return 1;
-	/* iWMMXt v2 */
-	if ((wcid & 0xffffff00) == 0x56052000)
-		return 2;
-
-	return -EINVAL;
-}
-
-/*
- * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
- * switch code handle iWMMXt context switching.
- */
-static int __init pj4_cp0_init(void)
-{
-	u32 __maybe_unused cp_access;
-	int vers;
-
-	if (!cpu_is_pj4())
-		return 0;
-
-	vers = pj4_get_iwmmxt_version();
-	if (vers < 0)
-		return 0;
-
-#ifndef CONFIG_IWMMXT
-	pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
-#else
-	cp_access = pj4_cp_access_read() & ~0xf;
-	pj4_cp_access_write(cp_access);
-
-	pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
-	elf_hwcap |= HWCAP_IWMMXT;
-	thread_register_notifier(&iwmmxt_notifier_block);
-	register_iwmmxt_undef_handler();
-#endif
-
-	return 0;
-}
-
-late_initcall(pj4_cp0_init);