[RFC v2 05/13] x86/mm: Set KeyIDs in encrypted VMAs

Sakkinen, Jarkko jarkko.sakkinen at intel.com
Thu Dec 6 08:37:15 UTC 2018


On Mon, 2018-12-03 at 23:39 -0800, Alison Schofield wrote:
> MKTME architecture requires the KeyID to be placed in PTE bits 51:46.
> To create an encrypted VMA, place the KeyID in the upper bits of
> vm_page_prot that matches the position of those PTE bits.
> 
> When the VMA is assigned a KeyID it is always considered a KeyID
> change. The VMA is either going from not encrypted to encrypted,
> or from encrypted with any KeyID to encrypted with any other KeyID.
> To make the change safely, remove the user pages held by the VMA
> and unlink the VMA's anonymous chain.
> 
> Change-Id: I676056525c49c8803898315a10b196ef5a5c5415

Remove.

> Signed-off-by: Alison Schofield <alison.schofield at intel.com>
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov at linux.intel.com>
> ---
>  arch/x86/include/asm/mktme.h |  4 ++++
>  arch/x86/mm/mktme.c          | 26 ++++++++++++++++++++++++++
>  include/linux/mm.h           |  6 ++++++
>  3 files changed, 36 insertions(+)
> 
> diff --git a/arch/x86/include/asm/mktme.h b/arch/x86/include/asm/mktme.h
> index dbb49909d665..de3e529f3ab0 100644
> --- a/arch/x86/include/asm/mktme.h
> +++ b/arch/x86/include/asm/mktme.h
> @@ -24,6 +24,10 @@ extern int mktme_map_keyid_from_key(void *key);
>  extern void *mktme_map_key_from_keyid(int keyid);
>  extern int mktme_map_get_free_keyid(void);
>  
> +/* Set the encryption keyid bits in a VMA */
> +extern void mprotect_set_encrypt(struct vm_area_struct *vma, int newkeyid,
> +				unsigned long start, unsigned long end);
> +
>  DECLARE_STATIC_KEY_FALSE(mktme_enabled_key);
>  static inline bool mktme_enabled(void)
>  {
> diff --git a/arch/x86/mm/mktme.c b/arch/x86/mm/mktme.c
> index 34224d4e3f45..e3fdf7b48173 100644
> --- a/arch/x86/mm/mktme.c
> +++ b/arch/x86/mm/mktme.c
> @@ -1,5 +1,6 @@
>  #include <linux/mm.h>
>  #include <linux/highmem.h>
> +#include <linux/rmap.h>
>  #include <asm/mktme.h>
>  #include <asm/set_memory.h>
>  
> @@ -131,6 +132,31 @@ int mktme_map_get_free_keyid(void)
>  	return 0;
>  }
>  
> +/* Set the encryption keyid bits in a VMA */

Maybe proper kdoc?

> +void mprotect_set_encrypt(struct vm_area_struct *vma, int newkeyid,
> +			  unsigned long start, unsigned long end)
> +{
> +	int oldkeyid = vma_keyid(vma);
> +	pgprotval_t newprot;
> +
> +	/* Unmap pages with old KeyID if there's any. */
> +	zap_page_range(vma, start, end - start);
> +
> +	if (oldkeyid == newkeyid)
> +		return;
> +
> +	newprot = pgprot_val(vma->vm_page_prot);
> +	newprot &= ~mktme_keyid_mask;
> +	newprot |= (unsigned long)newkeyid << mktme_keyid_shift;
> +	vma->vm_page_prot = __pgprot(newprot);
> +
> +	/*

No empty comment line.

> +	 * The VMA doesn't have any inherited pages.
> +	 * Start anon VMA tree from scratch.
> +	 */
> +}
> +
>  /* Prepare page to be used for encryption. Called from page allocator. */
>  void __prep_encrypted_page(struct page *page, int order, int keyid, bool
> zero)
>  {
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 1309761bb6d0..e2d87e92ca74 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2806,5 +2806,11 @@ void __init setup_nr_node_ids(void);
>  static inline void setup_nr_node_ids(void) {}
>  #endif
>  
> +#ifndef CONFIG_X86_INTEL_MKTME
> +static inline void mprotect_set_encrypt(struct vm_area_struct *vma,
> +					int newkeyid,
> +					unsigned long start,
> +					unsigned long end) {}

Add a new line and

{
}


> +#endif /* CONFIG_X86_INTEL_MKTME */
>  #endif /* __KERNEL__ */
>  #endif /* _LINUX_MM_H */

/Jarkko



More information about the Linux-security-module-archive mailing list