History log of /linux-master/arch/arm/lib/copy_template.S
Revision Date Author Comments
# ba999a04 03-Oct-2021 Ard Biesheuvel <ardb@kernel.org>

ARM: memcpy: use frame pointer as unwind anchor

The memcpy template is a bit unusual in the way it manages the stack
pointer: depending on the execution path through the function, the SP
assumes different values as different subsets of the register file are
preserved and restored again. This is problematic when it comes to EHABI
unwind info, as it is not instruction accurate, and does not allow
tracking the SP value as it changes.

Commit 279f487e0b471 ("ARM: 8225/1: Add unwinding support for memory
copy functions") addressed this by carving up the function in different
chunks as far as the unwinder is concerned, and keeping a set of unwind
directives for each of them, each corresponding with the state of the
stack pointer during execution of the chunk in question. This not only
duplicates unwind info unnecessarily, but it also complicates unwinding
the stack upon overflow.

Instead, let's do what the compiler does when the SP is updated halfway
through a function, which is to use a frame pointer and emit the
appropriate unwind directives to communicate this to the unwinder.

Note that Thumb-2 uses R7 for this, while ARM uses R11 aka FP. So let's
avoid touching R7 in the body of the template, so that Thumb-2 can use
it as the frame pointer. R11 was not modified in the first place.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Keith Packard <keithpac@amazon.com>
Tested-by: Marc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M


# d2912cb1 04-Jun-2019 Thomas Gleixner <tglx@linutronix.de>

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500

Based on 2 normalized pattern(s):

this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation

this program is free software you can redistribute it and or modify
it under the terms of the gnu general public license version 2 as
published by the free software foundation #

extracted by the scancode license scanner the SPDX license identifier

GPL-2.0-only

has been chosen to replace the boilerplate/reference in 4122 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Enrico Weigelt <info@metux.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190604081206.933168790@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# e44fc388 17-Feb-2019 Stefan Agner <stefan@agner.ch>

ARM: 8844/1: use unified assembler in assembly files

Use unified assembler syntax (UAL) in assembly files. Divided
syntax is considered deprecated. This will also allow to build
the kernel using LLVM's integrated assembler.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>


# baf2df8e 24-Jan-2019 Stefan Agner <stefan@agner.ch>

ARM: 8827/1: fix argument count to match macro definition

The macro str8w takes 10 arguments, abort being the 10th. In this
particular instantiation the abort argument is passed as 11th
argument leading to an error when using LLVM's integrated
assembler:
<instantiation>:46:47: error: too many positional arguments
str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
^
arch/arm/lib/copy_template.S:277:5: note: while in macro instantiation
18: forward_copy_shift pull=24 push=8
^

The argument is not used in the macro hence this does not change
code generation.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>


# 279f487e 26-Nov-2014 Lin Yongting <linyongting@gmail.com>

ARM: 8225/1: Add unwinding support for memory copy functions

The memory copy functions(memcpy, __copy_from_user, __copy_to_user)
never had unwinding annotations added. Currently, when accessing
invalid pointer by these functions occurs the backtrace shown will
stop at these functions or some completely unrelated function.
Add unwinding annotations in hopes of getting a more useful backtrace
in following cases:
1. die on accessing invalid pointer by these functions
2. kprobe trapped at any instruction within these functions
3. interrupted at any instruction within these functions

Signed-off-by: Lin Yongting <linyongting@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>


# d98b90ea 25-Feb-2014 Victor Kamensky <victor.kamensky@linaro.org>

ARM: 7990/1: asm: rename logical shift macros push pull into lspush lspull

Renames logical shift macros, 'push' and 'pull', defined in
arch/arm/include/asm/assembler.h, into 'lspush' and 'lspull'.
That eliminates name conflict between 'push' logical shift macro
and 'push' instruction mnemonic. That allows assembler.h to be
included in .S files that use 'push' instruction.

Suggested-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>


# 8b592783 23-Jul-2009 Catalin Marinas <catalin.marinas@arm.com>

Thumb-2: Implement the unified arch/arm/lib functions

This patch adds the ARM/Thumb-2 unified support for the arch/arm/lib/*
files.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>


# 2239aff6 30-Mar-2008 Nicolas Pitre <nico@cam.org>

[ARM] cache align destination pointer when copying memory for some processors

The implementation for memory copy functions on ARM had a (disabled)
provision for aligning the source pointer before loading registers with
data. Turns out that aligning the _destination_ pointer is much more
useful, as the read side is already sufficiently helped with the use of
preload.

So this changes the definition of the CALGN() macro to target the
destination pointer instead, and turns it on for Feroceon processors
where the gain is very noticeable.

Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>


# 7f927fcc 28-Mar-2006 Alexey Dobriyan <adobriyan@gmail.com>

[PATCH] Typo fixes

Fix a lot of typos. Eyeballed by jmc@ in OpenBSD.

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>


# 75494230 01-Nov-2005 Nicolas Pitre <nico@cam.org>

[ARM] 2947/1: copy template with new memcpy/memmove

Patch from Nicolas Pitre

This patch provides a new implementation for optimized memory copy
functions on ARM. It is made of two levels: a template that consists of
the core copy code and separate files that define macros to be used with
the core code depending on the type of copy needed. This allows for best
performances while sharing the same core for implementing memcpy(),
copy_from_user() and copy_to_user() for instance.

Two reasons for this work:

1) the current copy_to_user/copy_from_user implementation assumes no
task switch will ever occur in the middle of each copied page making
it completely unsafe with CONFIG_PREEMPT=y.

2) current copy implementations are measurably suboptimal and optimizing
different implementations separately is a pain and more opportunities
for bugs.

The reason for (1) is the fact that copy inside user pages are performed
with the ldm instruction which has no mean for testing user protections
and could possibly race with process preemption bypassing the COW mechanism
for example. This is a longstanding issue that we said ought to be fixed
for about two years now. The solution is to substitute those ldm insns
with a series of ldrt or strt insns to enforce user memory protection.
At least on StrongARM and XScale cores the ldm is not faster than the
equivalent ldr/str insns with a warm i-cache so there is no measurable
performance degradation with that change. The fact that the copy code is
a template makes it pretty easy to reuse the same core code as for memcpy
and benefit from the same performance optimizations.

Now (2) is best demonstrated with actual throughput measurements.
First, here is a summary of memcopy tests performed on a StrongARM core:

PTR alignment buffer size kernel version this version
------------------------------------------------------------
aligned 32 59.73 107.43
unaligned 32 61.31 74.72
aligned 100 132.47 136.15
unaligned 100 103.84 123.76
aligned 4096 130.67 130.80
unaligned 4096 130.68 130.64
aligned 1048576 68.03 68.18
unaligned 1048576 68.03 68.18

The buffer size is in bytes and the measured speed in MB/s. The copy
was performed repeatedly with given buffer and throughput averaged over
3 seconds.

Here we can see that the current kernel version has a higher entry cost
that shows up with small buffers. As buffer size grows both implementation
converge to the same throughput.

Now here's the exact same test performed on an XScale core (PXA255):

PTR alignment buffer size kernel version this version
------------------------------------------------------------
aligned 32 46.99 77.58
unaligned 32 53.61 59.59
aligned 100 107.19 136.59
unaligned 100 83.61 97.58
aligned 4096 129.13 129.98
unaligned 4096 128.36 128.53
aligned 1048576 53.76 59.41
unaligned 1048576 33.67 56.96

Again we can see the entry setup cost being higher for the current kernel
before getting to the main copy loop. Then throughput results converge
as long as the buffer remains in the cache. Then the 1MB case shows more
differences probably due to better pld placement and/or less instruction
interlocks in this proposed implementation.

Disclaimer: The PXA system was running with slower clocks than the
StrongARM system so trying to infer any conclusion by comparing those
separate sets of results side by side would be completely inappropriate.

So... What this patch does is to replace both memcpy and memmove with
an implementation based on the provided copy code template. The memmove
code is kept separate since it is used only if the memory areas involved
do overlap in which case the code is a transposition of the template but
with the copy occurring in the opposite direction (trying to fit that
mode into the template turned it into a mess not worth it for memmove
alone). And obviously both memcpy and memmove were tested with all kinds
of pointer alignments and buffer sizes to exercise all code paths for
correctness.

The next patch will provide the now trivial replacement implementation
copy_to_user and copy_from_user.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>