x86/asm: Provide ALTERNATIVE_3
authorPeter Zijlstra <peterz@infradead.org>
Thu, 15 Sep 2022 11:11:26 +0000 (13:11 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 17 Oct 2022 14:41:14 +0000 (16:41 +0200)
Fairly straight forward adaptation/extention of ALTERNATIVE_2.

Required for call depth tracking.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220915111147.787711192@infradead.org
arch/x86/include/asm/alternative.h

index ef007fa..4c416b2 100644 (file)
@@ -364,6 +364,7 @@ static inline int alternatives_text_reserved(void *start, void *end)
 #define old_len                        141b-140b
 #define new_len1               144f-143f
 #define new_len2               145f-144f
+#define new_len3               146f-145f
 
 /*
  * gas compatible max based on the idea from:
@@ -371,7 +372,8 @@ static inline int alternatives_text_reserved(void *start, void *end)
  *
  * The additional "-" is needed because gas uses a "true" value of -1.
  */
-#define alt_max_short(a, b)    ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
+#define alt_max_2(a, b)                ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
+#define alt_max_3(a, b, c)     (alt_max_2(alt_max_2(a, b), c))
 
 
 /*
@@ -383,8 +385,8 @@ static inline int alternatives_text_reserved(void *start, void *end)
 140:
        \oldinstr
 141:
-       .skip -((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \
-               (alt_max_short(new_len1, new_len2) - (old_len)),0x90
+       .skip -((alt_max_2(new_len1, new_len2) - (old_len)) > 0) * \
+               (alt_max_2(new_len1, new_len2) - (old_len)),0x90
 142:
 
        .pushsection .altinstructions,"a"
@@ -401,6 +403,31 @@ static inline int alternatives_text_reserved(void *start, void *end)
        .popsection
 .endm
 
+.macro ALTERNATIVE_3 oldinstr, newinstr1, feature1, newinstr2, feature2, newinstr3, feature3
+140:
+       \oldinstr
+141:
+       .skip -((alt_max_3(new_len1, new_len2, new_len3) - (old_len)) > 0) * \
+               (alt_max_3(new_len1, new_len2, new_len3) - (old_len)),0x90
+142:
+
+       .pushsection .altinstructions,"a"
+       altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f
+       altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f
+       altinstruction_entry 140b,145f,\feature3,142b-140b,146f-145f
+       .popsection
+
+       .pushsection .altinstr_replacement,"ax"
+143:
+       \newinstr1
+144:
+       \newinstr2
+145:
+       \newinstr3
+146:
+       .popsection
+.endm
+
 /* If @feature is set, patch in @newinstr_yes, otherwise @newinstr_no. */
 #define ALTERNATIVE_TERNARY(oldinstr, feature, newinstr_yes, newinstr_no) \
        ALTERNATIVE_2 oldinstr, newinstr_no, X86_FEATURE_ALWAYS,        \