public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: kvm@vger.kernel.org
Cc: "Stephen Hemminger" <sthemmin@microsoft.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	"Haiyang Zhang" <haiyangz@microsoft.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	"Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com>,
	"Bandan Das" <bsd@redhat.com>,
	"Roman Kagan" <rkagan@virtuozzo.com>,
	devel@linuxdriverproject.org,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Mohammed Gamal" <mmorsy@redhat.com>
Subject: [PATCH RFC 6/7] KVM: nVMX: add enlightened VMCS state
Date: Mon, 18 Dec 2017 18:17:41 +0100	[thread overview]
Message-ID: <20171218171742.5765-7-vkuznets@redhat.com> (raw)
In-Reply-To: <20171218171742.5765-1-vkuznets@redhat.com>

From: Ladi Prosek <lprosek@redhat.com>

Adds two bool fields and implements copy_enlightened_to_vmcs12() and
copy_enlightened_to_vmcs12().

Unlike shadow VMCS, enlightened VMCS is para-virtual and active only if
the nested guest explicitly enables it. The pattern repeating itself a
few times throughout this patch:

  if (vmx->nested.enlightened_vmcs_active) {
      /* enlightened! */
  } else if (enable_shadow_vmcs) {
      /* fall-back */
  }

reflects this. If the nested guest elects to not use enlightened VMCS,
the regular HW-assisted shadow VMCS feature is used, if enabled.
enlightened_vmcs_active is never going to be true if
enlightened_vmcs_enabled is not set.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
 arch/x86/kvm/vmx.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 320bb6670413..00b4a362351d 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -503,6 +503,16 @@ struct nested_vmx {
 	 * on what the enlightened VMCS supports.
 	 */
 	bool enlightened_vmcs_enabled;
+	/*
+	 * Indicates that the nested hypervisor performed the last vmentry with
+	 * a Hyper-V enlightened VMCS.
+	 */
+	bool enlightened_vmcs_active;
+
+	/*
+	 * Indicates that the enlightened VMCS must be synced with vmcs12
+	 */
+	bool sync_enlightened_vmcs;
 
 	/* vmcs02_list cache of VMCSs recently used to run L2 guests */
 	struct list_head vmcs02_pool;
@@ -991,6 +1001,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
 static bool guest_state_valid(struct kvm_vcpu *vcpu);
 static u32 vmx_segment_access_rights(struct kvm_segment *var);
 static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
+static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx);
 static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
 static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
 static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
@@ -7455,7 +7466,10 @@ static inline void nested_release_vmcs12(struct vcpu_vmx *vmx)
 	if (vmx->nested.current_vmptr == -1ull)
 		return;
 
-	if (enable_shadow_vmcs) {
+	if (vmx->nested.enlightened_vmcs_active) {
+		copy_enlightened_to_vmcs12(vmx);
+		vmx->nested.sync_enlightened_vmcs = false;
+	} else if (enable_shadow_vmcs) {
 		/* copy to memory all shadowed fields in case
 		   they were modified */
 		copy_shadow_to_vmcs12(vmx);
@@ -7642,6 +7656,20 @@ static inline int vmcs12_write_any(struct kvm_vcpu *vcpu,
 
 }
 
+static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx)
+{
+	kvm_vcpu_read_guest_page(&vmx->vcpu,
+				 vmx->nested.current_vmptr >> PAGE_SHIFT,
+				 vmx->nested.cached_vmcs12, 0, VMCS12_SIZE);
+}
+
+static void copy_vmcs12_to_enlightened(struct vcpu_vmx *vmx)
+{
+	kvm_vcpu_write_guest_page(&vmx->vcpu,
+				  vmx->nested.current_vmptr >> PAGE_SHIFT,
+				  vmx->nested.cached_vmcs12, 0, VMCS12_SIZE);
+}
+
 static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx)
 {
 	int i;
@@ -7841,7 +7869,9 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu)
 static void set_current_vmptr(struct vcpu_vmx *vmx, gpa_t vmptr)
 {
 	vmx->nested.current_vmptr = vmptr;
-	if (enable_shadow_vmcs) {
+	if (vmx->nested.enlightened_vmcs_active) {
+		vmx->nested.sync_enlightened_vmcs = true;
+	} else if (enable_shadow_vmcs) {
 		vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
 			      SECONDARY_EXEC_SHADOW_VMCS);
 		vmcs_write64(VMCS_LINK_POINTER,
@@ -9396,7 +9426,10 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
 		vmcs_write32(PLE_WINDOW, vmx->ple_window);
 	}
 
-	if (vmx->nested.sync_shadow_vmcs) {
+	if (vmx->nested.sync_enlightened_vmcs) {
+		copy_vmcs12_to_enlightened(vmx);
+		vmx->nested.sync_enlightened_vmcs = false;
+	} else if (vmx->nested.sync_shadow_vmcs) {
 		copy_vmcs12_to_shadow(vmx);
 		vmx->nested.sync_shadow_vmcs = false;
 	}
@@ -11017,7 +11050,9 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
 
 	vmcs12 = get_vmcs12(vcpu);
 
-	if (enable_shadow_vmcs)
+	if (vmx->nested.enlightened_vmcs_active)
+		copy_enlightened_to_vmcs12(vmx);
+	else if (enable_shadow_vmcs)
 		copy_shadow_to_vmcs12(vmx);
 
 	/*
@@ -11634,8 +11669,12 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
 	 */
 	kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
 
-	if (enable_shadow_vmcs && exit_reason != -1)
-		vmx->nested.sync_shadow_vmcs = true;
+	if (exit_reason != -1) {
+		if (vmx->nested.enlightened_vmcs_active)
+			vmx->nested.sync_enlightened_vmcs = true;
+		else if (enable_shadow_vmcs)
+			vmx->nested.sync_shadow_vmcs = true;
+	}
 
 	/* in case we halted in L2 */
 	vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
@@ -11714,12 +11753,17 @@ static void nested_vmx_entry_failure(struct kvm_vcpu *vcpu,
 			struct vmcs12 *vmcs12,
 			u32 reason, unsigned long qualification)
 {
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+
 	load_vmcs12_host_state(vcpu, vmcs12);
 	vmcs12->vm_exit_reason = reason | VMX_EXIT_REASONS_FAILED_VMENTRY;
 	vmcs12->exit_qualification = qualification;
 	nested_vmx_succeed(vcpu);
-	if (enable_shadow_vmcs)
-		to_vmx(vcpu)->nested.sync_shadow_vmcs = true;
+
+	if (vmx->nested.enlightened_vmcs_active)
+		vmx->nested.sync_enlightened_vmcs = true;
+	else if (enable_shadow_vmcs)
+		vmx->nested.sync_shadow_vmcs = true;
 }
 
 static int vmx_check_intercept(struct kvm_vcpu *vcpu,
-- 
2.14.3

  parent reply	other threads:[~2017-12-18 17:17 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-18 17:17 [PATCH RFC 0/7] KVM: nVMX: enlightened VMCS initial implementation Vitaly Kuznetsov
2017-12-18 17:17 ` [PATCH RFC 1/7] KVM: x86: rename HV_X64_MSR_APIC_ASSIST_PAGE to HV_X64_MSR_VP_ASSIST_PAGE Vitaly Kuznetsov
2017-12-18 17:17 ` [PATCH RFC 2/7] KVM: nVMX: modify vmcs12 fields to match Hyper-V enlightened VMCS Vitaly Kuznetsov
2017-12-18 20:23   ` Jim Mattson
2017-12-18 21:28     ` Jim Mattson
2017-12-19 12:25       ` Vitaly Kuznetsov
2017-12-19 12:37         ` Paolo Bonzini
2017-12-19 17:40           ` Jim Mattson
2017-12-19 21:19             ` Paolo Bonzini
2017-12-21 13:02           ` Vitaly Kuznetsov
2017-12-19 17:44         ` Jim Mattson
2017-12-18 17:17 ` [PATCH RFC 3/7] KVM: nVMX: add I/O exit ECX, ESI, EDI, EIP vmcs12 fields Vitaly Kuznetsov
2017-12-18 17:17 ` [PATCH RFC 4/7] KVM: hyperv: define VP assist page structure and add helpers Vitaly Kuznetsov
2017-12-18 17:17 ` [PATCH RFC 5/7] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability Vitaly Kuznetsov
2017-12-18 17:17 ` Vitaly Kuznetsov [this message]
2017-12-18 17:17 ` [PATCH RFC 7/7] KVM: nVMX: implement enlightened VMPTRLD Vitaly Kuznetsov
2017-12-19 12:41 ` [PATCH RFC 0/7] KVM: nVMX: enlightened VMCS initial implementation Paolo Bonzini
2017-12-19 13:21   ` Vitaly Kuznetsov
2017-12-21 12:50     ` Vitaly Kuznetsov
2017-12-21 14:32       ` Paolo Bonzini
2017-12-21 15:08         ` Vitaly Kuznetsov

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=20171218171742.5765-7-vkuznets@redhat.com \
    --to=vkuznets@redhat.com \
    --cc=Michael.H.Kelley@microsoft.com \
    --cc=bsd@redhat.com \
    --cc=devel@linuxdriverproject.org \
    --cc=haiyangz@microsoft.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mmorsy@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkagan@virtuozzo.com \
    --cc=rkrcmar@redhat.com \
    --cc=sthemmin@microsoft.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