On Sun, Jun 25, 2017 at 09:53:24PM +0100, Al Viro wrote: > Confirmed. It manages to bugger the loop immediately after the (successful) > copying of iovec array in rw_copy_check_uvector(); both with and without > INLINE_COPY_FROM_USER it has (just before the call of copy_from_user()) r27 > set to nr_segs * sizeof(struct iovec). The call is made, we check that it > has succeeded and that's when it hits the fan: without INLINE_COPY_FROM_USER > we have (interleaved with unrelated insns) > addi 27,27,-8 > srwi 27,27,3 > addi 27,27,1 > mtctr 27 > Weird, but manages to pass nr_segs to mtctr.
This weirdosity is https://gcc.gnu.org/PR67288 . Those three instructions are not the same as just srwi 27,27,3 in case r27 is 0; GCC does not figure out this cannot happen here. > _With_ INLINE_COPY_FROM_USER we > get this: > lis 9,0x2000 > mtctr 9 > In other words, the loop will try to go through 8192 iterations. No idea > where > that number has come from, but it sure as hell is wrong. 8192*65535, even. This is as if r27 was 0 always. Do you have a short stand-alone testcase? 4.6 is ancient, of course, but the actual problem may still exist in more recent compilers (if it _is_ a compiler problem; if it's not, you *really* want to know :-) ) Segher