Patch "x86/alternatives: Fix alt_max_short macro to really be a max()" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
x86/alternatives: Fix alt_max_short macro to really be a max()
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-alternatives-fix-alt_max_short-macro-to-really-be-a-max.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
6b32c126d33d5cb379bca280ab8acedc1ca978ffMon Sep 17 00:00:00 2001
From: Mathias Krause <[email protected]>
Date: Thu, 5 Oct 2017 20:30:12 +0200
Subject: x86/alternatives: Fix alt_max_short macro to really be a max()
From: Mathias Krause <[email protected]>
commit 6b32c126d33d5cb379bca280ab8acedc1ca978ff upstream.
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 dbe4058a6a44 ("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
--- arch/x86/include/asm/alternative-asm.h | 4 +++- arch/x86/include/asm/alternative.h | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/include/asm/alternative-asm.h +3 -1
@@ -62,8 +62,10 @@#define new_len2 145f-144f/* -* max without conditionals. Idea adapted from: +* gas compatible max based on the idea from: * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax +* +* The additional "-" is needed because gas uses a "true" value of -1. */ #define alt_max_short (a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
arch/x86/include/asm/alternative.h +3 -3
@@ -102,12 +102,12 @@ static inline int alternatives_text_rese alt_end_marker":\n" /* -* max without conditionals. Idea adapted from: +* gas compatible max based on the idea from: * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax * -* The additional "-" is needed because gas works with s32s. +* 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_short (a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))"/* * Pad the second replacement alternative with additional NOPs if it is
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/x86-alternatives-fix-alt_max_short-macro-to-really-be-a-max.patch