Skip to content

Commit 6b32c12

Browse files
minipliKAGA-KOKO
authored andcommitted
x86/alternatives: Fix alt_max_short macro to really be a max()
The alt_max_short() macro in asm/alternative.h does not work as intended, leading to nasty bugs. E.g. alt_max_short("1", "3") evaluates to 3, but alt_max_short("3", "1") evaluates to 1 -- not exactly the maximum of 1 and 3. In fact, I had to learn it the hard way by crashing my kernel in not so funny ways by attempting to make use of the ALTENATIVE_2 macro with alternatives where the first one was larger than the second one. According to [1] and commit dbe4058 ("x86/alternatives: Fix ALTERNATIVE_2 padding generation properly") the right handed side should read "-(-(a < b))" not "-(-(a - b))". Fix that, to make the macro work as intended. While at it, fix up the comments regarding the additional "-", too. It's not about gas' usage of s32 but brain dead logic of having a "true" value of -1 for the < operator ... *sigh* Btw., the one in asm/alternative-asm.h is correct. And, apparently, all current users of ALTERNATIVE_2() pass same sized alternatives, avoiding to hit the bug. [1] http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax Reviewed-and-tested-by: Borislav Petkov <[email protected]> Fixes: dbe4058 ("x86/alternatives: Fix ALTERNATIVE_2 padding generation properly") Signed-off-by: Mathias Krause <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 924c6b9 commit 6b32c12

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

arch/x86/include/asm/alternative-asm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@
6262
#define new_len2 145f-144f
6363

6464
/*
65-
* max without conditionals. Idea adapted from:
65+
* gas compatible max based on the idea from:
6666
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
67+
*
68+
* The additional "-" is needed because gas uses a "true" value of -1.
6769
*/
6870
#define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
6971

arch/x86/include/asm/alternative.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
103103
alt_end_marker ":\n"
104104

105105
/*
106-
* max without conditionals. Idea adapted from:
106+
* gas compatible max based on the idea from:
107107
* http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
108108
*
109-
* The additional "-" is needed because gas works with s32s.
109+
* The additional "-" is needed because gas uses a "true" value of -1.
110110
*/
111-
#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))"
111+
#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"
112112

113113
/*
114114
* Pad the second replacement alternative with additional NOPs if it is

0 commit comments

Comments
 (0)