On Sat, May 19, 2018 at 11:04 PM Ram Pai <linuxram@xxxxxxxxxx> wrote: > On Sat, May 19, 2018 at 04:47:23PM -0700, Andy Lutomirski wrote: > On Sat, May 19, 2018 at 1:28 PM Ram Pai <linuxram@xxxxxxxxxx> wrote: > ...snip... > > > > So is it possible for two threads to each call pkey_alloc() and end up with > > the same key? If so, it seems entirely broken. > No. Two threads cannot allocate the same key; just like x86. > > If not, then how do you > > intend for a multithreaded application to usefully allocate a new key? > > Regardless, it seems like the current behavior on POWER is very difficult > > to work with. Can you give an example of a use case for which POWER's > > behavior makes sense? > > > > For the use cases I've imagined, POWER's behavior does not make sense. > > x86's is not ideal but is still better. Here are my two example use cases: > > > > 1. A crypto library. Suppose I'm writing a TLS-terminating server, and I > > want it to be resistant to Heartbleed-like bugs. I could store my private > > keys protected by mprotect_key() and arrange for all threads and signal > > handlers to have PKRU/AMR values that prevent any access to the memory. > > When an explicit call is made to sign with the key, I would temporarily > > change PKRU/AMR to allow access, compute the signature, and change PKRU/AMR > > back. On x86 right now, this works nicely. On POWER, it doesn't, because > > any thread started before my pkey_alloc() call can access the protected > > memory, as can any signal handler. > > > > 2. A database using mmap() (with persistent memory or otherwise). It would > > be nice to be resistant to accidental corruption due to stray writes. I > > would do more or less the same thing as (1), except that I would want > > threads that are not actively writing to the database to be able the > > protected memory. On x86, I need to manually convince threads that may > > have been started before my pkey_alloc() call as well as signal handlers to > > update their PKRU values. On POWER, as in example (1), the error goes the > > other direction -- if I fail to propagate the AMR bits to all threads, > > writes are not blocked. > I see the problem from an application's point of view, on powerpc. If > the key allocated in one thread is not activated on all threads > (existing one and future one), than other threads will not be able > to modify the key's permissions. Hence they will not be able to control > access/write to pages to which the key is associated. > As Florian suggested, I should enable the key's bit in the UAMOR value > corresponding to existing threads, when a new key is allocated. > Now, looking at the implementation for x86, I see that sys_mpkey_alloc() > makes no attempt to modify anything of any other thread. How > does it manage to activate the key on any other thread? Is this > magic done by the hardware? x86 has no equivalent concept to UAMOR. There are 16 keys no matter what. --Andy