diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2015-07-03 11:26:22 +0530 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-07-09 17:36:32 +0530 |
commit | 80f420842ff42ad61f84584716d74ef635f13892 (patch) | |
tree | 7896f2d00bbac0afef8a1e8f6a3b12d05df27124 /mm/rmap.c | |
parent | e2fc61f384c9224b55990a644bbcf68c25e20203 (diff) | |
download | linux-80f420842ff42ad61f84584716d74ef635f13892.tar.bz2 |
ARC: Make ARC bitops "safer" (add anti-optimization)
ARCompact/ARCv2 ISA provide that any instructions which deals with
bitpos/count operand ASL, LSL, BSET, BCLR, BMSK .... will only consider
lower 5 bits. i.e. auto-clamp the pos to 0-31.
ARC Linux bitops exploited this fact by NOT explicitly masking out upper
bits for @nr operand in general, saving a bunch of AND/BMSK instructions
in generated code around bitops.
While this micro-optimization has worked well over years it is NOT safe
as shifting a number with a value, greater than native size is
"undefined" per "C" spec.
So as it turns outm EZChip ran into this eventually, in their massive
muti-core SMP build with 64 cpus. There was a test_bit() inside a loop
from 63 to 0 and gcc was weirdly optimizing away the first iteration
(so it was really adhering to standard by implementing undefined behaviour
vs. removing all the iterations which were phony i.e. (1 << [63..32])
| for i = 63 to 0
| X = ( 1 << i )
| if X == 0
| continue
So fix the code to do the explicit masking at the expense of generating
additional instructions. Fortunately, this can be mitigated to a large
extent as gcc has SHIFT_COUNT_TRUNCATED which allows combiner to fold
masking into shift operation itself. It is currently not enabled in ARC
gcc backend, but could be done after a bit of testing.
Fixes STAR 9000866918 ("unsafe "undefined behavior" code in kernel")
Reported-by: Noam Camus <noamc@ezchip.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'mm/rmap.c')
0 files changed, 0 insertions, 0 deletions