Re: [PATCH v4 1/6] KVM: nVMX: Use hardware MSR bitmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sorry, please ignore this mail, the subject is wrong : (

On Wed, Jan 28, 2015 at 11:50 PM, Wincy Van <fanwenyi0529@xxxxxxxxx> wrote:
> Currently, if L1 enables MSR_BITMAP, we will emulate this feature,
> all of L2's msr access is intercepted by L0. Since many features
> like virtualize x2apic mode has a complicated logic and it is
> difficult for us to emulate, we should use hardware and merge
> the bitmap.
>
> This patch introduces nested_vmx_merge_msr_bitmap for future use.
>
> Signed-off-by: Wincy Van <fanwenyi0529@xxxxxxxxx>
> ---
>  arch/x86/kvm/vmx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 66 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index c987374..787f886 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -798,6 +798,7 @@ static unsigned long *vmx_msr_bitmap_legacy;
>  static unsigned long *vmx_msr_bitmap_longmode;
>  static unsigned long *vmx_msr_bitmap_legacy_x2apic;
>  static unsigned long *vmx_msr_bitmap_longmode_x2apic;
> +static unsigned long *vmx_msr_bitmap_nested;
>  static unsigned long *vmx_vmread_bitmap;
>  static unsigned long *vmx_vmwrite_bitmap;
>
> @@ -5812,13 +5813,21 @@ static __init int hardware_setup(void)
>                                 (unsigned long *)__get_free_page(GFP_KERNEL);
>         if (!vmx_msr_bitmap_longmode_x2apic)
>                 goto out4;
> +
> +       if (nested) {
> +               vmx_msr_bitmap_nested =
> +                       (unsigned long *)__get_free_page(GFP_KERNEL);
> +               if (!vmx_msr_bitmap_nested)
> +                       goto out5;
> +       }
> +
>         vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
>         if (!vmx_vmread_bitmap)
> -               goto out5;
> +               goto out6;
>
>         vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
>         if (!vmx_vmwrite_bitmap)
> -               goto out6;
> +               goto out7;
>
>         memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
>         memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
> @@ -5834,10 +5843,12 @@ static __init int hardware_setup(void)
>
>         memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
>         memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
> +       if (nested)
> +               memset(vmx_msr_bitmap_nested, 0xff, PAGE_SIZE);
>
>         if (setup_vmcs_config(&vmcs_config) < 0) {
>                 r = -EIO;
> -               goto out7;
> +               goto out8;
>         }
>
>         if (boot_cpu_has(X86_FEATURE_NX))
> @@ -5944,10 +5955,13 @@ static __init int hardware_setup(void)
>
>         return alloc_kvm_area();
>
> -out7:
> +out8:
>         free_page((unsigned long)vmx_vmwrite_bitmap);
> -out6:
> +out7:
>         free_page((unsigned long)vmx_vmread_bitmap);
> +out6:
> +       if (nested)
> +               free_page((unsigned long)vmx_msr_bitmap_nested);
>  out5:
>         free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
>  out4:
> @@ -5974,6 +5988,8 @@ static __exit void hardware_unsetup(void)
>         free_page((unsigned long)vmx_io_bitmap_a);
>         free_page((unsigned long)vmx_vmwrite_bitmap);
>         free_page((unsigned long)vmx_vmread_bitmap);
> +       if (nested)
> +               free_page((unsigned long)vmx_msr_bitmap_nested);
>
>         free_kvm_area();
>  }
> @@ -8305,6 +8321,38 @@ static void vmx_start_preemption_timer(struct
> kvm_vcpu *vcpu)
>                       ns_to_ktime(preemption_timeout), HRTIMER_MODE_REL);
>  }
>
> +static int nested_vmx_check_msr_bitmap_controls(struct kvm_vcpu *vcpu,
> +                                               struct vmcs12 *vmcs12)
> +{
> +       int maxphyaddr;
> +       u64 addr;
> +
> +       if (!nested_cpu_has(vmcs12, CPU_BASED_USE_MSR_BITMAPS))
> +               return 0;
> +
> +       if (vmcs12_read_any(vcpu, MSR_BITMAP, &addr)) {
> +               WARN_ON(1);
> +               return -EINVAL;
> +       }
> +       maxphyaddr = cpuid_maxphyaddr(vcpu);
> +
> +       if (!PAGE_ALIGNED(vmcs12->msr_bitmap) ||
> +          ((addr + PAGE_SIZE) >> maxphyaddr))
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
> +/*
> + * Merge L0's and L1's MSR bitmap, return false to indicate that
> + * we do not use the hardware.
> + */
> +static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
> +                                              struct vmcs12 *vmcs12)
> +{
> +       return false;
> +}
> +
>  static int nested_vmx_check_msr_switch(struct kvm_vcpu *vcpu,
>                                        unsigned long count_field,
>                                        unsigned long addr_field,
> @@ -8637,11 +8685,17 @@ static void prepare_vmcs02(struct kvm_vcpu
> *vcpu, struct vmcs12 *vmcs12)
>                 vmcs_write32(TPR_THRESHOLD, vmcs12->tpr_threshold);
>         }
>
> +       if (cpu_has_vmx_msr_bitmap() &&
> +           exec_control & CPU_BASED_USE_MSR_BITMAPS &&
> +           nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) {
> +               vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_nested));
> +       } else
> +               exec_control &= ~CPU_BASED_USE_MSR_BITMAPS;
> +
>         /*
> -        * Merging of IO and MSR bitmaps not currently supported.
> +        * Merging of IO bitmap not currently supported.
>          * Rather, exit every time.
>          */
> -       exec_control &= ~CPU_BASED_USE_MSR_BITMAPS;
>         exec_control &= ~CPU_BASED_USE_IO_BITMAPS;
>         exec_control |= CPU_BASED_UNCOND_IO_EXITING;
>
> @@ -8792,15 +8846,13 @@ static int nested_vmx_run(struct kvm_vcpu
> *vcpu, bool launch)
>                 return 1;
>         }
>
> -       if ((vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_MSR_BITMAPS) &&
> -                       !PAGE_ALIGNED(vmcs12->msr_bitmap)) {
> +       if (!nested_get_vmcs12_pages(vcpu, vmcs12)) {
>                 /*TODO: Also verify bits beyond physical address width are 0*/
>                 nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
>                 return 1;
>         }
>
> -       if (!nested_get_vmcs12_pages(vcpu, vmcs12)) {
> -               /*TODO: Also verify bits beyond physical address width are 0*/
> +       if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12)) {
>                 nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
>                 return 1;
>         }
> @@ -9356,6 +9408,9 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
>         kvm_set_dr(vcpu, 7, 0x400);
>         vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
>
> +       if (cpu_has_vmx_msr_bitmap())
> +               vmx_set_msr_bitmap(vcpu);
> +
>         if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr,
>                                 vmcs12->vm_exit_msr_load_count))
>                 nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL);
> --
> 1.7.1
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux