[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