summaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorMartin Schwidefsky2019-05-17 12:50:43 +0200
committerHeiko Carstens2019-06-04 15:03:12 +0200
commita646ef398e72a2ac40bea974808ffcf1bea4e7f4 (patch)
tree6799167289a134b5c6f7c3d4cf4e1e52165f46b4 /arch/s390/mm
parentLinux 5.2-rc3 (diff)
downloadkernel-qcow2-linux-a646ef398e72a2ac40bea974808ffcf1bea4e7f4.tar.gz
kernel-qcow2-linux-a646ef398e72a2ac40bea974808ffcf1bea4e7f4.tar.xz
kernel-qcow2-linux-a646ef398e72a2ac40bea974808ffcf1bea4e7f4.zip
s390/jump_label: replace stop_machine with smp_call_function
The use of stop_machine to replace the mask bits of the jump label branch is a very heavy-weight operation. This is in fact not necessary, the mask of the branch can simply be updated, followed by a signal processor to all the other CPUs to force them to pick up the modified instruction. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [heiko.carstens@de.ibm.com]: Change jump_label_make_nop() so we get brcl 0,offset instead of brcl 0,0. This makes sure that only the mask part of the instruction gets changed when updated. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/maccess.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c
index 818deeb1ebc3..1864a8bb9622 100644
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -52,21 +52,22 @@ static notrace long s390_kernel_write_odd(void *dst, const void *src, size_t siz
* Therefore we have a read-modify-write sequence: the function reads eight
* bytes from destination at an eight byte boundary, modifies the bytes
* requested and writes the result back in a loop.
- *
- * Note: this means that this function may not be called concurrently on
- * several cpus with overlapping words, since this may potentially
- * cause data corruption.
*/
+static DEFINE_SPINLOCK(s390_kernel_write_lock);
+
void notrace s390_kernel_write(void *dst, const void *src, size_t size)
{
+ unsigned long flags;
long copied;
+ spin_lock_irqsave(&s390_kernel_write_lock, flags);
while (size) {
copied = s390_kernel_write_odd(dst, src, size);
dst += copied;
src += copied;
size -= copied;
}
+ spin_unlock_irqrestore(&s390_kernel_write_lock, flags);
}
static int __memcpy_real(void *dest, void *src, size_t count)