Re: [SPARSE] noderef & ASM statements

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

 



On Wed, Jan 16, 2019 at 05:22:48PM +1200, Linus Torvalds wrote:
> On Wed, Jan 16, 2019 at 10:59 AM Luc Van Oostenryck
> <luc.vanoostenryck@xxxxxxxxx> wrote:
> > *) I've always considered __noderef as really meaning "must not be
> >    dereferenced except by some special purpose operation which
> >    effectively do the real deref". In the present case (percpu &
> >    uaccess (on x86)), it's clear that the special operation is
> >    the asm memory op but isn't this essentially incidental?
> 
> I agree that it's somewhat incidental rather than anything hugely by design.
> 
> That said, the *design* of __noderef was literally to make sure that
> the *compiler* never derefences things, and the "special thing" that
> does dereference was literally meant to be an inline asm. The
> "{get,put}_user()" case was exactly what __noderef was designed for.
> 
> So it *is* very much by design,

OK, that's very clear.
I'm much more familiar with __iomem accesses which I kinda used
as reference.

> The good news is that the asm constraints aren't really all that
> architecture-specific. Yes, all the various  register classes etc
> obviously are, but within the concept of "the compiler never
> dereferences it", the only asm constraints that matter are "m" and
> "p", I think.
> 
> "m" means "memory", and "p" means "address". They are kind of the
> same, except for a gcc memory access ordering situation, I think.

Well, it's alas more complicated :(
The common constraints for memory operands are "m", "o" & "V".
"p" is different, it must be a memory *address*, so there is
no possible problem with noderef with it.

So far so good but, for example:
*) ARM also has "Q" as memory operand (while for ARM64, "Q" is a
    memory address) as well as "Uv", "Uy" & "Uq"
*) PPC also has "wF", "wG", "wO", "es" "Q" & "Z"
*) S390 has "Q", "R", "S" & "T"
*) ...

That's really annoying, especially the ARM vs ARM64 "Q".
Of course, sparse could just take care of "m", "o" & "V" but
that seems really wrong.

ARM64 also use "Ump" for memory *address*, so simply scanning for
the charatcer "m" will gives false positives. Sparse would need to
known all constraints for all archs :(
 
> >  Thinking a bit more about it and looking at some dumps I made:
> >    It seems that most of these these 'noderef in asm operand'
> >    warnings (99.5%) come from percpu operations (which have an API
> >    using an lvalue and not a pointer, unlike the uaccess API).
> >
> >    I begin to suspect that the warnings occuring with an uaccess
> >    operation come from some other kind of error (possibly a missing
> >    call to degenerate()).
> 
> Hmm. The uaccess cases definitely pass the lvalue in some cases. Not
> the cases where we just end up doing a special "call" sequence (the
> normal get_user/put_user() case). But look closer: the cases where we
> actaully inline the access itself, we generate a "LKmode" lvalue with
> that "__m(addr)" thing, and the actual access is done by the inline
> asm.
> 
> See __get_user_asm(), __get_user_asm_nozero(), __get_user_asm_ex() and
> __put_user_goto().

Yes, indeed I was misled by the relatively small number of these.
That said, asm input operands really miss a call to degenerate().

-- Luc



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux