Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] ARM: OMAP2+: Delete an unnecessary kfree() call in omap_hsmmc_pdata_init()
From: Tony Lindgren @ 2019-08-28 18:30 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Paul Walmsley, Balaji T K, kernel-janitors, Kishore Kadiyala,
	Russell King, LKML, Markus Elfring, Nikolaus Schaller, linux-omap,
	linux-arm-kernel, Benoit Cousson
In-Reply-To: <20190827181457.GA16333@lenoch>

* Ladislav Michl <ladis@linux-mips.org> [190827 18:15]:
> On Mon, Aug 26, 2019 at 09:20:50AM -0700, Tony Lindgren wrote:
> > * Markus Elfring <Markus.Elfring@web.de> [190826 06:31]:
> > > From: Markus Elfring <elfring@users.sourceforge.net>
> > > Date: Mon, 26 Aug 2019 15:05:31 +0200
> > > 
> > > A null pointer would be passed to a call of the function "kfree" directly
> > > after a call of the function "kzalloc" failed at one place.
> > > Remove this superfluous function call.
> > > 
> > > This issue was detected by using the Coccinelle software.
> > 
> > Applying into omap-for-v5.4/soc thanks.
> 
> Is it really wise touching almost dead code? Last user is pandora board, so
> +Cc: Nikolaus Schaller <hns@goldelico.com>

Yeah would be good to finally get rid of that old code.
Anyways, I'll keep the $subject patch to cut down on
coccinelle produced issue.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 14/22] ARM: omap1: use pci_ioremap_io() for omap_cf
From: Aaro Koskinen @ 2019-08-28 18:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Bartlomiej Zolnierkiewicz, Tony Lindgren, Greg Kroah-Hartman,
	Linus Walleij, Linux Kernel Mailing List, Dominik Brodowski,
	Tomi Valkeinen, linux-omap, Linux ARM
In-Reply-To: <CAK8P3a1PeBMRuweAmzrTQC85CmwdZPirG3HPg9aJ99p2U7zknQ@mail.gmail.com>

Hi,

On Wed, Aug 28, 2019 at 03:02:36PM +0200, Arnd Bergmann wrote:
> On Tue, Aug 27, 2019 at 9:05 PM Aaro Koskinen <aaro.koskinen@iki.fi> wrote:
> > On Tue, Aug 27, 2019 at 06:33:01PM +0200, Arnd Bergmann wrote:
> > > On Fri, Aug 16, 2019 at 10:34 AM Aaro Koskinen <aaro.koskinen@iki.fi> wrote:
> > > > However with earlyprintk it seems to hang as soon as kernel tries to print
> > > > something. So something goes wrong with early DEBUG_LL mapping code when
> > > > CONFIG_DEBUG_UART_VIRT=0xff000000 is used?
> > >
> > > I just redid the calculation and came out with the same address, so I
> > > don't think I put the wrong one there. The address also does not
> > > conflict with the PCI mapping, and the address is the same one that
> > > is installed later, so that should also be fine.
> > >
> > > Are you sure you used the correct address in the .config file? If you
> > > ran 'make oldconfig', the virtual address would not be changed here
> > > as I just modify the default for a fresh 'make omap1_defconfig'
> > > run or similar.
> >
> > Yes... You should be able to try this out also in QEMU to see the hang:
> 
> Haven't tried yet, but I took a look at the dump:
> 
> > $ qemu-system-arm -M sx1 -kernel sx1-zImage -nographic
> >
> > [ Hangs silently, press Ctrl-a c to enter monitor. ]
> >
> > QEMU 4.1.0 monitor - type 'help' for more information
> > (qemu) info registers
> > R00=c0379de1 R01=0000005b R02=00000000 R03=ff000000
> > R04=00000000 R05=00000031 R06=c038f119 R07=00000000
> > R08=00000000 R09=c038f50e R10=600001d3 R11=00000001
> > R12=00000010 R13=c0379de0 R14=c000e07c R15=c000dfcc
> > PSR=000001d3 ---- A svc32
> > FPSCR: 00000000
> >
> > from System.map:
> > c000df7c T printascii
> > c000dfe0 T printch
> 
> Ok, that is clearly the "busyloop" macro in
> arch/arm/include/debug/8250.S, checking if the data got sent.
> 
> The 'r2' register contains zero, so UART_LSR_TEMT and
> UART_LSR_THRE are not set, but presumably the mapping
> was installed right since you did not get a page fault.
> 
> I assume you checked that the uart output wasn't already broken
> by one of the earlier patches, right?

Correct, it's only with the mapping change patch it hangs.

> Also, looking at arch/arm/mach-omap1/include/mach/uncompress.h
> it seems that SX1 normally uses UART3, not UART1.
> Is that different in qemu?

In QEMU all uarts can be used, trying with UART3 as early console
hangs as well. (It prints Uncompressing... done. but I guess that's
done with the physical address.)

A.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] PCI: rockchip: Properly handle optional regulators
From: Heiko Stuebner @ 2019-08-28 18:15 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Lorenzo Pieralisi, linux-pci, Shawn Lin, Vidya Sagar,
	linux-rockchip, Bjorn Helgaas, Andrew Murray, linux-arm-kernel
In-Reply-To: <20190828150737.30285-1-thierry.reding@gmail.com>

Am Mittwoch, 28. August 2019, 17:07:37 CEST schrieb Thierry Reding:
> From: Thierry Reding <treding@nvidia.com>
> 
> regulator_get_optional() can fail for a number of reasons besides probe
> deferral. It can for example return -ENOMEM if it runs out of memory as
> it tries to allocate data structures. Propagating only -EPROBE_DEFER is
> problematic because it results in these legitimately fatal errors being
> treated as "regulator not specified in DT".
> 
> What we really want is to ignore the optional regulators only if they
> have not been specified in DT. regulator_get_optional() returns -ENODEV
> in this case, so that's the special case that we need to handle. So we
> propagate all errors, except -ENODEV, so that real failures will still
> cause the driver to fail probe.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>

on a rk3399-gru-scarlet with no 12v regulator defined and pcie-wifi
keeping on working with this patch:

Tested-by: Heiko Stuebner <heiko@sntech.de>

Change itself also looks correct,

Reviewed-by: Heiko Stuebner <heiko@sntech.de>

Thanks for doing that cleanup
Heiko



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: [PATCH] arm: xen: mm: use __GPF_DMA32 for arm64
From: Stefano Stabellini @ 2019-08-28 18:09 UTC (permalink / raw)
  To: Peng Fan
  Cc: sstabellini@kernel.org, linux@armlinux.org.uk,
	linux-kernel@vger.kernel.org, dl-linux-imx, van.freenix@gmail.com,
	xen-devel@lists.xenproject.org, Robin Murphy,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <AM0PR04MB4481386D2C54AEA6987E1B1588A30@AM0PR04MB4481.eurprd04.prod.outlook.com>

On Wed, 28 Aug 2019, Peng Fan wrote:
> Hi Robin,
> 
> > Subject: Re: [PATCH] arm: xen: mm: use __GPF_DMA32 for arm64
> > 
> > On 09/07/2019 09:22, Peng Fan wrote:
> > > arm64 shares some code under arch/arm/xen, including mm.c.
> > > However ZONE_DMA is removed by commit
> > > ad67f5a6545("arm64: replace ZONE_DMA with ZONE_DMA32").
> > > So to ARM64, need use __GFP_DMA32.

Hi Peng,

Sorry for being so late in replying, this email got lost in the noise.


> > > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > > ---
> > >   arch/arm/xen/mm.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index
> > > e1d44b903dfc..a95e76d18bf9 100644
> > > --- a/arch/arm/xen/mm.c
> > > +++ b/arch/arm/xen/mm.c
> > > @@ -27,7 +27,7 @@ unsigned long xen_get_swiotlb_free_pages(unsigned
> > > int order)
> > >
> > >   	for_each_memblock(memory, reg) {
> > >   		if (reg->base < (phys_addr_t)0xffffffff) {
> > > -			flags |= __GFP_DMA;
> > > +			flags |= __GFP_DMA | __GFP_DMA32;
> > 
> > Given the definition of GFP_ZONE_BAD, I'm not sure this combination of flags
> > is strictly valid, but rather is implicitly reliant on only one of those zones ever
> > actually existing. As such, it seems liable to blow up if the plans to add
> > ZONE_DMA to arm64[1] go ahead.
> 
> How about this, or do you have any suggestions?
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index d33b77e9add3..f61c29a4430f 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -28,7 +28,11 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
> 
>         for_each_memblock(memory, reg) {
>                 if (reg->base < (phys_addr_t)0xffffffff) {
> +#ifdef CONFIG_ARM64
> +                       flags |= __GFP_DMA32;
> +#else
>                         flags |= __GFP_DMA;
> +#endif
>                         break;
>                 }
>         }

Yes I think this is the way to go, but we are trying not to add any
#ifdef CONFIG_ARM64 under arch/arm. Maybe you could introduce a static
inline function to set GFP_DMA:

  static inline void xen_set_gfp_dma(gfp_t *flags)

it could be implemented under arch/arm/include/asm/xen/page.h for arm
and under arch/arm64/include/asm/xen/page.h for arm64 using __GFP_DMA
for the former and __GFP_DMA32 for the latter.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 0/3] arm64: meson-sm1: add support for the SM1 based VIM3L
From: Kevin Hilman @ 2019-08-28 17:55 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: linux-amlogic, linux-kernel, linux-arm-kernel, Neil Armstrong
In-Reply-To: <20190828141816.16328-1-narmstrong@baylibre.com>

Neil Armstrong <narmstrong@baylibre.com> writes:

> This patchset adds support for the Amlogic SM1 based Khadas VIM3L variant.
>
> The S903D3 package variant of SM1 is pin-to-pin compatible with the
> S922X and A311d, so only internal DT changes are needed :
> - DVFS support is different
> - Audio support not yet available for SM1
>
> This patchset moved all the non-g12b nodes to meson-khadas-vim3.dtsi
> and add the sm1 specific nodes into meson-sm1-khadas-vim3l.dts.

Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Tested-by: Kevin Hilman <khilman@baylibre.com>

Basic boot test + suspend/resume test OK on my vim3L (thanks to Khadas
for the board!)

> Display has a color conversion bug on SM1 by using a more recent vendor
> bootloader on the SM1 based VIM3, this is out of scope of this patchset
> and will be fixed in the drm/meson driver.
>
> Dependencies:
> - patch 1,2: None
> - patch 3: Depends on the "arm64: meson-sm1: add support for DVFS" patchset at [1]

I tested in my integ branch where this series is applied, but I'm not
seeing any OPPs created (/sys/devices/system/cpu/cpufreq/)

Kevin

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 5/5] arm64: atomics: remove atomic_ll_sc compilation unit
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

We no longer fall back to out-of-line atomics on systems with
CONFIG_ARM64_LSE_ATOMICS where ARM64_HAS_LSE_ATOMICS is not set. Let's
remove the now unused compilation unit which provided these symbols.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/lib/Makefile       | 19 -------------------
 arch/arm64/lib/atomic_ll_sc.c |  3 ---
 2 files changed, 22 deletions(-)
 delete mode 100644 arch/arm64/lib/atomic_ll_sc.c

diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 33c2a4abda04..f10809ef1690 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -11,25 +11,6 @@ CFLAGS_REMOVE_xor-neon.o	+= -mgeneral-regs-only
 CFLAGS_xor-neon.o		+= -ffreestanding
 endif
 
-# Tell the compiler to treat all general purpose registers (with the
-# exception of the IP registers, which are already handled by the caller
-# in case of a PLT) as callee-saved, which allows for efficient runtime
-# patching of the bl instruction in the caller with an atomic instruction
-# when supported by the CPU. Result and argument registers are handled
-# correctly, based on the function prototype.
-lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
-CFLAGS_atomic_ll_sc.o	:= -ffixed-x1 -ffixed-x2        		\
-		   -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6		\
-		   -ffixed-x7 -fcall-saved-x8 -fcall-saved-x9		\
-		   -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12	\
-		   -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15	\
-		   -fcall-saved-x18 -fomit-frame-pointer
-CFLAGS_REMOVE_atomic_ll_sc.o := $(CC_FLAGS_FTRACE)
-GCOV_PROFILE_atomic_ll_sc.o	:= n
-KASAN_SANITIZE_atomic_ll_sc.o	:= n
-KCOV_INSTRUMENT_atomic_ll_sc.o	:= n
-UBSAN_SANITIZE_atomic_ll_sc.o	:= n
-
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
 obj-$(CONFIG_CRC32) += crc32.o
diff --git a/arch/arm64/lib/atomic_ll_sc.c b/arch/arm64/lib/atomic_ll_sc.c
deleted file mode 100644
index b0c538b0da28..000000000000
--- a/arch/arm64/lib/atomic_ll_sc.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <asm/atomic.h>
-#define __ARM64_IN_ATOMIC_IMPL
-#include <asm/atomic_ll_sc.h>
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 4/5] arm64: avoid using hard-coded registers for LSE atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

Now that we have removed the out-of-line ll/sc atomics we can give
the compiler the freedom to choose its own register allocation. Let's
remove the hard-coded use of x30.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic_lse.h | 70 +++++++++++++++++------------
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 7dce5e1f074e..c6bd87d2915b 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -55,12 +55,14 @@ ATOMIC_FETCH_OPS(add, ldadd)
 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...)				\
 static inline int __lse_atomic_add_return##name(int i, atomic_t *v)	\
 {									\
+	u32 tmp;							\
+									\
 	asm volatile(							\
-	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30"				\
-	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
+	"	add	%w[i], %w[i], %w[tmp]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -113,13 +115,15 @@ static inline void __lse_atomic_sub(int i, atomic_t *v)
 #define ATOMIC_OP_SUB_RETURN(name, mb, cl...)				\
 static inline int __lse_atomic_sub_return##name(int i, atomic_t *v)	\
 {									\
+	u32 tmp;							\
+									\
 	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
-	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30"				\
-	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%w[i], %w[tmp], %[v]\n"			\
+	"	add	%w[i], %w[i], %w[tmp]"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);							\
 									\
 	return i;							\
 }
@@ -196,12 +200,14 @@ ATOMIC64_FETCH_OPS(add, ldadd)
 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...)				\
 static inline long __lse_atomic64_add_return##name(s64 i, atomic64_t *v)\
 {									\
+	unsigned long tmp;						\
+									\
 	asm volatile(							\
-	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30"				\
-	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
+	"	add	%[i], %[i], %x[tmp]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -254,13 +260,15 @@ static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)				\
 static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
 {									\
+	unsigned long tmp;						\
+									\
 	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
-	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30"				\
-	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	"	ldadd" #mb "	%[i], %x[tmp], %[v]\n"			\
+	"	add	%[i], %[i], %x[tmp]"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)	\
 	: "r" (v)							\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return i;							\
 }
@@ -294,18 +302,20 @@ ATOMIC64_FETCH_OP_SUB(        , al, "memory")
 
 static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 {
+	unsigned long tmp;
+
 	asm volatile(
-	"1:	ldr	x30, %[v]\n"
-	"	subs	%[ret], x30, #1\n"
+	"1:	ldr	%x[tmp], %[v]\n"
+	"	subs	%[ret], %x[tmp], #1\n"
 	"	b.lt	2f\n"
-	"	casal	x30, %[ret], %[v]\n"
-	"	sub	x30, x30, #1\n"
-	"	sub	x30, x30, %[ret]\n"
-	"	cbnz	x30, 1b\n"
+	"	casal	%x[tmp], %[ret], %[v]\n"
+	"	sub	%x[tmp], %x[tmp], #1\n"
+	"	sub	%x[tmp], %x[tmp], %[ret]\n"
+	"	cbnz	%x[tmp], 1b\n"
 	"2:"
-	: [ret] "+&r" (v), [v] "+Q" (v->counter)
+	: [ret] "+&r" (v), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)
 	:
-	: "x30", "cc", "memory");
+	: "cc", "memory");
 
 	return (long)v;
 }
@@ -318,14 +328,16 @@ static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr,	\
 	register unsigned long x0 asm ("x0") = (unsigned long)ptr;	\
 	register u##sz x1 asm ("x1") = old;				\
 	register u##sz x2 asm ("x2") = new;				\
+	unsigned long tmp;						\
 									\
 	asm volatile(							\
-	"	mov	" #w "30, %" #w "[old]\n"			\
-	"	cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n"	\
-	"	mov	%" #w "[ret], " #w "30"				\
-	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr)		\
+	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
+	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
+	"	mov	%" #w "[ret], %" #w "[tmp]"			\
+	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
+	  [tmp] "=&r" (tmp)						\
 	: [old] "r" (x1), [new] "r" (x2)				\
-	: "x30", ##cl);							\
+	: cl);								\
 									\
 	return x0;							\
 }
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 3/5] arm64: atomics: avoid out-of-line ll/sc atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

When building for LSE atomics (CONFIG_ARM64_LSE_ATOMICS), if the hardware
or toolchain doesn't support it the existing code will fallback to ll/sc
atomics. It achieves this by branching from inline assembly to a function
that is built with specical compile flags. Further this results in the
clobbering of registers even when the fallback isn't used increasing
register pressure.

Let's improve this by providing inline implementations of both LSE and
ll/sc and use a static key to select between them. This allows for the
compiler to generate better atomics code.

To improve icache performance for the LL/SC fallback atomics, we put them
in their own subsection.

Please note that as atomic_arch.h is included indirectly by kernel.h
(via bitops.h), we cannot depend on features provided later in the kernel.h
file. This prevents us from placing the system_uses_lse_atomics function
in cpu_feature.h due to its dependencies.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic.h       |  11 +-
 arch/arm64/include/asm/atomic_arch.h  | 155 +++++++++++
 arch/arm64/include/asm/atomic_ll_sc.h | 113 ++++----
 arch/arm64/include/asm/atomic_lse.h   | 365 ++++++++------------------
 arch/arm64/include/asm/cmpxchg.h      |   2 +-
 arch/arm64/include/asm/lse.h          |  11 -
 6 files changed, 329 insertions(+), 328 deletions(-)
 create mode 100644 arch/arm64/include/asm/atomic_arch.h

diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
index 657b0457d83c..c70d3f389d29 100644
--- a/arch/arm64/include/asm/atomic.h
+++ b/arch/arm64/include/asm/atomic.h
@@ -17,16 +17,7 @@
 
 #ifdef __KERNEL__
 
-#define __ARM64_IN_ATOMIC_IMPL
-
-#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
-#include <asm/atomic_lse.h>
-#else
-#include <asm/atomic_ll_sc.h>
-#endif
-
-#undef __ARM64_IN_ATOMIC_IMPL
-
+#include <asm/atomic_arch.h>
 #include <asm/cmpxchg.h>
 
 #define ATOMIC_INIT(i)	{ (i) }
diff --git a/arch/arm64/include/asm/atomic_arch.h b/arch/arm64/include/asm/atomic_arch.h
new file mode 100644
index 000000000000..1aac7fc65084
--- /dev/null
+++ b/arch/arm64/include/asm/atomic_arch.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Selection between LSE and LL/SC atomics.
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ * Author: Andrew Murray <andrew.murray@arm.com>
+ */
+
+#ifndef __ASM_ATOMIC_ARCH_H
+#define __ASM_ATOMIC_ARCH_H
+
+
+#include <linux/jump_label.h>
+
+#include <asm/cpucaps.h>
+#include <asm/atomic_ll_sc.h>
+#include <asm/atomic_lse.h>
+
+extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
+extern struct static_key_false arm64_const_caps_ready;
+
+static inline bool system_uses_lse_atomics(void)
+{
+	return (IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) &&
+		IS_ENABLED(CONFIG_AS_LSE) &&
+		static_branch_likely(&arm64_const_caps_ready)) &&
+		static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
+}
+
+#define __lse_ll_sc_body(op, ...)					\
+({									\
+	system_uses_lse_atomics() ?					\
+		__lse_##op(__VA_ARGS__) :				\
+		__ll_sc_##op(__VA_ARGS__);				\
+})
+
+#define ATOMIC_OP(op)							\
+static inline void arch_##op(int i, atomic_t *v)			\
+{									\
+	__lse_ll_sc_body(op, i, v);					\
+}
+
+ATOMIC_OP(atomic_andnot)
+ATOMIC_OP(atomic_or)
+ATOMIC_OP(atomic_xor)
+ATOMIC_OP(atomic_add)
+ATOMIC_OP(atomic_and)
+ATOMIC_OP(atomic_sub)
+
+
+#define ATOMIC_FETCH_OP(name, op)					\
+static inline int arch_##op##name(int i, atomic_t *v)			\
+{									\
+	return __lse_ll_sc_body(op##name, i, v);			\
+}
+
+#define ATOMIC_FETCH_OPS(op)						\
+	ATOMIC_FETCH_OP(_relaxed, op)					\
+	ATOMIC_FETCH_OP(_acquire, op)					\
+	ATOMIC_FETCH_OP(_release, op)					\
+	ATOMIC_FETCH_OP(        , op)
+
+ATOMIC_FETCH_OPS(atomic_fetch_andnot)
+ATOMIC_FETCH_OPS(atomic_fetch_or)
+ATOMIC_FETCH_OPS(atomic_fetch_xor)
+ATOMIC_FETCH_OPS(atomic_fetch_add)
+ATOMIC_FETCH_OPS(atomic_fetch_and)
+ATOMIC_FETCH_OPS(atomic_fetch_sub)
+ATOMIC_FETCH_OPS(atomic_add_return)
+ATOMIC_FETCH_OPS(atomic_sub_return)
+
+
+#define ATOMIC64_OP(op)							\
+static inline void arch_##op(long i, atomic64_t *v)			\
+{									\
+	__lse_ll_sc_body(op, i, v);					\
+}
+
+ATOMIC64_OP(atomic64_andnot)
+ATOMIC64_OP(atomic64_or)
+ATOMIC64_OP(atomic64_xor)
+ATOMIC64_OP(atomic64_add)
+ATOMIC64_OP(atomic64_and)
+ATOMIC64_OP(atomic64_sub)
+
+
+#define ATOMIC64_FETCH_OP(name, op)					\
+static inline long arch_##op##name(long i, atomic64_t *v)		\
+{									\
+	return __lse_ll_sc_body(op##name, i, v);			\
+}
+
+#define ATOMIC64_FETCH_OPS(op)						\
+	ATOMIC64_FETCH_OP(_relaxed, op)					\
+	ATOMIC64_FETCH_OP(_acquire, op)					\
+	ATOMIC64_FETCH_OP(_release, op)					\
+	ATOMIC64_FETCH_OP(        , op)
+
+ATOMIC64_FETCH_OPS(atomic64_fetch_andnot)
+ATOMIC64_FETCH_OPS(atomic64_fetch_or)
+ATOMIC64_FETCH_OPS(atomic64_fetch_xor)
+ATOMIC64_FETCH_OPS(atomic64_fetch_add)
+ATOMIC64_FETCH_OPS(atomic64_fetch_and)
+ATOMIC64_FETCH_OPS(atomic64_fetch_sub)
+ATOMIC64_FETCH_OPS(atomic64_add_return)
+ATOMIC64_FETCH_OPS(atomic64_sub_return)
+
+
+static inline long arch_atomic64_dec_if_positive(atomic64_t *v)
+{
+	return __lse_ll_sc_body(atomic64_dec_if_positive, v);
+}
+
+#define __CMPXCHG_CASE(name, sz)			\
+static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
+					      u##sz old,		\
+					      u##sz new)		\
+{									\
+	return __lse_ll_sc_body(_cmpxchg_case_##name##sz,		\
+				ptr, old, new);				\
+}
+
+__CMPXCHG_CASE(    ,  8)
+__CMPXCHG_CASE(    , 16)
+__CMPXCHG_CASE(    , 32)
+__CMPXCHG_CASE(    , 64)
+__CMPXCHG_CASE(acq_,  8)
+__CMPXCHG_CASE(acq_, 16)
+__CMPXCHG_CASE(acq_, 32)
+__CMPXCHG_CASE(acq_, 64)
+__CMPXCHG_CASE(rel_,  8)
+__CMPXCHG_CASE(rel_, 16)
+__CMPXCHG_CASE(rel_, 32)
+__CMPXCHG_CASE(rel_, 64)
+__CMPXCHG_CASE(mb_,  8)
+__CMPXCHG_CASE(mb_, 16)
+__CMPXCHG_CASE(mb_, 32)
+__CMPXCHG_CASE(mb_, 64)
+
+
+#define __CMPXCHG_DBL(name)						\
+static inline long __cmpxchg_double##name(unsigned long old1,		\
+					 unsigned long old2,		\
+					 unsigned long new1,		\
+					 unsigned long new2,		\
+					 volatile void *ptr)		\
+{									\
+	return __lse_ll_sc_body(_cmpxchg_double##name, 			\
+				old1, old2, new1, new2, ptr);		\
+}
+
+__CMPXCHG_DBL(   )
+__CMPXCHG_DBL(_mb)
+
+#endif	/* __ASM_ATOMIC_LSE_H */
diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index 6dd011e0b434..95091f72228b 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -10,83 +10,86 @@
 #ifndef __ASM_ATOMIC_LL_SC_H
 #define __ASM_ATOMIC_LL_SC_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
+#if IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) && IS_ENABLED(CONFIG_AS_LSE)
+#define __LL_SC_FALLBACK(asm_ops)					\
+"	b	3f\n"							\
+"	.subsection	1\n"						\
+"3:\n"									\
+asm_ops "\n"								\
+"	b	4f\n"							\
+"	.previous\n"							\
+"4:\n"
+#else
+#define __LL_SC_FALLBACK(asm_ops) asm_ops
 #endif
 
 /*
  * AArch64 UP and SMP safe atomic ops.  We use load exclusive and
  * store exclusive to ensure that these are atomic.  We may loop
  * to ensure that the update happens.
- *
- * NOTE: these functions do *not* follow the PCS and must explicitly
- * save any clobbered registers other than x0 (regardless of return
- * value).  This is achieved through -fcall-saved-* compiler flags for
- * this file, which unfortunately don't work on a per-function basis
- * (the optimize attribute silently ignores these options).
  */
 
 #define ATOMIC_OP(op, asm_op, constraint)				\
-__LL_SC_INLINE void							\
-__LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
+static inline void							\
+__ll_sc_atomic_##op(int i, atomic_t *v)					\
 {									\
 	unsigned long tmp;						\
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "\n"				\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ldxr	%w0, %2\n"						\
 "	" #asm_op "	%w0, %w0, %w3\n"				\
 "	stxr	%w1, %w0, %2\n"						\
-"	cbnz	%w1, 1b"						\
+"	cbnz	%w1, 1b\n")						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i));						\
-}									\
-__LL_SC_EXPORT(arch_atomic_##op);
+}
 
 #define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE int							\
-__LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
+static inline int							\
+__ll_sc_atomic_##op##_return##name(int i, atomic_t *v)			\
 {									\
 	unsigned long tmp;						\
 	int result;							\
 									\
 	asm volatile("// atomic_" #op "_return" #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ld" #acq "xr	%w0, %2\n"					\
 "	" #asm_op "	%w0, %w0, %w3\n"				\
 "	st" #rel "xr	%w1, %w0, %2\n"					\
 "	cbnz	%w1, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic_##op##_return##name);
+}
 
-#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)	\
-__LL_SC_INLINE int							\
-__LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
+#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint) \
+static inline int							\
+__ll_sc_atomic_fetch_##op##name(int i, atomic_t *v)			\
 {									\
 	unsigned long tmp;						\
 	int val, result;						\
 									\
 	asm volatile("// atomic_fetch_" #op #name "\n"			\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %3\n"					\
 "1:	ld" #acq "xr	%w0, %3\n"					\
 "	" #asm_op "	%w1, %w0, %w4\n"				\
 "	st" #rel "xr	%w2, %w1, %3\n"					\
 "	cbnz	%w2, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic_fetch_##op##name);
+}
 
 #define ATOMIC_OPS(...)							\
 	ATOMIC_OP(__VA_ARGS__)						\
@@ -121,66 +124,66 @@ ATOMIC_OPS(xor, eor, )
 #undef ATOMIC_OP
 
 #define ATOMIC64_OP(op, asm_op, constraint)				\
-__LL_SC_INLINE void							\
-__LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
+static inline void							\
+__ll_sc_atomic64_##op(s64 i, atomic64_t *v)				\
 {									\
 	s64 result;							\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "\n"				\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ldxr	%0, %2\n"						\
 "	" #asm_op "	%0, %0, %3\n"					\
 "	stxr	%w1, %0, %2\n"						\
-"	cbnz	%w1, 1b"						\
+"	cbnz	%w1, 1b")						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i));						\
-}									\
-__LL_SC_EXPORT(arch_atomic64_##op);
+}
 
 #define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE s64							\
-__LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
+static inline long							\
+__ll_sc_atomic64_##op##_return##name(s64 i, atomic64_t *v)		\
 {									\
 	s64 result;							\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_" #op "_return" #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %2\n"					\
 "1:	ld" #acq "xr	%0, %2\n"					\
 "	" #asm_op "	%0, %0, %3\n"					\
 "	st" #rel "xr	%w1, %0, %2\n"					\
 "	cbnz	%w1, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic64_##op##_return##name);
+}
 
 #define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
-__LL_SC_INLINE s64							\
-__LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
+static inline long							\
+__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v)		\
 {									\
 	s64 result, val;						\
 	unsigned long tmp;						\
 									\
 	asm volatile("// atomic64_fetch_" #op #name "\n"		\
+	__LL_SC_FALLBACK(						\
 "	prfm	pstl1strm, %3\n"					\
 "1:	ld" #acq "xr	%0, %3\n"					\
 "	" #asm_op "	%1, %0, %4\n"					\
 "	st" #rel "xr	%w2, %1, %3\n"					\
 "	cbnz	%w2, 1b\n"						\
-"	" #mb								\
+"	" #mb )								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
 	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
-}									\
-__LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
+}
 
 #define ATOMIC64_OPS(...)						\
 	ATOMIC64_OP(__VA_ARGS__)					\
@@ -214,13 +217,14 @@ ATOMIC64_OPS(xor, eor, L)
 #undef ATOMIC64_OP_RETURN
 #undef ATOMIC64_OP
 
-__LL_SC_INLINE s64
-__LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
+static inline s64
+__ll_sc_atomic64_dec_if_positive(atomic64_t *v)
 {
 	s64 result;
 	unsigned long tmp;
 
 	asm volatile("// atomic64_dec_if_positive\n"
+	__LL_SC_FALLBACK(
 "	prfm	pstl1strm, %2\n"
 "1:	ldxr	%0, %2\n"
 "	subs	%0, %0, #1\n"
@@ -228,20 +232,19 @@ __LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
 "	stlxr	%w1, %0, %2\n"
 "	cbnz	%w1, 1b\n"
 "	dmb	ish\n"
-"2:"
+"2:")
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)
 	:
 	: "cc", "memory");
 
 	return result;
 }
-__LL_SC_EXPORT(arch_atomic64_dec_if_positive);
 
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl, constraint)	\
-__LL_SC_INLINE u##sz							\
-__LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
+static inline u##sz							\
+__ll_sc__cmpxchg_case_##name##sz(volatile void *ptr,			\
 					 unsigned long old,		\
-					 u##sz new))			\
+					 u##sz new)			\
 {									\
 	unsigned long tmp;						\
 	u##sz oldval;							\
@@ -255,6 +258,7 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 		old = (u##sz)old;					\
 									\
 	asm volatile(							\
+	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %[v]\n"				\
 	"1:	ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n"		\
 	"	eor	%" #w "[tmp], %" #w "[oldval], %" #w "[old]\n"	\
@@ -262,15 +266,14 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 	"	st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n"	\
 	"	cbnz	%w[tmp], 1b\n"					\
 	"	" #mb "\n"						\
-	"2:"								\
+	"2:")								\
 	: [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),			\
 	  [v] "+Q" (*(u##sz *)ptr)					\
 	: [old] #constraint "r" (old), [new] "r" (new)			\
 	: cl);								\
 									\
 	return oldval;							\
-}									\
-__LL_SC_EXPORT(__cmpxchg_case_##name##sz);
+}
 
 /*
  * Earlier versions of GCC (no later than 8.1.0) appear to incorrectly
@@ -297,16 +300,17 @@ __CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory", L)
 #undef __CMPXCHG_CASE
 
 #define __CMPXCHG_DBL(name, mb, rel, cl)				\
-__LL_SC_INLINE long							\
-__LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,		\
+static inline long							\
+__ll_sc__cmpxchg_double##name(unsigned long old1,			\
 				      unsigned long old2,		\
 				      unsigned long new1,		\
 				      unsigned long new2,		\
-				      volatile void *ptr))		\
+				      volatile void *ptr)		\
 {									\
 	unsigned long tmp, ret;						\
 									\
 	asm volatile("// __cmpxchg_double" #name "\n"			\
+	__LL_SC_FALLBACK(						\
 	"	prfm	pstl1strm, %2\n"				\
 	"1:	ldxp	%0, %1, %2\n"					\
 	"	eor	%0, %0, %3\n"					\
@@ -316,14 +320,13 @@ __LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,		\
 	"	st" #rel "xp	%w0, %5, %6, %2\n"			\
 	"	cbnz	%w0, 1b\n"					\
 	"	" #mb "\n"						\
-	"2:"								\
+	"2:")								\
 	: "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr)	\
 	: "r" (old1), "r" (old2), "r" (new1), "r" (new2)		\
 	: cl);								\
 									\
 	return ret;							\
-}									\
-__LL_SC_EXPORT(__cmpxchg_double##name);
+}
 
 __CMPXCHG_DBL(   ,        ,  ,         )
 __CMPXCHG_DBL(_mb, dmb ish, l, "memory")
diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 69acb1c19a15..7dce5e1f074e 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -10,22 +10,13 @@
 #ifndef __ASM_ATOMIC_LSE_H
 #define __ASM_ATOMIC_LSE_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
-#endif
-
-#define __LL_SC_ATOMIC(op)	__LL_SC_CALL(arch_atomic_##op)
 #define ATOMIC_OP(op, asm_op)						\
-static inline void arch_atomic_##op(int i, atomic_t *v)			\
+static inline void __lse_atomic_##op(int i, atomic_t *v)			\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op),		\
-"	" #asm_op "	%w[i], %[v]\n")					\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS);						\
+	asm volatile(							\
+"	" #asm_op "	%w[i], %[v]\n"					\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v));							\
 }
 
 ATOMIC_OP(andnot, stclr)
@@ -36,21 +27,15 @@ ATOMIC_OP(add, stadd)
 #undef ATOMIC_OP
 
 #define ATOMIC_FETCH_OP(name, mb, op, asm_op, cl...)			\
-static inline int arch_atomic_fetch_##op##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_##op##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_##op##name),				\
-	/* LSE atomics */						\
-"	" #asm_op #mb "	%w[i], %w[i], %[v]")				\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	asm volatile(							\
+"	" #asm_op #mb "	%w[i], %w[i], %[v]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 #define ATOMIC_FETCH_OPS(op, asm_op)					\
@@ -68,23 +53,16 @@ ATOMIC_FETCH_OPS(add, ldadd)
 #undef ATOMIC_FETCH_OPS
 
 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...)				\
-static inline int arch_atomic_add_return##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_add_return##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(add_return##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30")				\
-	: [i] "+r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%w[i], %w[i], w30"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_OP_ADD_RETURN(_relaxed,   )
@@ -94,41 +72,26 @@ ATOMIC_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC_OP_ADD_RETURN
 
-static inline void arch_atomic_and(int i, atomic_t *v)
+static inline void __lse_atomic_and(int i, atomic_t *v)
 {
-	register int w0 asm ("w0") = i;
-	register atomic_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC(and)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	mvn	%w[i], %w[i]\n"
-	"	stclr	%w[i], %[v]")
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stclr	%w[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC_FETCH_OP_AND(name, mb, cl...)				\
-static inline int arch_atomic_fetch_and##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_and##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_and##name)					\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mvn	%w[i], %w[i]\n"					\
-	"	ldclr" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldclr" #mb "	%w[i], %w[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_FETCH_OP_AND(_relaxed,   )
@@ -138,42 +101,27 @@ ATOMIC_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_AND
 
-static inline void arch_atomic_sub(int i, atomic_t *v)
+static inline void __lse_atomic_sub(int i, atomic_t *v)
 {
-	register int w0 asm ("w0") = i;
-	register atomic_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC(sub)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	neg	%w[i], %w[i]\n"
-	"	stadd	%w[i], %[v]")
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stadd	%w[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC_OP_SUB_RETURN(name, mb, cl...)				\
-static inline int arch_atomic_sub_return##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_sub_return##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(sub_return##name)				\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
 	"	ldadd" #mb "	%w[i], w30, %[v]\n"			\
-	"	add	%w[i], %w[i], w30")				\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS , ##cl);					\
+	"	add	%w[i], %w[i], w30"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_OP_SUB_RETURN(_relaxed,   )
@@ -184,23 +132,16 @@ ATOMIC_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC_OP_SUB_RETURN
 
 #define ATOMIC_FETCH_OP_SUB(name, mb, cl...)				\
-static inline int arch_atomic_fetch_sub##name(int i, atomic_t *v)	\
+static inline int __lse_atomic_fetch_sub##name(int i, atomic_t *v)	\
 {									\
-	register int w0 asm ("w0") = i;					\
-	register atomic_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC(fetch_sub##name)					\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%w[i], %w[i]\n"					\
-	"	ldadd" #mb "	%w[i], %w[i], %[v]")			\
-	: [i] "+&r" (w0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldadd" #mb "	%w[i], %w[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return w0;							\
+	return i;							\
 }
 
 ATOMIC_FETCH_OP_SUB(_relaxed,   )
@@ -209,20 +150,14 @@ ATOMIC_FETCH_OP_SUB(_release,  l, "memory")
 ATOMIC_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_SUB
-#undef __LL_SC_ATOMIC
 
-#define __LL_SC_ATOMIC64(op)	__LL_SC_CALL(arch_atomic64_##op)
 #define ATOMIC64_OP(op, asm_op)						\
-static inline void arch_atomic64_##op(s64 i, atomic64_t *v)		\
+static inline void __lse_atomic64_##op(s64 i, atomic64_t *v)		\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op),	\
-"	" #asm_op "	%[i], %[v]\n")					\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS);						\
+	asm volatile(							\
+"	" #asm_op "	%[i], %[v]\n"					\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v));							\
 }
 
 ATOMIC64_OP(andnot, stclr)
@@ -233,21 +168,15 @@ ATOMIC64_OP(add, stadd)
 #undef ATOMIC64_OP
 
 #define ATOMIC64_FETCH_OP(name, mb, op, asm_op, cl...)			\
-static inline s64 arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_##op##name(s64 i, atomic64_t *v)\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_##op##name),				\
-	/* LSE atomics */						\
-"	" #asm_op #mb "	%[i], %[i], %[v]")				\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	asm volatile(							\
+"	" #asm_op #mb "	%[i], %[i], %[v]"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 #define ATOMIC64_FETCH_OPS(op, asm_op)					\
@@ -265,23 +194,16 @@ ATOMIC64_FETCH_OPS(add, ldadd)
 #undef ATOMIC64_FETCH_OPS
 
 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...)				\
-static inline s64 arch_atomic64_add_return##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_add_return##name(s64 i, atomic64_t *v)\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(add_return##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30")				\
-	: [i] "+r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%[i], %[i], x30"				\
+	: [i] "+r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_OP_ADD_RETURN(_relaxed,   )
@@ -291,41 +213,26 @@ ATOMIC64_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC64_OP_ADD_RETURN
 
-static inline void arch_atomic64_and(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_and(s64 i, atomic64_t *v)
 {
-	register s64 x0 asm ("x0") = i;
-	register atomic64_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(and)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	mvn	%[i], %[i]\n"
-	"	stclr	%[i], %[v]")
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stclr	%[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC64_FETCH_OP_AND(name, mb, cl...)				\
-static inline s64 arch_atomic64_fetch_and##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_and##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_and##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mvn	%[i], %[i]\n"					\
-	"	ldclr" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldclr" #mb "	%[i], %[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_FETCH_OP_AND(_relaxed,   )
@@ -335,42 +242,27 @@ ATOMIC64_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_AND
 
-static inline void arch_atomic64_sub(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 {
-	register s64 x0 asm ("x0") = i;
-	register atomic64_t *x1 asm ("x1") = v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(sub)
-	__nops(1),
-	/* LSE atomics */
+	asm volatile(
 	"	neg	%[i], %[i]\n"
-	"	stadd	%[i], %[v]")
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)
-	: "r" (x1)
-	: __LL_SC_CLOBBERS);
+	"	stadd	%[i], %[v]"
+	: [i] "+&r" (i), [v] "+Q" (v->counter)
+	: "r" (v));
 }
 
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)				\
-static inline s64 arch_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(sub_return##name)				\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
 	"	ldadd" #mb "	%[i], x30, %[v]\n"			\
-	"	add	%[i], %[i], x30")				\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	add	%[i], %[i], x30"				\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: "x30", ##cl);							\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_OP_SUB_RETURN(_relaxed,   )
@@ -381,23 +273,16 @@ ATOMIC64_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC64_OP_SUB_RETURN
 
 #define ATOMIC64_FETCH_OP_SUB(name, mb, cl...)				\
-static inline s64 arch_atomic64_fetch_sub##name(s64 i, atomic64_t *v)	\
+static inline long __lse_atomic64_fetch_sub##name(s64 i, atomic64_t *v)	\
 {									\
-	register s64 x0 asm ("x0") = i;					\
-	register atomic64_t *x1 asm ("x1") = v;				\
-									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_ATOMIC64(fetch_sub##name)				\
-	__nops(1),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	neg	%[i], %[i]\n"					\
-	"	ldadd" #mb "	%[i], %[i], %[v]")			\
-	: [i] "+&r" (x0), [v] "+Q" (v->counter)				\
-	: "r" (x1)							\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	"	ldadd" #mb "	%[i], %[i], %[v]"			\
+	: [i] "+&r" (i), [v] "+Q" (v->counter)				\
+	: "r" (v)							\
+	: cl);								\
 									\
-	return x0;							\
+	return i;							\
 }
 
 ATOMIC64_FETCH_OP_SUB(_relaxed,   )
@@ -407,15 +292,9 @@ ATOMIC64_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_SUB
 
-static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
+static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 {
-	register long x0 asm ("x0") = (long)v;
-
-	asm volatile(ARM64_LSE_ATOMIC_INSN(
-	/* LL/SC */
-	__LL_SC_ATOMIC64(dec_if_positive)
-	__nops(6),
-	/* LSE atomics */
+	asm volatile(
 	"1:	ldr	x30, %[v]\n"
 	"	subs	%[ret], x30, #1\n"
 	"	b.lt	2f\n"
@@ -423,20 +302,16 @@ static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
 	"	sub	x30, x30, #1\n"
 	"	sub	x30, x30, %[ret]\n"
 	"	cbnz	x30, 1b\n"
-	"2:")
-	: [ret] "+&r" (x0), [v] "+Q" (v->counter)
+	"2:"
+	: [ret] "+&r" (v), [v] "+Q" (v->counter)
 	:
-	: __LL_SC_CLOBBERS, "cc", "memory");
+	: "x30", "cc", "memory");
 
-	return x0;
+	return (long)v;
 }
 
-#undef __LL_SC_ATOMIC64
-
-#define __LL_SC_CMPXCHG(op)	__LL_SC_CALL(__cmpxchg_case_##op)
-
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...)			\
-static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
+static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr,	\
 					      u##sz old,		\
 					      u##sz new)		\
 {									\
@@ -444,17 +319,13 @@ static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,	\
 	register u##sz x1 asm ("x1") = old;				\
 	register u##sz x2 asm ("x2") = new;				\
 									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_CMPXCHG(name##sz)					\
-	__nops(2),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	mov	" #w "30, %" #w "[old]\n"			\
 	"	cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n"	\
-	"	mov	%" #w "[ret], " #w "30")			\
+	"	mov	%" #w "[ret], " #w "30"				\
 	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr)		\
 	: [old] "r" (x1), [new] "r" (x2)				\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	: "x30", ##cl);							\
 									\
 	return x0;							\
 }
@@ -476,13 +347,10 @@ __CMPXCHG_CASE(w, h,  mb_, 16, al, "memory")
 __CMPXCHG_CASE(w,  ,  mb_, 32, al, "memory")
 __CMPXCHG_CASE(x,  ,  mb_, 64, al, "memory")
 
-#undef __LL_SC_CMPXCHG
 #undef __CMPXCHG_CASE
 
-#define __LL_SC_CMPXCHG_DBL(op)	__LL_SC_CALL(__cmpxchg_double##op)
-
 #define __CMPXCHG_DBL(name, mb, cl...)					\
-static inline long __cmpxchg_double##name(unsigned long old1,		\
+static inline long __lse__cmpxchg_double##name(unsigned long old1,	\
 					 unsigned long old2,		\
 					 unsigned long new1,		\
 					 unsigned long new2,		\
@@ -496,20 +364,16 @@ static inline long __cmpxchg_double##name(unsigned long old1,		\
 	register unsigned long x3 asm ("x3") = new2;			\
 	register unsigned long x4 asm ("x4") = (unsigned long)ptr;	\
 									\
-	asm volatile(ARM64_LSE_ATOMIC_INSN(				\
-	/* LL/SC */							\
-	__LL_SC_CMPXCHG_DBL(name)					\
-	__nops(3),							\
-	/* LSE atomics */						\
+	asm volatile(							\
 	"	casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
 	"	eor	%[old1], %[old1], %[oldval1]\n"			\
 	"	eor	%[old2], %[old2], %[oldval2]\n"			\
-	"	orr	%[old1], %[old1], %[old2]")			\
+	"	orr	%[old1], %[old1], %[old2]"			\
 	: [old1] "+&r" (x0), [old2] "+&r" (x1),				\
 	  [v] "+Q" (*(unsigned long *)ptr)				\
 	: [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),		\
 	  [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)		\
-	: __LL_SC_CLOBBERS, ##cl);					\
+	: cl);								\
 									\
 	return x0;							\
 }
@@ -517,7 +381,6 @@ static inline long __cmpxchg_double##name(unsigned long old1,		\
 __CMPXCHG_DBL(   ,   )
 __CMPXCHG_DBL(_mb, al, "memory")
 
-#undef __LL_SC_CMPXCHG_DBL
 #undef __CMPXCHG_DBL
 
 #endif	/* __ASM_ATOMIC_LSE_H */
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index 7a299a20f6dc..e5fff8cd4904 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -10,7 +10,7 @@
 #include <linux/build_bug.h>
 #include <linux/compiler.h>
 
-#include <asm/atomic.h>
+#include <asm/atomic_arch.h>
 #include <asm/barrier.h>
 #include <asm/lse.h>
 
diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h
index 8262325e2fc6..52b80846d1b7 100644
--- a/arch/arm64/include/asm/lse.h
+++ b/arch/arm64/include/asm/lse.h
@@ -22,14 +22,6 @@
 
 __asm__(".arch_extension	lse");
 
-/* Move the ll/sc atomics out-of-line */
-#define __LL_SC_INLINE		notrace
-#define __LL_SC_PREFIX(x)	__ll_sc_##x
-#define __LL_SC_EXPORT(x)	EXPORT_SYMBOL(__LL_SC_PREFIX(x))
-
-/* Macro for constructing calls to out-of-line ll/sc atomics */
-#define __LL_SC_CALL(op)	"bl\t" __stringify(__LL_SC_PREFIX(op)) "\n"
-#define __LL_SC_CLOBBERS	"x16", "x17", "x30"
 
 /* In-line patching at runtime */
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)				\
@@ -46,9 +38,6 @@ __asm__(".arch_extension	lse");
 
 #else	/* __ASSEMBLER__ */
 
-#define __LL_SC_INLINE		static inline
-#define __LL_SC_PREFIX(x)	x
-#define __LL_SC_EXPORT(x)
 
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)	llsc
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 2/5] arm64: Use correct ll/sc atomic constraints
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

The A64 ISA accepts distinct (but overlapping) ranges of immediates for:

 * add arithmetic instructions ('I' machine constraint)
 * sub arithmetic instructions ('J' machine constraint)
 * 32-bit logical instructions ('K' machine constraint)
 * 64-bit logical instructions ('L' machine constraint)

... but we currently use the 'I' constraint for many atomic operations
using sub or logical instructions, which is not always valid.

When CONFIG_ARM64_LSE_ATOMICS is not set, this allows invalid immediates
to be passed to instructions, potentially resulting in a build failure.
When CONFIG_ARM64_LSE_ATOMICS is selected the out-of-line ll/sc atomics
always use a register as they have no visibility of the value passed by
the caller.

This patch adds a constraint parameter to the ATOMIC_xx and
__CMPXCHG_CASE macros so that we can pass appropriate constraints for
each case, with uses updated accordingly.

Unfortunately prior to GCC 8.1.0 the 'K' constraint erroneously accepted
0xffffffff, so we must instead force the use of a register.

Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
 arch/arm64/include/asm/atomic_ll_sc.h | 89 ++++++++++++++-------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index c8c850bc3dfb..6dd011e0b434 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -26,7 +26,7 @@
  * (the optimize attribute silently ignores these options).
  */
 
-#define ATOMIC_OP(op, asm_op)						\
+#define ATOMIC_OP(op, asm_op, constraint)				\
 __LL_SC_INLINE void							\
 __LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
 {									\
@@ -40,11 +40,11 @@ __LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))			\
 "	stxr	%w1, %w0, %2\n"						\
 "	cbnz	%w1, 1b"						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i));							\
+	: #constraint "r" (i));						\
 }									\
 __LL_SC_EXPORT(arch_atomic_##op);
 
-#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE int							\
 __LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
 {									\
@@ -59,14 +59,14 @@ __LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))	\
 "	cbnz	%w1, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
 }									\
 __LL_SC_EXPORT(arch_atomic_##op##_return##name);
 
-#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)	\
 __LL_SC_INLINE int							\
 __LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
 {									\
@@ -81,7 +81,7 @@ __LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))	\
 "	cbnz	%w2, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
@@ -99,8 +99,8 @@ __LL_SC_EXPORT(arch_atomic_fetch_##op##name);
 	ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
 	ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(add, add)
-ATOMIC_OPS(sub, sub)
+ATOMIC_OPS(add, add, I)
+ATOMIC_OPS(sub, sub, J)
 
 #undef ATOMIC_OPS
 #define ATOMIC_OPS(...)							\
@@ -110,17 +110,17 @@ ATOMIC_OPS(sub, sub)
 	ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
 	ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(and, and)
-ATOMIC_OPS(andnot, bic)
-ATOMIC_OPS(or, orr)
-ATOMIC_OPS(xor, eor)
+ATOMIC_OPS(and, and, )
+ATOMIC_OPS(andnot, bic, )
+ATOMIC_OPS(or, orr, )
+ATOMIC_OPS(xor, eor, )
 
 #undef ATOMIC_OPS
 #undef ATOMIC_FETCH_OP
 #undef ATOMIC_OP_RETURN
 #undef ATOMIC_OP
 
-#define ATOMIC64_OP(op, asm_op)						\
+#define ATOMIC64_OP(op, asm_op, constraint)				\
 __LL_SC_INLINE void							\
 __LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
 {									\
@@ -134,11 +134,11 @@ __LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))		\
 "	stxr	%w1, %0, %2\n"						\
 "	cbnz	%w1, 1b"						\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i));							\
+	: #constraint "r" (i));						\
 }									\
 __LL_SC_EXPORT(arch_atomic64_##op);
 
-#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE s64							\
 __LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
 {									\
@@ -153,14 +153,14 @@ __LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
 "	cbnz	%w1, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (tmp), "+Q" (v->counter)		\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
 }									\
 __LL_SC_EXPORT(arch_atomic64_##op##_return##name);
 
-#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)		\
+#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
 __LL_SC_INLINE s64							\
 __LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
 {									\
@@ -175,7 +175,7 @@ __LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))	\
 "	cbnz	%w2, 1b\n"						\
 "	" #mb								\
 	: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)	\
-	: "Ir" (i)							\
+	: #constraint "r" (i)						\
 	: cl);								\
 									\
 	return result;							\
@@ -193,8 +193,8 @@ __LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
 	ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)	\
 	ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(add, add)
-ATOMIC64_OPS(sub, sub)
+ATOMIC64_OPS(add, add, I)
+ATOMIC64_OPS(sub, sub, J)
 
 #undef ATOMIC64_OPS
 #define ATOMIC64_OPS(...)						\
@@ -204,10 +204,10 @@ ATOMIC64_OPS(sub, sub)
 	ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)	\
 	ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(and, and)
-ATOMIC64_OPS(andnot, bic)
-ATOMIC64_OPS(or, orr)
-ATOMIC64_OPS(xor, eor)
+ATOMIC64_OPS(and, and, L)
+ATOMIC64_OPS(andnot, bic, )
+ATOMIC64_OPS(or, orr, L)
+ATOMIC64_OPS(xor, eor, L)
 
 #undef ATOMIC64_OPS
 #undef ATOMIC64_FETCH_OP
@@ -237,7 +237,7 @@ __LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
 }
 __LL_SC_EXPORT(arch_atomic64_dec_if_positive);
 
-#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl)		\
+#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl, constraint)	\
 __LL_SC_INLINE u##sz							\
 __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 					 unsigned long old,		\
@@ -265,29 +265,34 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,		\
 	"2:"								\
 	: [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),			\
 	  [v] "+Q" (*(u##sz *)ptr)					\
-	: [old] "Kr" (old), [new] "r" (new)				\
+	: [old] #constraint "r" (old), [new] "r" (new)			\
 	: cl);								\
 									\
 	return oldval;							\
 }									\
 __LL_SC_EXPORT(__cmpxchg_case_##name##sz);
 
-__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         )
-__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         )
-__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         )
-__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         )
-__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory")
-__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory")
-__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory")
-__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory")
-__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory")
-__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory")
-__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory")
-__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory")
-__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory")
-__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory")
+/*
+ * Earlier versions of GCC (no later than 8.1.0) appear to incorrectly
+ * handle the 'K' constraint for the value 4294967295 - thus we use no
+ * constraint for 32 bit operations.
+ */
+__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         , )
+__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         , )
+__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         , )
+__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         , L)
+__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory", )
+__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory", )
+__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory", )
+__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory", L)
+__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory", )
+__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory", )
+__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory", )
+__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory", L)
+__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory", )
+__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory", L)
 
 #undef __CMPXCHG_CASE
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 1/5] jump_label: Don't warn on __exit jump entries
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel
In-Reply-To: <20190828175009.15457-1-andrew.murray@arm.com>

On architectures that discard .exit.* sections at runtime, a
warning is printed for each jump label that is used within an
in-kernel __exit annotated function:

can't patch jump_label at ehci_hcd_cleanup+0x8/0x3c
WARNING: CPU: 0 PID: 1 at kernel/jump_label.c:410 __jump_label_update+0x12c/0x138

As these functions will never get executed (they are free'd along
with the rest of initmem) - we do not need to patch them and should
not display any warnings.

The warning is displayed because the test required to satisfy
jump_entry_is_init is based on init_section_contains (__init_begin to
__init_end) whereas the test in __jump_label_update is based on
init_kernel_text (_sinittext to _einittext) via kernel_text_address).

Fixes: 19483677684b ("jump_label: Annotate entries that operate on __init code earlier")
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Mark Rutland <mark.rutland@arm.com>
---
 kernel/jump_label.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index df3008419a1d..cdb3ffab128b 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -407,7 +407,9 @@ static bool jump_label_can_update(struct jump_entry *entry, bool init)
 		return false;
 
 	if (!kernel_text_address(jump_entry_code(entry))) {
-		WARN_ONCE(1, "can't patch jump_label at %pS", (void *)jump_entry_code(entry));
+		WARN_ONCE(!jump_entry_is_init(entry),
+			  "can't patch jump_label at %pS",
+			  (void *)jump_entry_code(entry));
 		return false;
 	}
 
-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 0/5] arm64: avoid out-of-line ll/sc atomics
From: Andrew Murray @ 2019-08-28 17:50 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Peter Zijlstra, Ard.Biesheuvel
  Cc: Mark Rutland, Boqun Feng, linux-arm-kernel

When building for LSE atomics (CONFIG_ARM64_LSE_ATOMICS), if the hardware
or toolchain doesn't support it the existing code will fallback to ll/sc
atomics. It achieves this by branching from inline assembly to a function
that is built with specical compile flags. Further this results in the
clobbering of registers even when the fallback isn't used increasing
register pressure.

Let's improve this by providing inline implementatins of both LSE and
ll/sc and use a static key to select between them. This allows for the
compiler to generate better atomics code.

Whilst it may be difficult to understand the performance impact, we gain
improved code readability, ability to use Clang, and improved backtrace
reliability.

Build and boot tested, along with atomic_64_test.

Following is the assembly of a function that has three consecutive
atomic_add calls when built with LSE and this patchset:

Dump of assembler code for function atomics_test:
   0xffff000010084338 <+0>:     b       0xffff000010084388 <atomics_test+80>
   0xffff00001008433c <+4>:     b       0xffff000010084388 <atomics_test+80>
   0xffff000010084340 <+8>:     adrp    x0, 0xffff0000118d5000 <reset_devices>
   0xffff000010084344 <+12>:    add     x2, x0, #0x0
   0xffff000010084348 <+16>:    mov     w1, #0x1                        // #1
   0xffff00001008434c <+20>:    add     x3, x2, #0x28
   0xffff000010084350 <+24>:    stadd   w1, [x3]
   0xffff000010084354 <+28>:    b       0xffff00001008439c <atomics_test+100>
   0xffff000010084358 <+32>:    b       0xffff00001008439c <atomics_test+100>
   0xffff00001008435c <+36>:    add     x1, x0, #0x0
   0xffff000010084360 <+40>:    mov     w2, #0x1                        // #1
   0xffff000010084364 <+44>:    add     x3, x1, #0x28
   0xffff000010084368 <+48>:    stadd   w2, [x3]
   0xffff00001008436c <+52>:    b       0xffff0000100843ac <atomics_test+116>
   0xffff000010084370 <+56>:    b       0xffff0000100843ac <atomics_test+116>
   0xffff000010084374 <+60>:    add     x0, x0, #0x0
   0xffff000010084378 <+64>:    mov     w1, #0x1                        // #1
   0xffff00001008437c <+68>:    add     x2, x0, #0x28
   0xffff000010084380 <+72>:    stadd   w1, [x2]
   0xffff000010084384 <+76>:    ret
   0xffff000010084388 <+80>:    adrp    x0, 0xffff0000118d5000 <reset_devices>
   0xffff00001008438c <+84>:    add     x1, x0, #0x0
   0xffff000010084390 <+88>:    add     x1, x1, #0x28
   0xffff000010084394 <+92>:    b       0xffff000010084570
   0xffff000010084398 <+96>:    b       0xffff000010084354 <atomics_test+28>
   0xffff00001008439c <+100>:   add     x1, x0, #0x0
   0xffff0000100843a0 <+104>:   add     x1, x1, #0x28
   0xffff0000100843a4 <+108>:   b       0xffff000010084588
   0xffff0000100843a8 <+112>:   b       0xffff00001008436c <atomics_test+52>
   0xffff0000100843ac <+116>:   add     x0, x0, #0x0
   0xffff0000100843b0 <+120>:   add     x0, x0, #0x28
   0xffff0000100843b4 <+124>:   b       0xffff0000100845a0
   0xffff0000100843b8 <+128>:   ret
End of assembler dump.

ffff000010084570:       f9800031        prfm    pstl1strm, [x1]
ffff000010084574:       885f7c22        ldxr    w2, [x1]
ffff000010084578:       11000442        add     w2, w2, #0x1
ffff00001008457c:       88037c22        stxr    w3, w2, [x1]
ffff000010084580:       35ffffa3        cbnz    w3, ffff000010084574 <do_one_initcall+0x1b4>
ffff000010084584:       17ffff85        b       ffff000010084398 <atomics_test+0x60>
ffff000010084588:       f9800031        prfm    pstl1strm, [x1]
ffff00001008458c:       885f7c22        ldxr    w2, [x1]
ffff000010084590:       11000442        add     w2, w2, #0x1
ffff000010084594:       88037c22        stxr    w3, w2, [x1]
ffff000010084598:       35ffffa3        cbnz    w3, ffff00001008458c <do_one_initcall+0x1cc>
ffff00001008459c:       17ffff83        b       ffff0000100843a8 <atomics_test+0x70>
ffff0000100845a0:       f9800011        prfm    pstl1strm, [x0]
ffff0000100845a4:       885f7c01        ldxr    w1, [x0]
ffff0000100845a8:       11000421        add     w1, w1, #0x1
ffff0000100845ac:       88027c01        stxr    w2, w1, [x0]
ffff0000100845b0:       35ffffa2        cbnz    w2, ffff0000100845a4 <do_one_initcall+0x1e4>
ffff0000100845b4:       17ffff81        b       ffff0000100843b8 <atomics_test+0x80>

The two branches before each section of atomics relates to the two static
keys which both become nop's when LSE is available. When LSE isn't
available the branches are used to run the slowpath fallback LL/SC atomics.

In v1 of this series, due to the use of likely/unlikely for the LSE code,
the fallback code ended up in one place at the end of the function. In this
v2 patchset we move the fallback code into its own subsection, this moves
any atomics code to the end of each compilation unit. It is felt that this
may improve icache performance for both LSE and LL/SC.

Where CONFIG_ARM64_LSE_ATOMICS isn't enabled then the same function is as
follows:

Dump of assembler code for function atomics_test:
   0xffff000010084338 <+0>:     adrp    x0, 0xffff000011865000 <reset_devices>
   0xffff00001008433c <+4>:     add     x0, x0, #0x0
   0xffff000010084340 <+8>:     add     x3, x0, #0x28
   0xffff000010084344 <+12>:    prfm    pstl1strm, [x3]
   0xffff000010084348 <+16>:    ldxr    w1, [x3]
   0xffff00001008434c <+20>:    add     w1, w1, #0x1
   0xffff000010084350 <+24>:    stxr    w2, w1, [x3]
   0xffff000010084354 <+28>:    cbnz    w2, 0xffff000010084348 <atomics_test+16>
   0xffff000010084358 <+32>:    prfm    pstl1strm, [x3]
   0xffff00001008435c <+36>:    ldxr    w1, [x3]
   0xffff000010084360 <+40>:    add     w1, w1, #0x1
   0xffff000010084364 <+44>:    stxr    w2, w1, [x3]
   0xffff000010084368 <+48>:    cbnz    w2, 0xffff00001008435c <atomics_test+36>
   0xffff00001008436c <+52>:    prfm    pstl1strm, [x3]
   0xffff000010084370 <+56>:    ldxr    w1, [x3]
   0xffff000010084374 <+60>:    add     w1, w1, #0x1
   0xffff000010084378 <+64>:    stxr    w2, w1, [x3]
   0xffff00001008437c <+68>:    cbnz    w2, 0xffff000010084370 <atomics_test+56>
   0xffff000010084380 <+72>:    ret
End of assembler dump.

These changes add some bloat on defconfig according to bloat-o-meter:

For LSE build (text):
  add/remove: 4/109 grow/shrink: 3398/67 up/down: 151556/-4940
  Total: Before=12759457, After=12906073, chg +1.15%

For LL/LSC only build (text):
  add/remove: 2/2 grow/shrink: 1423/57 up/down: 12224/-564 (11660)
  Total: Before=12836417, After=12848077, chg +0.09%

The bloat for LSE is due to the provision of LL/SC fallback atomics no longer
being !inline.

The bloat for LL/SC seems to be due to patch 2, which changes some assembly
constraints (i.e. moving an intermediate to a register).

When comparing the number of data transfer instructions (those starting or
ending with ld or st) in vmlinux we see a reduction from 30.8% to 30.6% when
applying this series. And no change when CONFIG_ARM64_LSE_ATOMICS isn't
enabled (30.9%). This was a feable attempt to measure register spilling.

Changes since v3:

 - Remove stale sentence from commit message of 'jump_label: Don't warn on...'

 - Reorder include statements in atomic_arch.h (asm last)

 - Reword commit message of 'arm64: Use correct ll/sc atomic constraints...' as
   suggested by Mark Rutland

 - Drop buggy 'K' contraints for LL/SC atomic_[and, or, xor] functions

 - Use correct 'L' constrints for LL/SC atomic64_[and, or, xor] functions

 - Rebased onto v5.3-rc3

Changes since v2:

 - Ensure _{relaxed,acquire,release} qualifers are used

 - Rebased onto arm64/for-next/fixes (v5.3-rc3)

Changes since v1:

 - Move LL/SC atomics to a subsection when being used as a fallback

 - Rebased onto arm64/for-next/fixes


Andrew Murray (5):
  jump_label: Don't warn on __exit jump entries
  arm64: Use correct ll/sc atomic constraints
  arm64: atomics: avoid out-of-line ll/sc atomics
  arm64: avoid using hard-coded registers for LSE atomics
  arm64: atomics: remove atomic_ll_sc compilation unit

 arch/arm64/include/asm/atomic.h       |  11 +-
 arch/arm64/include/asm/atomic_arch.h  | 155 ++++++++++
 arch/arm64/include/asm/atomic_ll_sc.h | 200 ++++++-------
 arch/arm64/include/asm/atomic_lse.h   | 395 +++++++++-----------------
 arch/arm64/include/asm/cmpxchg.h      |   2 +-
 arch/arm64/include/asm/lse.h          |  11 -
 arch/arm64/lib/Makefile               |  19 --
 arch/arm64/lib/atomic_ll_sc.c         |   3 -
 kernel/jump_label.c                   |   4 +-
 9 files changed, 399 insertions(+), 401 deletions(-)
 create mode 100644 arch/arm64/include/asm/atomic_arch.h
 delete mode 100644 arch/arm64/lib/atomic_ll_sc.c

-- 
2.21.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [GIT PULL] arm64: Fixes for -rc7
From: pr-tracker-bot @ 2019-08-28 17:45 UTC (permalink / raw)
  To: Will Deacon
  Cc: kvm, rkrcmar, marc.zyngier, catalin.marinas, linux-kernel,
	pbonzini, torvalds, kvmarm, linux-arm-kernel
In-Reply-To: <20190828173233.zqwm5nd4p5xa4jxi@willie-the-truck>

The pull request you sent on Wed, 28 Aug 2019 18:32:33 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9cf6b756cdf2cd38b8b0dac2567f7c6daf5e79d5

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] arm-smmu: check for generic bindings first
From: Stefano Stabellini @ 2019-08-28 17:38 UTC (permalink / raw)
  To: will
  Cc: sstabellini, linux-kernel, michal.simek, git, Stefano Stabellini,
	robin.murphy, linux-arm-kernel

From: Stefano Stabellini <stefano.stabellini@xilinx.com>

Today, the arm-smmu driver checks for mmu-masters on device tree, the
legacy property, if it is absent it assumes that we are using the new
bindings. If it is present it assumes that we are using the legacy
bindings. All arm-smmus need to use the same bindings: legacy or new.

There are two issues with this:

- we are not actually checking for the new bindings explicitly
It would be better to have an explicit check for the new bindings rather
than assuming we must be using the new if the old are not there.

- old and new bindings cannot coexist
It would be nice to be able to provide both old and new bindings so
that software that hasn't been updated yet is still able to get IOMMU
information from the legacy bindings while at the same time newer
software can get the latest information via the new bindings. (Xen has
not been updated to use the new binding yet for instance.) The current
code breaks under these circumstances because if the old bindings are
present, the new are not even checked.

This patch changes the scheme by checking for #iommu-cells, which is
only present with the new bindings, before checking for mmu-masters.
The new bindings are always favored when present. All SMMUs still need
to use the same bindings: mix-and-matching new and old bindings between
different SMMUs is not allowed.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---

Let me know if you'd like me to turn the two using_*_binding variables
into a single one.

Also, please note that this is not meant as an excuse not to get Xen
updated to use the new binding.

 drivers/iommu/arm-smmu.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 64977c131ee6..79b518ff215c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2118,7 +2118,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 {
 	const struct arm_smmu_match_data *data;
 	struct device *dev = &pdev->dev;
-	bool legacy_binding;
+	bool legacy_binding, generic_binding;
 
 	if (of_property_read_u32(dev->of_node, "#global-interrupts",
 				 &smmu->num_global_irqs)) {
@@ -2132,16 +2132,20 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 
 	parse_driver_options(smmu);
 
-	legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL);
-	if (legacy_binding && !using_generic_binding) {
-		if (!using_legacy_binding)
-			pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
-		using_legacy_binding = true;
-	} else if (!legacy_binding && !using_legacy_binding) {
+	generic_binding = of_find_property(dev->of_node, "#iommu-cells", NULL);
+	if (generic_binding && !using_legacy_binding) {
 		using_generic_binding = true;
 	} else {
-		dev_err(dev, "not probing due to mismatched DT properties\n");
-		return -ENODEV;
+		legacy_binding = of_find_property(dev->of_node, "mmu-masters",
+						  NULL);
+		if (legacy_binding && !using_generic_binding) {
+			if (!using_legacy_binding)
+				pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
+			using_legacy_binding = true;
+		} else {
+			dev_err(dev, "not probing due to mismatched DT properties\n");
+			return -ENODEV;
+		}
 	}
 
 	if (of_dma_is_coherent(dev->of_node))
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v9 2/3] fdt: add support for rng-seed
From: Kees Cook @ 2019-08-24 19:04 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Josh Poimboeuf, Grzegorz Halat, H . Peter Anvin, Guenter Roeck,
	Will Deacon, Marek Szyprowski, Rob Herring, Daniel Thompson,
	Anders Roxell, Yury Norov, Marc Zyngier, Russell King,
	Aaro Koskinen, Ingo Molnar, Viresh Kumar, Waiman Long,
	Paul E . McKenney, Wei Li, Alexey Dobriyan, Julien Thierry,
	Len Brown, Arnd Bergmann, Rik van Riel, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Hsin-Yi Wang, Thomas Gleixner,
	linux-arm-kernel, Theodore Y . Ts'o, Greg Kroah-Hartman,
	Marcelo Tosatti, linux-kernel, Armijn Hemel, Jiri Kosina,
	Mathieu Desnoyers, Andrew Morton, Tim Chen, David S . Miller
In-Reply-To: <5d5ed368.1c69fb81.419fc.0803@mx.google.com>

On Thu, Aug 22, 2019 at 10:39:51AM -0700, Stephen Boyd wrote:
> Quoting Hsin-Yi Wang (2019-08-22 00:15:22)
> > Introducing a chosen node, rng-seed, which is an entropy that can be
> > passed to kernel called very early to increase initial device
> > randomness. Bootloader should provide this entropy and the value is
> > read from /chosen/rng-seed in DT.
> > 
> > Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
> > since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.
> > 
> > Add a new interface add_bootloader_randomness() for rng-seed use case.
> > Depends on whether the seed is trustworthy, rng seed would be passed to
> > add_hwgenerator_randomness(). Otherwise it would be passed to
> > add_device_randomness(). Decision is controlled by kernel config
> > RANDOM_TRUST_BOOTLOADER.
> > 
> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > ---
> > Change from v8:
> > * Add a new interface add_bootloader_randomness
> > * Add a new kernel config
> > ---
> >  drivers/char/Kconfig   | 10 ++++++++++
> >  drivers/char/random.c  | 15 +++++++++++++++
> >  drivers/of/fdt.c       | 14 ++++++++++++--
> >  include/linux/random.h |  1 +
> >  4 files changed, 38 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> > index 96156c729a31..5974a5906fd0 100644
> > --- a/drivers/char/Kconfig
> > +++ b/drivers/char/Kconfig
> > @@ -551,3 +551,13 @@ config RANDOM_TRUST_CPU
> >         has not installed a hidden back door to compromise the CPU's
> >         random number generation facilities. This can also be configured
> >         at boot with "random.trust_cpu=on/off".
> > +
> > +config RANDOM_TRUST_BOOTLOADER
> > +       bool "Trust the bootloader to initialize Linux's CRNG"
> > +       default n
> 
> You can drop the default.
> 
> > +       help
> > +       Bootloader could provide rng-seed set in /chosen/rng-seed in DT to help
> > +       increase initial device randomness. Assume the entropy provided is
> > +       trustworthy, it would be regarded as true hardware RNGs and update the
> > +       entropy estimate. Otherwise it would be regarded as device input that
> > +       could help mix the entropy pool, but won't be added to actual entropy.
> 
> Maybe reword this to something like:
> 
> 	Some bootloaders can provide entropy to increase the kernel's
> 	initial device randomness. Say Y here to assume the entropy
> 	provided by the booloader is trustworthy so it will be added to
> 	the kernel's entropy pool. Otherwise, say N here so it will be
> 	regarded as device input that only mixes the entropy pool.
> 
> > \ No newline at end of file
> > diff --git a/drivers/char/random.c b/drivers/char/random.c
> > index 5d5ea4ce1442..29d3ff3de1e1 100644
> > --- a/drivers/char/random.c
> > +++ b/drivers/char/random.c
> > @@ -2445,3 +2445,18 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
> >         credit_entropy_bits(poolp, entropy);
> >  }
> >  EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
> > +
> > +/* Handle random seed passed by bootloader.
> > + * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
> > + * it would be regarded as device data.
> > + * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
> > + */
> > +void add_bootloader_randomness(const void *buf, unsigned int size)
> > +{
> > +#ifdef CONFIG_RANDOM_TRUST_BOOTLOADER

Can this please be a boot param (with the default controlled by the
CONFIG)? See how CONFIG_RANDOM_TRUST_CPU is wired up...

-Kees

> > +       add_hwgenerator_randomness(buf, size, size * 8);
> > +#else
> > +       add_device_randomness(buf, size);
> > +#endif
> 
> Maybe use
> 
> 	if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
> 		add_hwgenerator_randomness(buf, size, size * 8);
> 	else
> 		add_device_randomness(buf, size);
> 	
> > +}
> > +EXPORT_SYMBOL_GPL(add_bootloader_randomness);
> > \ No newline at end of file

-- 
Kees Cook

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 02/11] kselftest: arm64: adds first test and common utils
From: Cristian Marussi @ 2019-08-28 17:34 UTC (permalink / raw)
  To: Dave Martin; +Cc: andreyknvl, shuah, linux-arm-kernel, linux-kselftest
In-Reply-To: <20190813162411.GZ10425@arm.com>

Hi

On 13/08/2019 17:24, Dave Martin wrote:
> For the subject line, maybe name the test being added (same as for the
> other patches).

I doubt to be able to fit within 50 chars Subject line constraint, if I add
the test case name.

> 
> On Fri, Aug 02, 2019 at 06:02:51PM +0100, Cristian Marussi wrote:
>> Added some arm64/signal specific boilerplate and utility code to help
>> further testcase development.
>>
>> A simple testcase and related helpers are also introduced in this commit:
>> mangle_pstate_invalid_compat_toggle is a simple mangle testcase which
>> messes with the ucontext_t from within the sig_handler, trying to toggle
> 
> "signal handler"?
> 

ok

>> PSTATE state bits to switch the system between 32bit/64bit execution state.
>> Expects SIGSEGV on test PASS.
>>
>> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
>> ---
>> A few fixes:
>> - test_arm64_signals.sh runner script generation has been reviewed in order to
>>   be safe against the .gitignore
>> - using kselftest.h officially provided defines for tests' return values
>> - removed SAFE_WRITE()/dump_uc()
>> - looking for si_code==SEGV_ACCERR on SEGV test cases to better understand if
>>   the sigfault had been directly triggered by Kernel
>> ---
>>  tools/testing/selftests/arm64/Makefile        |   2 +-
>>  .../testing/selftests/arm64/signal/.gitignore |   6 +
>>  tools/testing/selftests/arm64/signal/Makefile |  88 ++++++
>>  tools/testing/selftests/arm64/signal/README   |  59 ++++
>>  .../arm64/signal/test_arm64_signals.src_shell |  55 ++++
>>  .../selftests/arm64/signal/test_signals.c     |  26 ++
>>  .../selftests/arm64/signal/test_signals.h     | 137 +++++++++
>>  .../arm64/signal/test_signals_utils.c         | 261 ++++++++++++++++++
>>  .../arm64/signal/test_signals_utils.h         |  13 +
>>  .../arm64/signal/testcases/.gitignore         |   1 +
>>  .../mangle_pstate_invalid_compat_toggle.c     |  25 ++
>>  .../arm64/signal/testcases/testcases.c        | 150 ++++++++++
>>  .../arm64/signal/testcases/testcases.h        |  83 ++++++
>>  13 files changed, 905 insertions(+), 1 deletion(-)
>>  create mode 100644 tools/testing/selftests/arm64/signal/.gitignore
>>  create mode 100644 tools/testing/selftests/arm64/signal/Makefile
>>  create mode 100644 tools/testing/selftests/arm64/signal/README
>>  create mode 100755 tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals.h
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.h
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/.gitignore
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.c
>>  create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.h
>>
>> diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
>> index 03a0d4f71218..af59dc74e0dc 100644
>> --- a/tools/testing/selftests/arm64/Makefile
>> +++ b/tools/testing/selftests/arm64/Makefile
>> @@ -6,7 +6,7 @@ ARCH ?= $(shell uname -m)
>>  ARCH := $(shell echo $(ARCH) | sed -e s/aarch64/arm64/)
>>  
>>  ifeq ("x$(ARCH)", "xarm64")
>> -SUBDIRS :=
>> +SUBDIRS := signal
>>  else
>>  SUBDIRS :=
>>  endif
>> diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
>> new file mode 100644
>> index 000000000000..434f65c15f03
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/.gitignore
>> @@ -0,0 +1,6 @@
>> +# Helper script's internal testcases list (TPROGS) is regenerated
>> +# each time by Makefile on standalone (non KSFT driven) runs.
>> +# Committing such list creates a dependency between testcases
>> +# patches such that they are no more easily revertable. Just ignore.
>> +test_arm64_signals.src_shell
>> +test_arm64_signals.sh
>> diff --git a/tools/testing/selftests/arm64/signal/Makefile b/tools/testing/selftests/arm64/signal/Makefile
>> new file mode 100644
>> index 000000000000..8c8d08be4b0d
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/Makefile
>> @@ -0,0 +1,88 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2019 ARM Limited
>> +
>> +# Supports also standalone invokation out of KSFT-tree
>> +# Compile standalone and run on your device with:
>> +#
>> +#  $ make -C tools/testing/selftests/arm64/signal INSTALL_PATH=<your-dir> install
> 
> I'm wondering whether supporting stand-alone invocation is actually
> worth it.  Maybe this just adds complexity for little benefit.
> 
> Although it's useful for debugging and development, it doesn't look like
> other tests in kselftest support standalone invocation -- did I miss
> some?

I introduced standalone to be able to 'detach' from KSFT during tests' devel phase,
but it does not seem worth all this work to maintain it. So I'm removing it in V4.

> 
>> +#
>> +# Run standalone on device with:
>> +#
>> +#  $ <your-device-instdir>/test_arm64_signals.sh [-k|-v]
>> +#
>> +# If INSTALL_PATH= is NOT provided it will default to ./install
>> +
>> +# A proper top_srcdir is needed both by KSFT(lib.mk)
>> +# and standalone builds
>> +top_srcdir = ../../../../..
>> +
>> +CFLAGS += -std=gnu99 -I. -I$(top_srcdir)/tools/testing/selftests/
>> +SRCS := $(filter-out testcases/testcases.c,$(wildcard testcases/*.c))
>> +PROGS := $(patsubst %.c,%,$(SRCS))
>> +
>> +# Guessing as best as we can where the Kernel headers
>> +# could have been installed depending on ENV config and
>> +# type of invocation.
>> +ifeq ($(KBUILD_OUTPUT),)
>> +khdr_dir = $(top_srcdir)/usr/include
>> +else
>> +ifeq (0,$(MAKELEVEL))
>> +khdr_dir = $(KBUILD_OUTPUT)/usr/include
>> +else
>> +# the KSFT preferred location when KBUILD_OUTPUT is set
>> +khdr_dir = $(KBUILD_OUTPUT)/kselftest/usr/include
>> +endif
>> +endif
> 
> When is KBUILD_OUTPUT set / not set?
> 

Depending how the user/CI is configured KSFT installs the kernel
headers in different places....here I'm trying to guess where they
have been installed by KSFT.

>> +
>> +CFLAGS += -I$(khdr_dir)
> 
> Do we rely on any non-UAPI headers?  If not, the default should probably
> be to rely on the system headers (or toolchain default headers) -- i.e.,
> add no -I option at all.

I only need updated UAPI headers, but I cannot build without this specific -I..
that points to the installed kernel headers directory.

As an example it fails with: undefined  HWCAP_SSBS if I remove the -I

> 
> I'm wondering why none of the other kselftests need this header search
> logic.
> 

Well... a lot of KSFT tests has something related to headers search in their Makefiles:

../kcmp/Makefile:CFLAGS += -I../../../../usr/include/
../networking/timestamping/Makefile:CFLAGS += -I../../../../../usr/include
../ipc/Makefile:CFLAGS += -I../../../../usr/include/
../memfd/Makefile:CFLAGS += -I../../../../include/uapi/
../memfd/Makefile:CFLAGS += -I../../../../include/
../memfd/Makefile:CFLAGS += -I../../../../usr/include/

which seems aimed at doing the same thing, but it is a broken approach
as far as I can see since if KBUILD_OUTPUT is set, KSFT will install the
headers accordingly, so that the above static includes won't work anymore.

Not sure if I'm missing something here, but my understanding was that

- some KSFT requires arch specific bits, usually included within the dedicated kernel
headers provided with the source itself and installed with make headers_install.

and that

- such headers can be found naturally, being included from top level libc headers
only if:

1. a fully updated toolchain containing updated headers too is available at CROSS_COMPILE=

or

2. proper -I options are specified to the compiler to specify where KSFT installed the 
  kernel headers related to this kernel and its related KSFT testcases

or

3. updated kernel headers were installed on top of the available CROSS_COMPILE toolchain

or

4. we are building and running natively, so you can install the kernel headers on
   system default path and those will be searched


My 'feeling' would have been that in the KSFT scenario we should try to stick with option  2.,
in order to be able to run KSFT and run the related testcases, relying just on the shipped
Kernel/KSFT and possibly underlying hw features, but not having any dependencies
on the toolchain/libc.

My question is: what happens on a CI-somewhere if suddenly there's the need to update
the toolchain somehow (fully or partially only the headers) to be able to simply
build/run the new KSFT included with this Kernel ?; even if we accept this need to update
the toochain, where this CI should get/scrap-from these minimum toolchain requirements ?
(in an automated manner)

If instead we can agree to stick with 2.,  I wonder if this locate-headers mechanism which I introduced
here should be in charge of the KSFT framework or if there is something broken in my tests: but 
in these regards similar issues seems to affect KSFT arm64 tags tests queued on arm64/for-next

https://lkml.org/lkml/2019/8/23/721


>> +
>> +# Standalone run
>> +ifeq (0,$(MAKELEVEL))
>> +CC := $(CROSS_COMPILE)gcc
>> +RUNNER_SRC = test_arm64_signals.src_shell
>> +RUNNER = test_arm64_signals.sh
>> +INSTALL_PATH ?= install/
>> +
>> +all: $(RUNNER)
>> +
>> +$(RUNNER): $(PROGS)
> 
> $(RUNNER_SRC) should also be in the dependencies here.
> 
>> +	cp $(RUNNER_SRC) $(RUNNER)
>> +	sed -i -e 's#PROGS=.*#PROGS="$(PROGS)"#' $@
> 
> Or just a single command: sed -e '...' <$< >$@

I'll drop all of this together with standalone mode.
> 
>> +
>> +install: all
>> +	mkdir -p $(INSTALL_PATH)/testcases
>> +	cp $(PROGS) $(INSTALL_PATH)/testcases
>> +	cp $(RUNNER) $(INSTALL_PATH)/
>> +
>> +.PHONY clean:
>> +	rm -f $(PROGS)
>> +# KSFT run
>> +else
>> +# Generated binaries to be installed by top KSFT script
>> +TEST_GEN_PROGS := $(notdir $(PROGS))
>> +
>> +# Get Kernel headers installed and use them.
>> +KSFT_KHDR_INSTALL := 1
>> +
>> +# This include mk will also mangle the TEST_GEN_PROGS list
>> +# to account for any OUTPUT target-dirs optionally provided
>> +# by the toplevel makefile
>> +include ../../lib.mk
>> +
>> +$(TEST_GEN_PROGS): $(PROGS)
>> +	cp $(PROGS) $(OUTPUT)/
>> +
>> +clean:
>> +	$(CLEAN)
>> +	rm -f $(PROGS)
>> +endif
>> +
>> +# Common test-unit targets to build common-layout test-cases executables
>> +# Needs secondary expansion to properly include the testcase c-file in pre-reqs
>> +.SECONDEXPANSION:
>> +$(PROGS): test_signals.c test_signals_utils.c testcases/testcases.c $$@.c test_signals.h test_signals_utils.h testcases/testcases.h
>> +	@if [ ! -d $(khdr_dir) ]; then \
>> +		echo -n "\n!!! WARNING: $(khdr_dir) NOT FOUND."; \
>> +		echo "===>  Are you sure Kernel Headers have been installed properly ?\n"; \
>> +	fi
>> +	$(CC) $(CFLAGS) $^ -o $@
>> diff --git a/tools/testing/selftests/arm64/signal/README b/tools/testing/selftests/arm64/signal/README
>> new file mode 100644
>> index 000000000000..53f005f7910a
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/README
>> @@ -0,0 +1,59 @@
>> +KSelfTest arm64/signal/
>> +=======================
>> +
>> +Signals Tests
>> ++++++++++++++
>> +
>> +- Tests are built around a common main compilation unit: such shared main
>> +  enforces a standard sequence of operations needed to perform a single
>> +  signal-test (setup/trigger/run/result/cleanup)
>> +
>> +- The above mentioned ops are configurable on a test-by-test basis: each test
>> +  is described (and configured) using the descriptor signals.h::struct tdescr
>> +
>> +- Each signal testcase is compiled into its own executable: a separate
>> +  executable is used for each test since many tests complete successfully
>> +  by receiving some kind of fatal signal from the Kernel, so it's safer
>> +  to run each test unit in its own standalone process, so as to start each
>> +  test from a clean slate.
>> +
>> +- New tests can be simply defined in testcases/ dir providing a proper struct
>> +  tdescr overriding all the defaults we wish to change (as of now providing a
>> +  custom run method is mandatory though)
>> +
>> +- Signals' test-cases hereafter defined belong currently to two
>> +  principal families:
>> +
>> +  - 'mangle_' tests: a real signal (SIGUSR1) is raised and used as a trigger
>> +    and then the test case code messes-up with the sigframe ucontext_t from
>> +    inside the sighandler itself.
> 
> "messes-up" makes it sound a bit like the test case code itself goes
> wrong.
> 
> Maybe just say something like "the test case code modifies the signal
> frame from inside the signal handler itself."

ok
> 
>> +
>> +  - 'fake_sigreturn_' tests: a brand new custom artificial sigframe structure
>> +    is placed on the stack and a sigreturn syscall is called to simulate a
>> +    real signal return. This kind of tests does not use a trigger usually and
>> +    they are just fired using some simple included assembly trampoline code.
>> +
>> + - Most of these tests are successfully passing if the process gets killed by
>> +   some fatal signal: usually SIGSEGV or SIGBUS. Since while writing this
>> +   kind of tests it is extremely easy in fact to end-up injecting other
>> +   unrelated SEGV bugs in the testcases, it becomes extremely tricky to
>> +   be really sure that the tests are really addressing what they are meant
>> +   to address and they are not instead falling apart due to unplanned bugs
>> +   in the test code.
>> +   In order to alleviate the misery of the life of such test-developer, a few
>> +   helpers are provided:
>> +
>> +   - a couple of ASSERT_BAD/GOOD_CONTEXT() macros to easily parse a ucontext_t
>> +     and verify if it is indeed GOOD or BAD (depending on what we were
>> +     expecting), using the same logic/perspective as in the arm64 Kernel signals
>> +     routines.
>> +
>> +   - a sanity mechanism to be used in 'fake_sigreturn_'-alike tests: enabled by
>> +     default it takes care to verify that the test-execution had at least
>> +     successfully progressed up to the stage of triggering the fake sigreturn
>> +     call.
>> +
>> +  In both cases test results are expected in terms of:
>> +   - some fatal signal sent by the Kernel to the test process
>> +  or
>> +  - analyzing some final regs state
>> diff --git a/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
>> new file mode 100755
>> index 000000000000..163e941e2997
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> 
> Unusual filename?
> 
> In the non-standalone case, is this run directly with TPROGS set in the
> environment instead of modifying the script?  (I haven't understood all
> the logic yet.)
> 
> If so, it is a shell script, and should just be called
> test_arm64_signals.sh
> 
> Otherwise, it's a non-executable template for a shell script, so should
> have 0644 permissions and could be called test_arm64_signals.sh.in or
> test_arm64_signals.sh.template, say.
> 

It's a non-executable template for a shell script and all of this is needed
only in standalone mode. I'm dropping it.
(this re-generation on the fly from a template was needed to properly .gitignoring this)

>> @@ -0,0 +1,55 @@
>> +#!/bin/sh
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (C) 2019 ARM Limited
>> +
>> +ret=0
>> +keep_on_fail=0
>> +err_out="2> /dev/null"
>> +
>> +usage() {
>> +	echo "Usage: `basename $0` [-v] [-k]"
>> +	exit 1
>> +}
>> +
>> +# avoiding getopt to avoid compatibility issues on targets
>> +# with limited resources
>> +while [ $# -gt 0 ]
>> +do
>> +	case $1 in
>> +		"-k")
>> +			keep_on_fail=1
>> +			;;
>> +		"-v")
>> +			err_out=
>> +			;;
>> +		*)
>> +			usage
>> +			;;
>> +	esac
>> +	shift
>> +done
>> +
>> +TPROGS=
>> +
>> +tot=$(echo $TPROGS | wc -w)
>> +
>> +# Tests are expected in testcases/ subdir inside the installation path
>> +workdir="`dirname $0 2>/dev/null`"
>> +[ -n $workdir ] && cd $workdir
>> +
>> +passed=0
>> +run=0
>> +for test in $TPROGS
>> +do
>> +	run=$((run + 1))
>> +	eval ./$test $err_out
>> +	if [ $? != 0 ]; then
>> +		[ $keep_on_fail = 0 ] && echo "===>>> FAILED:: $test <<<===" && ret=1 && break
>> +	else
>> +		passed=$((passed + 1))
>> +	fi
>> +done
>> +
>> +echo "==>> PASSED: $passed/$run on $tot available tests."
>> +
>> +exit $ret
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals.c b/tools/testing/selftests/arm64/signal/test_signals.c
>> new file mode 100644
>> index 000000000000..3447d7011aec
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals.c
>> @@ -0,0 +1,26 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
> 
> We should probably have a brief comment to say what this is.
> For example:
> 
> /*
>  * Generic test wrapper for arm64 signal tests
>  * Each test provides its own tde to link with this wrapper.
>  */
> 
Ok I'll do.

>> +
>> +#include <kselftest.h>
>> +
>> +#include "test_signals.h"
>> +#include "test_signals_utils.h"
>> +
>> +struct tdescr *current;
>> +extern struct tdescr tde;
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +	current = &tde;
>> +
>> +	ksft_print_msg("%s :: %s - SIG_TRIG:%d  SIG_OK:%d -- current:%p\n",
>> +		       current->name, current->descr, current->sig_trig,
>> +		       current->sig_ok, current);
> 
> Does the user need all this?
> 
> It's sufficient to print the test name, a one-line description and
> results.  If something goes wrong, we can print a bit more detail.
> 
> Maybe just do something like
> 
> #ifdef DEBUG
> #define debug_printf(format, ...) ksft_print_msg(format, ## __VA_ARGS__)
> #else
> #define debug_printf(format, ...) ((void)0)
> #endif
> 
> (Unless kselftest already has something like this, in which case you
> could just use that.)

I don't think KSFT has this capability by itself.
I was thinking about reducing verbosity.

> 
>> +	if (test_setup(current)) {
>> +		if (test_run(current))
>> +			test_result(current);
>> +		test_cleanup(current);
>> +	}
>> +
>> +	return current->pass ? KSFT_PASS : KSFT_FAIL;
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
>> new file mode 100644
>> index 000000000000..85db3ac44b32
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals.h
>> @@ -0,0 +1,137 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#ifndef __TEST_SIGNALS_H__
>> +#define __TEST_SIGNALS_H__
>> +
>> +#include <assert.h>
>> +#include <stdbool.h>
>> +#include <signal.h>
>> +#include <ucontext.h>
>> +#include <stdint.h>
> 
> Does anything in this header use <assert.h> or <stdint.h>?
> 

Probably no more...I'll check.

>> +
>> +/*
>> + * Using ARCH specific and sanitized Kernel headers installed by KSFT
>> + * framework since we asked for it by setting flag KSFT_KHDR_INSTALL
>> + * in our Makefile.
>> + */
>> +#include <asm/ptrace.h>
>> +#include <asm/hwcap.h>
>> +
>> +/* pasted from include/linux/stringify.h */
>> +#define __stringify_1(x...)	#x
>> +#define __stringify(x...)	__stringify_1(x)
>> +
>> +/*
> 
> I think we can delete this entire comment.
> 
> The macro name is fairly self-explanatory anyway.  Although the
> rationale is interesting, our approach to reading system registers
> here is just the same as elsewhere in the kernel.

OK
> 
>> + * Reads a sysreg using the, possibly provided, S3_ encoding in order to
>> + * avoid inject any dependency on the used toolchain regarding possibly
>> + * still unsupported ARMv8 extensions.
>> + *
>> + * Using a standard mnemonic here to indicate the specific sysreg (like SSBS)
>> + * would introduce a compile-time dependency on possibly unsupported ARMv8
>> + * Extensions: you could end-up failing to build the test depending on the
>> + * available toolchain.
>> + * This is undesirable since some tests, even if specifically targeted at some
>> + * ARMv8 Extensions, can be plausibly run even on hardware lacking the above
>> + * optional ARM features. (SSBS bit preservation is an example: Kernel handles
>> + * it transparently not caring at all about the effective set of supported
>> + * features).
>> + * On the other side we will expect to observe different behaviours if the
>> + * feature is supported or not: usually getting a SIGILL when trying to use
>> + * unsupported features. For this reason we have anyway in place some
>> + * preliminary run-time checks about the cpu effectively supported features.
>> + *
>> + * This helper macro is meant to be used for regs readable at EL0, BUT some
>> + * EL1 sysregs are indeed readable too through MRS emulation Kernel-mechanism
>> + * if the required reg is included in the supported encoding space:
>> + *
>> + *  Documentation/arm64/cpu-feature-regsiters.txt
>> + *
>> + *  "The infrastructure emulates only the following system register space:
>> + *   	Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7
>> + */
>> +#define get_regval(regname, out) \
>> +	asm volatile("mrs %0, " __stringify(regname) : "=r" (out) :: "memory")
>> +
>> +/* Regs encoding and masks naming copied in from sysreg.h */
>> +#define SYS_ID_AA64MMFR1_EL1	S3_0_C0_C7_1	/* MRS Emulated */
>> +#define SYS_ID_AA64MMFR2_EL1	S3_0_C0_C7_2	/* MRS Emulated */
> 
> These ID regs are part of armv8.0-a, so we don't need to use the magic
> syntax.
> mmm... why I found them in non UAPI headers defined as follows ?

arch/arm64/include/asm/sysreg.h:#define SYS_ID_AA64MMFR1_EL1            sys_reg(3, 0, 0, 7, 1)

anyway I tried to use nonS3 regular sysreg naming (with a reasonably new compiler:

/opt/toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-

and it fails (only on id_aa64mmfr2_el1) as follows:
/tmp/ccqAyE8P.s: Assembler messages:                      
/tmp/ccoGrnGc.s:1085: Error: selected processor does not support system register name 'id_aa64mmfr2_el1'

In fact this seems to remind me (not totally sure) that this was the reason to use such S3 syntax on this
sysregs too.

>> +#define ID_AA64MMFR1_PAN_SHIFT	20
>> +#define ID_AA64MMFR2_UAO_SHIFT	4
>> +
>> +/* Local Helpers */
> 
> Can these names indicate the sysreg they should be used with, e.g.
> 
> #define ID_AA64MMFR1_EL1_PAN_SUPPORTED(val) ...
> #define ID_AA64MMFR2_EL1_UAO_SUPPORTED(val) ...
> 
ok

>> +#define IS_PAN_SUPPORTED(val) \
>> +	(!!((val) & (0xfUL << ID_AA64MMFR1_PAN_SHIFT)))
>> +#define IS_UAO_SUPPORTED(val) \
>> +	(!!((val) & (0xfUL << ID_AA64MMFR2_UAO_SHIFT)))
>> +
>> +#define S3_MRS_SSBS_SYSREG		S3_3_C4_C2_6	/* EL0 supported */
> 
> Maybe just SSBS_SYSREG.
> 
> Sysreg encodings are always for use with MRS/MSR anyway, and "S3" is
> really part of the definition rather than part of the name.
> 
ok

>> +
>> +/*
>> + * Feature flags used in tdescr.feats_required to specify
>> + * any feature by the test
>> + */
>> +enum {
>> +	FSSBS_BIT,
>> +	FPAN_BIT,
>> +	FUAO_BIT,
>> +	FMAX_END
>> +};
>> +
>> +#define FEAT_SSBS		(1UL << FSSBS_BIT)
>> +#define FEAT_PAN		(1UL << FPAN_BIT)
>> +#define FEAT_UAO		(1UL << FUAO_BIT)
>> +
>> +/*
>> + * A descriptor used to describe and configure a test case.
>> + * Fields with a non-trivial meaning are described inline in the following.
>> + */
>> +struct tdescr {
>> +	/* KEEP THIS FIELD FIRST for easier lookup from assembly */
>> +	void		*token;
>> +	/* when disabled token based sanity checking is skipped in handler */
>> +	bool		sanity_disabled;
>> +	/* just a name for the test-case; manadatory field */
>> +	char		*name;
>> +	char		*descr;
>> +	unsigned long	feats_required;
>> +	/* bitmask of effectively supported feats: populated at run-time */
>> +	unsigned long	feats_supported;
>> +	bool		feats_ok;
> 
> Is feats_ok used?

Removed.

> 
>> +	bool		initialized;
>> +	unsigned int	minsigstksz;
>> +	/* signum used as a test trigger. Zero if no trigger-signal is used */
>> +	int		sig_trig;
>> +	/*
>> +	 * signum considered as a successful test completion.
>> +	 * Zero when no signal is expected on success
>> +	 */
>> +	int		sig_ok;
>> +	/* signum expected on unsupported CPU features. */
>> +	int		sig_unsupp;
>> +	/* a timeout in second for test completion */
>> +	unsigned int	timeout;
>> +	bool		triggered;
>> +	bool		pass;
>> +	/* optional sa_flags for the installed handler */
>> +	int		sa_flags;
>> +	ucontext_t	saved_uc;
>> +
>> +	/* a setup function to be called before test starts */
>> +	int (*setup)(struct tdescr *td);
>> +	void (*cleanup)(struct tdescr *td);
> 
> Add a comment to say what cleanup() is?
> 
ok
>> +
>> +	/* an optional function to be used as a trigger for test starting */
>> +	int (*trigger)(struct tdescr *td);
>> +	/*
>> +	 * the actual test-core: invoked differently depending on the
>> +	 * presence of the trigger function above; this is mandatory
>> +	 */
>> +	int (*run)(struct tdescr *td, siginfo_t *si, ucontext_t *uc);
>> +
>> +	/* an optional function for custom results' processing */
>> +	void (*check_result)(struct tdescr *td);
>> +
>> +	void *priv;
>> +};
>> +#endif
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
>> new file mode 100644
>> index 000000000000..ac0055f6340b
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
>> @@ -0,0 +1,261 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <signal.h>
>> +#include <string.h>
>> +#include <unistd.h>
>> +#include <assert.h>
>> +#include <sys/auxv.h>
>> +#include <linux/auxvec.h>
>> +#include <ucontext.h>
>> +
>> +#include "test_signals.h"
>> +#include "test_signals_utils.h"
>> +#include "testcases/testcases.h"
>> +
>> +extern struct tdescr *current;
>> +
>> +static char *feats_store[FMAX_END] = {
>> +	"SSBS",
>> +	"PAN",
>> +	"UAO"
>> +};
>> +
>> +#define MAX_FEATS_SZ	128
>> +static inline char *feats_to_string(unsigned long feats)
>> +{
>> +	static char feats_string[MAX_FEATS_SZ];
>> +
>> +	for (int i = 0; i < FMAX_END && feats_store[i][0]; i++) {
>> +		if (feats & 1UL << i)
>> +			snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
>> +				 feats_string, feats_store[i]);
>> +	}
>> +
>> +	return feats_string;
>> +}
>> +
>> +static void unblock_signal(int signum)
>> +{
>> +	sigset_t sset;
>> +
>> +	sigemptyset(&sset);
>> +	sigaddset(&sset, signum);
>> +	sigprocmask(SIG_UNBLOCK, &sset, NULL);
>> +}
>> +
>> +static void default_result(struct tdescr *td, bool force_exit)
>> +{
>> +	if (td->pass)
>> +		fprintf(stderr, "==>> completed. PASS(1)\n");
>> +	else
>> +		fprintf(stdout, "==>> completed. FAIL(0)\n");
>> +	if (force_exit)
>> +		exit(td->pass ? EXIT_SUCCESS : EXIT_FAILURE);
>> +}
>> +
>> +static inline bool are_feats_ok(struct tdescr *td)
>> +{
>> +	return td ? td->feats_required == td->feats_supported : 0;
> 
> Should this be something like
> (td->feats_required & td->feats_supported) == td->feats_required ?
> 
> Otherwise additional supported features that our test doesn't care about
> will cause this check to fail.
> 
Yes better.

> 
> Do we really need to check td?
> 

Overly defensive

> assert(foo); followed by dereferincing foo is usually a bit pointless
> because you'd get a SIGSEGV anyway.
>
> However, since the tests generate deliberate SIGSEGVs too this could
> be confusing -- in which case, having an explicit assert() here does
> no harm.
> 
not sure about which assert you refer here

>> +}
>> +
>> +static void default_handler(int signum, siginfo_t *si, void *uc)
>> +{
>> +	if (current->sig_trig && signum == current->sig_trig) {
>> +		fprintf(stderr, "Handling SIG_TRIG\n");
>> +		current->triggered = 1;
>> +		/* ->run was asserted NON-NULL in test_setup() already */
>> +		current->run(current, si, uc);
>> +	} else if (signum == SIGILL && !current->initialized) {
>> +		/*
>> +		 * A SIGILL here while still not initialized means we failed
>> +		 * even to asses the existence of features during init
>> +		 */
>> +		fprintf(stdout,
>> +			"Got SIGILL test_init. Marking ALL features UNSUPPORTED.\n");
>> +		current->feats_supported = 0;
>> +	} else if (current->sig_ok && signum == current->sig_ok) {
>> +		/* it's a bug in the test code when this assert fail */
> 
> Why?  Is this because sig_ok is considered acceptable only as an effect
> of the test -- i.e., we shouldn't see it if the test hasn't been
> triggered yet?

This assert would like to ensure that when you receive a sig_ok signal,
if a sig_trig was defined != 0, the trigger have been in fact used and processed before
receiving this sig_ok here: so you didn't define a signal trigger at all, or, if defined
it has been fired to arrive here. I'll add some commenting about this.

> 
>> +		assert(!current->sig_trig || current->triggered);
>> +		fprintf(stderr,
>> +			"SIG_OK -- SP:%p  si_addr@:0x%p  si_code:%d  token@:0x%p  offset:%ld\n",
>> +			((ucontext_t *)uc)->uc_mcontext.sp,
>> +			si->si_addr, si->si_code, current->token,
>> +			current->token - si->si_addr);
>> +		/*
>> +		 * fake_sigreturn tests, which have sanity_enabled=1, set, at
>> +		 * the very last time, the token field to the SP address used
>> +		 * to place the fake sigframe: so token==0 means we never made
>> +		 * it to the end, segfaulting well-before, and the test is
>> +		 * possibly broken.
>> +		 */
>> +		if (!current->sanity_disabled && !current->token) {
>> +			fprintf(stdout,
>> +				"current->token ZEROED...test is probably broken!\n");
>> +			assert(0);
> 
> In case someone builds with -DNDEBUG, should we add abort()?
> 
Well, in such a case all the test suite is mostly compromised anyway.
But you are right, I'll add an abort() at least here when broken tests are detected.

>> +		}
>> +		/*
>> +		 * Trying to narrow down the SEGV to the ones generated by
>> +		 * Kernel itself via arm64_notify_segfault()
>> +		 */
>> +		if (current->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
>> +			fprintf(stdout,
>> +				"si_code != SEGV_ACCERR...test is probably broken!\n");
>> +			assert(0);
>> +		}
> 
> I'm not sure whether si_code is really ABI here, though I'm not sure
> what else we can do to diagnose the signal more accurately.
> 
> Maybe add a comment to say that this might need to change if this
> aspect of the kernel ABI evolves.
Ok
> 
>> +		fprintf(stderr, "Handling SIG_OK\n");
>> +		current->pass = 1;
>> +		/*
>> +		 * Some tests can lead to SEGV loops: in such a case we want
>> +		 * to terminate immediately exiting straight away
>> +		 */
>> +		default_result(current, 1);
>> +	} else {
>> +		if (signum == current->sig_unsupp && !are_feats_ok(current)) {
>> +			fprintf(stderr, "-- RX SIG_UNSUPP on unsupported feature...OK\n");
>> +			current->pass = 1;
>> +		} else if (signum == SIGALRM && current->timeout) {
>> +			fprintf(stderr, "-- Timeout !\n");
>> +		} else {
>> +			fprintf(stderr,
>> +				"-- RX UNEXPECTED SIGNAL: %d\n", signum);
>> +		}
>> +		default_result(current, 1);
>> +	}
>> +}
>> +
>> +static int default_setup(struct tdescr *td)
>> +{
>> +	struct sigaction sa;
>> +
>> +	sa.sa_sigaction = default_handler;
>> +	sa.sa_flags = SA_SIGINFO;
> 
> Add SA_RESTART?
> 
> I'm not sure whether this affects these tests, but the libc stdio
> functions don't like being interrupted by signals.  SA_RESTART should
> hide most issues of this sort.
> 

Ok...I was not aware of these possible issues.

>> +	if (td->sa_flags)
>> +		sa.sa_flags |= td->sa_flags;
> 
> Do we need the if() here?  If td->sa_flags == 0, the assignment is
> harmless anyway.
True.

> 
>> +	sigemptyset(&sa.sa_mask);
>> +	/* uncatchable signals naturally skipped ... */
>> +	for (int sig = 1; sig < 32; sig++)
>> +		sigaction(sig, &sa, NULL);
>> +	/*
>> +	 * RT Signals default disposition is Term but they cannot be
>> +	 * generated by the Kernel in response to our tests; so just catch
>> +	 * them all and report them as UNEXPECTED signals.
>> +	 */
>> +	for (int sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
>> +		sigaction(sig, &sa, NULL);
>> +
>> +	/* just in case...unblock explicitly all we need */
>> +	if (td->sig_trig)
>> +		unblock_signal(td->sig_trig);
>> +	if (td->sig_ok)
>> +		unblock_signal(td->sig_ok);
>> +	if (td->sig_unsupp)
>> +		unblock_signal(td->sig_unsupp);
>> +
>> +	if (td->timeout) {
>> +		unblock_signal(SIGALRM);
>> +		alarm(td->timeout);
>> +	}
>> +	fprintf(stderr, "Registered handlers for all signals.\n");
>> +
>> +	return 1;
>> +}
>> +
>> +static inline int default_trigger(struct tdescr *td)
>> +{
>> +	return !raise(td->sig_trig);
>> +}
>> +
>> +static int test_init(struct tdescr *td)
>> +{
>> +	td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
>> +	if (!td->minsigstksz)
>> +		td->minsigstksz = MINSIGSTKSZ;
>> +	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
>> +
>> +	if (td->feats_required) {
>> +		bool feats_ok = false;
>> +		td->feats_supported = 0;
>> +		/*
>> +		 * Checking for CPU required features using both the
>> +		 * auxval and the arm64 MRS Emulation to read sysregs.
>> +		 */
>> +		if (getauxval(AT_HWCAP) & HWCAP_CPUID) {
>> +			uint64_t val = 0;
>> +
> 
> Would it be simpler just to query all these features unconditionally?
> 
> We just need to check that all the features the test needs are present.
> If other features are present, we can happily ignore them, but
> discovering them is harmless.
> 
Ok
>> +			if (td->feats_required & FEAT_SSBS) {
>> +				/* Uses HWCAP to check capability */
>> +				if (getauxval(AT_HWCAP) & HWCAP_SSBS)
>> +					td->feats_supported |= FEAT_SSBS;
>> +			}
>> +			if (td->feats_required & FEAT_PAN) {
>> +				/* Uses MRS emulation to check capability */
>> +				get_regval(SYS_ID_AA64MMFR1_EL1, val);
>> +				if (IS_PAN_SUPPORTED(val))
>> +					td->feats_supported |= FEAT_PAN;
>> +			}
>> +			if (td->feats_required & FEAT_UAO) {
>> +				/* Uses MRS emulation to check capability */
>> +				get_regval(SYS_ID_AA64MMFR2_EL1 , val);
>> +				if (IS_UAO_SUPPORTED(val))
>> +					td->feats_supported |= FEAT_UAO;
>> +			}
>> +		} else {
>> +			fprintf(stderr,
>> +				"HWCAP_CPUID NOT available. Mark ALL feats UNSUPPORTED.\n");
>> +		}
>> +		feats_ok = are_feats_ok(td);
>> +		fprintf(stderr,
>> +			"Required Features: [%s] %ssupported\n",
>> +			feats_ok ? feats_to_string(td->feats_supported) :
>> +		        feats_to_string(td->feats_required ^ td->feats_supported),
>> +			!feats_ok ? "NOT " : "");
>> +	}
>> +
>> +	td->initialized = 1;
>> +	return 1;
>> +}
>> +
>> +int test_setup(struct tdescr *td)
>> +{
>> +	/* assert core invariants symptom of a rotten testcase */
>> +	assert(current);
>> +	assert(td);
>> +	assert(td->name);
>> +	assert(td->run);
>> +
>> +	if (!test_init(td))
>> +		return 0;
>> +
>> +	if (td->setup)
>> +		return td->setup(td);
>> +	else
>> +		return default_setup(td);
>> +}
>> +
>> +int test_run(struct tdescr *td)
>> +{
>> +	if (td->sig_trig) {
>> +		if (td->trigger)
>> +			return td->trigger(td);
>> +		else
>> +			return default_trigger(td);
>> +	} else {
>> +		return td->run(td, NULL, NULL);
>> +	}
>> +}
>> +
>> +void test_result(struct tdescr *td)
>> +{
>> +	if (td->check_result)
>> +		td->check_result(td);
>> +	default_result(td, 0);
>> +}
>> +
>> +void test_cleanup(struct tdescr *td)
>> +{
>> +	if (td->cleanup)
>> +		td->cleanup(td);
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> new file mode 100644
>> index 000000000000..8658d1a7d4b9
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
>> @@ -0,0 +1,13 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
>> +#ifndef __TEST_SIGNALS_UTILS_H__
>> +#define __TEST_SIGNALS_UTILS_H__
>> +
>> +#include "test_signals.h"
>> +
>> +int test_setup(struct tdescr *td);
>> +void test_cleanup(struct tdescr *td);
>> +int test_run(struct tdescr *td);
>> +void test_result(struct tdescr *td);
>> +#endif
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/.gitignore b/tools/testing/selftests/arm64/signal/testcases/.gitignore
>> new file mode 100644
>> index 000000000000..8651272e3cfc
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/.gitignore
>> @@ -0,0 +1 @@
>> +mangle_pstate_invalid_compat_toggle
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>> new file mode 100644
>> index 000000000000..971193e7501b
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
>> @@ -0,0 +1,25 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2019 ARM Limited */
>> +
> 
> Each testcase should have a comment explaining what it is trying to
> test, and how.
> 
Ok

>> +#include "test_signals_utils.h"
>> +#include "testcases.h"
>> +
>> +static int mangle_invalid_pstate_run(struct tdescr *td, siginfo_t *si,
>> +				     ucontext_t *uc)
>> +{
>> +	ASSERT_GOOD_CONTEXT(uc);
>> +
>> +	/* This config should trigger a SIGSEGV by Kernel */
>> +	uc->uc_mcontext.pstate ^= PSR_MODE32_BIT;
>> +
>> +	return 1;
>> +}
>> +
>> +struct tdescr tde = {
>> +		.sanity_disabled = true,
>> +		.name = "MANGLE_PSTATE_INVALID_STATE_TOGGLE",
>> +		.descr = "Mangling uc_mcontext with INVALID STATE_TOGGLE",
>> +		.sig_trig = SIGUSR1,
>> +		.sig_ok = SIGSEGV,
>> +		.run = mangle_invalid_pstate_run,
>> +};
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
>> new file mode 100644
>> index 000000000000..a59785092e1f
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
>> @@ -0,0 +1,150 @@
>> +#include "testcases.h"
>> +
>> +struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
>> +				size_t resv_sz, size_t *offset)
>> +{
>> +	size_t offs = 0;
>> +	struct _aarch64_ctx *found = NULL;
>> +
>> +	if (!head || resv_sz < HDR_SZ)
>> +		return found;
>> +
>> +	do {
>> +		if (head->magic == magic) {
>> +			found = head;
>> +			break;
>> +		}
>> +		offs += head->size;
>> +		head = GET_RESV_NEXT_HEAD(head);
> 
> Are offs and head tracking the same thing here?
> 
> Maybe it would be cleaner to have GET_RESV_NEXT_HEAD() do the bounds
> checking itself.
> 
offs is used for bound checking but it is also optionally provided to the
caller as the offset in bytes at which the header was found, and yes it tracks the
underlying same thing at the end.
I'll try to cleanup and re-org this function a bit.

>> +	} while (offs < resv_sz - HDR_SZ);
>> +
>> +	if (offset)
>> +		*offset = offs;
>> +
>> +	return found;
>> +}
>> +
>> +bool validate_extra_context(struct extra_context *extra, char **err)
>> +{
>> +	struct _aarch64_ctx *term;
>> +
>> +	if (!extra || !err)
>> +		return false;
>> +
>> +	fprintf(stderr, "Validating EXTRA...\n");
>> +	term = GET_RESV_NEXT_HEAD(extra);
>> +	if (!term || term->magic || term->size) {
>> +		*err = "UN-Terminated EXTRA context";
> 
> This sounds like the extra context doesn't contain a terminator, which
> isn't what we're checking here.  Maybe say "terminator missing after
> extra context", or similar.

ok
> 
>> +		return false;
>> +	}
>> +	if (extra->datap & 0x0fUL)
>> +		*err = "Extra DATAP misaligned";
>> +	else if (extra->size & 0x0fUL)
>> +		*err = "Extra SIZE misaligned";
>> +	else if (extra->datap != (uint64_t)term + sizeof(*term))
>> +		*err = "Extra DATAP misplaced (not contiguos)";
>> +	if (*err)
>> +		return false;
>> +
>> +	return true;
>> +}
>> +
>> +bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
>> +{
>> +	bool terminated = false;
>> +	size_t offs = 0;
>> +	int flags = 0;
>> +	struct extra_context *extra = NULL;
>> +	struct _aarch64_ctx *head =
>> +		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
>> +
>> +	if (!err)
>> +		return false;
>> +	/* Walk till the end terminator verifying __reserved contents */
>> +	while (head && !terminated && offs < resv_sz) {
>> +		if ((uint64_t)head & 0x0fUL) {
>> +			*err = "Misaligned HEAD";
>> +			return false;
>> +		}
>> +
>> +		switch (head->magic) {
>> +			case 0:
>> +				if (head->size)
>> +					*err = "Bad size for MAGIC0";
> 
> Or "terminator".  We don't have an actual symbolic name for magic number
> 0.  (Arguably it would have been nice to have a name, but we managed
> without.)

ok
> 
>> +				else
>> +					terminated = true;
>> +				break;
>> +			case FPSIMD_MAGIC:
>> +				if (flags & FPSIMD_CTX)
>> +					*err = "Multiple FPSIMD_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct fpsimd_context))
>> +					*err = "Bad size for fpsimd_context";
>> +				flags |= FPSIMD_CTX;
>> +				break;
>> +			case ESR_MAGIC:
>> +				if (head->size != sizeof(struct esr_context))
>> +					fprintf(stderr,
>> +						"Bad size for esr_context is not an error...just ignore.\n");
> 
> Why isn't this an error?  Should the kernel ever write an esr_context
> with a different size?

There is no check on Kernel side:

    case ESR_MAGIC:
    	/* ignore */
        break;

so I sticked with that, since this function can be used to validate a Kernel originated sigframe
or a crafted one which will be passed down to the Kernel.

> 
>> +				break;
>> +			case SVE_MAGIC:
>> +				if (flags & SVE_CTX)
>> +					*err = "Multiple SVE_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct sve_context))
>> +					*err = "Bad size for sve_context";
>> +				flags |= SVE_CTX;
>> +				break;
>> +			case EXTRA_MAGIC:
>> +				if (flags & EXTRA_CTX)
>> +					*err = "Multiple EXTRA_MAGIC";
>> +				else if (head->size !=
>> +					 sizeof(struct extra_context))
>> +					*err = "Bad size for extra_context";
>> +				flags |= EXTRA_CTX;
>> +				extra = (struct extra_context *)head;
>> +				break;
>> +			case KSFT_BAD_MAGIC:
>> +				/*
>> +				 * This is a BAD magic header defined
>> +				 * artificially by a testcase and surely
>> +				 * unknown to the Kernel parse_user_sigframe().
>> +				 * It MUST cause a Kernel induced SEGV
>> +				 */
>> +				*err = "BAD MAGIC !";
>> +				break;
>> +			default:
>> +				/*
>> +				 * A still unknown Magic: potentially freshly added
>> +				 * to the Kernel code and still unknown to the
>> +				 * tests.
>> +				 */
>> +				fprintf(stdout,
>> +					"SKIP Unknown MAGIC: 0x%X - Is KSFT arm64/signal up to date ?\n",
>> +					head->magic);
>> +				break;
>> +		}
>> +
>> +		if (*err)
>> +			return false;
>> +
>> +		offs += head->size;
> 
> Can this addition cause offs to become > resv_sz?  If so, the next
> comparison will go wrong.

True. I'll refactor the comparison to avoid subtraction like in :

	if (resv_sz < offs + sizeof(*head)) {

> 
>> +		if (resv_sz - offs < sizeof(*head)) {
>> +			*err = "HEAD Overrun";
>> +			return false;
>> +		}
>> +
>> +		if (flags & EXTRA_CTX)
>> +			if (!validate_extra_context(extra, err))
>> +				return false;
> 
> Can we validate the contents of the extra context too?
> 
> Ideally we can use the same code to check __reserved[] and the extra
> context.
> 
Do you mean the content pointed by extra->datap ?
This extra_context validation routine is generally under review and fixes in a further
arm64/signal SVE extensions patch still to be published (and cleaned up):
[kselftest: arm64: adds SVE-related signal test], given that EXTRA_CONTEXT can effectively
appear only when SVE related instruction are used properly.

Should I introduce this and other extra-context related fixes here instead ?
(it is hard to test and debug without any triggering SVE instruction though...)

>> +
>> +		head = GET_RESV_NEXT_HEAD(head);
>> +	}
>> +
>> +	if (terminated && !(flags & FPSIMD_CTX)) {
>> +		*err = "Missing FPSIMD";
>> +		return false;
>> +	}
>> +
>> +	return true;
>> +}
>> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
>> new file mode 100644
>> index 000000000000..624717c71b1d
>> --- /dev/null
>> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
>> @@ -0,0 +1,83 @@
>> +#ifndef __TESTCASES_H__
>> +#define __TESTCASES_H__
>> +
> 
> Pedantically, we should have <stddef.h> for NULL.
> 

ok

>> +#include <stdio.h>
>> +#include <stdbool.h>
>> +#include <stdint.h>
>> +#include <unistd.h>
> 
> Is <unistd.h> used now that SAFE_WRITE() is gone?
> 

Removed.

>> +#include <ucontext.h>
>> +#include <assert.h>
>> +
>> +/* Architecture specific sigframe definitions */
>> +#include <asm/sigcontext.h>
> 
> [...]
> 
> Cheers
> ---Dave
> 

Cheers

Cristian

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [GIT PULL] arm64: Fixes for -rc7
From: Will Deacon @ 2019-08-28 17:32 UTC (permalink / raw)
  To: torvalds
  Cc: kvm, rkrcmar, marc.zyngier, catalin.marinas, linux-kernel,
	pbonzini, kvmarm, linux-arm-kernel

Hi Linus,

Hot on the heels of our last set of fixes are a few more for -rc7. Two
of them are fixing issues with our virtual interrupt controller
implementation in KVM/arm, while the other is a longstanding but
straightforward kallsyms fix which was been acked by Masami and resolves
an initialisation failure in kprobes observed on arm64.

Please pull, thanks.

Will

--->8

The following changes since commit b6143d10d23ebb4a77af311e8b8b7f019d0163e6:

  arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side (2019-08-16 17:40:03 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 82e40f558de566fdee214bec68096bbd5e64a6a4:

  KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI (2019-08-28 11:21:42 +0100)

----------------------------------------------------------------
arm64 fixes for -rc7

- Fix GICv2 emulation bug (KVM)

- Fix deadlock in virtual GIC interrupt injection code (KVM)

- Fix kprobes blacklist init failure due to broken kallsyms lookup

----------------------------------------------------------------
Heyi Guo (1):
      KVM: arm/arm64: vgic: Fix potential deadlock when ap_list is long

Marc Zyngier (2):
      kallsyms: Don't let kallsyms_lookup_size_offset() fail on retrieving the first symbol
      KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI

 kernel/kallsyms.c             |  6 ++++--
 virt/kvm/arm/vgic/vgic-mmio.c | 18 ++++++++++++++++++
 virt/kvm/arm/vgic/vgic-v2.c   |  5 ++++-
 virt/kvm/arm/vgic/vgic-v3.c   |  5 ++++-
 virt/kvm/arm/vgic/vgic.c      |  7 +++++++
 5 files changed, 37 insertions(+), 4 deletions(-)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH V3 6/6] arm64: tegra: Add PCIe slot supply information in p2972-0000 platform
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add 3.3V and 12V supplies regulators information of x16 PCIe slot in
p2972-0000 platform which is owned by C5 controller and also enable C5
controller.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 24 +++++++++++++++++++
 .../boot/dts/nvidia/tegra194-p2972-0000.dts   |  4 +++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index 62e07e1197cc..4c38426a6969 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -289,5 +289,29 @@
 			gpio = <&gpio TEGRA194_MAIN_GPIO(A, 3) GPIO_ACTIVE_HIGH>;
 			enable-active-high;
 		};
+
+		vdd_3v3_pcie: regulator@2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+
+			regulator-name = "PEX_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio TEGRA194_MAIN_GPIO(Z, 2) GPIO_ACTIVE_HIGH>;
+			regulator-boot-on;
+			enable-active-high;
+		};
+
+		vdd_12v_pcie: regulator@3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+
+			regulator-name = "VDD_12V";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_LOW>;
+			regulator-boot-on;
+			enable-active-low;
+		};
 	};
 };
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
index 23597d53c9c9..d47cd8c4dd24 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
@@ -93,9 +93,11 @@
 	};
 
 	pcie@141a0000 {
-		status = "disabled";
+		status = "okay";
 
 		vddio-pex-ctl-supply = <&vdd_1v8ao>;
+		vpcie3v3-supply = <&vdd_3v3_pcie>;
+		vpcie12v-supply = <&vdd_12v_pcie>;
 
 		phys = <&p2u_nvhs_0>, <&p2u_nvhs_1>, <&p2u_nvhs_2>,
 		       <&p2u_nvhs_3>, <&p2u_nvhs_4>, <&p2u_nvhs_5>,
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 5/6] arm64: tegra: Add configuration for PCIe C5 sideband signals
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to configure PCIe C5's sideband signals PERST# and CLKREQ#
as output and bi-directional signals respectively which unlike other
PCIe controllers sideband signals are not configured by default.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 38 +++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index adebbbf36bd0..3c0cf54f0aab 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -3,8 +3,9 @@
 #include <dt-bindings/gpio/tegra194-gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/mailbox/tegra186-hsp.h>
-#include <dt-bindings/reset/tegra194-reset.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
 #include <dt-bindings/power/tegra194-powergate.h>
+#include <dt-bindings/reset/tegra194-reset.h>
 #include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
 
 / {
@@ -130,6 +131,38 @@
 			};
 		};
 
+		pinmux: pinmux@2430000 {
+			compatible = "nvidia,tegra194-pinmux";
+			reg = <0x2430000 0x17000
+			       0xc300000 0x4000>;
+
+			status = "okay";
+
+			pex_rst_c5_out_state: pex_rst_c5_out {
+				pex_rst {
+					nvidia,pins = "pex_l5_rst_n_pgg1";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+
+			clkreq_c5_bi_dir_state: clkreq_c5_bi_dir {
+				clkreq {
+					nvidia,pins = "pex_l5_clkreq_n_pgg0";
+					nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+					nvidia,lpdr = <TEGRA_PIN_ENABLE>;
+					nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+					nvidia,io-high-voltage = <TEGRA_PIN_ENABLE>;
+					nvidia,tristate = <TEGRA_PIN_DISABLE>;
+					nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				};
+			};
+		};
+
 		uarta: serial@3100000 {
 			compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
 			reg = <0x03100000 0x40>;
@@ -1365,6 +1398,9 @@
 		num-viewport = <8>;
 		linux,pci-domain = <5>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pex_rst_c5_out_state>, <&clkreq_c5_bi_dir_state>;
+
 		clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>,
 			<&bpmp TEGRA194_CLK_PEX1_CORE_5M>;
 		clock-names = "core", "core_m";
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 4/6] PCI: tegra: Add support to enable slot regulators
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to get regulator information of 3.3V and 12V supplies of a PCIe
slot from the respective controller's device-tree node and enable those
supplies. This is required in platforms like p2972-0000 where the supplies
to x16 slot owned by C5 controller need to be enabled before attempting to
enumerate the devices.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* Added a dev_err() print for failure case of tegra_pcie_get_slot_regulators() API
* Modified to make 100ms sleep valid only if at least one of the regulator handles exist

V2:
* Addressed review comments from Thierry Reding and Andrew Murray
* Handled failure case of devm_regulator_get_optional() for -ENODEV cleanly

 drivers/pci/controller/dwc/pcie-tegra194.c | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 77fa6f70bc96..18453cc5e7e4 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -278,6 +278,8 @@ struct tegra_pcie_dw {
 	u32 aspm_l0s_enter_lat;
 
 	struct regulator *pex_ctl_supply;
+	struct regulator *slot_ctl_3v3;
+	struct regulator *slot_ctl_12v;
 
 	unsigned int phy_count;
 	struct phy **phys;
@@ -1047,6 +1049,73 @@ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
 	}
 }
 
+static int tegra_pcie_get_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	pcie->slot_ctl_3v3 = devm_regulator_get_optional(pcie->dev, "vpcie3v3");
+	if (IS_ERR(pcie->slot_ctl_3v3)) {
+		if (PTR_ERR(pcie->slot_ctl_3v3) != -ENODEV)
+			return PTR_ERR(pcie->slot_ctl_3v3);
+
+		pcie->slot_ctl_3v3 = NULL;
+	}
+
+	pcie->slot_ctl_12v = devm_regulator_get_optional(pcie->dev, "vpcie12v");
+	if (IS_ERR(pcie->slot_ctl_12v)) {
+		if (PTR_ERR(pcie->slot_ctl_12v) != -ENODEV)
+			return PTR_ERR(pcie->slot_ctl_12v);
+
+		pcie->slot_ctl_12v = NULL;
+	}
+
+	return 0;
+}
+
+static int tegra_pcie_enable_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	int ret;
+
+	if (pcie->slot_ctl_3v3) {
+		ret = regulator_enable(pcie->slot_ctl_3v3);
+		if (ret < 0) {
+			dev_err(pcie->dev,
+				"Failed to enable 3.3V slot supply: %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (pcie->slot_ctl_12v) {
+		ret = regulator_enable(pcie->slot_ctl_12v);
+		if (ret < 0) {
+			dev_err(pcie->dev,
+				"Failed to enable 12V slot supply: %d\n", ret);
+			goto fail_12v_enable;
+		}
+	}
+
+	/*
+	 * According to PCI Express Card Electromechanical Specification
+	 * Revision 1.1, Table-2.4, T_PVPERL (Power stable to PERST# inactive)
+	 * should be a minimum of 100ms.
+	 */
+	if (pcie->slot_ctl_3v3 || pcie->slot_ctl_12v)
+		msleep(100);
+
+	return 0;
+
+fail_12v_enable:
+	if (pcie->slot_ctl_3v3)
+		regulator_disable(pcie->slot_ctl_3v3);
+	return ret;
+}
+
+static void tegra_pcie_disable_slot_regulators(struct tegra_pcie_dw *pcie)
+{
+	if (pcie->slot_ctl_12v)
+		regulator_disable(pcie->slot_ctl_12v);
+	if (pcie->slot_ctl_3v3)
+		regulator_disable(pcie->slot_ctl_3v3);
+}
+
 static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 					bool en_hw_hot_rst)
 {
@@ -1060,6 +1129,10 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 		return ret;
 	}
 
+	ret = tegra_pcie_enable_slot_regulators(pcie);
+	if (ret < 0)
+		goto fail_slot_reg_en;
+
 	ret = regulator_enable(pcie->pex_ctl_supply);
 	if (ret < 0) {
 		dev_err(pcie->dev, "Failed to enable regulator: %d\n", ret);
@@ -1142,6 +1215,8 @@ static int tegra_pcie_config_controller(struct tegra_pcie_dw *pcie,
 fail_core_clk:
 	regulator_disable(pcie->pex_ctl_supply);
 fail_reg_en:
+	tegra_pcie_disable_slot_regulators(pcie);
+fail_slot_reg_en:
 	tegra_pcie_bpmp_set_ctrl_state(pcie, false);
 
 	return ret;
@@ -1174,6 +1249,8 @@ static int __deinit_controller(struct tegra_pcie_dw *pcie)
 		return ret;
 	}
 
+	tegra_pcie_disable_slot_regulators(pcie);
+
 	ret = tegra_pcie_bpmp_set_ctrl_state(pcie, false);
 	if (ret) {
 		dev_err(pcie->dev, "Failed to disable controller %d: %d\n",
@@ -1373,6 +1450,12 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = tegra_pcie_get_slot_regulators(pcie);
+	if (ret < 0) {
+		dev_err(dev, "Failed to get slot regulators: %d\n", ret);
+		return ret;
+	}
+
 	pcie->pex_ctl_supply = devm_regulator_get(dev, "vddio-pex-ctl");
 	if (IS_ERR(pcie->pex_ctl_supply)) {
 		dev_err(dev, "Failed to get regulator: %ld\n",
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 3/6] PCI: tegra: Add support to configure sideband pins
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add support to configure sideband signal pins when information is present
in respective controller's device-tree node.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* Used 'dev' instead of 'pcie->dev'

V2:
* Addressed review comment from Andrew Murray
* Handled failure case of pinctrl_pm_select_default_state() cleanly

 drivers/pci/controller/dwc/pcie-tegra194.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index fc0dbeb31d78..77fa6f70bc96 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -1304,8 +1304,13 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
 	if (ret < 0) {
 		dev_err(dev, "Failed to get runtime sync for PCIe dev: %d\n",
 			ret);
-		pm_runtime_disable(dev);
-		return ret;
+		goto fail_pm_get_sync;
+	}
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret < 0) {
+		dev_err(dev, "Failed to configure sideband pins: %d\n", ret);
+		goto fail_pinctrl;
 	}
 
 	tegra_pcie_init_controller(pcie);
@@ -1332,7 +1337,9 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)
 
 fail_host_init:
 	tegra_pcie_deinit_controller(pcie);
+fail_pinctrl:
 	pm_runtime_put_sync(dev);
+fail_pm_get_sync:
 	pm_runtime_disable(dev);
 	return ret;
 }
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 2/6] dt-bindings: PCI: tegra: Add PCIe slot supplies regulator entries
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add optional bindings "vpcie3v3-supply" and "vpcie12v-supply" to describe
regulators of a PCIe slot's supplies 3.3V and 12V provided the platform
is designed to have regulator controlled slot supplies.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../devicetree/bindings/pci/nvidia,tegra194-pcie.txt      | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
index 0ac1b867ac24..b739f92da58e 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
@@ -104,6 +104,12 @@ Optional properties:
    specified in microseconds
 - nvidia,aspm-l0s-entrance-latency-us: ASPM L0s entrance latency to be
    specified in microseconds
+- vpcie3v3-supply: A phandle to the regulator node that supplies 3.3V to the slot
+  if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
+  in p2972-0000 platform).
+- vpcie12v-supply: A phandle to the regulator node that supplies 12V to the slot
+  if the platform has one such slot. (Ex:- x16 slot owned by C5 controller
+  in p2972-0000 platform).
 
 Examples:
 =========
@@ -156,6 +162,8 @@ Tegra194:
 			  0xc2000000 0x18 0x00000000 0x18 0x00000000 0x4 0x00000000>;  /* prefetchable memory (16GB) */
 
 		vddio-pex-ctl-supply = <&vdd_1v8ao>;
+		vpcie3v3-supply = <&vdd_3v3_pcie>;
+		vpcie12v-supply = <&vdd_12v_pcie>;
 
 		phys = <&p2u_hsio_2>, <&p2u_hsio_3>, <&p2u_hsio_4>,
 		       <&p2u_hsio_5>;
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 1/6] dt-bindings: PCI: tegra: Add sideband pins configuration entries
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv
In-Reply-To: <20190828172850.19871-1-vidyas@nvidia.com>

Add optional bindings "pinctrl-names" and "pinctrl-0" to describe pin
configuration information of a particular PCIe controller.

Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
---
V3:
* None

V2:
* None

 .../devicetree/bindings/pci/nvidia,tegra194-pcie.txt      | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
index 674e5adb2895..0ac1b867ac24 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt
@@ -83,6 +83,11 @@ Required properties:
 - vddio-pex-ctl-supply: Regulator supply for PCIe side band signals
 
 Optional properties:
+- pinctrl-names: A list of pinctrl state names.
+  It is mandatory for C5 controller and optional for other controllers.
+  - "default": Configures PCIe I/O for proper operation.
+- pinctrl-0: phandle for the 'default' state of pin configuration.
+  It is mandatory for C5 controller and optional for other controllers.
 - supports-clkreq: Refer to Documentation/devicetree/bindings/pci/pci.txt
 - nvidia,update-fc-fixup: This is a boolean property and needs to be present to
     improve performance when a platform is designed in such a way that it
@@ -120,6 +125,9 @@ Tegra194:
 		num-lanes = <8>;
 		linux,pci-domain = <0>;
 
+		pinctrl-names = "default";
+		pinctrl-0 = <&pex_rst_c5_out_state>, <&clkreq_c5_bi_dir_state>;
+
 		clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>;
 		clock-names = "core";
 
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V3 0/6] PCI: tegra: Enable PCIe C5 controller of Tegra194 in p2972-0000 platform
From: Vidya Sagar @ 2019-08-28 17:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, robh+dt, thierry.reding, jonathanh,
	andrew.murray
  Cc: devicetree, mmaddireddy, kthota, gustavo.pimentel, vidyas,
	linux-kernel, mperttunen, linux-pci, linux-tegra, digetx, kishon,
	linux-arm-kernel, sagar.tv

This patch series enables Tegra194's C5 controller which owns x16 slot in
p2972-0000 platform. C5 controller's PERST# and CLKREQ# are not configured as
output and bi-directional signals by default and hence they need to be
configured explicitly. Also, x16 slot's 3.3V and 12V supplies are controlled
through GPIOs and hence they need to be enabled through regulator framework.
This patch series adds required infrastructural support to address both the
aforementioned requirements.
Testing done on p2972-0000 platform
- Able to enumerate devices connected to x16 slot (owned by C5 controller)
- Enumerated device's functionality verified
- Suspend-Resume sequence is verified with device connected to x16 slot
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1;
	t=1567013340; bh=TvQY7ZhhxcvoKbpcEAh6qHqIQEasISWH+/X/STdQQk0=;
	h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer:
	 X-NVConfidentiality:MIME-Version:Content-Type;
	b=gVtBiB2IR+pKYaZJQ+f6BYQX23e2leD7q8vdf+vr0+12GlPQc/30oFhIDgzGmLr3W
	 81mgV2Pp3bLNf9oNOB7tnv+yjoJK+qPGAB0bQ+VPMKGOkpvVfFtN4K3D+TkNjEQnQc
	 eBs35Pzc7zQ3jso4y80hoeIGegqfu4qLvORCW3qsy7OuPxjELUpGKvJTozekRSZVw3
	 voa570Uvaiotu9UgYqdAyJe0S4iuNUmJ8eWJDZLb9zkj1gfWhuQaDxt6bOMK8pyr7e
	 SVhNP0p2cTOaV0ALtd16tvi7+vRmcV4uQeArl0l1XPwxwHkR6ShLYbyji3Zb+JxJGN
	 vrTsP917B385w==

V3:
* Addressed some more review comments from Andrew Murray and Thierry Reding

V2:
* Changed the order of patches in the series for easy merging
* Addressed review comments from Thierry Reding and Andrew Murray

Vidya Sagar (6):
  dt-bindings: PCI: tegra: Add sideband pins configuration entries
  dt-bindings: PCI: tegra: Add PCIe slot supplies regulator entries
  PCI: tegra: Add support to configure sideband pins
  PCI: tegra: Add support to enable slot regulators
  arm64: tegra: Add configuration for PCIe C5 sideband signals
  arm64: tegra: Add PCIe slot supply information in p2972-0000 platform

 .../bindings/pci/nvidia,tegra194-pcie.txt     | 16 ++++
 .../arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 24 +++++
 .../boot/dts/nvidia/tegra194-p2972-0000.dts   |  4 +-
 arch/arm64/boot/dts/nvidia/tegra194.dtsi      | 38 +++++++-
 drivers/pci/controller/dwc/pcie-tegra194.c    | 94 ++++++++++++++++++-
 5 files changed, 172 insertions(+), 4 deletions(-)

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/5] arm64: Use correct ll/sc atomic constraints
From: Andrew Murray @ 2019-08-28 16:42 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Peter Zijlstra, Catalin Marinas, Boqun Feng, Will Deacon,
	Ard.Biesheuvel, linux-arm-kernel
In-Reply-To: <20190828162409.GC42408@lakrids.cambridge.arm.com>

On Wed, Aug 28, 2019 at 05:24:09PM +0100, Mark Rutland wrote:
> On Wed, Aug 28, 2019 at 04:44:22PM +0100, Andrew Murray wrote:
> > On Wed, Aug 28, 2019 at 04:25:40PM +0100, Mark Rutland wrote:
> > > On Wed, Aug 28, 2019 at 02:01:19PM +0100, Andrew Murray wrote:
> > > > On Thu, Aug 22, 2019 at 04:32:23PM +0100, Mark Rutland wrote:
> > > > > On Mon, Aug 12, 2019 at 03:36:22PM +0100, Andrew Murray wrote:
> > > > > [...]
> > > > > 
> > > > > > -ATOMIC64_OPS(and, and)
> > > > > > -ATOMIC64_OPS(andnot, bic)
> > > > > > -ATOMIC64_OPS(or, orr)
> > > > > > -ATOMIC64_OPS(xor, eor)
> > > > > > +ATOMIC64_OPS(and, and, K)
> > > > > > +ATOMIC64_OPS(andnot, bic, )
> > > > > > +ATOMIC64_OPS(or, orr, K)
> > > > > > +ATOMIC64_OPS(xor, eor, K)
> > > > > 
> > > > > Shouldn't these be 'L'?
> > > > > 
> > > > > IIUC K is a subset of L, so if that's deliberate we should call that out
> > > > > explicitly...
> > > > 
> > > > Oooh yes that's wrong. I guess the atomic64_[and,or,xor] are rarely called
> > > > in the kernel which perhaps is why the compiler hasn't shouted at me.
> > > > 
> > > > Do you agree that the and, orr and eor should all be 'L' instead of 'K'?
> > > 
> > > Yes, I think all the 64-bit logical ops should all use 'L'.
> > 
> > With the exception of bic? I don't think there is an appropriate constraint
> > for this (it requires an 8 bit immediate).
> 
> The ARM ARM doesn't mention BIC (Immediate), and AFAICT that's an
> (undocumented?) alias for AND (Immediate) with a negated immediate.
> 
> Where did you find a description with an 8-bit immediate?
> 

I think it's a SIMD instruction, see C7.2.13 of ARM DDI 0487D or 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0802a/EOR_log_imm.html

> Regardless, yes, drop the 'L' there -- I can't find any suitable
> constraint either.

OK I'll drop it, thanks for the feedback.

Thanks,

Andrew Murray

> 
> Thanks,
> Mark.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 8/8] coresight: etm4x: docs: Additional documentation for ETM4x.
From: Mathieu Poirier @ 2019-08-28 16:36 UTC (permalink / raw)
  To: Mike Leach; +Cc: Coresight ML, linux-arm-kernel, Suzuki K. Poulose
In-Reply-To: <CAJ9a7VhU8P8BrT_UNbm=2W9CVjPpmqtkZ76TYw8Z8zzHQFraFw@mail.gmail.com>

On Wed, 28 Aug 2019 at 08:20, Mike Leach <mike.leach@linaro.org> wrote:
>
> Hi Mathieu,
>
> I assume you want the split to be ? :-
> 1. the update in Documentation/ARM/testing/sysfs-bus-coresight-devices-etm4x
> 2. the moving of coresight docs to their new common directory.
> 3. the addition of the new etm4x doc

Yes, that would be great.

>
> On Tue, 27 Aug 2019 at 23:34, Mathieu Poirier
> <mathieu.poirier@linaro.org> wrote:
> >
> > On Mon, Aug 19, 2019 at 09:57:20PM +0100, Mike Leach wrote:
> > > Update existing docs for new sysfs API features.
> > > Add new ETMv4 reference document for sysfs programming.
> > > Move coresight documentation to common directory.
> > >
> >
> > I also get the following warnings when adding the patch:
> >
> > $ git am 0008-coresight-etm4x-docs-Additional-documentation-for-ET.patch
> > Applying: coresight: etm4x: docs: Additional documentation for ETM4x.
> > .git/rebase-apply/patch:620: space before tab in indent.
> >                 bitfield up to 32 bits setting trace features.
> > .git/rebase-apply/patch:950: space before tab in indent.
> >                                     ; range comparator
> > .git/rebase-apply/patch:954: space before tab in indent.
> >                                     ; address comparator
> > .git/rebase-apply/patch:1057: new blank line at EOF.
> > +
> > warning: 4 lines add whitespace errors.
> >
>
> OK - I'll re-look at this, but don't recall seeing any errors myself
> & al cleared by checkpatch.

I didn't get any errors from checkpatch either.  I got these while
applying the patch.

>
> Regards
>
> Mike
>
>
> > > Signed-off-by: Mike Leach <mike.leach@linaro.org>
> > > ---
> > >  .../testing/sysfs-bus-coresight-devices-etm4x | 183 ++++---
> > >  .../{ => coresight}/coresight-cpu-debug.txt   |   0
> > >  .../coresight/coresight-etm4x-reference.txt   | 459 ++++++++++++++++++
> > >  .../trace/{ => coresight}/coresight.txt       |   0
> > >  MAINTAINERS                                   |   3 +-
> > >  5 files changed, 575 insertions(+), 70 deletions(-)
> > >  rename Documentation/trace/{ => coresight}/coresight-cpu-debug.txt (100%)
> > >  create mode 100644 Documentation/trace/coresight/coresight-etm4x-reference.txt
> > >  rename Documentation/trace/{ => coresight}/coresight.txt (100%)
> > >
> > > diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > index 36258bc1b473..112c50ae9986 100644
> > > --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> > > @@ -1,4 +1,4 @@
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/enable_source
> > > +What:                /sys/bus/coresight/devices/etm<N>/enable_source
> > >  Date:                April 2015
> > >  KernelVersion:  4.01
> > >  Contact:        Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -8,82 +8,82 @@ Description:        (RW) Enable/disable tracing on this specific trace entiry.
> > >               of coresight components linking the source to the sink is
> > >               configured and managed automatically by the coresight framework.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cpu
> > > +What:                /sys/bus/coresight/devices/etm<N>/cpu
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) The CPU this tracing entity is associated with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_pe_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_pe_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of PE comparator inputs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_addr_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_addr_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of address comparator pairs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_cntr
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_cntr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of counters that are available for
> > >               tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_ext_inp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_ext_inp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates how many external inputs are implemented.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/numcidc
> > > +What:                /sys/bus/coresight/devices/etm<N>/numcidc
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of Context ID comparators that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/numvmidc
> > > +What:                /sys/bus/coresight/devices/etm<N>/numvmidc
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of VMID comparators that are available
> > >               for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nrseqstate
> > > +What:                /sys/bus/coresight/devices/etm<N>/nrseqstate
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of sequencer states that are
> > >               implemented.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_resource
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_resource
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of resource selection pairs that are
> > >               available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/nr_ss_cmp
> > > +What:                /sys/bus/coresight/devices/etm<N>/nr_ss_cmp
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Indicates the number of single-shot comparator controls that
> > >               are available for tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/reset
> > > +What:                /sys/bus/coresight/devices/etm<N>/reset
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (W) Cancels all configuration on a trace unit and set it back
> > >               to its boot configuration.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mode
> > > +What:                /sys/bus/coresight/devices/etm<N>/mode
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -91,302 +91,349 @@ Description:    (RW) Controls various modes supported by this ETM, for example
> > >               P0 instruction tracing, branch broadcast, cycle counting and
> > >               context ID tracing.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/pe
> > > +What:                /sys/bus/coresight/devices/etm<N>/pe
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls which PE to trace.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event
> > > +What:                /sys/bus/coresight/devices/etm<N>/event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the tracing of arbitrary events from bank 0 to 3.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_instren
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_instren
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the behavior of the events in bank 0 to 3.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_ts
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_ts
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the insertion of global timestamps in the trace
> > >               streams.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/syncfreq
> > > +What:                /sys/bus/coresight/devices/etm<N>/syncfreq
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls how often trace synchronization requests occur.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cyc_threshold
> > > +What:                /sys/bus/coresight/devices/etm<N>/cyc_threshold
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Sets the threshold value for cycle counting.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/bb_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/bb_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls which regions in the memory map are enabled to
> > >               use branch broadcasting.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/event_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/event_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls instruction trace filtering.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/s_exlevel_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/s_exlevel_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) In Secure state, each bit controls whether instruction
> > >               tracing is enabled for the corresponding exception level.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ns_exlevel_vinst
> > > +What:                /sys/bus/coresight/devices/etm<N>/ns_exlevel_vinst
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) In non-secure state, each bit controls whether instruction
> > >               tracing is enabled for the corresponding exception level.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which address comparator or pair (of comparators) to
> > >               work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_instdatatype
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_instdatatype
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls what type of comparison the trace unit performs.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_single
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_single
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Used to setup single address comparator values.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/addr_range
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_range
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Used to setup address range comparator values.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which sequensor.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_state
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_state
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Use this to set, or read, the sequencer state.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_event
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Moves the sequencer state to a specific state.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/seq_reset_event
> > > +What:                /sys/bus/coresight/devices/etm<N>/seq_reset_event
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Moves the sequencer to state 0 when a programmed event
> > >               occurs.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which counter unit to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntrldvr
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntrldvr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) This sets or returns the reload count value of the
> > >               specific counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_val
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_val
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) This sets or returns the current count value of the
> > >                  specific counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/cntr_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/cntr_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the operation of the selected counter.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/res_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/res_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Select which resource selection unit to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/res_ctrl
> > > +What:                /sys/bus/coresight/devices/etm<N>/res_ctrl
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description:         (RW) Controls the selection of the resources in the trace unit.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Select which context ID comparator to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_pid
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_pid
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Get/Set the context ID comparator value to trigger on.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_masks
> > > +What:                /sys/bus/coresight/devices/etm<N>/ctxid_masks
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Mask for all 8 context ID comparator value
> > >               registers (if implemented).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_idx
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_idx
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Select which virtual machine ID comparator to work with.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_val
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_val
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Get/Set the virtual machine ID comparator value to
> > >               trigger on.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/vmid_masks
> > > +What:                /sys/bus/coresight/devices/etm<N>/vmid_masks
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (RW) Mask for all 8 virtual machine ID comparator value
> > >               registers (if implemented).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcoslsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_exlevel_s_ns
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Set the Exception Level matching bits for secure and
> > > +             non-secure exception levels.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/vinst_pe_cmp_start_stop
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the start stop control register for PE input
> > > +             comparators.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/addr_cmp_view
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (R) Print the current settings for the selected address
> > > +             comparator.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_idx
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Select the single shot control register to access.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_ctrl
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the selected single shot control register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_status
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (R) Print the current value of the selected single shot
> > > +             status register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/sshot_pe_ctrl
> > > +Date:                August 2019
> > > +KernelVersion:       5.4
> > > +Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > +Description: (RW) Access the selected single show PE comparator control
> > > +             register.
> > > +
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcoslsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the OS Lock Status Register (0x304).
> > >               The value it taken directly  from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdcr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpdcr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Power Down Control Register
> > >               (0x310).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpdsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpdsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Power Down Status Register
> > >               (0x314).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trclsr
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trclsr
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the SW Lock Status Register
> > >               (0xFB4).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcauthstatus
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcauthstatus
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Authentication Status Register
> > >               (0xFB8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevid
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcdevid
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Device ID Register
> > >               (0xFC8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcdevtype
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcdevtype
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Device Type Register
> > >               (0xFCC).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr0
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr0
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID0 Register
> > >               (0xFE0).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr1
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr1
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID1 Register
> > >               (0xFE4).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr2
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr2
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID2 Register
> > >               (0xFE8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcpidr3
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcpidr3
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the Peripheral ID3 Register
> > >               (0xFEC).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trcconfig
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trcconfig
> > >  Date:                February 2016
> > >  KernelVersion:       4.07
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the trace configuration register
> > >               (0x010) as currently set by SW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/mgmt/trctraceid
> > > +What:                /sys/bus/coresight/devices/etm<N>/mgmt/trctraceid
> > >  Date:                February 2016
> > >  KernelVersion:       4.07
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Print the content of the trace ID register (0x040).
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr0
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr0
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the tracing capabilities of the trace unit (0x1E0).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr1
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr1
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the tracing capabilities of the trace unit (0x1E4).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr2
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr2
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -394,7 +441,7 @@ Description:      (R) Returns the maximum size of the data value, data address,
> > >               VMID, context ID and instuction address in the trace unit
> > >               (0x1E8).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr3
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr3
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -403,42 +450,42 @@ Description:    (R) Returns the value associated with various resources
> > >               architecture specification for more details (0x1E8).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr4
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr4
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns how many resources the trace unit supports (0x1F0).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr5
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr5
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns how many resources the trace unit supports (0x1F4).
> > >               The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr8
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr8
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the maximum speculation depth of the instruction
> > >               trace stream. (0x180).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr9
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr9
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the number of P0 right-hand keys that the trace unit
> > >               can use (0x184).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr10
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr10
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > >  Description: (R) Returns the number of P1 right-hand keys that the trace unit
> > >               can use (0x188).  The value is taken directly from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr11
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr11
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -446,7 +493,7 @@ Description:      (R) Returns the number of special P1 right-hand keys that the
> > >               trace unit can use (0x18C).  The value is taken directly from
> > >               the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr12
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr12
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > @@ -454,7 +501,7 @@ Description:      (R) Returns the number of conditional P1 right-hand keys that
> > >               the trace unit can use (0x190).  The value is taken directly
> > >               from the HW.
> > >
> > > -What:                /sys/bus/coresight/devices/<memory_map>.etm/trcidr/trcidr13
> > > +What:                /sys/bus/coresight/devices/etm<N>/trcidr/trcidr13
> > >  Date:                April 2015
> > >  KernelVersion:       4.01
> > >  Contact:     Mathieu Poirier <mathieu.poirier@linaro.org>
> > > diff --git a/Documentation/trace/coresight-cpu-debug.txt b/Documentation/trace/coresight/coresight-cpu-debug.txt
> > > similarity index 100%
> > > rename from Documentation/trace/coresight-cpu-debug.txt
> > > rename to Documentation/trace/coresight/coresight-cpu-debug.txt
> > > diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.txt b/Documentation/trace/coresight/coresight-etm4x-reference.txt
> > > new file mode 100644
> > > index 000000000000..72e81bbbef43
> > > --- /dev/null
> > > +++ b/Documentation/trace/coresight/coresight-etm4x-reference.txt
> > > @@ -0,0 +1,459 @@
> > > +ETMv4 sysfs linux driver programming reference - v2.
> > > +====================================================
> > > +
> > > +Supplement to existing ETMv4 driver documentation.
> > > +
> > > +Sysfs files and directories
> > > +---------------------------
> > > +
> > > +Root: /sys/bus/coresight/devices/etm<N>
> > > +
> > > +
> > > +The following paragraphs explain the association between sysfs files and the
> > > +ETMv4 registers that they effect. Note the register names are given without
> > > +the ‘TRC’ prefix.
> > > +
> > > +File         : mode (rw)
> > > +Trace Registers      : {CONFIGR + others}
> > > +Notes                : Bit select trace features. See ‘mode’ section below. Bits
> > > +             in this will cause equivalent programming of trace config and
> > > +             other registers to enable the features requested.
> > > +Syntax & eg  : 'echo bitfield > mode'
> > > +                     bitfield up to 32 bits setting trace features.
> > > +Example              : $> echo 0x > mode
> > > +
> > > +File         : reset (wo)
> > > +Trace Registers      : All
> > > +Notes                : Reset all programming to trace nothing / no logic programmed.
> > > +Syntax               : 'echo 1 > reset'
> > > +
> > > +File         : enable_source (wo)
> > > +Trace Registers      : PRGCTLR, All hardware regs.
> > > +Notes                :  >0: Programs up the hardware with the current values held in
> > > +             the driver and enables trace.
> > > +             0: disable trace hardware.
> > > +Syntax               : 'echo 1 > enable_source'
> > > +
> > > +File         : cpu (ro)
> > > +Trace Registers      : None.
> > > +Notes                : CPU ID that this ETM is attached to.
> > > +Example              :$> cat cpu
> > > +             $> 0
> > > +
> > > +File         : addr_idx (rw)
> > > +Trace Registers      : None.
> > > +Notes                : Virtual register to index address comparator and range
> > > +             features. Set index for first of the pair in a range.
> > > +Syntax               : 'echo idx > addr_idx'
> > > +             Where idx <  nr_addr_cmp x 2
> > > +
> > > +File         : addr_range (rw)
> > > +Trace Registers      : ACVR[idx, idx+1], VIIECTLR
> > > +Notes                : Pair of addresses for a range selected by addr_idx. Include
> > > +             / exclude according to the optional parameter, or if omitted
> > > +             uses the current ‘mode’ setting. Select comparator range in
> > > +             control register. Error if index is odd value.
> > > +Depends              : mode, addr_idx
> > > +Syntax               : 'echo addr1 addr2 [exclude] > addr_range'
> > > +             Where addr1 and addr2 define the range and addr1 < addr2.
> > > +             Optional exclude value - 0 for include, 1 for exclude.
> > > +Example              : $> echo 0x0000 0x2000 0 > addr_range
> > > +
> > > +File         : addr_single (rw)
> > > +Trace Registers      : ACVR[idx]
> > > +Notes                : Set a single address comparator according to addr_idx. This
> > > +             is used if the address comparator is used as part of event
> > > +             generation logic etc.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_single'
> > > +
> > > +File         : addr_start (rw)
> > > +Trace Registers      : ACVR[idx], VISSCTLR
> > > +Notes                : Set a trace start address comparator according to addr_idx.
> > > +             Select comparator in control register.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_start'
> > > +
> > > +File         : addr_stop (rw)
> > > +Trace Registers      : ACVR[idx], VISSCTLR
> > > +Notes                : Set a trace stop address comparator according to addr_idx.
> > > +             Select comparator in control register.
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo addr1 > addr_stop'
> > > +
> > > +File         : addr_context (rw)
> > > +Trace Registers      : ACATR[idx,{6:4}]
> > > +Notes                : Link context ID comparator to address comparator addr_idx
> > > +Depends              : addr_idx.
> > > +Syntax               : 'echo ctxt_idx > addr_context'
> > > +             Where ctxt_idx is the index of the linked context id / vmid
> > > +             comparator.
> > > +
> > > +File         : addr_ctxtype (rw)
> > > +Trace Registers      : ACATR[idx,{3:2}]
> > > +Notes                : Input value string. Set type for linked context ID comparator
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo type > addr_ctxtype'
> > > +             Type one of {all, vmid, ctxid, none}
> > > +Example              : $> echo ctxid > addr_ctxtype
> > > +
> > > +File         : addr_exlevel_s_ns (rw)
> > > +Trace Registers      : ACATR[idx,{14:8}]
> > > +Notes                : Set the ELx secure and non-secure  matching bits for the
> > > +             selected address comparator
> > > +Depends              : addr_idx
> > > +Syntax               : 'echo val > addr_exlevel_s_ns'
> > > +             val is a 7 bit value for exception levels to exclude. Input
> > > +             value shifted to correct bits in register.
> > > +Example              : $> echo 0x4F > addr_exlevel_s_ns
> > > +
> > > +File         : addr_instdatatype (rw)
> > > +Trace Registers      : ACATR[idx,{1:0}]
> > > +Notes                : Set the comparator address type for matching. Driver only
> > > +             supports setting instruction address type.
> > > +Depends              : addr_idx
> > > +
> > > +File         : addr_cmp_view (ro)
> > > +Trace Registers      : ACVR[idx, idx+1], ACATR[idx], VIIECTLR
> > > +Notes                : Read the currently selected address comparator. If part of
> > > +             address range then display both addresses.
> > > +Depends              : addr_idx
> > > +Syntax               : 'cat addr_cmp_view'
> > > +Example              : $> cat addr_cmp_view
> > > +             addr_cmp[0] range 0x0 0xffffffffffffffff include ctrl(0x4b00)
> > > +
> > > +File         : nr_addr_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of address comparator pairs
> > > +
> > > +File         : sshot_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select  single shot register set.
> > > +
> > > +File         : sshot_ctrl (rw)
> > > +Trace Registers      : SSCCR[idx]
> > > +Notes                : Access a single shot comparator control register.
> > > +Depends              : sshot_idx
> > > +Syntax               : 'echo val > sshot_ctrl'
> > > +             Writes val into the selected control register.
> > > +
> > > +File         : sshot_status (ro)
> > > +Trace Registers      : SSCSR[idx]
> > > +Notes                : Read a single shot comparator status register
> > > +Depends              : sshot_idx
> > > +Syntax               : 'cat sshot_status'
> > > +             Read status.
> > > +Example              : $> cat sshot_status
> > > +             0x1
> > > +
> > > +File         : sshot_pe_ctrl (rw)
> > > +Trace Registers      : SSPCICR[idx]
> > > +Notes                : Access a single shot PE comparator input control register.
> > > +Depends              : sshot_idx
> > > +Syntax               : echo val > sshot_pe_ctrl
> > > +             Writes val into the selected control register.
> > > +
> > > +File         : ns_exlevel_vinst (rw)
> > > +Trace Registers      : VICTLR{23:20}
> > > +Notes                : Program non-secure exception level filters. Set / clear NS
> > > +             exception filter bits. Setting ‘1’ excludes trace from the
> > > +             exception level.
> > > +Syntax               : 'echo bitfield > ns_exlevel_viinst'
> > > +             Where bitfield contains bits to set clear for EL0 to EL2
> > > +Example              : %> echo 0x4 > ns_exlevel_viinst
> > > +             ; Exclude EL2 NS trace.
> > > +
> > > +File         : vinst_pe_cmp_start_stop (rw)
> > > +Trace Registers      : VIPCSSCTLR
> > > +Notes                : Access PE start stop comparator input control registers
> > > +
> > > +File         : bb_ctrl (rw)
> > > +Trace Registers      : BBCTLR
> > > +Notes                : Define ranges that Branch Broadcast will operate in.
> > > +             Default (0x0) is all addresses.
> > > +Depends              : BB enabled.
> > > +
> > > +File         : cyc_threshold (rw)
> > > +Trace Registers      : CCCTLR
> > > +Notes                : Set the threshold for which cycle counts will be emitted.
> > > +             Error if attempt to set below minimum defined in IDR3, masked
> > > +             to width of valid bits.
> > > +Depends              : CC enabled.
> > > +
> > > +File         : syncfreq (rw)
> > > +Trace Registers      : SYNCPR
> > > +Notes                : Set trace synchronisation period. Power of 2 value, 0 (off)
> > > +             or 8-20. Driver defaults to 12 (every 4096 bytes).
> > > +
> > > +File         : cntr_idx (rw)
> > > +Trace Registers      : none
> > > +Notes                : Select the counter to access
> > > +Syntax               : 'echo idx > cntr_idx'
> > > +             Where idx <  nr_cntr
> > > +
> > > +File         : cntr_ctrl (rw)
> > > +Trace Registers      : CNTCTLR[idx]
> > > +Notes                : Set counter control value
> > > +Depends              : cntr_idx
> > > +Syntax               : 'echo val > cntr_ctrl'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : cntrldvr (rw)
> > > +Trace Registers      : CNTRLDVR[idx]
> > > +Notes                : Set counter reload value
> > > +Depends              : cntr_idx
> > > +Syntax               : 'echo val > cntrldvr'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : nr_cntr (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of counters implemented.
> > > +
> > > +File         : ctxid_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select the context ID comparator to access
> > > +Syntax               : 'echo idx > ctxid_idx'
> > > +             Where idx <  numcidc
> > > +
> > > +File         : ctxid_pid (rw)
> > > +Trace Registers      : CIDCVR[idx]
> > > +Notes                : Set the context ID comparator value
> > > +Depends              : ctxid_idx
> > > +
> > > +File         : ctxid_masks (rw)
> > > +Trace Registers      : CIDCCTLR0, CIDCCTLR1, CIDCVR<0-7>
> > > +Notes                : Pair of values to set the byte masks for 1-8 context ID
> > > +             comparators. Automatically clears masked bytes to 0 in CID
> > > +             value registers.
> > > +Syntax               : 'echo m3m2m1m0 [m7m6m5m4] > ctxid_masks'
> > > +             32 bit values made up of mask bytes, where mN represents a
> > > +             byte mask value for Ctxt ID comparator N.
> > > +             Second value not required on systems that have fewer than 4
> > > +             context ID comparators
> > > +
> > > +File         : numcidc (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of Context ID comparators
> > > +
> > > +File         : vmid_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Select the VM ID comparator to access.
> > > +Syntax               : 'echo idx > vmid_idx'
> > > +             Where idx <  numvmidc
> > > +
> > > +File         : vmid_val (rw)
> > > +Trace Registers      : VMIDCVR[idx]
> > > +Notes                : Set the VM ID comparator value
> > > +Depends              : vmid_idx
> > > +
> > > +File         : vmid_masks (rw)
> > > +Trace Registers      : VMIDCCTLR0, VMIDCCTLR1, VMIDCVR<0-7>
> > > +Notes                : Pair of values to set the byte masks for 1-8 VM ID
> > > +             comparators. Automatically clears masked bytes to 0 in VMID
> > > +             value registers.
> > > +Syntax               : 'echo m3m2m1m0 [m7m6m5m4] > vmid_masks'
> > > +             Where mN represents a byte mask value for VMID comparator N.
> > > +             Second value not required on systems that have fewer than
> > > +             4 VMID comparators.
> > > +
> > > +File         : numvmidc (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of VMID comparators
> > > +
> > > +File         : res_idx (rw)
> > > +Trace Registers      : None.
> > > +Notes                : Select the resource selector control to access. Must be 2 or
> > > +             higher as selectors 0 and 1 are hardwired.
> > > +Syntax               : 'echo idx > res_idx'
> > > +             Where 2 <= idx <  nr_resource x 2
> > > +
> > > +File         : res_ctrl (rw)
> > > +Trace Registers      : RSCTLR[idx]
> > > +Notes                : Set resource selector control value. Value per ETMv4 spec.
> > > +Depends              : res_idx
> > > +Syntax               : 'echo val > res_cntr'
> > > +             Where val is per ETMv4 spec.
> > > +
> > > +File         : nr_resource (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of resource selector pairs
> > > +
> > > +File         : event (rw)
> > > +Trace Registers      : EVENTCTRL0R
> > > +Notes                : Set up to 4 implemented event fields.
> > > +Syntax               : 'echo ev3ev2ev1ev0 > event'
> > > +             Where evN is an 8 bit event field. Up to 4 event fields make up
> > > +             the 32bit input value. Number of valid fields implementation
> > > +             dependent defined in IDR0.
> > > +
> > > +File         : event_instren (rw)
> > > +Trace Registers      : EVENTCTRL1R
> > > +Notes                : Choose events which insert event packets into trace stream.
> > > +Depends              : EVENTCTRL0R
> > > +Syntax               : 'echo bitfield > event_instren'
> > > +             Where bitfield is up to 4 bits according to number of event
> > > +             fields.
> > > +
> > > +File         : event_ts (rw)
> > > +Trace Registers      : TSCTLR
> > > +Notes                : Set the event that will generate timestamp requests.
> > > +Depends              : TS activated
> > > +Syntax               : 'echo evfield > event_ts'
> > > +             Where evfield is an 8 bit event selector.
> > > +
> > > +File         : seq_idx (rw)
> > > +Trace Registers      : None
> > > +Notes                : Sequencer event register select - 0 to 2
> > > +
> > > +
> > > +File         : seq_state (rw)
> > > +Trace Registers      : SEQSTR
> > > +Notes                : Sequencer current state - 0 to 3.
> > > +
> > > +File         : seq_event (rw)
> > > +Trace Registers      : SEQEVR[idx]
> > > +Notes                : State transition event registers
> > > +Depends              : seq_idx
> > > +Syntax               : 'echo evBevF > seq_event'
> > > +             Where evBevF is a 16 bit value made up of two event selectors,
> > > +             evB - back, evF - forwards.
> > > +
> > > +File         : seq_reset_event (rw)
> > > +Trace Registers      : SEQRSTEVR
> > > +Notes                : Sequencer reset event
> > > +Syntax               : 'echo evfield > seq_reset_event'
> > > +             Where evfield is an 8 bit event selector.
> > > +
> > > +File         : nrseqstate (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of sequencer states (0 or 4)
> > > +
> > > +File         : nr_pe_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of PE comparator inputs
> > > +
> > > +File         : nr_ext_inp (ro)
> > > +Trace Registers      : From IDR5
> > > +Notes                : Number of external inputs
> > > +
> > > +File         : nr_ss_cmp (ro)
> > > +Trace Registers      : From IDR4
> > > +Notes                : Number of Single Shot control registers
> > > +
> > > +Note: When programming any address comparator the driver will tag the
> > > +comparator with a type used - i.e. RANGE, SINGLE, START, STOP. Once this tag
> > > +is set, then only the values can be changed using the same sysfs file / type
> > > +used to program it.
> > > +
> > > +Thus:-
> > > +% echo 0 > addr_idx              ; select address comparator 0
> > > +% echo 0x1000 0x5000 0 > addr_range ; set address range on comparators 0 and 1.
> > > +% echo 0x2000 > addr_start       ; this will error as comparator 0 is a
> > > +                                         ; range comparator
> > > +% echo 2 > addr_idx              ; select address comparator 2
> > > +% echo 0x2000 > addr_start       ; this is OK as comparator 2 is unused,
> > > +% echo 0x3000 > addr_stop        ; this will error as comparator 2 a start
> > > +                                         ; address comparator
> > > +% echo 2 > addr_idx              ; select address comparator 3
> > > +% echo 0x3000 > addr_stop        ; this is OK
> > > +
> > > +To remove programming on all the comparators (and all the other hardware) use
> > > +the reset parameter:
> > > +
> > > +% echo 1 > reset
> > > +
> > > +The ‘mode’ sysfs parameter.
> > > +---------------------------
> > > +
> > > +This is a bitfield selection parameter that sets the overall trace mode for the
> > > +ETM. The table below describes the bits, using the defines from the driver
> > > +source file, along with a description of the feature these represent. Many
> > > +features are optional and therefore dependent on implementation in the
> > > +hardware.
> > > +
> > > +Bit assignements shown below:-
> > > +
> > > +bit (0)          : #define ETM_MODE_EXCLUDE
> > > +description : This is the default value for the include / exclude function when
> > > +           setting address ranges. Set 1 for exclude range. When the mode
> > > +           parameter is set this value is applied to the currently indexed
> > > +           address range.
> > > +
> > > +bit (4)          : #define ETM_MODE_BB
> > > +description : Set to enable branch broadcast if supported in hardware [IDR0].
> > > +
> > > +bit (5)          : #define ETMv4_MODE_CYCACC
> > > +description : Set to enable cycle accurate trace if supported [IDR0].
> > > +
> > > +bit (6)          : ETMv4_MODE_CTXID
> > > +description : Set to enable context ID tracing if supported in hardware [IDR2].
> > > +
> > > +bit (7)          : ETM_MODE_VMID
> > > +description : Set to enable virtual machine ID tracing if supported [IDR2].
> > > +
> > > +bit (11)    : ETMv4_MODE_TIMESTAMP
> > > +description : Set to enable timestamp generation if supported [IDR0].
> > > +
> > > +bit (12)    : ETM_MODE_RETURNSTACK
> > > +description : Set to enable trace return stack use if supported [IDR0].
> > > +
> > > +bit (13-14) : ETM_MODE_QELEM(val)
> > > +description : ‘val’ determines level of Q element support enabled if
> > > +         implemented by the ETM [IDR0]
> > > +
> > > +bit (19)    : ETM_MODE_ATB_TRIGGER
> > > +description : Set to enable the ATBTRIGGER bit in the event control register
> > > +         [EVENTCTLR1] if supported [IDR5].
> > > +
> > > +bit (20)    : ETM_MODE_LPOVERRIDE
> > > +description : Set to enable the LPOVERRIDE bit in the event control register
> > > +         [EVENTCTLR1], if supported [IDR5].
> > > +
> > > +bit (21)    : ETM_MODE_ISTALL_EN
> > > +description : Set to enable the ISTALL bit in the stall control register
> > > +         [STALLCTLR]
> > > +
> > > +bit (23)    : ETM_MODE_INSTPRIO
> > > +description : Set to enable the INSTPRIORITY bit in the stall control register
> > > +         [STALLCTLR] , if supported [IDR0].
> > > +
> > > +bit (24)    : ETM_MODE_NOOVERFLOW
> > > +description : Set to enable the NOOVERFLOW bit in the stall control register
> > > +         [STALLCTLR], if supported [IDR3].
> > > +
> > > +bit (25)    : ETM_MODE_TRACE_RESET
> > > +description : Set to enable the TRCRESET bit in the viewinst control register
> > > +         [VICTLR] , if supported [IDR3].
> > > +
> > > +bit (26)    : ETM_MODE_TRACE_ERR
> > > +description : Set to enable the TRCCTRL bit in the viewinst control register
> > > +         [VICTLR].
> > > +
> > > +bit (27)    : ETM_MODE_VIEWINST_STARTSTOP
> > > +description : Set the initial state value of the ViewInst start / stop logic
> > > +         in the viewinst control register [VICTLR]
> > > +
> > > +bit (30)    : ETM_MODE_EXCL_KERN
> > > +description : Set default trace setup to exclude kernel mode trace (see note a)
> > > +
> > > +bit (31)    : ETM_MODE_EXCL_USER
> > > +description : Set default trace setup to exclude user space trace (see note a)
> > > +
> > > +Note a) On startup the ETM is programmed to trace the complete address space
> > > +using address range comparator 0. ‘mode’ bits 30 / 31 modify this setting to
> > > +set EL exclude bits for NS state in either user space (EL0) or kernel space
> > > +(EL1) in the address range comparator. (the default setting excludes all
> > > +secure EL, and NS EL2)
> > > +
> > > +Once the reset parameter has been used, and/or custom programming has been
> > > +implemented - using these bits will result in the EL bits for address
> > > +comparator 0 being set in the same way.
> > > +
> > > +Note b) Bits 2-3, 8-10, 15-16, 18, 22, control features that only work with
> > > +data trace. As A profile data trace is architecturally prohibited in ETMv4,
> > > +these have been omitted here. Possible uses could be where a kernel has
> > > +support for control of R or M profile infrastructure as part of a heterogeneous
> > > +system.
> > > +
> > > +Bits 17, 28-29 are unused.
> > > +
> > > diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight/coresight.txt
> > > similarity index 100%
> > > rename from Documentation/trace/coresight.txt
> > > rename to Documentation/trace/coresight/coresight.txt
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 783569e3c4b4..777b77fde29b 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -1582,8 +1582,7 @@ R:      Suzuki K Poulose <suzuki.poulose@arm.com>
> > >  L:   linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
> > >  S:   Maintained
> > >  F:   drivers/hwtracing/coresight/*
> > > -F:   Documentation/trace/coresight.txt
> > > -F:   Documentation/trace/coresight-cpu-debug.txt
> > > +F:   Documentation/trace/coresight/*
> > >  F:   Documentation/devicetree/bindings/arm/coresight.txt
> > >  F:   Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt
> > >  F:   Documentation/ABI/testing/sysfs-bus-coresight-devices-*
> > > --
> > > 2.17.1
> > >
>
>
>
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox