[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 7/7] x86/nospec: Optimise array_index_mask_nospec() for power-of-2 arrays
On 25.10.2019 14:58, Andrew Cooper wrote: > On 25/10/2019 13:24, Jan Beulich wrote: >> On 23.10.2019 15:58, Andrew Cooper wrote: >>> @@ -21,9 +28,15 @@ static inline unsigned long >>> array_index_mask_nospec(unsigned long index, >>> { >>> unsigned long mask; >>> >>> - asm volatile ( "cmp %[size], %[index]; sbb %[mask], %[mask];" >>> - : [mask] "=r" (mask) >>> - : [size] "g" (size), [index] "r" (index) ); >>> + if ( __builtin_constant_p(size) && IS_POWER_OF_2(size) ) >>> + { >>> + mask = size - 1; >>> + OPTIMIZER_HIDE_VAR(mask); >> I can't seem to be able to figure why you need this. > > Because I found cases where the AND was elided by the compiler entirely > without it. Would you mind mentioning this in the description, or in a comment? >>> --- a/xen/include/xen/config.h >>> +++ b/xen/include/xen/config.h >>> @@ -75,6 +75,7 @@ >>> #define GB(_gb) (_AC(_gb, ULL) << 30) >>> >>> #define IS_ALIGNED(val, align) (((val) & ((align) - 1)) == 0) >>> +#define IS_POWER_OF_2(val) ((val) && IS_ALIGNED(val, val)) >> While the risk may seem low for someone to pass an expression with >> side effect here, evaluating "val" up to three times here doesn't >> look very desirable. > > That is easy to fix. > >> As a minor remark, without considering representation I'd expect >> an expression IS_ALIGNED(val, val) to consistently produce "true" >> for all non-zero values. E.g. 3 is certainly "aligned" on a >> boundary of 3. > > IS_ALIGNED() comes with an expectation of being against a power of 2, > because otherwise you'd need a DIV instruction for the general case. > > Some users can't cope with a compile time check. > >> Finally this may want guarding against use on signed types - at >> the very least it looks to produce the wrong answer for e.g. >> INT_MIN or LONG_MIN. I.e. perhaps the expression to the left of >> && wants to be (val) > 0. > > How about the above expansion fix becoming: > > ({ > unsigned typeof(val) _val = val; > _val && (_val & (_val - 1)) == 0; > }) Well, if the "unsigned typeof()" construct works - why not (with "val" properly parenthesized, and preferable the leading underscore changed to a trailing one). > This check makes no sense on negative numbers. Of course not, but someone might use it on a signed type and get back true when it was supposed to be false, just because the value used ended up being a negative number. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |