Discussion:
Question on "Using deprecated CP15 barrier instruction".
s***@comcast.net
2016-09-05 15:10:27 UTC
Permalink
Hi,

For reference, the following questions refer to a Linux 3.10 aarch64 kernel (ARMv8, ARMv8-A) compiled with Linaro 5.3-2016.02 (5.3-2016.02 arm64 CROSS_COMPILE and 5.3-2016.02 armhf CROSS32CC cross compiled from x86_64). This Linux kernel compile requires the full 64-bit tool chain plus the 32-bit gcc.

There is a Linux kernel file "arch/arm64/kernel/deprecated.c". Within that file is a block of code which is apparently designed to detect some sort of older obsolete 32-bit code. Specifically, the warning message is "Using deprecated CP15 barrier instruction". I wouldn't think that this kernel, when compiled with such a recent compiler, would ever introduce CP15 barrier code (from what I see barrier code was deprecated in ARMv7 and used to deal with obsolete ARMv6 code). Is there any chance the 32-bit 5.3 gcc would still generate CP15 barrier code?

Although this kernel and "most" modules are built with Linaro 5.3 I'd like to be able to narrow the cause down to existing binary modules not compiled with the 5.3 Linaro. If I can guarantee 5.3 32-bit gcc does not produce the CP15 barrier instruction then I'll know it is in pre-built binary modules. Can anyone tell me if C code compiled from Linaro version 5.3 32-bit gcc code would ever contain CP15 instructions?

Thanks!
s***@comcast.net
2016-09-05 18:05:52 UTC
Permalink
What I need to confirm is if the Linaro 5.3 would generate such code from a normal block of C without any kind of asm in it? Detecting the code is part of the kernel...I need to figure out where it was generated. Is Linaro 5.3 going to generate such code without explicitly writing it in?

----- Original Message -----From: Andrew Pinski <***@cavium.com>To: ***@comcast.net, Linaro Toolchain Mailman List <linaro-***@lists.linaro.org>Sent: Mon, 05 Sep 2016 17:21:24 -0000 (UTC)Subject: RE: Question on "Using deprecated CP15 barrier instruction".


Simple answer is yes. There are a lot of assembly out there and someone (seen it in the past) could have used this barrier method in their code and not really thought it was going to change in the future.

Thanks,
Andrew

From: linaro-toolchain [mailto:linaro-toolchain-***@lists.linaro.org]On Behalf Of ***@comcast.netSent: Monday, September 5, 2016 8:10 AMTo: Linaro Toolchain Mailman List <linaro-***@lists.linaro.org>Subject: Question on "Using deprecated CP15 barrier instruction".


Hi,





For reference, the following questions refer to a Linux 3.10 aarch64 kernel (ARMv8, ARMv8-A) compiled with Linaro5.3-2016.02 (5.3-2016.02 arm64 CROSS_COMPILE and 5.3-2016.02 armhf CROSS32CC cross compiled from x86_64). This Linux kernel compile requires the full 64-bit tool chain plus the 32-bit gcc.





There is a Linux kernel file "arch/arm64/kernel/deprecated.c". Within that file is a block of code which is apparently designed to detect some sort of older obsolete 32-bit code. Specifically, the warning message is "Using deprecated CP15 barrier instruction". I wouldn't think that this kernel, when compiled with such a recent compiler, would ever introduce CP15 barrier code (from what I see barrier code was deprecated in ARMv7 and used to deal with obsolete ARMv6 code). Is there any chance the 32-bit 5.3 gcc would still generate CP15 barrier code?





Although this kernel and "most" modules are built with Linaro 5.3 I'd like to be able to narrow the cause down to existing binary modules not compiled with the 5.3 Linaro. If I can guarantee 5.3 32-bit gcc does not produce the CP15 barrier instruction then I'll know it is in pre-built binary modules. Can anyone tell me if C code compiled from Linaro version 5.3 32-bit gcc code would ever contain CP15 instructions?





Thanks!
Renato Golin
2016-09-05 19:16:39 UTC
Permalink
Post by s***@comcast.net
What I need to confirm is if the Linaro 5.3 would generate such code from a
normal block of C without any kind of asm in it? Detecting the code is part
of the kernel...I need to figure out where it was generated. Is Linaro 5.3
going to generate such code without explicitly writing it in?
Hi,

I could be wrong, but it would be very weird if the compiler generated
co-processor code from C sources. Those instructions were only created
to cope with "unknown extensions", even though they god used by a
number of known ones. Unless, of course, they were in inline assembly,
in which case it's not really the compiler's output, but it will "come
from C code".

It should be pretty easy to grep for asm/cp15 inline asm (or asm
files) in a source three, though, so you can know if a project will
emit them or not without looking at the compiler.

cheers,
--renato
Jim Wilson
2016-09-05 21:20:07 UTC
Permalink
Post by s***@comcast.net
There is a Linux kernel file "arch/arm64/kernel/deprecated.c". Within that
file is a block of code which is apparently designed to detect some sort of
older obsolete 32-bit code. Specifically, the warning message is "Using
deprecated CP15 barrier instruction".
I assume this is the same file as armv8_deprecated.c in the linux 4.0
sources I have. The file provides code to emulate deprecated
instructions. You can emulate a deprecated instruction if you catch
the illegal instruction trap that was generated, and then call some
emulation code instead of sending a signal to the program. The
emulation code prints a warning to let you know that you have some
very old code that really should be re-compiled. That is the point of
the emulation. it isn't to handle any code generated by the current
compiler for current targets, but rather code generated by an old
compiler or for old targets that is using instructions that have since
been deprecated.

It appears that you need to use an armv6 compiler to get the cp15
barrier instruction, which was deprecated in favor of the new dmb/dsb
instructions in armv7.

Since these are memory synchronization barriers, you can get them from
C code, but only if you are doing something special, like calling the
old sync built-ins or the new atomic built-ins, or using a compiler
feature that will cause these builtins to be called automatically such
as a feature that uses thread support or coroutines or some similar
feature.

There is no synchronization support in gcc-4.3. Looking at the
gcc-4.4 arm support, I see that there are two special instructions for
getting memory synchronization support from the kernel.
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
It appears that reading from a protected memory location is somehow
triggering the kernel support. In gcc-4.7, the sync intrinsics were
rewritten, and here I see that gcc is now emitting dmb for armv7 and a
cp15 barrier for armv6. The current support is the same.

So you can get a cp15 barrier from the current compiler, but you need
to compile for armv6, and directly or indirectly call the
synchronization and/or atomic builtins.

Jim
Peter Maydell
2016-09-05 22:10:46 UTC
Permalink
Post by Jim Wilson
Post by s***@comcast.net
There is a Linux kernel file "arch/arm64/kernel/deprecated.c". Within that
file is a block of code which is apparently designed to detect some sort of
older obsolete 32-bit code. Specifically, the warning message is "Using
deprecated CP15 barrier instruction".
I assume this is the same file as armv8_deprecated.c in the linux 4.0
sources I have. The file provides code to emulate deprecated
instructions. You can emulate a deprecated instruction if you catch
the illegal instruction trap that was generated, and then call some
emulation code instead of sending a signal to the program. The
emulation code prints a warning to let you know that you have some
very old code that really should be re-compiled. That is the point of
the emulation. it isn't to handle any code generated by the current
compiler for current targets, but rather code generated by an old
compiler or for old targets that is using instructions that have since
been deprecated.
In particular, this emulation is for handling occurrences of
these old barrier operations in *userspace binaries*. In your
initial email you write:

# Although this kernel and "most" modules are built with Linaro 5.3
# I'd like to be able to narrow the cause down to existing binary
# modules not compiled with the 5.3 Linaro. If I can guarantee 5.3
# 32-bit gcc does not produce the CP15 barrier instruction then
# I'll know it is in pre-built binary modules.

but this code will not handle any cp15 barriers in kernel code
(modules or otherwise). If the CPU doesn't support the cp15
barriers then trying to execute them will result in an Oops
or panic. So the symptoms you're seeing are nothing to do with the
binary kernel modules or the compiler version you're using to
build the kernel.

The thing you need to recompile is not your kernel but whatever
old userspace code you're running. (Or don't bother, and put up
with the poor performance and the warning messages. The code
will still work fine.)
Post by Jim Wilson
There is no synchronization support in gcc-4.3. Looking at the
gcc-4.4 arm support, I see that there are two special instructions for
getting memory synchronization support from the kernel.
#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
It appears that reading from a protected memory location is somehow
triggering the kernel support.
(A point of detail only) This is a function pointer to be called,
not a data location to be read. It's in the kernel user helpers
page as documented here:
https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
(Since the kernel knows what host CPU it's on it can put the
right kind of barrier insn in the function in the helper page.
So the compiler can use this if it's not already compiling for a
sufficiently new CPU that it knows what kind of barriers it supports.)

thanks
-- PMM

Loading...