Re: [PATCH rdma-next v1 1/3] overflow.h: Add arithmetic shift helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 10, 2018 at 08:09:32AM +0200, Rasmus Villemoes wrote:
> On 2018-07-08 12:38, Leon Romanovsky wrote:
> > From: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> >
> > Add shift_overflow() helper to help driver authors to ensure that
> > shift operand doesn't cause to overflow.
> >
> > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
> > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
> > ---
> >  include/linux/overflow.h | 23 +++++++++++++++++++++++
> >  1 file changed, 23 insertions(+)
> >
> > diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> > index 8712ff70995f..21ff032773e0 100644
> > --- a/include/linux/overflow.h
> > +++ b/include/linux/overflow.h
> > @@ -202,6 +202,29 @@
> >
> >  #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
> >
> > +/*
> > + * Compute *d = (a << s)
> > + *
> > + * Returns true if '*d' cannot hold the result or 'a << s' doesn't make sense.
> > + * - 'a << s' causes bits to be lost when stored in d
> > + * - 's' is garbage (eg negative) or so large that a << s is guaranteed to be 0
> > + * - 'a' is negative
> > + * - 'a << s' sets the sign bit, if any, in '*d'
> > + * *d is not defined if false is returned.
> > + */
>
> You mean if true is returned, i.e. some kind of overflow or nonsense
> input was detected. *d is very much defined if the result is false.
>
> > +#define check_shift_overflow(a, s, d) ({				\
> > +	typeof(a) _a = a;						\
> > +	typeof(s) _s = s;						\
> > +	typeof(d) _d = d;						\
> > +	u64 _a_full = _a;						\
> > +	unsigned int _to_shift =					\
> > +	_s >= 0 && _s < 8 * sizeof(*d) ? _s : 0;			\
> > +	*_d = (_a_full << _to_shift);					\
> > +	*d = *_d;							\
>
> As others have pointed out, this assignment is useless at best, but
> potentially harmful - the whole point of the standard typeof dance is to
> prevent double evaluation of macro arguments...

In the lib/test_overflow.c, there is expectation what result of
check_one_op will be defined anyway (line 231). I wanted a way to have
overflowed result placed in *d for tests, but didn't want for users rely
on that, so this is why comment says that the result is unreliable.

220 #define check_one_op(t, fmt, op, sym, a, b, r, of) do {         \
221         t _r;                                                   \
222         bool _of;                                               \
223                                                                 \
224         _of = check_ ## op ## _overflow(a, b, &_r);             \
225         if (_of != of) {                                        \
226                 pr_warn("expected "fmt" "sym" "fmt              \
227                         " to%s overflow (type %s)\n",           \
228                         a, b, of ? "" : " not", #t);            \
229                 err = 1;                                        \
230         }                                                       \
231         if (_r != r) {                                          \
232                 pr_warn("expected "fmt" "sym" "fmt" == "        \
233                         fmt", got "fmt" (type %s)\n",           \
234                         a, b, r, _r, #t);                       \
235                 err = 1;                                        \
236         }                                                       \
237 } while (0)

So or we are getting rid from *d assignment in check_shift_overflow()
macro and changing the test suite to skip line 231 or define *d, like I
did.

Thanks

>
> Rasmus

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux