summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/vmlinux.lds.S
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.vnet.ibm.com>2017-10-12 13:01:47 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-10-18 14:11:29 +0200
commit686140a1a9c41d85a4212a1c26d671139b76404b (patch)
tree2d19e98601a9d9855f7eac6cca6cb364f5a9d650 /arch/s390/kernel/vmlinux.lds.S
parent76b3b62ade4baa13b270bafb96be730ebff913f0 (diff)
downloadlinux-686140a1a9c41d85a4212a1c26d671139b76404b.tar.gz
linux-686140a1a9c41d85a4212a1c26d671139b76404b.tar.bz2
linux-686140a1a9c41d85a4212a1c26d671139b76404b.zip
s390: introduce CPU alternatives
Implement CPU alternatives, which allows to optionally patch newer instructions at runtime, based on CPU facilities availability. A new kernel boot parameter "noaltinstr" disables patching. Current implementation is derived from x86 alternatives. Although ideal instructions padding (when altinstr is longer then oldinstr) is added at compile time, and no oldinstr nops optimization has to be done at runtime. Also couple of compile time sanity checks are done: 1. oldinstr and altinstr must be <= 254 bytes long, 2. oldinstr and altinstr must not have an odd length. alternative(oldinstr, altinstr, facility); alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2); Both compile time and runtime padding consists of either 6/4/2 bytes nop or a jump (brcl) + 2 bytes nop filler if padding is longer then 6 bytes. .altinstructions and .altinstr_replacement sections are part of __init_begin : __init_end region and are freed after initialization. Signed-off-by: Vasily Gorbik <gor@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/vmlinux.lds.S')
-rw-r--r--arch/s390/kernel/vmlinux.lds.S23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 6e2c42bd1c3b..7c9fcf7cb43d 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -104,6 +104,29 @@ SECTIONS
EXIT_DATA
}
+ /*
+ * struct alt_inst entries. From the header (alternative.h):
+ * "Alternative instructions for different CPU types or capabilities"
+ * Think locking instructions on spinlocks.
+ * Note, that it is a part of __init region.
+ */
+ . = ALIGN(8);
+ .altinstructions : {
+ __alt_instructions = .;
+ *(.altinstructions)
+ __alt_instructions_end = .;
+ }
+
+ /*
+ * And here are the replacement instructions. The linker sticks
+ * them as binary blobs. The .altinstructions has enough data to
+ * get the address and the length of them to patch the kernel safely.
+ * Note, that it is a part of __init region.
+ */
+ .altinstr_replacement : {
+ *(.altinstr_replacement)
+ }
+
/* early.c uses stsi, which requires page aligned data. */
. = ALIGN(PAGE_SIZE);
INIT_DATA_SECTION(0x100)