diff mbox series

ARM: bcmbca: add VFP and NEON fixup for bcm6846 SoC

Message ID 20220525003509.2812-1-william.zhang@broadcom.com (mailing list archive)
State New, archived
Headers show
Series ARM: bcmbca: add VFP and NEON fixup for bcm6846 SoC | expand

Commit Message

William Zhang May 25, 2022, 12:35 a.m. UTC
BCM6846 SoC only has VFP and NEON support on core 0. So kernel VPF/NEON
support is disabled in this chip. Add this fixup to manually turn on
VFP/NEON in case userspace app need to access them on core 0.

Signed-off-by: William Zhang <william.zhang@broadcom.com>

---

 arch/arm/mach-bcm/Makefile |  5 ++++
 arch/arm/mach-bcm/bcmbca.c | 54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 arch/arm/mach-bcm/bcmbca.c

Comments

Florian Fainelli June 15, 2022, 5:43 p.m. UTC | #1
On 5/24/22 17:35, William Zhang wrote:
> BCM6846 SoC only has VFP and NEON support on core 0. So kernel VPF/NEON
> support is disabled in this chip. Add this fixup to manually turn on
> VFP/NEON in case userspace app need to access them on core 0.
> 
> Signed-off-by: William Zhang <william.zhang@broadcom.com>

We have had this conversation internally already, but I do not think 
this is sufficient in order to have a workable solution, you indicated 
that there is all sorts of user-space involvement in your SDK to ensure 
that only VFP tasks are scheduled on core 0, but if we were to seek a 
proper solution we would have to modify the ARM Linux kernel to forcibly 
migrate VFP tasks onto a core that can support executing them, or accept 
emulating them with the implied slow down.

Russell, what are your thoughts on this?

> 
> ---
> 
>   arch/arm/mach-bcm/Makefile |  5 ++++
>   arch/arm/mach-bcm/bcmbca.c | 54 ++++++++++++++++++++++++++++++++++++++
>   2 files changed, 59 insertions(+)
>   create mode 100644 arch/arm/mach-bcm/bcmbca.c
> 
> diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
> index b2394ddb0558..137b24b52139 100644
> --- a/arch/arm/mach-bcm/Makefile
> +++ b/arch/arm/mach-bcm/Makefile
> @@ -68,3 +68,8 @@ CFLAGS_platsmp-brcmstb.o	+= -march=armv7-a
>   obj-y				+= brcmstb.o
>   obj-$(CONFIG_SMP)		+= platsmp-brcmstb.o
>   endif
> +
> +# BCMBCA
> +ifeq ($(CONFIG_ARCH_BCMBCA),y)
> +obj-y				+= bcmbca.o
> +endif
> diff --git a/arch/arm/mach-bcm/bcmbca.c b/arch/arm/mach-bcm/bcmbca.c
> new file mode 100644
> index 000000000000..6fcdfe0b94c1
> --- /dev/null
> +++ b/arch/arm/mach-bcm/bcmbca.c
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 Broadcom Ltd
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/smp.h>
> +#include <asm/mach/arch.h>
> +#include <asm/vfp.h>
> +#include <asm/cp15.h>
> +
> +#include "../vfp/vfpinstr.h"
> +
> +/*
> + * In some low end BCA chips, only core 0 has VPF/NEON support. Kernel VPF
> + * NEON are disabled on these platforms. Add this fixup to enable VFP/NEON
> + * on core 0 manually in case some user app need to access vfp/neon on core 0
> + */
> +static void __init neon_enable(void *data)
> +{
> +	u32 access, fpexc;
> +	(void)data;
> +
> +	/* Enable full access to VFP (cp10 and cp11) */
> +	access = get_copro_access();
> +	set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
> +
> +	/* enable NEON and VFP extension */
> +	fpexc = fmrx(FPEXC);
> +	fmxr(FPEXC, fpexc | FPEXC_EN);
> +}
> +
> +static void __init bcmbca_neon_fixup(void)
> +{
> +	smp_call_function_single(0, neon_enable, NULL, 1);
> +}
> +
> +static const char *const bcmbca_match[] __initconst = {
> +	"brcm,bcm6846",
> +	NULL
> +};
> +
> +DT_MACHINE_START(BCMBCA, "Broadcom BCMBCA SoC")
> +	.dt_compat		= bcmbca_match,
> +	.init_late		= bcmbca_neon_fixup,
> +MACHINE_END
Russell King (Oracle) June 15, 2022, 6:14 p.m. UTC | #2
On Wed, Jun 15, 2022 at 10:43:28AM -0700, Florian Fainelli wrote:
> On 5/24/22 17:35, William Zhang wrote:
> > BCM6846 SoC only has VFP and NEON support on core 0. So kernel VPF/NEON
> > support is disabled in this chip. Add this fixup to manually turn on
> > VFP/NEON in case userspace app need to access them on core 0.
> > 
> > Signed-off-by: William Zhang <william.zhang@broadcom.com>
> 
> We have had this conversation internally already, but I do not think this is
> sufficient in order to have a workable solution, you indicated that there is
> all sorts of user-space involvement in your SDK to ensure that only VFP
> tasks are scheduled on core 0, but if we were to seek a proper solution we
> would have to modify the ARM Linux kernel to forcibly migrate VFP tasks onto
> a core that can support executing them, or accept emulating them with the
> implied slow down.
> 
> Russell, what are your thoughts on this?

The patch only enables access to the VFP, which adds the additional
instructions on that core. However, if the kernel has decided that
VFP isn't available, then we won't be advertising VFP via the HWCAPS
and therefore libraries won't be using it.

However, there may be some userspace that "probes" for VFP instruction
presence by trying to execute a VFP instruction, and catching the
SIGILL. The problem here is if we enable it on core 0 and such an app
is used, then it will think VFP is generally available when it isn't.

So, in terms of system stability, I don't think this is something we
want to generally do.

Also, without the VFP kernel support code, VFP registers won't be
saved and restored across context switches (which makes them a nice
path for covert communication) and neither will they be saved and
restored properly for signal handlers - so any use of VFP on that
core would need to be carefully thought through.

It doesn't sound like a particularly good idea for a generic kernel
to me, even one running on the specific hardware. For example, a
debian hardfp userspace may well run on core 0 but not properly.
diff mbox series

Patch

diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index b2394ddb0558..137b24b52139 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -68,3 +68,8 @@  CFLAGS_platsmp-brcmstb.o	+= -march=armv7-a
 obj-y				+= brcmstb.o
 obj-$(CONFIG_SMP)		+= platsmp-brcmstb.o
 endif
+
+# BCMBCA
+ifeq ($(CONFIG_ARCH_BCMBCA),y)
+obj-y				+= bcmbca.o
+endif
diff --git a/arch/arm/mach-bcm/bcmbca.c b/arch/arm/mach-bcm/bcmbca.c
new file mode 100644
index 000000000000..6fcdfe0b94c1
--- /dev/null
+++ b/arch/arm/mach-bcm/bcmbca.c
@@ -0,0 +1,54 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Broadcom Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/smp.h>
+#include <asm/mach/arch.h>
+#include <asm/vfp.h>
+#include <asm/cp15.h>
+
+#include "../vfp/vfpinstr.h"
+
+/*
+ * In some low end BCA chips, only core 0 has VPF/NEON support. Kernel VPF
+ * NEON are disabled on these platforms. Add this fixup to enable VFP/NEON
+ * on core 0 manually in case some user app need to access vfp/neon on core 0
+ */
+static void __init neon_enable(void *data)
+{
+	u32 access, fpexc;
+	(void)data;
+
+	/* Enable full access to VFP (cp10 and cp11) */
+	access = get_copro_access();
+	set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+
+	/* enable NEON and VFP extension */
+	fpexc = fmrx(FPEXC);
+	fmxr(FPEXC, fpexc | FPEXC_EN);
+}
+
+static void __init bcmbca_neon_fixup(void)
+{
+	smp_call_function_single(0, neon_enable, NULL, 1);
+}
+
+static const char *const bcmbca_match[] __initconst = {
+	"brcm,bcm6846",
+	NULL
+};
+
+DT_MACHINE_START(BCMBCA, "Broadcom BCMBCA SoC")
+	.dt_compat		= bcmbca_match,
+	.init_late		= bcmbca_neon_fixup,
+MACHINE_END