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
WARNING: multiple messages have this Message-ID (diff)
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: kvm@vger.kernel.org
Cc: x86@kernel.org, "Paolo Bonzini" <pbonzini@redhat.com>,
"Radim Krčmář" <rkrcmar@redhat.com>,
"K. Y. Srinivasan" <kys@microsoft.com>,
"Haiyang Zhang" <haiyangz@microsoft.com>,
"Stephen Hemminger" <sthemmin@microsoft.com>,
"Michael Kelley (EOSG)" <Michael.H.Kelley@microsoft.com>,
"Mohammed Gamal" <mmorsy@redhat.com>,
"Cathy Avery" <cavery@redhat.com>, "Bandan Das" <bsd@redhat.com>,
"Roman Kagan" <rkagan@virtuozzo.com>,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org
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
next prev parent reply other threads:[~2017-12-18 17:17 UTC|newest]
Thread overview: 38+ 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 ` 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 17:17 ` Vitaly Kuznetsov
2017-12-18 20:23 ` Jim Mattson
2017-12-18 20:23 ` Jim Mattson
2017-12-18 21:28 ` Jim Mattson
2017-12-18 21:28 ` Jim Mattson
2017-12-19 12:25 ` Vitaly Kuznetsov
2017-12-19 12:25 ` Vitaly Kuznetsov
2017-12-19 12:37 ` Paolo Bonzini
2017-12-19 12:37 ` Paolo Bonzini
2017-12-19 17:40 ` Jim Mattson
2017-12-19 17:40 ` Jim Mattson
2017-12-19 21:19 ` Paolo Bonzini
2017-12-21 13:02 ` Vitaly Kuznetsov
2017-12-21 13:02 ` Vitaly Kuznetsov
2017-12-19 17:44 ` Jim Mattson
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 ` 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 ` 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
2017-12-18 17:17 ` Vitaly Kuznetsov [this message]
2017-12-18 17:17 ` [PATCH RFC 6/7] KVM: nVMX: add enlightened VMCS state Vitaly Kuznetsov
2017-12-18 17:17 ` [PATCH RFC 7/7] KVM: nVMX: implement enlightened VMPTRLD Vitaly Kuznetsov
2017-12-18 17:17 ` Vitaly Kuznetsov
2017-12-19 12:41 ` [PATCH RFC 0/7] KVM: nVMX: enlightened VMCS initial implementation Paolo Bonzini
2017-12-19 12:41 ` 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 14:32 ` Paolo Bonzini
2017-12-21 15:08 ` Vitaly Kuznetsov
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 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.