x86/alternatives: Rework get_ideal_nops()

The {k8,p6}_nops[] arrays are both 80-byte structures indexing 45-byte
structures.  Furthermore, perhaps unusually for C, the source layout is an
obvious hint about the triangular nature of the structure.

Therefore, we can replace the pointer chase with some simple arithmetic.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2026-08-05 09:49:32 +01:00
1 parent 0d32eb2844
commit ea20eafb46
1 file changed
+20 -28
+20 -28
View File
@@ -20,7 +20,7 @@
#define MAX_PATCH_LEN (255-1)
#ifdef K8_NOP1
static const unsigned char k8nops[] init_or_livepatch_const = {
static const unsigned char k8_nops[] init_or_livepatch_const = {
K8_NOP1,
K8_NOP2,
K8_NOP3,
@@ -31,22 +31,10 @@ static const unsigned char k8nops[] init_or_livepatch_const = {
K8_NOP8,
K8_NOP9,
};
static const unsigned char * const k8_nops[ASM_NOP_MAX+1] init_or_livepatch_constrel = {
NULL,
k8nops,
k8nops + 1,
k8nops + 1 + 2,
k8nops + 1 + 2 + 3,
k8nops + 1 + 2 + 3 + 4,
k8nops + 1 + 2 + 3 + 4 + 5,
k8nops + 1 + 2 + 3 + 4 + 5 + 6,
k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
};
#endif
#ifdef P6_NOP1
static const unsigned char p6nops[] init_or_livepatch_const = {
static const unsigned char p6_nops[] init_or_livepatch_const = {
P6_NOP1,
P6_NOP2,
P6_NOP3,
@@ -57,21 +45,9 @@ static const unsigned char p6nops[] init_or_livepatch_const = {
P6_NOP8,
P6_NOP9,
};
static const unsigned char * const p6_nops[ASM_NOP_MAX+1] init_or_livepatch_constrel = {
NULL,
p6nops,
p6nops + 1,
p6nops + 1 + 2,
p6nops + 1 + 2 + 3,
p6nops + 1 + 2 + 3 + 4,
p6nops + 1 + 2 + 3 + 4 + 5,
p6nops + 1 + 2 + 3 + 4 + 5 + 6,
p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
};
#endif
static const unsigned char * const *ideal_nops init_or_livepatch_data = p6_nops;
static const unsigned char *ideal_nops init_or_livepatch_data = p6_nops;
#ifdef HAVE_AS_NOPS_DIRECTIVE
@@ -86,9 +62,19 @@ static bool init_or_livepatch_read_mostly toolchain_nops_are_ideal;
# define toolchain_nops_are_ideal false
#endif
#define TRIANGLE(x) (((x) * ((x) + 1)) / 2)
/*
* Both k8_nops[] and p6_nops[] are flattened triangular data structures,
* making the offsets easy to calculate.
*
* To get the start of NOP $N, we want to calculate TRIANGLE($N - 1)
*/
static const unsigned char *init_or_livepatch get_ideal_nops(unsigned int noplen)
{
return ideal_nops[noplen];
unsigned int offset = TRIANGLE(noplen - 1);
return &ideal_nops[offset];
}
static void __init arch_init_ideal_nops(void)
@@ -601,3 +587,9 @@ void __init boot_apply_alt_calls(void)
_alternative_instructions(ALT_CALLS);
local_irq_enable();
}
static void __init __maybe_unused build_assertions(void)
{
BUILD_BUG_ON(ARRAY_SIZE(k8_nops) != TRIANGLE(ASM_NOP_MAX));
BUILD_BUG_ON(ARRAY_SIZE(p6_nops) != TRIANGLE(ASM_NOP_MAX));
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.