linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rick Edgecombe <rick.p.edgecombe@intel.com>
To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	x86@kernel.org, linux-mm@kvack.org, luto@kernel.org,
	peterz@infradead.org, dave.hansen@intel.com, pbonzini@redhat.com,
	sean.j.christopherson@intel.com, keescook@chromium.org
Cc: kristen@linux.intel.com, deneen.t.dock@intel.com,
	Rick Edgecombe <rick.p.edgecombe@intel.com>
Subject: [RFC PATCH 12/13] mmap: Add XO support for KVM XO
Date: Thu,  3 Oct 2019 14:23:59 -0700	[thread overview]
Message-ID: <20191003212400.31130-13-rick.p.edgecombe@intel.com> (raw)
In-Reply-To: <20191003212400.31130-1-rick.p.edgecombe@intel.com>

The KVM XO feature enables the ability to create execute-only virtual
memory. Use this feature to create XO memory when PROT_EXEC and not
PROT_READ, as the behavior in the case of protection keys for userspace
and some arm64 platforms.

In the case of the ability to create execute only memory with protection
keys AND the ability to create native execute only memory, use the KVM
XO method of creating execute only memory to save a protection key.

Set the values of the __P100 and __S100 in protection_map during boot
instead of statically because the actual KVM XO bit in the PTE is
determinted at boot time and so can't be known at compile time.

Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
 arch/x86/include/asm/pgtable_types.h |  2 ++
 arch/x86/kernel/head64.c             |  3 +++
 mm/mmap.c                            | 30 +++++++++++++++++++++++-----
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index d3c92c992089..fe976b4f0132 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -176,6 +176,8 @@ enum page_cache_mode {
 					 _PAGE_ACCESSED | _PAGE_NX)
 #define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
 					 _PAGE_ACCESSED)
+#define PAGE_EXECONLY		__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+					 _PAGE_ACCESSED | _PAGE_NR)
 
 #define __PAGE_KERNEL_EXEC						\
 	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 7091702a7bec..69772b6e1810 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -133,6 +133,9 @@ static void __head check_kvmxo_support(unsigned long physaddr)
 
 	*fixup_int(&__pgtable_kvmxo_enabled, physaddr) = 1;
 	*fixup_int(&__pgtable_kvmxo_bit, physaddr) = physbits;
+
+	protection_map[4] = PAGE_EXECONLY;
+	protection_map[12] = PAGE_EXECONLY;
 }
 #else /* CONFIG_KVM_XO */
 static void __head check_kvmxo_support(unsigned long physaddr) { }
diff --git a/mm/mmap.c b/mm/mmap.c
index 7e8c3e8ae75f..034ffa0255b2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1379,6 +1379,29 @@ static inline bool file_mmap_ok(struct file *file, struct inode *inode,
 	return true;
 }
 
+static inline int get_pkey(unsigned long flags)
+{
+	const unsigned long p_xo = pgprot_val(protection_map[4]);
+	const unsigned long p_xr = pgprot_val(protection_map[5]);
+	const unsigned long s_xo = pgprot_val(protection_map[12]);
+	const unsigned long s_xr = pgprot_val(protection_map[13]);
+	int pkey;
+
+	/* Prefer non-pkey XO capability if available, to save a pkey */
+
+	if (flags & MAP_PRIVATE && (p_xo != p_xr))
+		return 0;
+
+	if (flags & MAP_SHARED && (s_xo != s_xr))
+		return 0;
+
+	pkey = execute_only_pkey(current->mm);
+	if (pkey < 0)
+		pkey = 0;
+
+	return pkey;
+}
+
 /*
  * The caller must hold down_write(&current->mm->mmap_sem).
  */
@@ -1440,11 +1463,8 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
 			return -EEXIST;
 	}
 
-	if (prot == PROT_EXEC) {
-		pkey = execute_only_pkey(mm);
-		if (pkey < 0)
-			pkey = 0;
-	}
+	if (prot == PROT_EXEC)
+		pkey = get_pkey(flags);
 
 	/* Do simple checking here so the lower-level routines won't have
 	 * to. we assume access permissions have been handled by the open
-- 
2.17.1


  parent reply	other threads:[~2019-10-03 21:39 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-03 21:23 [RFC PATCH 00/13] XOM for KVM guest userspace Rick Edgecombe
2019-10-03 21:23 ` [RFC PATCH 01/13] kvm: Enable MTRR to work with GFNs with perm bits Rick Edgecombe
2019-10-14  6:47   ` Yu Zhang
2019-10-14 18:44     ` Edgecombe, Rick P
2019-10-03 21:23 ` [RFC PATCH 02/13] kvm: Add support for X86_FEATURE_KVM_XO Rick Edgecombe
2019-10-03 21:23 ` [RFC PATCH 03/13] kvm: Add XO memslot type Rick Edgecombe
2019-10-04  7:27   ` Paolo Bonzini
2019-10-04 19:06     ` Edgecombe, Rick P
2019-10-06 16:15       ` Paolo Bonzini
2019-10-03 21:23 ` [RFC PATCH 04/13] kvm, vmx: Add support for gva exit qualification Rick Edgecombe
2019-10-03 21:23 ` [RFC PATCH 05/13] kvm: Add #PF injection for KVM XO Rick Edgecombe
2019-10-04  7:42   ` Paolo Bonzini
2019-10-04 19:11     ` Edgecombe, Rick P
2019-10-03 21:23 ` [RFC PATCH 06/13] kvm: Add KVM_CAP_EXECONLY_MEM Rick Edgecombe
2019-10-04  7:24   ` Paolo Bonzini
2019-10-04 19:11     ` Edgecombe, Rick P
2019-10-03 21:23 ` [RFC PATCH 07/13] kvm: Add docs for KVM_CAP_EXECONLY_MEM Rick Edgecombe
2019-10-03 21:23 ` [RFC PATCH 08/13] x86/boot: Rename USE_EARLY_PGTABLE_L5 Rick Edgecombe
2019-10-03 21:23 ` [RFC PATCH 09/13] x86/cpufeature: Add detection of KVM XO Rick Edgecombe
2019-10-29 23:33   ` Kees Cook
2019-10-29 23:52     ` Edgecombe, Rick P
2019-10-30 14:55       ` Sean Christopherson
2019-10-30 21:02         ` Edgecombe, Rick P
2019-10-03 21:23 ` [RFC PATCH 10/13] x86/mm: Add NR page bit for " Rick Edgecombe
2019-10-04  7:33   ` Paolo Bonzini
2019-10-03 21:23 ` [RFC PATCH 11/13] x86, ptdump: Add NR bit to page table dump Rick Edgecombe
2019-10-03 21:23 ` Rick Edgecombe [this message]
2019-10-04  7:34   ` [RFC PATCH 12/13] mmap: Add XO support for KVM XO Paolo Bonzini
2019-10-04 19:12     ` Edgecombe, Rick P
2019-10-03 21:24 ` [RFC PATCH 13/13] x86/Kconfig: Add Kconfig for KVM based XO Rick Edgecombe
2019-10-29 23:36   ` Kees Cook
2019-10-30  0:01     ` Edgecombe, Rick P
2019-10-30 18:36       ` Kees Cook
2019-10-04  7:22 ` [RFC PATCH 00/13] XOM for KVM guest userspace Paolo Bonzini
2019-10-04 19:03   ` Edgecombe, Rick P
2019-10-04 14:56 ` Andy Lutomirski
2019-10-04 20:09   ` Edgecombe, Rick P
2019-10-05  1:33     ` Andy Lutomirski
2019-10-07 18:14       ` Edgecombe, Rick P
2019-10-29 23:40 ` Kees Cook
2019-10-30  0:27   ` Edgecombe, Rick P

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191003212400.31130-13-rick.p.edgecombe@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=deneen.t.dock@intel.com \
    --cc=keescook@chromium.org \
    --cc=kristen@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=sean.j.christopherson@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).