* [PATCH] x86/kvm/nVMX: tweak shadow fields @ 2018-10-19 14:16 Vitaly Kuznetsov 2018-10-19 16:45 ` Paolo Bonzini 0 siblings, 1 reply; 5+ messages in thread From: Vitaly Kuznetsov @ 2018-10-19 14:16 UTC (permalink / raw) To: kvm Cc: Paolo Bonzini, Radim Krčmář, Jim Mattson, Liran Alon, linux-kernel It seems we have some leftovers from times when 'unrestricted guest' wasn't exposed to L1. Stop shadowing GUEST_CS_{BASE,LIMIT,AR_SELECTOR} and GUEST_ES_BASE, shadow GUEST_SS_AR_BYTES as it was found that some hypervisors (e.g. Hyper-V without Enlightened VMCS) access it pretty often. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> --- arch/x86/kvm/vmx.c | 10 +++++----- arch/x86/kvm/vmx_shadow_fields.h | 5 +---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index abeeb45d1c33..641a65b30685 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -12715,6 +12715,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector); + vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); vmcs_write16(GUEST_SS_SELECTOR, vmcs12->guest_ss_selector); vmcs_write16(GUEST_DS_SELECTOR, vmcs12->guest_ds_selector); vmcs_write16(GUEST_FS_SELECTOR, vmcs12->guest_fs_selector); @@ -12722,6 +12723,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) vmcs_write16(GUEST_LDTR_SELECTOR, vmcs12->guest_ldtr_selector); vmcs_write16(GUEST_TR_SELECTOR, vmcs12->guest_tr_selector); vmcs_write32(GUEST_ES_LIMIT, vmcs12->guest_es_limit); + vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); vmcs_write32(GUEST_SS_LIMIT, vmcs12->guest_ss_limit); vmcs_write32(GUEST_DS_LIMIT, vmcs12->guest_ds_limit); vmcs_write32(GUEST_FS_LIMIT, vmcs12->guest_fs_limit); @@ -12731,12 +12733,13 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) vmcs_write32(GUEST_GDTR_LIMIT, vmcs12->guest_gdtr_limit); vmcs_write32(GUEST_IDTR_LIMIT, vmcs12->guest_idtr_limit); vmcs_write32(GUEST_ES_AR_BYTES, vmcs12->guest_es_ar_bytes); - vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); vmcs_write32(GUEST_DS_AR_BYTES, vmcs12->guest_ds_ar_bytes); vmcs_write32(GUEST_FS_AR_BYTES, vmcs12->guest_fs_ar_bytes); vmcs_write32(GUEST_GS_AR_BYTES, vmcs12->guest_gs_ar_bytes); vmcs_write32(GUEST_LDTR_AR_BYTES, vmcs12->guest_ldtr_ar_bytes); vmcs_write32(GUEST_TR_AR_BYTES, vmcs12->guest_tr_ar_bytes); + vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); + vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); vmcs_writel(GUEST_SS_BASE, vmcs12->guest_ss_base); vmcs_writel(GUEST_DS_BASE, vmcs12->guest_ds_base); vmcs_writel(GUEST_FS_BASE, vmcs12->guest_fs_base); @@ -12838,11 +12841,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, */ if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { - vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); - vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); vmcs_write32(GUEST_CS_AR_BYTES, vmcs12->guest_cs_ar_bytes); - vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); - vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); + vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); } if (vmx->nested.nested_run_pending && diff --git a/arch/x86/kvm/vmx_shadow_fields.h b/arch/x86/kvm/vmx_shadow_fields.h index cd0c75f6d037..132432f375c2 100644 --- a/arch/x86/kvm/vmx_shadow_fields.h +++ b/arch/x86/kvm/vmx_shadow_fields.h @@ -28,7 +28,6 @@ */ /* 16-bits */ -SHADOW_FIELD_RW(GUEST_CS_SELECTOR) SHADOW_FIELD_RW(GUEST_INTR_STATUS) SHADOW_FIELD_RW(GUEST_PML_INDEX) SHADOW_FIELD_RW(HOST_FS_SELECTOR) @@ -47,8 +46,8 @@ SHADOW_FIELD_RW(VM_ENTRY_EXCEPTION_ERROR_CODE) SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD) SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN) SHADOW_FIELD_RW(TPR_THRESHOLD) -SHADOW_FIELD_RW(GUEST_CS_LIMIT) SHADOW_FIELD_RW(GUEST_CS_AR_BYTES) +SHADOW_FIELD_RW(GUEST_SS_AR_BYTES) SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO) SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE) @@ -61,8 +60,6 @@ SHADOW_FIELD_RW(GUEST_CR0) SHADOW_FIELD_RW(GUEST_CR3) SHADOW_FIELD_RW(GUEST_CR4) SHADOW_FIELD_RW(GUEST_RFLAGS) -SHADOW_FIELD_RW(GUEST_CS_BASE) -SHADOW_FIELD_RW(GUEST_ES_BASE) SHADOW_FIELD_RW(CR0_GUEST_HOST_MASK) SHADOW_FIELD_RW(CR0_READ_SHADOW) SHADOW_FIELD_RW(CR4_READ_SHADOW) -- 2.17.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/kvm/nVMX: tweak shadow fields 2018-10-19 14:16 [PATCH] x86/kvm/nVMX: tweak shadow fields Vitaly Kuznetsov @ 2018-10-19 16:45 ` Paolo Bonzini 2018-11-09 22:11 ` Jim Mattson 0 siblings, 1 reply; 5+ messages in thread From: Paolo Bonzini @ 2018-10-19 16:45 UTC (permalink / raw) To: Vitaly Kuznetsov, kvm Cc: Radim Krčmář, Jim Mattson, Liran Alon, linux-kernel On 19/10/2018 16:16, Vitaly Kuznetsov wrote: > It seems we have some leftovers from times when 'unrestricted guest' > wasn't exposed to L1. Stop shadowing GUEST_CS_{BASE,LIMIT,AR_SELECTOR} > and GUEST_ES_BASE, shadow GUEST_SS_AR_BYTES as it was found that some > hypervisors (e.g. Hyper-V without Enlightened VMCS) access it pretty > often. > > Suggested-by: Paolo Bonzini <pbonzini@redhat.com> > Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Queued, thanks. Paolo > --- > arch/x86/kvm/vmx.c | 10 +++++----- > arch/x86/kvm/vmx_shadow_fields.h | 5 +---- > 2 files changed, 6 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index abeeb45d1c33..641a65b30685 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -12715,6 +12715,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) > if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & > HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { > vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector); > + vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); > vmcs_write16(GUEST_SS_SELECTOR, vmcs12->guest_ss_selector); > vmcs_write16(GUEST_DS_SELECTOR, vmcs12->guest_ds_selector); > vmcs_write16(GUEST_FS_SELECTOR, vmcs12->guest_fs_selector); > @@ -12722,6 +12723,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) > vmcs_write16(GUEST_LDTR_SELECTOR, vmcs12->guest_ldtr_selector); > vmcs_write16(GUEST_TR_SELECTOR, vmcs12->guest_tr_selector); > vmcs_write32(GUEST_ES_LIMIT, vmcs12->guest_es_limit); > + vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); > vmcs_write32(GUEST_SS_LIMIT, vmcs12->guest_ss_limit); > vmcs_write32(GUEST_DS_LIMIT, vmcs12->guest_ds_limit); > vmcs_write32(GUEST_FS_LIMIT, vmcs12->guest_fs_limit); > @@ -12731,12 +12733,13 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) > vmcs_write32(GUEST_GDTR_LIMIT, vmcs12->guest_gdtr_limit); > vmcs_write32(GUEST_IDTR_LIMIT, vmcs12->guest_idtr_limit); > vmcs_write32(GUEST_ES_AR_BYTES, vmcs12->guest_es_ar_bytes); > - vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); > vmcs_write32(GUEST_DS_AR_BYTES, vmcs12->guest_ds_ar_bytes); > vmcs_write32(GUEST_FS_AR_BYTES, vmcs12->guest_fs_ar_bytes); > vmcs_write32(GUEST_GS_AR_BYTES, vmcs12->guest_gs_ar_bytes); > vmcs_write32(GUEST_LDTR_AR_BYTES, vmcs12->guest_ldtr_ar_bytes); > vmcs_write32(GUEST_TR_AR_BYTES, vmcs12->guest_tr_ar_bytes); > + vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); > + vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); > vmcs_writel(GUEST_SS_BASE, vmcs12->guest_ss_base); > vmcs_writel(GUEST_DS_BASE, vmcs12->guest_ds_base); > vmcs_writel(GUEST_FS_BASE, vmcs12->guest_fs_base); > @@ -12838,11 +12841,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, > */ > if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & > HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { > - vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); > - vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); > vmcs_write32(GUEST_CS_AR_BYTES, vmcs12->guest_cs_ar_bytes); > - vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); > - vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); > + vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); > } > > if (vmx->nested.nested_run_pending && > diff --git a/arch/x86/kvm/vmx_shadow_fields.h b/arch/x86/kvm/vmx_shadow_fields.h > index cd0c75f6d037..132432f375c2 100644 > --- a/arch/x86/kvm/vmx_shadow_fields.h > +++ b/arch/x86/kvm/vmx_shadow_fields.h > @@ -28,7 +28,6 @@ > */ > > /* 16-bits */ > -SHADOW_FIELD_RW(GUEST_CS_SELECTOR) > SHADOW_FIELD_RW(GUEST_INTR_STATUS) > SHADOW_FIELD_RW(GUEST_PML_INDEX) > SHADOW_FIELD_RW(HOST_FS_SELECTOR) > @@ -47,8 +46,8 @@ SHADOW_FIELD_RW(VM_ENTRY_EXCEPTION_ERROR_CODE) > SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD) > SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN) > SHADOW_FIELD_RW(TPR_THRESHOLD) > -SHADOW_FIELD_RW(GUEST_CS_LIMIT) > SHADOW_FIELD_RW(GUEST_CS_AR_BYTES) > +SHADOW_FIELD_RW(GUEST_SS_AR_BYTES) > SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO) > SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE) > > @@ -61,8 +60,6 @@ SHADOW_FIELD_RW(GUEST_CR0) > SHADOW_FIELD_RW(GUEST_CR3) > SHADOW_FIELD_RW(GUEST_CR4) > SHADOW_FIELD_RW(GUEST_RFLAGS) > -SHADOW_FIELD_RW(GUEST_CS_BASE) > -SHADOW_FIELD_RW(GUEST_ES_BASE) > SHADOW_FIELD_RW(CR0_GUEST_HOST_MASK) > SHADOW_FIELD_RW(CR0_READ_SHADOW) > SHADOW_FIELD_RW(CR4_READ_SHADOW) > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/kvm/nVMX: tweak shadow fields 2018-10-19 16:45 ` Paolo Bonzini @ 2018-11-09 22:11 ` Jim Mattson 2018-11-12 14:39 ` Vitaly Kuznetsov 0 siblings, 1 reply; 5+ messages in thread From: Jim Mattson @ 2018-11-09 22:11 UTC (permalink / raw) To: Paolo Bonzini Cc: Vitaly Kuznetsov, kvm list, Radim Krčmář, Liran Alon, LKML I'm not convinced that the "one size fits all" and "context-free" approaches to VMCS shadowing are terribly effective. For example, we never shadow VMX_INSTRUCTION_INFO, but if we just reflected an exit to L1 for which that field is defined, there's probably a good chance that L1 will use it. We always shadow VM_EXIT_INTR_INFO, but if we didn't just reflect exit reason 0 to L1, it's not likely to be read. If the L2 guest is in legacy mode or compatibility mode, L1 is much more likely to be interested in the contents of the descriptor cache than if the guest is in 64-bit mode. Some hypervisors write TSC_OFFSET quite frequently. Others rarely. Last time I checked (it's been a while), VirtualBox was always interested in everything. :-) Kvm, Hyper-V, VMware, VirtualBox, Parallels...they all have different patterns, and they change from release to release. Is it worth having a set of VMCS shadowing bitmaps per-vCPU, in order to make better use of this feature? On Fri, Oct 19, 2018 at 9:45 AM, Paolo Bonzini <pbonzini@redhat.com> wrote: > On 19/10/2018 16:16, Vitaly Kuznetsov wrote: >> It seems we have some leftovers from times when 'unrestricted guest' >> wasn't exposed to L1. Stop shadowing GUEST_CS_{BASE,LIMIT,AR_SELECTOR} >> and GUEST_ES_BASE, shadow GUEST_SS_AR_BYTES as it was found that some >> hypervisors (e.g. Hyper-V without Enlightened VMCS) access it pretty >> often. >> >> Suggested-by: Paolo Bonzini <pbonzini@redhat.com> >> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> > > Queued, thanks. > > Paolo > >> --- >> arch/x86/kvm/vmx.c | 10 +++++----- >> arch/x86/kvm/vmx_shadow_fields.h | 5 +---- >> 2 files changed, 6 insertions(+), 9 deletions(-) >> >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c >> index abeeb45d1c33..641a65b30685 100644 >> --- a/arch/x86/kvm/vmx.c >> +++ b/arch/x86/kvm/vmx.c >> @@ -12715,6 +12715,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) >> if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & >> HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { >> vmcs_write16(GUEST_ES_SELECTOR, vmcs12->guest_es_selector); >> + vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); >> vmcs_write16(GUEST_SS_SELECTOR, vmcs12->guest_ss_selector); >> vmcs_write16(GUEST_DS_SELECTOR, vmcs12->guest_ds_selector); >> vmcs_write16(GUEST_FS_SELECTOR, vmcs12->guest_fs_selector); >> @@ -12722,6 +12723,7 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) >> vmcs_write16(GUEST_LDTR_SELECTOR, vmcs12->guest_ldtr_selector); >> vmcs_write16(GUEST_TR_SELECTOR, vmcs12->guest_tr_selector); >> vmcs_write32(GUEST_ES_LIMIT, vmcs12->guest_es_limit); >> + vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); >> vmcs_write32(GUEST_SS_LIMIT, vmcs12->guest_ss_limit); >> vmcs_write32(GUEST_DS_LIMIT, vmcs12->guest_ds_limit); >> vmcs_write32(GUEST_FS_LIMIT, vmcs12->guest_fs_limit); >> @@ -12731,12 +12733,13 @@ static void prepare_vmcs02_full(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) >> vmcs_write32(GUEST_GDTR_LIMIT, vmcs12->guest_gdtr_limit); >> vmcs_write32(GUEST_IDTR_LIMIT, vmcs12->guest_idtr_limit); >> vmcs_write32(GUEST_ES_AR_BYTES, vmcs12->guest_es_ar_bytes); >> - vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); >> vmcs_write32(GUEST_DS_AR_BYTES, vmcs12->guest_ds_ar_bytes); >> vmcs_write32(GUEST_FS_AR_BYTES, vmcs12->guest_fs_ar_bytes); >> vmcs_write32(GUEST_GS_AR_BYTES, vmcs12->guest_gs_ar_bytes); >> vmcs_write32(GUEST_LDTR_AR_BYTES, vmcs12->guest_ldtr_ar_bytes); >> vmcs_write32(GUEST_TR_AR_BYTES, vmcs12->guest_tr_ar_bytes); >> + vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); >> + vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); >> vmcs_writel(GUEST_SS_BASE, vmcs12->guest_ss_base); >> vmcs_writel(GUEST_DS_BASE, vmcs12->guest_ds_base); >> vmcs_writel(GUEST_FS_BASE, vmcs12->guest_fs_base); >> @@ -12838,11 +12841,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, >> */ >> if (!hv_evmcs || !(hv_evmcs->hv_clean_fields & >> HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) { >> - vmcs_write16(GUEST_CS_SELECTOR, vmcs12->guest_cs_selector); >> - vmcs_write32(GUEST_CS_LIMIT, vmcs12->guest_cs_limit); >> vmcs_write32(GUEST_CS_AR_BYTES, vmcs12->guest_cs_ar_bytes); >> - vmcs_writel(GUEST_ES_BASE, vmcs12->guest_es_base); >> - vmcs_writel(GUEST_CS_BASE, vmcs12->guest_cs_base); >> + vmcs_write32(GUEST_SS_AR_BYTES, vmcs12->guest_ss_ar_bytes); >> } >> >> if (vmx->nested.nested_run_pending && >> diff --git a/arch/x86/kvm/vmx_shadow_fields.h b/arch/x86/kvm/vmx_shadow_fields.h >> index cd0c75f6d037..132432f375c2 100644 >> --- a/arch/x86/kvm/vmx_shadow_fields.h >> +++ b/arch/x86/kvm/vmx_shadow_fields.h >> @@ -28,7 +28,6 @@ >> */ >> >> /* 16-bits */ >> -SHADOW_FIELD_RW(GUEST_CS_SELECTOR) >> SHADOW_FIELD_RW(GUEST_INTR_STATUS) >> SHADOW_FIELD_RW(GUEST_PML_INDEX) >> SHADOW_FIELD_RW(HOST_FS_SELECTOR) >> @@ -47,8 +46,8 @@ SHADOW_FIELD_RW(VM_ENTRY_EXCEPTION_ERROR_CODE) >> SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD) >> SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN) >> SHADOW_FIELD_RW(TPR_THRESHOLD) >> -SHADOW_FIELD_RW(GUEST_CS_LIMIT) >> SHADOW_FIELD_RW(GUEST_CS_AR_BYTES) >> +SHADOW_FIELD_RW(GUEST_SS_AR_BYTES) >> SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO) >> SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE) >> >> @@ -61,8 +60,6 @@ SHADOW_FIELD_RW(GUEST_CR0) >> SHADOW_FIELD_RW(GUEST_CR3) >> SHADOW_FIELD_RW(GUEST_CR4) >> SHADOW_FIELD_RW(GUEST_RFLAGS) >> -SHADOW_FIELD_RW(GUEST_CS_BASE) >> -SHADOW_FIELD_RW(GUEST_ES_BASE) >> SHADOW_FIELD_RW(CR0_GUEST_HOST_MASK) >> SHADOW_FIELD_RW(CR0_READ_SHADOW) >> SHADOW_FIELD_RW(CR4_READ_SHADOW) >> > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/kvm/nVMX: tweak shadow fields 2018-11-09 22:11 ` Jim Mattson @ 2018-11-12 14:39 ` Vitaly Kuznetsov 2018-11-14 11:34 ` Paolo Bonzini 0 siblings, 1 reply; 5+ messages in thread From: Vitaly Kuznetsov @ 2018-11-12 14:39 UTC (permalink / raw) To: Jim Mattson, Paolo Bonzini Cc: kvm list, Radim Krčmář, Liran Alon, LKML Jim Mattson <jmattson@google.com> writes: > I'm not convinced that the "one size fits all" and "context-free" > approaches to VMCS shadowing are terribly effective. > > For example, we never shadow VMX_INSTRUCTION_INFO, but if we just > reflected an exit to L1 for which that field is defined, there's > probably a good chance that L1 will use it. We always shadow > VM_EXIT_INTR_INFO, but if we didn't just reflect exit reason 0 to L1, > it's not likely to be read. If the L2 guest is in legacy mode or > compatibility mode, L1 is much more likely to be interested in the > contents of the descriptor cache than if the guest is in 64-bit mode. > > Some hypervisors write TSC_OFFSET quite frequently. Others rarely. > Last time I checked (it's been a while), VirtualBox was always > interested in everything. :-) Kvm, Hyper-V, VMware, VirtualBox, > Parallels...they all have different patterns, and they change from > release to release. > > Is it worth having a set of VMCS shadowing bitmaps per-vCPU, in order > to make better use of this feature? Per CPU or not, to improve the feature we'll probably need some sort of an 'adaptive' algorithm picking which fields to shadow. I haven't thought this through, especially read/write shadowing, but we can probably start with an empty bitmap and later shadow it when we get over some threshold of vmread/vmwrite exits we enabling shadowing. The question is when we un-shadow it. For example, we can un-shadow a field for writing every time we see it was not changed between two exits to L0 (so we're trying to write the same value to vmcs12). -- Vitaly ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] x86/kvm/nVMX: tweak shadow fields 2018-11-12 14:39 ` Vitaly Kuznetsov @ 2018-11-14 11:34 ` Paolo Bonzini 0 siblings, 0 replies; 5+ messages in thread From: Paolo Bonzini @ 2018-11-14 11:34 UTC (permalink / raw) To: Vitaly Kuznetsov, Jim Mattson Cc: kvm list, Radim Krčmář, Liran Alon, LKML On 12/11/2018 15:39, Vitaly Kuznetsov wrote: >> Is it worth having a set of VMCS shadowing bitmaps per-vCPU, in order >> to make better use of this feature? > Per CPU or not, to improve the feature we'll probably need some sort of > an 'adaptive' algorithm picking which fields to shadow. I agree, making it per-VCPU is not useful alone. The question is to balance. The complexity and the number of fields that have to be copied between the VMCSes. If a vmexit type is rare, it makes sense not to shadow a field that would be always defined by that vmexit type, rather than pay a fixed price (even if it is loop overhead only) on all vmexits; this is the case VMX_INSTRUCTION_INFO. One thing that would make sense is to have separate shadow bitmaps for 32- and 64-bit L2. 32-bit L2 probably will need to shadow at least the segment bases. But for 64-bit L2, the current set is small and nice. There are still a few things that can be refined, but it's small things: 1) EXCEPTION_BITMAP which can go because everyone is probably using eager FPU these days---and has always been if you have shadow VMCS; 2) CR0_READ_SHADOW/CR4_READ_SHADOW/GUEST_CR0/GUEST_CR4 were needed on old KVM and would need to be tested on other hypervisors, but are probably unnecessary; 3) I would be surprised if HOST_FS_BASE/HOST_GS_BASE are needed too, though again you'd need testing on other hypervisors Overall, I prefer simple code that optimizes the common case very well, rather than complex code that tries to cover all bases... Paolo ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-11-14 11:34 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-10-19 14:16 [PATCH] x86/kvm/nVMX: tweak shadow fields Vitaly Kuznetsov 2018-10-19 16:45 ` Paolo Bonzini 2018-11-09 22:11 ` Jim Mattson 2018-11-12 14:39 ` Vitaly Kuznetsov 2018-11-14 11:34 ` Paolo Bonzini
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).