All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw@amazon.co.uk>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Jim Mattson" <jmattson@google.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	"KarimAllah Ahmed" <karahmed@amazon.de>,
	gregkh@linuxfoundation.org, stable@vger.kernel.org
Subject: [PATCH 2/9] KVM: nVMX: mark vmcs12 pages dirty on L2 exit
Date: Tue,  6 Feb 2018 17:29:34 +0000	[thread overview]
Message-ID: <1517938181-15317-3-git-send-email-dwmw@amazon.co.uk> (raw)
In-Reply-To: <1517938181-15317-1-git-send-email-dwmw@amazon.co.uk>

From: David Matlack <dmatlack@google.com>

The host physical addresses of L1's Virtual APIC Page and Posted
Interrupt descriptor are loaded into the VMCS02. The CPU may write
to these pages via their host physical address while L2 is running,
bypassing address-translation-based dirty tracking (e.g. EPT write
protection). Mark them dirty on every exit from L2 to prevent them
from getting out of sync with dirty tracking.

Also mark the virtual APIC page and the posted interrupt descriptor
dirty when KVM is virtualizing posted interrupt processing.

Signed-off-by: David Matlack <dmatlack@google.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>

(cherry picked from commit c9f04407f2e0b3fc9ff7913c65fcfcb0a4b61570)
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 arch/x86/kvm/vmx.c | 53 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 43 insertions(+), 10 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index fd890af..9408ae8 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4736,6 +4736,28 @@ static bool vmx_get_enable_apicv(void)
 	return enable_apicv;
 }
 
+static void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu)
+{
+	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+	gfn_t gfn;
+
+	/*
+	 * Don't need to mark the APIC access page dirty; it is never
+	 * written to by the CPU during APIC virtualization.
+	 */
+
+	if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) {
+		gfn = vmcs12->virtual_apic_page_addr >> PAGE_SHIFT;
+		kvm_vcpu_mark_page_dirty(vcpu, gfn);
+	}
+
+	if (nested_cpu_has_posted_intr(vmcs12)) {
+		gfn = vmcs12->posted_intr_desc_addr >> PAGE_SHIFT;
+		kvm_vcpu_mark_page_dirty(vcpu, gfn);
+	}
+}
+
+
 static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -4743,18 +4765,15 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
 	void *vapic_page;
 	u16 status;
 
-	if (vmx->nested.pi_desc &&
-	    vmx->nested.pi_pending) {
-		vmx->nested.pi_pending = false;
-		if (!pi_test_and_clear_on(vmx->nested.pi_desc))
-			return;
-
-		max_irr = find_last_bit(
-			(unsigned long *)vmx->nested.pi_desc->pir, 256);
+	if (!vmx->nested.pi_desc || !vmx->nested.pi_pending)
+		return;
 
-		if (max_irr == 256)
-			return;
+	vmx->nested.pi_pending = false;
+	if (!pi_test_and_clear_on(vmx->nested.pi_desc))
+		return;
 
+	max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
+	if (max_irr != 256) {
 		vapic_page = kmap(vmx->nested.virtual_apic_page);
 		if (!vapic_page) {
 			WARN_ON(1);
@@ -4770,6 +4789,8 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
 			vmcs_write16(GUEST_INTR_STATUS, status);
 		}
 	}
+
+	nested_mark_vmcs12_pages_dirty(vcpu);
 }
 
 static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
@@ -8026,6 +8047,18 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
 				vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
 				KVM_ISA_VMX);
 
+	/*
+	 * The host physical addresses of some pages of guest memory
+	 * are loaded into VMCS02 (e.g. L1's Virtual APIC Page). The CPU
+	 * may write to these pages via their host physical address while
+	 * L2 is running, bypassing any address-translation-based dirty
+	 * tracking (e.g. EPT write protection).
+	 *
+	 * Mark them dirty on every exit from L2 to prevent them from
+	 * getting out of sync with dirty tracking.
+	 */
+	nested_mark_vmcs12_pages_dirty(vcpu);
+
 	if (vmx->nested.nested_run_pending)
 		return false;
 
-- 
2.7.4

  parent reply	other threads:[~2018-02-06 17:33 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-06 17:29 [STABLE 4.9.y PATCH 0/9] Backport of KVM Speculation Control support David Woodhouse
2018-02-06 17:29 ` [PATCH 1/9] KVM: nVMX: vmx_complete_nested_posted_interrupt() can't fail David Woodhouse
2018-02-06 17:29 ` David Woodhouse [this message]
2018-02-06 17:29 ` [PATCH 3/9] KVM: nVMX: Eliminate vmcs02 pool David Woodhouse
2018-02-06 17:29 ` [PATCH 4/9] KVM: VMX: introduce alloc_loaded_vmcs David Woodhouse
2018-02-06 17:29 ` [PATCH 5/9] KVM: VMX: make MSR bitmaps per-VCPU David Woodhouse
2018-02-06 17:29 ` [PATCH 6/9] KVM/x86: Add IBPB support David Woodhouse
2018-02-06 17:29 ` [PATCH 7/9] KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES David Woodhouse
2018-02-16 14:18   ` Paolo Bonzini
2018-02-16 16:29     ` Jim Mattson
2018-02-16 16:33       ` David Woodhouse
2018-02-19 13:10       ` Paolo Bonzini
2018-02-19 13:35         ` David Woodhouse
2018-02-19 14:07           ` Paolo Bonzini
2018-02-06 17:29 ` [PATCH 8/9] KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL David Woodhouse
2018-02-16  4:02   ` Jim Mattson
2018-02-16  4:16   ` Jim Mattson
2018-02-06 17:29 ` [PATCH 9/9] KVM/SVM: " David Woodhouse
2018-02-06 18:01 ` [STABLE 4.9.y PATCH 0/9] Backport of KVM Speculation Control support Paolo Bonzini
2018-02-06 21:05   ` Woodhouse, David
2018-02-08  2:49     ` Greg KH
2018-02-08  2:49       ` Greg KH
2018-02-08 17:14       ` Greg KH
2018-02-08 17:14         ` Greg KH
2018-02-08 17:42         ` Paolo Bonzini
2018-02-08 17:57           ` Greg KH
2018-02-08 17:57             ` Greg KH
2018-02-09  7:58             ` Greg KH
2018-02-09  7:58               ` Greg KH
2018-02-15 10:15 ` Thomas Voegtle
2018-02-15 10:23   ` Greg KH
2018-02-15 10:49     ` Thomas Voegtle
2018-02-15 13:57       ` Greg KH

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=1517938181-15317-3-git-send-email-dwmw@amazon.co.uk \
    --to=dwmw@amazon.co.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=jmattson@google.com \
    --cc=karahmed@amazon.de \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=stable@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.