On Fri, 2018-09-07 at 15:36 -0700, Alison Schofield wrote: > Define a global mapping structure to track the mapping of userspace > keys to hardware keyids in MKTME (Multi-Key Total Memory Encryption). > This data will be used for the memory encryption system call and the > kernel key service API. This is also for earlier patches. I kind of feel uncomfortable because I can neither TME nor MKTME how they reside in the chipset/board. Are they inside the CPU package? Or is it perhaps a separate chip outside the CPU? I would guess not but the problem is that I have to guess in the first place. > Implement helper functions to access this mapping structure and make > them visible to the MKTME Kernel Key Service: security/keys/mktme_keys > > Signed-off-by: Alison Schofield <alison.schofield@xxxxxxxxx> > --- > arch/x86/include/asm/mktme.h | 11 ++++++ > arch/x86/mm/mktme.c | 85 > ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 96 insertions(+) > > diff --git a/arch/x86/include/asm/mktme.h b/arch/x86/include/asm/mktme.h > index dbfbd955da98..f6acd551457f 100644 > --- a/arch/x86/include/asm/mktme.h > +++ b/arch/x86/include/asm/mktme.h > @@ -13,6 +13,17 @@ extern phys_addr_t mktme_keyid_mask; > extern int mktme_nr_keyids; > extern int mktme_keyid_shift; > > +/* Manage mappings between hardware keyids and userspace keys */ > +extern int mktme_map_alloc(void); > +extern void mktme_map_free(void); > +extern void mktme_map_lock(void); > +extern void mktme_map_unlock(void); > +extern int mktme_map_get_free_keyid(void); > +extern void mktme_map_clear_keyid(int keyid); > +extern void mktme_map_set_keyid(int keyid, unsigned int serial); > +extern int mktme_map_keyid_from_serial(unsigned int serial); > +extern unsigned int mktme_map_serial_from_keyid(int keyid); > + > extern struct page_ext_operations page_mktme_ops; > > #define page_keyid page_keyid > diff --git a/arch/x86/mm/mktme.c b/arch/x86/mm/mktme.c > index 660caf6a5ce1..5246d8323359 100644 > --- a/arch/x86/mm/mktme.c > +++ b/arch/x86/mm/mktme.c > @@ -63,6 +63,91 @@ int vma_keyid(struct vm_area_struct *vma) > return (prot & mktme_keyid_mask) >> mktme_keyid_shift; > } > > +/* > + * struct mktme_mapping and the mktme_map_* functions manage the mapping > + * of userspace keys to hardware keyids in MKTME. They are used by the > + * the encrypt_mprotect system call and the MKTME Key Service API. > + */ > +struct mktme_mapping { > + struct mutex lock; /* protect this map & HW > state */ > + unsigned int mapped_keyids; > + unsigned int serial[]; > +}; > + > +struct mktme_mapping *mktme_map; > + > +static inline long mktme_map_size(void) > +{ > + long size = 0; > + > + size += sizeof(mktme_map); > + size += sizeof(mktme_map->serial[0]) * mktme_nr_keyids; > + return size; > +} > + > +int mktme_map_alloc(void) > +{ > + mktme_map = kzalloc(mktme_map_size(), GFP_KERNEL); > + if (!mktme_map) > + return 0; > + mutex_init(&mktme_map->lock); > + return 1; > +} > + > +void mktme_map_free(void) > +{ > + kfree(mktme_map); > +} > + > +void mktme_map_lock(void) > +{ > + mutex_lock(&mktme_map->lock); > +} > + > +void mktme_map_unlock(void) > +{ > + mutex_unlock(&mktme_map->lock); > +} > + > +void mktme_map_set_keyid(int keyid, unsigned int serial) > +{ > + mktme_map->serial[keyid] = serial; > + mktme_map->mapped_keyids++; > +} > + > +void mktme_map_clear_keyid(int keyid) > +{ > + mktme_map->serial[keyid] = 0; > + mktme_map->mapped_keyids--; > +} > + > +unsigned int mktme_map_serial_from_keyid(int keyid) > +{ > + return mktme_map->serial[keyid]; > +} > + > +int mktme_map_keyid_from_serial(unsigned int serial) > +{ > + int i; > + > + for (i = 1; i < mktme_nr_keyids; i++) > + if (mktme_map->serial[i] == serial) > + return i; > + return 0; > +} > + > +int mktme_map_get_free_keyid(void) > +{ > + int i; > + > + if (mktme_map->mapped_keyids < mktme_nr_keyids) { > + for (i = 1; i < mktme_nr_keyids; i++) > + if (mktme_map->serial[i] == 0) > + return i; > + } > + return 0; > +} The kdoc header is missing from all above. /Jarkko