Thread (72 messages) 72 messages, 11 authors, 2020-11-02

RE: Buggy commit tracked to: "Re: [PATCH 2/9] iov_iter: move rw_copy_check_uvector() into lib/iov_iter.c"

flat view

From: David Laight <hidden>
Date: 2020-10-23 21:29:13
Also in: io-uring, keyrings, linux-arch, linux-arm-kernel, linux-block, linux-fsdevel, linux-mips, linux-mm, linux-s390, linux-scsi, linux-security-module, lkml, netdev, sparclinux

From: Segher Boessenkool
Sent: 23 October 2020 19:27

On Fri, Oct 23, 2020 at 06:58:57PM +0100, Al Viro wrote:
quoted
On Fri, Oct 23, 2020 at 03:09:30PM +0200, David Hildenbrand wrote:
quoted
Now, I am not a compiler expert, but as I already cited, at least on
x86-64 clang expects that the high bits were cleared by the caller - in
contrast to gcc. I suspect it's the same on arm64, but again, I am no
compiler expert.

If what I said and cites for x86-64 is correct, if the function expects
an "unsigned int", it will happily use 64bit operations without further
checks where valid when assuming high bits are zero. That's why even
converting everything to "unsigned int" as proposed by me won't work on
clang - it assumes high bits are zero (as indicated by Nick).

As I am neither a compiler experts (did I mention that already? ;) ) nor
an arm64 experts, I can't tell if this is a compiler BUG or not.
On arm64 when callee expects a 32bit argument, the caller is *not* responsible
for clearing the upper half of 64bit register used to pass the value - it only
needs to store the actual value into the lower half.  The callee must consider
the contents of the upper half of that register as undefined.  See AAPCS64 (e.g.
https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#parameter-passing-rules
); AFAICS, the relevant bit is
	"Unlike in the 32-bit AAPCS, named integral values must be narrowed by
the callee rather than the caller."
Or the formal rule:

C.9 	If the argument is an Integral or Pointer Type, the size of the
	argument is less than or equal to 8 bytes and the NGRN is less
	than 8, the argument is copied to the least significant bits in
	x[NGRN]. The NGRN is incremented by one. The argument has now
	been allocated.
So, in essence, if the value is in a 64bit register the calling
code is independent of the actual type of the formal parameter.
Clearly a value might need explicit widening.

I've found a copy of the 64 bit arm instruction set.
Unfortunately it is alpha sorted and repetitive so shows none
of the symmetry and makes things difficult to find.
But, contrary to what someone suggested most register writes
(eg from arithmetic) seem to zero/extend the high bits.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help