[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20191217170719.GA869@willie-the-truck>
Date: Tue, 17 Dec 2019 17:07:19 +0000
From: Will Deacon <will@...nel.org>
To: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Peter Zijlstra <peterz@...radead.org>,
Michael Ellerman <mpe@...erman.id.au>, dja@...ens.net,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
linuxppc-dev@...ts.ozlabs.org,
Christophe Leroy <christophe.leroy@....fr>,
linux-arch <linux-arch@...r.kernel.org>,
Mark Rutland <mark.rutland@....com>,
Segher Boessenkool <segher@...nel.crashing.org>,
Arnd Bergmann <arnd@...db.de>,
Christian Borntraeger <borntraeger@...ibm.com>
Subject: Re: READ_ONCE() + STACKPROTECTOR_STRONG == :/ (was Re: [GIT PULL]
Please pull powerpc/linux.git powerpc-5.5-2 tag (topic/kasan-bitops))
On Thu, Dec 12, 2019 at 12:49:52PM -0800, Linus Torvalds wrote:
> On Thu, Dec 12, 2019 at 11:34 AM Will Deacon <will@...nel.org> wrote:
> >
> > The root of my concern in all of this, and what started me looking at it in
> > the first place, is the interaction with 'typeof()'. Inheriting 'volatile'
> > for a pointer means that local variables in macros declared using typeof()
> > suddenly start generating *hideous* code, particularly when pointless stack
> > spills get stackprotector all excited.
>
> Yeah, removing volatile can be a bit annoying.
>
> For the particular case of the bitops, though, it's not an issue.
> Since you know the type there, you can just cast it.
>
> And if we had the rule that READ_ONCE() was an arithmetic type, you could do
>
> typeof(0+(*p)) __var;
>
> since you might as well get the integer promotion anyway (on the
> non-volatile result).
>
> But that doesn't work with structures or unions, of course.
>
> I'm not entirely sure we have READ_ONCE() with a struct. I do know we
> have it with 64-bit entities on 32-bit machines, but that's ok with
> the "0+" trick.
Other than the two trivial examples Arnd and I spotted, it looks like
we're in for some fun with the page-table types such as pud_t but that
/should/ be fixable with enough effort.
However, I'm really banging my head against the compiler trying to get
your trick above to work for pointer types when the pointed-to-type is
not defined. As a very cut down example (I pulled this back out of the
preprocessor and cleaned it up a bit):
struct dentry {
struct inode *d_inode;
};
static inline struct inode *d_inode_rcu(struct dentry *dentry)
{
return ({
typeof(0 + dentry->d_inode) __x = (*(volatile typeof(dentry->d_inode) *)&(dentry->d_inode));
(typeof(dentry->d_inode))__x;
});
}
Trying to compile this results in:
| In function 'd_inode_rcu':
| error: invalid use of undefined type 'struct inode'
whereas it compiles fine if you remove the '0 +' from the first typeof.
What am I missing? Perhaps the compiler wants the size information of
'struct inode' before it will contemplate the arithmetic, but if so then
I don't think we can use this trick after all. Hmm.
Will
Powered by blists - more mailing lists