kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexandre Chartre <alexandre.chartre@oracle.com>
To: pbonzini@redhat.com, rkrcmar@redhat.com, tglx@linutronix.de,
	mingo@redhat.com, bp@alien8.de, hpa@zytor.com,
	dave.hansen@linux.intel.com, luto@kernel.org,
	peterz@infradead.org, kvm@vger.kernel.org, x86@kernel.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Cc: konrad.wilk@oracle.com, jan.setjeeilers@oracle.com,
	liran.alon@oracle.com, jwadams@google.com, graf@amazon.de,
	rppt@linux.vnet.ibm.com, alexandre.chartre@oracle.com
Subject: [RFC v2 25/26] KVM: x86/asi: Switch to KVM address space on entry to guest
Date: Thu, 11 Jul 2019 16:25:37 +0200	[thread overview]
Message-ID: <1562855138-19507-26-git-send-email-alexandre.chartre@oracle.com> (raw)
In-Reply-To: <1562855138-19507-1-git-send-email-alexandre.chartre@oracle.com>

From: Liran Alon <liran.alon@oracle.com>

Switch to KVM address space on entry to guest. Most of KVM #VMExit
handlers will run in KVM isolated address space and switch back to
host address space only before accessing sensitive data. Sensitive
data is defined as either host data or other VM data.

Currently, we switch back to the host address space on the following
scenarios:
1) When handling guest page-faults:
   As this will access SPTs which contains host PFNs.
2) On schedule-out of vCPU thread
3) On write to guest virtual memory
   (kvm_write_guest_virt_system() can pull in tons of pages)
4) On return to userspace (e.g. QEMU)
5) On interrupt or exception

Signed-off-by: Liran Alon <liran.alon@oracle.com>
Signed-off-by: Alexandre Chartre <alexandre.chartre@oracle.com>
---
 arch/x86/kvm/mmu.c           |    2 +-
 arch/x86/kvm/vmx/isolation.c |    2 +-
 arch/x86/kvm/vmx/vmx.c       |    6 ++++++
 arch/x86/kvm/vmx/vmx.h       |   18 ++++++++++++++++++
 arch/x86/kvm/x86.c           |   34 +++++++++++++++++++++++++++++++++-
 arch/x86/kvm/x86.h           |    1 +
 6 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 98f6e4f..298f602 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -4067,7 +4067,7 @@ int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code,
 {
 	int r = 1;
 
-	vcpu->arch.l1tf_flush_l1d = true;
+	kvm_may_access_sensitive_data(vcpu);
 	switch (vcpu->arch.apf.host_apf_reason) {
 	default:
 		trace_kvm_page_fault(fault_address, error_code);
diff --git a/arch/x86/kvm/vmx/isolation.c b/arch/x86/kvm/vmx/isolation.c
index d82f6b6..8f57f10 100644
--- a/arch/x86/kvm/vmx/isolation.c
+++ b/arch/x86/kvm/vmx/isolation.c
@@ -34,7 +34,7 @@
  * This is set to false by default because it incurs a performance hit
  * which some users will not want to take for security gain.
  */
-static bool __read_mostly address_space_isolation;
+bool __read_mostly address_space_isolation;
 module_param(address_space_isolation, bool, 0444);
 
 /*
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index d47f093..b5867cc 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6458,8 +6458,14 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	if (vcpu->arch.cr2 != read_cr2())
 		write_cr2(vcpu->arch.cr2);
 
+	/*
+	 * Use an isolation barrier as VMExit will restore the isolation
+	 * CR3 while interrupts can abort isolation.
+	 */
+	vmx_isolation_barrier_begin(vmx);
 	vmx->fail = __vmx_vcpu_run(vmx, (unsigned long *)&vcpu->arch.regs,
 				   vmx->loaded_vmcs->launched);
+	vmx_isolation_barrier_end(vmx);
 
 	vcpu->arch.cr2 = read_cr2();
 
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index e8de23b..b65f059 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -531,4 +531,22 @@ static inline void decache_tsc_multiplier(struct vcpu_vmx *vmx)
 int vmx_isolation_init(struct vcpu_vmx *vmx);
 void vmx_isolation_uninit(struct vcpu_vmx *vmx);
 
+extern bool __read_mostly address_space_isolation;
+
+static inline void vmx_isolation_barrier_begin(struct vcpu_vmx *vmx)
+{
+	if (!address_space_isolation || !vmx->vcpu.asi)
+		return;
+
+	asi_barrier_begin();
+}
+
+static inline void vmx_isolation_barrier_end(struct vcpu_vmx *vmx)
+{
+	if (!address_space_isolation || !vmx->vcpu.asi)
+		return;
+
+	asi_barrier_end();
+}
+
 #endif /* __KVM_X86_VMX_H */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9857992..9458413 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3346,6 +3346,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 	 * guest. do_debug expects dr6 to be cleared after it runs, do the same.
 	 */
 	set_debugreg(0, 6);
+
+	kvm_may_access_sensitive_data(vcpu);
 }
 
 static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
@@ -5259,7 +5261,7 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
 				unsigned int bytes, struct x86_exception *exception)
 {
 	/* kvm_write_guest_virt_system can pull in tons of pages. */
-	vcpu->arch.l1tf_flush_l1d = true;
+	kvm_may_access_sensitive_data(vcpu);
 
 	return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
 					   PFERR_WRITE_MASK, exception);
@@ -7744,6 +7746,32 @@ void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
 }
 EXPORT_SYMBOL_GPL(__kvm_request_immediate_exit);
 
+static void vcpu_isolation_enter(struct kvm_vcpu *vcpu)
+{
+	int err;
+
+	if (!vcpu->asi)
+		return;
+
+	err = asi_enter(vcpu->asi);
+	if (err)
+		pr_debug("KVM isolation failed: error %d\n", err);
+}
+
+static void vcpu_isolation_exit(struct kvm_vcpu *vcpu)
+{
+	if (!vcpu->asi)
+		return;
+
+	asi_exit(vcpu->asi);
+}
+
+void kvm_may_access_sensitive_data(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.l1tf_flush_l1d = true;
+	vcpu_isolation_exit(vcpu);
+}
+
 /*
  * Returns 1 to let vcpu_run() continue the guest execution loop without
  * exiting to the userspace.  Otherwise, the value will be returned to the
@@ -7944,6 +7972,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 		goto cancel_injection;
 	}
 
+	vcpu_isolation_enter(vcpu);
+
 	if (req_immediate_exit) {
 		kvm_make_request(KVM_REQ_EVENT, vcpu);
 		kvm_x86_ops->request_immediate_exit(vcpu);
@@ -8130,6 +8160,8 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
 
 	srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 
+	kvm_may_access_sensitive_data(vcpu);
+
 	return r;
 }
 
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index a470ff0..69a7402 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -356,5 +356,6 @@ static inline bool kvm_pat_valid(u64 data)
 
 void kvm_load_guest_xcr0(struct kvm_vcpu *vcpu);
 void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu);
+void kvm_may_access_sensitive_data(struct kvm_vcpu *vcpu);
 
 #endif
-- 
1.7.1


  parent reply	other threads:[~2019-07-11 14:28 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-11 14:25 [RFC v2 00/27] Kernel Address Space Isolation Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 01/26] mm/x86: Introduce kernel address space isolation Alexandre Chartre
2019-07-11 21:33   ` Thomas Gleixner
2019-07-12  7:43     ` Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 02/26] mm/asi: Abort isolation on interrupt, exception and context switch Alexandre Chartre
2019-07-11 20:11   ` Andi Kleen
2019-07-11 20:17     ` Mike Rapoport
2019-07-11 20:41       ` Alexandre Chartre
2019-07-12  0:05   ` Andy Lutomirski
2019-07-12  7:50     ` Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 03/26] mm/asi: Handle page fault due to address space isolation Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 04/26] mm/asi: Functions to track buffers allocated for an ASI page-table Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 05/26] mm/asi: Add ASI page-table entry offset functions Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 06/26] mm/asi: Add ASI page-table entry allocation functions Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 07/26] mm/asi: Add ASI page-table entry set functions Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 08/26] mm/asi: Functions to populate an ASI page-table from a VA range Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 09/26] mm/asi: Helper functions to map module into ASI Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 10/26] mm/asi: Keep track of VA ranges mapped in ASI page-table Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 11/26] mm/asi: Functions to clear ASI page-table entries for a VA range Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 12/26] mm/asi: Function to copy page-table entries for percpu buffer Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 13/26] mm/asi: Add asi_remap() function Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 14/26] mm/asi: Handle ASI mapped range leaks and overlaps Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 15/26] mm/asi: Initialize the ASI page-table with core mappings Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 16/26] mm/asi: Option to map current task into ASI Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 17/26] rcu: Move tree.h static forward declarations to tree.c Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 18/26] rcu: Make percpu rcu_data non-static Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 19/26] mm/asi: Add option to map RCU data Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 20/26] mm/asi: Add option to map cpu_hw_events Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 21/26] mm/asi: Make functions to read cr3/cr4 ASI aware Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 22/26] KVM: x86/asi: Introduce address_space_isolation module parameter Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 23/26] KVM: x86/asi: Introduce KVM address space isolation Alexandre Chartre
2019-07-11 14:25 ` [RFC v2 24/26] KVM: x86/asi: Populate the KVM ASI page-table Alexandre Chartre
2019-07-11 14:25 ` Alexandre Chartre [this message]
2019-07-11 14:25 ` [RFC v2 26/26] KVM: x86/asi: Map KVM memslots and IO buses into KVM ASI Alexandre Chartre
2019-07-11 14:40 ` [RFC v2 00/27] Kernel Address Space Isolation Alexandre Chartre
2019-07-11 22:38 ` Dave Hansen
2019-07-12  8:09   ` Alexandre Chartre
2019-07-12 13:51     ` Dave Hansen
2019-07-12 14:06       ` Alexandre Chartre
2019-07-12 15:23         ` Thomas Gleixner
2019-07-12 10:44   ` Thomas Gleixner
2019-07-12 11:56     ` Alexandre Chartre
2019-07-12 12:50       ` Peter Zijlstra
2019-07-12 13:43         ` Alexandre Chartre
2019-07-12 13:58           ` Dave Hansen
2019-07-12 14:36           ` Andy Lutomirski
2019-07-14 18:17             ` Alexander Graf
2019-07-12 13:54         ` Dave Hansen
2019-07-12 15:20           ` Peter Zijlstra
2019-07-12 15:16         ` Thomas Gleixner
2019-07-12 16:37           ` Alexandre Chartre
2019-07-12 16:45             ` Andy Lutomirski
2019-07-14 17:11               ` Mike Rapoport
2019-07-12 19:06             ` Peter Zijlstra
2019-07-14 15:06               ` Andy Lutomirski
2019-07-15 10:33                 ` Peter Zijlstra
2019-07-12 19:48             ` Thomas Gleixner
2019-07-15  8:23               ` Alexandre Chartre
2019-07-15  8:28                 ` Thomas Gleixner
2019-07-12 16:00       ` Thomas Gleixner
2019-07-12 11:44 ` Peter Zijlstra
2019-07-12 12:17   ` Alexandre Chartre
2019-07-12 12:36     ` Peter Zijlstra
2019-07-12 12:47       ` Alexandre Chartre
2019-07-12 13:07         ` Peter Zijlstra
2019-07-12 13:46           ` Alexandre Chartre
2019-07-31 16:31             ` Dario Faggioli
2019-08-22 12:31               ` Alexandre Chartre

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=1562855138-19507-26-git-send-email-alexandre.chartre@oracle.com \
    --to=alexandre.chartre@oracle.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=graf@amazon.de \
    --cc=hpa@zytor.com \
    --cc=jan.setjeeilers@oracle.com \
    --cc=jwadams@google.com \
    --cc=konrad.wilk@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=liran.alon@oracle.com \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rkrcmar@redhat.com \
    --cc=rppt@linux.vnet.ibm.com \
    --cc=tglx@linutronix.de \
    --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).