2017-12-04 10:39:38 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
#ifndef _ASM_S390_ALTERNATIVE_H
|
|
|
|
#define _ASM_S390_ALTERNATIVE_H
|
|
|
|
|
2024-07-16 13:50:53 +02:00
|
|
|
/*
|
|
|
|
* Each alternative comes with a 32 bit feature field:
|
|
|
|
* union {
|
|
|
|
* u32 feature;
|
|
|
|
* struct {
|
|
|
|
* u32 ctx : 4;
|
|
|
|
* u32 type : 8;
|
|
|
|
* u32 data : 20;
|
|
|
|
* };
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* @ctx is a bitfield, where only one bit must be set. Each bit defines
|
|
|
|
* in which context an alternative is supposed to be applied to the
|
|
|
|
* kernel image:
|
|
|
|
*
|
|
|
|
* - from the decompressor before the kernel itself is executed
|
|
|
|
* - from early kernel code from within the kernel
|
|
|
|
*
|
|
|
|
* @type is a number which defines the type and with that the type
|
|
|
|
* specific alternative patching.
|
|
|
|
*
|
|
|
|
* @data is additional type specific information which defines if an
|
|
|
|
* alternative should be applied.
|
|
|
|
*/
|
|
|
|
|
2024-07-16 13:50:54 +02:00
|
|
|
#define ALT_CTX_EARLY 1
|
|
|
|
#define ALT_CTX_LATE 2
|
|
|
|
#define ALT_CTX_ALL (ALT_CTX_EARLY | ALT_CTX_LATE)
|
2024-07-16 13:50:53 +02:00
|
|
|
|
2024-07-16 13:50:56 +02:00
|
|
|
#define ALT_TYPE_FACILITY 0
|
|
|
|
#define ALT_TYPE_SPEC 1
|
s390: Add infrastructure to patch lowcore accesses
The s390 architecture defines two special per-CPU data pages
called the "prefix area". In s390-linux terminology this is usually
called "lowcore". This memory area contains system configuration
data like old/new PSW's for system call/interrupt/machine check
handlers and lots of other data. It is normally mapped to logical
address 0. This area can only be accessed when in supervisor mode.
This means that kernel code can dereference NULL pointers, because
accesses to address 0 are allowed. Parts of lowcore can be write
protected, but read accesses and write accesses outside of the write
protected areas are not caught.
To remove this limitation for debugging and testing, remap lowcore to
another address and define a function get_lowcore() which simply
returns the address where lowcore is mapped at. This would normally
introduce a pointer dereference (=memory read). As lowcore is used
for several very often used variables, add code to patch this function
during runtime, so we avoid the memory reads.
For C code get_lowcore() has to be used, for assembly code it is
the GET_LC macro. When using this macro/function a reference is added
to alternative patching. All these locations will be patched to the
actual lowcore location when the kernel is booted or a module is loaded.
To make debugging/bisecting problems easier, this patch adds all the
infrastructure but the lowcore address is still hardwired to 0. This
way the code can be converted on a per function basis, and the
functionality is enabled in a patch after all the functions have
been converted.
Note that this requires at least z16 because the old lpsw instruction
only allowed a 12 bit displacement. z16 introduced lpswey which allows
20 bits (signed), so the lowcore can effectively be mapped from
address 0 - 0x7e000. To use 0x7e000 as address, a 6 byte lgfi
instruction would have to be used in the alternative. To save two
bytes, llilh can be used, but this only allows to set bits 16-31 of
the address. In order to use the llilh instruction, use 0x70000 as
alternative lowcore address. This is still large enough to catch
NULL pointer dereferences into large arrays.
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2024-07-22 15:41:14 +02:00
|
|
|
#define ALT_TYPE_LOWCORE 2
|
2024-07-16 13:50:53 +02:00
|
|
|
|
|
|
|
#define ALT_DATA_SHIFT 0
|
|
|
|
#define ALT_TYPE_SHIFT 20
|
|
|
|
#define ALT_CTX_SHIFT 28
|
|
|
|
|
2024-09-13 15:05:38 +02:00
|
|
|
#define ALT_FACILITY(facility) (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
|
2024-07-16 13:50:53 +02:00
|
|
|
ALT_TYPE_FACILITY << ALT_TYPE_SHIFT | \
|
|
|
|
(facility) << ALT_DATA_SHIFT)
|
|
|
|
|
2024-07-16 13:50:55 +02:00
|
|
|
#define ALT_SPEC(facility) (ALT_CTX_LATE << ALT_CTX_SHIFT | \
|
|
|
|
ALT_TYPE_SPEC << ALT_TYPE_SHIFT | \
|
|
|
|
(facility) << ALT_DATA_SHIFT)
|
|
|
|
|
s390: Add infrastructure to patch lowcore accesses
The s390 architecture defines two special per-CPU data pages
called the "prefix area". In s390-linux terminology this is usually
called "lowcore". This memory area contains system configuration
data like old/new PSW's for system call/interrupt/machine check
handlers and lots of other data. It is normally mapped to logical
address 0. This area can only be accessed when in supervisor mode.
This means that kernel code can dereference NULL pointers, because
accesses to address 0 are allowed. Parts of lowcore can be write
protected, but read accesses and write accesses outside of the write
protected areas are not caught.
To remove this limitation for debugging and testing, remap lowcore to
another address and define a function get_lowcore() which simply
returns the address where lowcore is mapped at. This would normally
introduce a pointer dereference (=memory read). As lowcore is used
for several very often used variables, add code to patch this function
during runtime, so we avoid the memory reads.
For C code get_lowcore() has to be used, for assembly code it is
the GET_LC macro. When using this macro/function a reference is added
to alternative patching. All these locations will be patched to the
actual lowcore location when the kernel is booted or a module is loaded.
To make debugging/bisecting problems easier, this patch adds all the
infrastructure but the lowcore address is still hardwired to 0. This
way the code can be converted on a per function basis, and the
functionality is enabled in a patch after all the functions have
been converted.
Note that this requires at least z16 because the old lpsw instruction
only allowed a 12 bit displacement. z16 introduced lpswey which allows
20 bits (signed), so the lowcore can effectively be mapped from
address 0 - 0x7e000. To use 0x7e000 as address, a 6 byte lgfi
instruction would have to be used in the alternative. To save two
bytes, llilh can be used, but this only allows to set bits 16-31 of
the address. In order to use the llilh instruction, use 0x70000 as
alternative lowcore address. This is still large enough to catch
NULL pointer dereferences into large arrays.
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2024-07-22 15:41:14 +02:00
|
|
|
#define ALT_LOWCORE (ALT_CTX_EARLY << ALT_CTX_SHIFT | \
|
|
|
|
ALT_TYPE_LOWCORE << ALT_TYPE_SHIFT)
|
|
|
|
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/stddef.h>
|
|
|
|
#include <linux/stringify.h>
|
|
|
|
|
|
|
|
struct alt_instr {
|
|
|
|
s32 instr_offset; /* original instruction */
|
|
|
|
s32 repl_offset; /* offset to replacement instruction */
|
2024-07-16 13:50:53 +02:00
|
|
|
union {
|
|
|
|
u32 feature; /* feature required for replacement */
|
|
|
|
struct {
|
|
|
|
u32 ctx : 4; /* context */
|
|
|
|
u32 type : 8; /* type of alternative */
|
|
|
|
u32 data : 20; /* patching information */
|
|
|
|
};
|
|
|
|
};
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
u8 instrlen; /* length of original instruction */
|
|
|
|
} __packed;
|
|
|
|
|
2024-07-16 13:50:53 +02:00
|
|
|
extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
|
|
|
|
|
|
|
|
void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsigned int ctx);
|
|
|
|
|
|
|
|
static inline void apply_alternative_instructions(void)
|
|
|
|
{
|
|
|
|
__apply_alternatives(__alt_instructions, __alt_instructions_end, ALT_CTX_LATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
|
|
|
|
{
|
|
|
|
__apply_alternatives(start, end, ALT_CTX_ALL);
|
|
|
|
}
|
2017-11-14 15:20:24 +01:00
|
|
|
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
/*
|
2022-05-11 14:05:26 +02:00
|
|
|
* +---------------------------------+
|
|
|
|
* |661: |662:
|
|
|
|
* | oldinstr |
|
|
|
|
* +---------------------------------+
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
*
|
|
|
|
* .altinstr_replacement section
|
2022-05-11 14:05:26 +02:00
|
|
|
* +---------------------------------+
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
* |6641: |6651:
|
|
|
|
* | alternative instr 1 |
|
2022-05-11 14:05:26 +02:00
|
|
|
* +---------------------------------+
|
|
|
|
* |6642: |6652:
|
|
|
|
* | alternative instr 2 |
|
|
|
|
* +---------------------------------+
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
*
|
|
|
|
* .altinstructions section
|
|
|
|
* +---------------------------------+
|
|
|
|
* | alt_instr entries for each |
|
|
|
|
* | alternative instr |
|
|
|
|
* +---------------------------------+
|
|
|
|
*/
|
|
|
|
|
2022-05-11 14:05:26 +02:00
|
|
|
#define b_altinstr(num) "664"#num
|
|
|
|
#define e_altinstr(num) "665"#num
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
#define oldinstr_len "662b-661b"
|
|
|
|
#define altinstr_len(num) e_altinstr(num)"b-"b_altinstr(num)"b"
|
|
|
|
|
2022-05-11 14:05:26 +02:00
|
|
|
#define OLDINSTR(oldinstr) \
|
|
|
|
"661:\n\t" oldinstr "\n662:\n"
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
|
2024-07-16 13:50:49 +02:00
|
|
|
#define ALTINSTR_ENTRY(feature, num) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
"\t.long 661b - .\n" /* old instruction */ \
|
|
|
|
"\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \
|
2024-07-16 13:50:53 +02:00
|
|
|
"\t.long " __stringify(feature) "\n" /* feature */ \
|
2022-05-11 14:05:26 +02:00
|
|
|
"\t.byte " oldinstr_len "\n" /* instruction len */ \
|
2024-05-13 12:16:20 +02:00
|
|
|
"\t.org . - (" oldinstr_len ") & 1\n" \
|
2022-05-11 14:05:26 +02:00
|
|
|
"\t.org . - (" oldinstr_len ") + (" altinstr_len(num) ")\n" \
|
|
|
|
"\t.org . - (" altinstr_len(num) ") + (" oldinstr_len ")\n"
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
|
|
|
|
#define ALTINSTR_REPLACEMENT(altinstr, num) /* replacement */ \
|
2022-05-11 14:05:26 +02:00
|
|
|
b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
|
|
|
|
/* alternative assembly primitive: */
|
2024-07-16 13:50:49 +02:00
|
|
|
#define ALTERNATIVE(oldinstr, altinstr, feature) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".pushsection .altinstr_replacement, \"ax\"\n" \
|
|
|
|
ALTINSTR_REPLACEMENT(altinstr, 1) \
|
|
|
|
".popsection\n" \
|
2022-05-11 14:05:26 +02:00
|
|
|
OLDINSTR(oldinstr) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".pushsection .altinstructions,\"a\"\n" \
|
2024-07-16 13:50:49 +02:00
|
|
|
ALTINSTR_ENTRY(feature, 1) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".popsection\n"
|
|
|
|
|
2024-07-16 13:50:49 +02:00
|
|
|
#define ALTERNATIVE_2(oldinstr, altinstr1, feature1, altinstr2, feature2)\
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".pushsection .altinstr_replacement, \"ax\"\n" \
|
|
|
|
ALTINSTR_REPLACEMENT(altinstr1, 1) \
|
|
|
|
ALTINSTR_REPLACEMENT(altinstr2, 2) \
|
|
|
|
".popsection\n" \
|
2022-05-11 14:05:26 +02:00
|
|
|
OLDINSTR(oldinstr) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".pushsection .altinstructions,\"a\"\n" \
|
2024-07-16 13:50:49 +02:00
|
|
|
ALTINSTR_ENTRY(feature1, 1) \
|
|
|
|
ALTINSTR_ENTRY(feature2, 2) \
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
".popsection\n"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Alternative instructions for different CPU types or capabilities.
|
|
|
|
*
|
|
|
|
* This allows to use optimized instructions even on generic binary
|
|
|
|
* kernels.
|
|
|
|
*
|
|
|
|
* oldinstr is padded with jump and nops at compile time if altinstr is
|
|
|
|
* longer. altinstr is padded with jump and nops at run-time during patching.
|
|
|
|
*
|
|
|
|
* For non barrier like inlines please define new variants
|
|
|
|
* without volatile and memory clobber.
|
|
|
|
*/
|
2024-07-16 13:50:49 +02:00
|
|
|
#define alternative(oldinstr, altinstr, feature) \
|
|
|
|
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) : : : "memory")
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
|
2024-07-16 13:50:49 +02:00
|
|
|
#define alternative_2(oldinstr, altinstr1, feature1, altinstr2, feature2) \
|
|
|
|
asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, feature1, \
|
|
|
|
altinstr2, feature2) ::: "memory")
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
|
2021-02-02 17:10:49 +01:00
|
|
|
/* Alternative inline assembly with input. */
|
|
|
|
#define alternative_input(oldinstr, newinstr, feature, input...) \
|
|
|
|
asm_inline volatile (ALTERNATIVE(oldinstr, newinstr, feature) \
|
|
|
|
: : input)
|
|
|
|
|
|
|
|
/* Like alternative_input, but with a single output argument */
|
2024-07-16 13:50:49 +02:00
|
|
|
#define alternative_io(oldinstr, altinstr, feature, output, input...) \
|
|
|
|
asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, feature) \
|
2021-02-02 17:10:49 +01:00
|
|
|
: output : input)
|
|
|
|
|
|
|
|
/* Use this macro if more than one output parameter is needed. */
|
|
|
|
#define ASM_OUTPUT2(a...) a
|
|
|
|
|
|
|
|
/* Use this macro if clobbers are needed without inputs. */
|
|
|
|
#define ASM_NO_INPUT_CLOBBER(clobber...) : clobber
|
|
|
|
|
2024-07-16 13:50:50 +02:00
|
|
|
#else /* __ASSEMBLY__ */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Issue one struct alt_instr descriptor entry (need to put it into
|
|
|
|
* the section .altinstructions, see below). This entry contains
|
|
|
|
* enough information for the alternatives patching code to patch an
|
|
|
|
* instruction. See apply_alternatives().
|
|
|
|
*/
|
|
|
|
.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature
|
|
|
|
.long \orig_start - .
|
|
|
|
.long \alt_start - .
|
2024-07-16 13:50:53 +02:00
|
|
|
.long \feature
|
2024-07-16 13:50:50 +02:00
|
|
|
.byte \orig_end - \orig_start
|
|
|
|
.org . - ( \orig_end - \orig_start ) & 1
|
|
|
|
.org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
|
|
|
|
.org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
|
|
|
|
.endm
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Define an alternative between two instructions. If @feature is
|
|
|
|
* present, early code in apply_alternatives() replaces @oldinstr with
|
|
|
|
* @newinstr.
|
|
|
|
*/
|
|
|
|
.macro ALTERNATIVE oldinstr, newinstr, feature
|
|
|
|
.pushsection .altinstr_replacement,"ax"
|
|
|
|
770: \newinstr
|
|
|
|
771: .popsection
|
|
|
|
772: \oldinstr
|
|
|
|
773: .pushsection .altinstructions,"a"
|
|
|
|
alt_entry 772b, 773b, 770b, 771b, \feature
|
|
|
|
.popsection
|
|
|
|
.endm
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Define an alternative between two instructions. If @feature is
|
|
|
|
* present, early code in apply_alternatives() replaces @oldinstr with
|
|
|
|
* @newinstr.
|
|
|
|
*/
|
|
|
|
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
|
|
|
|
.pushsection .altinstr_replacement,"ax"
|
|
|
|
770: \newinstr1
|
|
|
|
771: \newinstr2
|
|
|
|
772: .popsection
|
|
|
|
773: \oldinstr
|
|
|
|
774: .pushsection .altinstructions,"a"
|
|
|
|
alt_entry 773b, 774b, 770b, 771b,\feature1
|
|
|
|
alt_entry 773b, 774b, 771b, 772b,\feature2
|
|
|
|
.popsection
|
|
|
|
.endm
|
|
|
|
|
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>
2017-10-12 13:01:47 +02:00
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
|
|
|
|
#endif /* _ASM_S390_ALTERNATIVE_H */
|