Re: [PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-15 Thread Vitaly Kuznetsov
Liran Alon  writes:

> - vkuzn...@redhat.com wrote:
>
>> Enlightened VMCS is opt-in. The current version does not contain all
>> fields supported by nested VMX so we must not advertise the
>> corresponding VMX features if enlightened VMCS is enabled.
>> 
>> Userspace is given the enlightened VMCS version supported by KVM as
>> part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
>> be advertised to the nested hypervisor, currently done via a cpuid
>> leaf for Hyper-V.
>> 
>> Suggested-by: Ladi Prosek 
>> Signed-off-by: Vitaly Kuznetsov 
>> ---
>>  arch/x86/include/asm/kvm_host.h |   3 +
>>  arch/x86/kvm/svm.c  |   9 +++
>>  arch/x86/kvm/vmx.c  | 138
>> ++--
>>  arch/x86/kvm/x86.c  |  15 +
>>  include/uapi/linux/kvm.h|   1 +
>>  5 files changed, 105 insertions(+), 61 deletions(-)
>> 
>> diff --git a/arch/x86/include/asm/kvm_host.h
>> b/arch/x86/include/asm/kvm_host.h
>> index 0ebe659f2802..d7e8f7155d79 100644
>> --- a/arch/x86/include/asm/kvm_host.h
>> +++ b/arch/x86/include/asm/kvm_host.h
>> @@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
>>  int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region
>> *argp);
>>  
>>  int (*get_msr_feature)(struct kvm_msr_entry *entry);
>> +
>> +int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
>> +   uint16_t *vmcs_version);
>>  };
>>  
>>  struct kvm_arch_async_pf {
>> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
>> index d9305f1723f5..6dc42c870565 100644
>> --- a/arch/x86/kvm/svm.c
>> +++ b/arch/x86/kvm/svm.c
>> @@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm
>> *kvm,
>>  return ret;
>>  }
>>  
>> +static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
>> +   uint16_t *vmcs_version)
>> +{
>> +/* Intel-only feature */
>> +return -ENODEV;
>> +}
>> +
>>  static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
>>  .cpu_has_kvm_support = has_svm,
>>  .disabled_by_bios = is_disabled,
>> @@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops
>> __ro_after_init = {
>>  .mem_enc_op = svm_mem_enc_op,
>>  .mem_enc_reg_region = svm_register_enc_region,
>>  .mem_enc_unreg_region = svm_unregister_enc_region,
>> +
>> +.nested_enable_evmcs = nested_enable_evmcs,
>>  };
>>  
>>  static int __init svm_init(void)
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 48989f78be60..51749207cef1 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -648,6 +648,13 @@ struct nested_vmx {
>>  
>>  bool change_vmcs01_virtual_apic_mode;
>>  
>> +/*
>> + * Enlightened VMCS has been enabled. It does not mean that L1 has
>> to
>> + * use it. However, VMX features available to L1 will be limited
>> based
>> + * on what the enlightened VMCS supports.
>> + */
>> +bool enlightened_vmcs_enabled;
>> +
>>  /* L2 must run next, and mustn't decide to exit to L1. */
>>  bool nested_run_pending;
>>  
>> @@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
>>  
>>  #define KVM_EVMCS_VERSION 1
>>  
>> +/*
>> + * Enlightened VMCSv1 doesn't support these:
>> + *
>> + *  POSTED_INTR_NV  = 0x0002,
>> + *  GUEST_INTR_STATUS   = 0x0810,
>> + *  APIC_ACCESS_ADDR= 0x2014,
>> + *  POSTED_INTR_DESC_ADDR   = 0x2016,
>> + *  EOI_EXIT_BITMAP0= 0x201c,
>> + *  EOI_EXIT_BITMAP1= 0x201e,
>> + *  EOI_EXIT_BITMAP2= 0x2020,
>> + *  EOI_EXIT_BITMAP3= 0x2022,
>> + *  GUEST_PML_INDEX = 0x0812,
>> + *  PML_ADDRESS = 0x200e,
>> + *  VM_FUNCTION_CONTROL = 0x2018,
>> + *  EPTP_LIST_ADDRESS   = 0x2024,
>> + *  VMREAD_BITMAP   = 0x2026,
>> + *  VMWRITE_BITMAP  = 0x2028,
>> + *
>> + *  TSC_MULTIPLIER  = 0x2032,
>> + *  PLE_GAP = 0x4020,
>> + *  PLE_WINDOW  = 0x4022,
>> + *  VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
>> + *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
>> + *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
>> + *
>> + * Currently unsupported in KVM:
>> + *  GUEST_IA32_RTIT_CTL = 0x2814,
>> + */
>> +#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
>> +PIN_BASED_VMX_PREEMPTION_TIMER)
>> +#define EVMCS1_UNSUPPORTED_2NDEXEC  \
>> +(SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
>> + SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
>> + SECONDARY_EXEC_APIC_REGISTER_VIRT |\
>> + SECONDARY_EXEC_ENABLE_PML |\
>> + SECONDARY_EXEC_ENABLE_VMFUNC |

Re: [PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-15 Thread Vitaly Kuznetsov
Liran Alon  writes:

> - vkuzn...@redhat.com wrote:
>
>> Enlightened VMCS is opt-in. The current version does not contain all
>> fields supported by nested VMX so we must not advertise the
>> corresponding VMX features if enlightened VMCS is enabled.
>> 
>> Userspace is given the enlightened VMCS version supported by KVM as
>> part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
>> be advertised to the nested hypervisor, currently done via a cpuid
>> leaf for Hyper-V.
>> 
>> Suggested-by: Ladi Prosek 
>> Signed-off-by: Vitaly Kuznetsov 
>> ---
>>  arch/x86/include/asm/kvm_host.h |   3 +
>>  arch/x86/kvm/svm.c  |   9 +++
>>  arch/x86/kvm/vmx.c  | 138
>> ++--
>>  arch/x86/kvm/x86.c  |  15 +
>>  include/uapi/linux/kvm.h|   1 +
>>  5 files changed, 105 insertions(+), 61 deletions(-)
>> 
>> diff --git a/arch/x86/include/asm/kvm_host.h
>> b/arch/x86/include/asm/kvm_host.h
>> index 0ebe659f2802..d7e8f7155d79 100644
>> --- a/arch/x86/include/asm/kvm_host.h
>> +++ b/arch/x86/include/asm/kvm_host.h
>> @@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
>>  int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region
>> *argp);
>>  
>>  int (*get_msr_feature)(struct kvm_msr_entry *entry);
>> +
>> +int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
>> +   uint16_t *vmcs_version);
>>  };
>>  
>>  struct kvm_arch_async_pf {
>> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
>> index d9305f1723f5..6dc42c870565 100644
>> --- a/arch/x86/kvm/svm.c
>> +++ b/arch/x86/kvm/svm.c
>> @@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm
>> *kvm,
>>  return ret;
>>  }
>>  
>> +static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
>> +   uint16_t *vmcs_version)
>> +{
>> +/* Intel-only feature */
>> +return -ENODEV;
>> +}
>> +
>>  static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
>>  .cpu_has_kvm_support = has_svm,
>>  .disabled_by_bios = is_disabled,
>> @@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops
>> __ro_after_init = {
>>  .mem_enc_op = svm_mem_enc_op,
>>  .mem_enc_reg_region = svm_register_enc_region,
>>  .mem_enc_unreg_region = svm_unregister_enc_region,
>> +
>> +.nested_enable_evmcs = nested_enable_evmcs,
>>  };
>>  
>>  static int __init svm_init(void)
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index 48989f78be60..51749207cef1 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -648,6 +648,13 @@ struct nested_vmx {
>>  
>>  bool change_vmcs01_virtual_apic_mode;
>>  
>> +/*
>> + * Enlightened VMCS has been enabled. It does not mean that L1 has
>> to
>> + * use it. However, VMX features available to L1 will be limited
>> based
>> + * on what the enlightened VMCS supports.
>> + */
>> +bool enlightened_vmcs_enabled;
>> +
>>  /* L2 must run next, and mustn't decide to exit to L1. */
>>  bool nested_run_pending;
>>  
>> @@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
>>  
>>  #define KVM_EVMCS_VERSION 1
>>  
>> +/*
>> + * Enlightened VMCSv1 doesn't support these:
>> + *
>> + *  POSTED_INTR_NV  = 0x0002,
>> + *  GUEST_INTR_STATUS   = 0x0810,
>> + *  APIC_ACCESS_ADDR= 0x2014,
>> + *  POSTED_INTR_DESC_ADDR   = 0x2016,
>> + *  EOI_EXIT_BITMAP0= 0x201c,
>> + *  EOI_EXIT_BITMAP1= 0x201e,
>> + *  EOI_EXIT_BITMAP2= 0x2020,
>> + *  EOI_EXIT_BITMAP3= 0x2022,
>> + *  GUEST_PML_INDEX = 0x0812,
>> + *  PML_ADDRESS = 0x200e,
>> + *  VM_FUNCTION_CONTROL = 0x2018,
>> + *  EPTP_LIST_ADDRESS   = 0x2024,
>> + *  VMREAD_BITMAP   = 0x2026,
>> + *  VMWRITE_BITMAP  = 0x2028,
>> + *
>> + *  TSC_MULTIPLIER  = 0x2032,
>> + *  PLE_GAP = 0x4020,
>> + *  PLE_WINDOW  = 0x4022,
>> + *  VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
>> + *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
>> + *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
>> + *
>> + * Currently unsupported in KVM:
>> + *  GUEST_IA32_RTIT_CTL = 0x2814,
>> + */
>> +#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
>> +PIN_BASED_VMX_PREEMPTION_TIMER)
>> +#define EVMCS1_UNSUPPORTED_2NDEXEC  \
>> +(SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
>> + SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
>> + SECONDARY_EXEC_APIC_REGISTER_VIRT |\
>> + SECONDARY_EXEC_ENABLE_PML |\
>> + SECONDARY_EXEC_ENABLE_VMFUNC |

Re: [PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-14 Thread Liran Alon


- vkuzn...@redhat.com wrote:

> Enlightened VMCS is opt-in. The current version does not contain all
> fields supported by nested VMX so we must not advertise the
> corresponding VMX features if enlightened VMCS is enabled.
> 
> Userspace is given the enlightened VMCS version supported by KVM as
> part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
> be advertised to the nested hypervisor, currently done via a cpuid
> leaf for Hyper-V.
> 
> Suggested-by: Ladi Prosek 
> Signed-off-by: Vitaly Kuznetsov 
> ---
>  arch/x86/include/asm/kvm_host.h |   3 +
>  arch/x86/kvm/svm.c  |   9 +++
>  arch/x86/kvm/vmx.c  | 138
> ++--
>  arch/x86/kvm/x86.c  |  15 +
>  include/uapi/linux/kvm.h|   1 +
>  5 files changed, 105 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h
> b/arch/x86/include/asm/kvm_host.h
> index 0ebe659f2802..d7e8f7155d79 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
>   int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region
> *argp);
>  
>   int (*get_msr_feature)(struct kvm_msr_entry *entry);
> +
> + int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
> +uint16_t *vmcs_version);
>  };
>  
>  struct kvm_arch_async_pf {
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index d9305f1723f5..6dc42c870565 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm
> *kvm,
>   return ret;
>  }
>  
> +static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
> +uint16_t *vmcs_version)
> +{
> + /* Intel-only feature */
> + return -ENODEV;
> +}
> +
>  static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
>   .cpu_has_kvm_support = has_svm,
>   .disabled_by_bios = is_disabled,
> @@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops
> __ro_after_init = {
>   .mem_enc_op = svm_mem_enc_op,
>   .mem_enc_reg_region = svm_register_enc_region,
>   .mem_enc_unreg_region = svm_unregister_enc_region,
> +
> + .nested_enable_evmcs = nested_enable_evmcs,
>  };
>  
>  static int __init svm_init(void)
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 48989f78be60..51749207cef1 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -648,6 +648,13 @@ struct nested_vmx {
>  
>   bool change_vmcs01_virtual_apic_mode;
>  
> + /*
> +  * Enlightened VMCS has been enabled. It does not mean that L1 has
> to
> +  * use it. However, VMX features available to L1 will be limited
> based
> +  * on what the enlightened VMCS supports.
> +  */
> + bool enlightened_vmcs_enabled;
> +
>   /* L2 must run next, and mustn't decide to exit to L1. */
>   bool nested_run_pending;
>  
> @@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
>  
>  #define KVM_EVMCS_VERSION 1
>  
> +/*
> + * Enlightened VMCSv1 doesn't support these:
> + *
> + *   POSTED_INTR_NV  = 0x0002,
> + *   GUEST_INTR_STATUS   = 0x0810,
> + *   APIC_ACCESS_ADDR= 0x2014,
> + *   POSTED_INTR_DESC_ADDR   = 0x2016,
> + *   EOI_EXIT_BITMAP0= 0x201c,
> + *   EOI_EXIT_BITMAP1= 0x201e,
> + *   EOI_EXIT_BITMAP2= 0x2020,
> + *   EOI_EXIT_BITMAP3= 0x2022,
> + *   GUEST_PML_INDEX = 0x0812,
> + *   PML_ADDRESS = 0x200e,
> + *   VM_FUNCTION_CONTROL = 0x2018,
> + *   EPTP_LIST_ADDRESS   = 0x2024,
> + *   VMREAD_BITMAP   = 0x2026,
> + *   VMWRITE_BITMAP  = 0x2028,
> + *
> + *   TSC_MULTIPLIER  = 0x2032,
> + *   PLE_GAP = 0x4020,
> + *   PLE_WINDOW  = 0x4022,
> + *   VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
> + *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
> + *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
> + *
> + * Currently unsupported in KVM:
> + *   GUEST_IA32_RTIT_CTL = 0x2814,
> + */
> +#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
> + PIN_BASED_VMX_PREEMPTION_TIMER)
> +#define EVMCS1_UNSUPPORTED_2NDEXEC   \
> + (SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
> +  SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
> +  SECONDARY_EXEC_APIC_REGISTER_VIRT |\
> +  SECONDARY_EXEC_ENABLE_PML |\
> +  SECONDARY_EXEC_ENABLE_VMFUNC | \
> +  SECONDARY_EXEC_SHADOW_VMCS |   \
> +  

Re: [PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-14 Thread Liran Alon


- vkuzn...@redhat.com wrote:

> Enlightened VMCS is opt-in. The current version does not contain all
> fields supported by nested VMX so we must not advertise the
> corresponding VMX features if enlightened VMCS is enabled.
> 
> Userspace is given the enlightened VMCS version supported by KVM as
> part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
> be advertised to the nested hypervisor, currently done via a cpuid
> leaf for Hyper-V.
> 
> Suggested-by: Ladi Prosek 
> Signed-off-by: Vitaly Kuznetsov 
> ---
>  arch/x86/include/asm/kvm_host.h |   3 +
>  arch/x86/kvm/svm.c  |   9 +++
>  arch/x86/kvm/vmx.c  | 138
> ++--
>  arch/x86/kvm/x86.c  |  15 +
>  include/uapi/linux/kvm.h|   1 +
>  5 files changed, 105 insertions(+), 61 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h
> b/arch/x86/include/asm/kvm_host.h
> index 0ebe659f2802..d7e8f7155d79 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
>   int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region
> *argp);
>  
>   int (*get_msr_feature)(struct kvm_msr_entry *entry);
> +
> + int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
> +uint16_t *vmcs_version);
>  };
>  
>  struct kvm_arch_async_pf {
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index d9305f1723f5..6dc42c870565 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm
> *kvm,
>   return ret;
>  }
>  
> +static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
> +uint16_t *vmcs_version)
> +{
> + /* Intel-only feature */
> + return -ENODEV;
> +}
> +
>  static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
>   .cpu_has_kvm_support = has_svm,
>   .disabled_by_bios = is_disabled,
> @@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops
> __ro_after_init = {
>   .mem_enc_op = svm_mem_enc_op,
>   .mem_enc_reg_region = svm_register_enc_region,
>   .mem_enc_unreg_region = svm_unregister_enc_region,
> +
> + .nested_enable_evmcs = nested_enable_evmcs,
>  };
>  
>  static int __init svm_init(void)
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 48989f78be60..51749207cef1 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -648,6 +648,13 @@ struct nested_vmx {
>  
>   bool change_vmcs01_virtual_apic_mode;
>  
> + /*
> +  * Enlightened VMCS has been enabled. It does not mean that L1 has
> to
> +  * use it. However, VMX features available to L1 will be limited
> based
> +  * on what the enlightened VMCS supports.
> +  */
> + bool enlightened_vmcs_enabled;
> +
>   /* L2 must run next, and mustn't decide to exit to L1. */
>   bool nested_run_pending;
>  
> @@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
>  
>  #define KVM_EVMCS_VERSION 1
>  
> +/*
> + * Enlightened VMCSv1 doesn't support these:
> + *
> + *   POSTED_INTR_NV  = 0x0002,
> + *   GUEST_INTR_STATUS   = 0x0810,
> + *   APIC_ACCESS_ADDR= 0x2014,
> + *   POSTED_INTR_DESC_ADDR   = 0x2016,
> + *   EOI_EXIT_BITMAP0= 0x201c,
> + *   EOI_EXIT_BITMAP1= 0x201e,
> + *   EOI_EXIT_BITMAP2= 0x2020,
> + *   EOI_EXIT_BITMAP3= 0x2022,
> + *   GUEST_PML_INDEX = 0x0812,
> + *   PML_ADDRESS = 0x200e,
> + *   VM_FUNCTION_CONTROL = 0x2018,
> + *   EPTP_LIST_ADDRESS   = 0x2024,
> + *   VMREAD_BITMAP   = 0x2026,
> + *   VMWRITE_BITMAP  = 0x2028,
> + *
> + *   TSC_MULTIPLIER  = 0x2032,
> + *   PLE_GAP = 0x4020,
> + *   PLE_WINDOW  = 0x4022,
> + *   VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
> + *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
> + *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
> + *
> + * Currently unsupported in KVM:
> + *   GUEST_IA32_RTIT_CTL = 0x2814,
> + */
> +#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
> + PIN_BASED_VMX_PREEMPTION_TIMER)
> +#define EVMCS1_UNSUPPORTED_2NDEXEC   \
> + (SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
> +  SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
> +  SECONDARY_EXEC_APIC_REGISTER_VIRT |\
> +  SECONDARY_EXEC_ENABLE_PML |\
> +  SECONDARY_EXEC_ENABLE_VMFUNC | \
> +  SECONDARY_EXEC_SHADOW_VMCS |   \
> +  

[PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-14 Thread Vitaly Kuznetsov
Enlightened VMCS is opt-in. The current version does not contain all
fields supported by nested VMX so we must not advertise the
corresponding VMX features if enlightened VMCS is enabled.

Userspace is given the enlightened VMCS version supported by KVM as
part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
be advertised to the nested hypervisor, currently done via a cpuid
leaf for Hyper-V.

Suggested-by: Ladi Prosek 
Signed-off-by: Vitaly Kuznetsov 
---
 arch/x86/include/asm/kvm_host.h |   3 +
 arch/x86/kvm/svm.c  |   9 +++
 arch/x86/kvm/vmx.c  | 138 ++--
 arch/x86/kvm/x86.c  |  15 +
 include/uapi/linux/kvm.h|   1 +
 5 files changed, 105 insertions(+), 61 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0ebe659f2802..d7e8f7155d79 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region 
*argp);
 
int (*get_msr_feature)(struct kvm_msr_entry *entry);
+
+   int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
+  uint16_t *vmcs_version);
 };
 
 struct kvm_arch_async_pf {
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d9305f1723f5..6dc42c870565 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm *kvm,
return ret;
 }
 
+static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
+  uint16_t *vmcs_version)
+{
+   /* Intel-only feature */
+   return -ENODEV;
+}
+
 static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.cpu_has_kvm_support = has_svm,
.disabled_by_bios = is_disabled,
@@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.mem_enc_op = svm_mem_enc_op,
.mem_enc_reg_region = svm_register_enc_region,
.mem_enc_unreg_region = svm_unregister_enc_region,
+
+   .nested_enable_evmcs = nested_enable_evmcs,
 };
 
 static int __init svm_init(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 48989f78be60..51749207cef1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -648,6 +648,13 @@ struct nested_vmx {
 
bool change_vmcs01_virtual_apic_mode;
 
+   /*
+* Enlightened VMCS has been enabled. It does not mean that L1 has to
+* use it. However, VMX features available to L1 will be limited based
+* on what the enlightened VMCS supports.
+*/
+   bool enlightened_vmcs_enabled;
+
/* L2 must run next, and mustn't decide to exit to L1. */
bool nested_run_pending;
 
@@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
 
 #define KVM_EVMCS_VERSION 1
 
+/*
+ * Enlightened VMCSv1 doesn't support these:
+ *
+ * POSTED_INTR_NV  = 0x0002,
+ * GUEST_INTR_STATUS   = 0x0810,
+ * APIC_ACCESS_ADDR= 0x2014,
+ * POSTED_INTR_DESC_ADDR   = 0x2016,
+ * EOI_EXIT_BITMAP0= 0x201c,
+ * EOI_EXIT_BITMAP1= 0x201e,
+ * EOI_EXIT_BITMAP2= 0x2020,
+ * EOI_EXIT_BITMAP3= 0x2022,
+ * GUEST_PML_INDEX = 0x0812,
+ * PML_ADDRESS = 0x200e,
+ * VM_FUNCTION_CONTROL = 0x2018,
+ * EPTP_LIST_ADDRESS   = 0x2024,
+ * VMREAD_BITMAP   = 0x2026,
+ * VMWRITE_BITMAP  = 0x2028,
+ *
+ * TSC_MULTIPLIER  = 0x2032,
+ * PLE_GAP = 0x4020,
+ * PLE_WINDOW  = 0x4022,
+ * VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
+ *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
+ *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
+ *
+ * Currently unsupported in KVM:
+ * GUEST_IA32_RTIT_CTL = 0x2814,
+ */
+#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
+   PIN_BASED_VMX_PREEMPTION_TIMER)
+#define EVMCS1_UNSUPPORTED_2NDEXEC \
+   (SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
+SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
+SECONDARY_EXEC_APIC_REGISTER_VIRT |\
+SECONDARY_EXEC_ENABLE_PML |\
+SECONDARY_EXEC_ENABLE_VMFUNC | \
+SECONDARY_EXEC_SHADOW_VMCS |   \
+SECONDARY_EXEC_TSC_SCALING |   \
+SECONDARY_EXEC_PAUSE_LOOP_EXITING)
+#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
+#define 

[PATCH 2/5] KVM: nVMX: add KVM_CAP_HYPERV_ENLIGHTENED_VMCS capability

2018-06-14 Thread Vitaly Kuznetsov
Enlightened VMCS is opt-in. The current version does not contain all
fields supported by nested VMX so we must not advertise the
corresponding VMX features if enlightened VMCS is enabled.

Userspace is given the enlightened VMCS version supported by KVM as
part of enabling KVM_CAP_HYPERV_ENLIGHTENED_VMCS. The version is to
be advertised to the nested hypervisor, currently done via a cpuid
leaf for Hyper-V.

Suggested-by: Ladi Prosek 
Signed-off-by: Vitaly Kuznetsov 
---
 arch/x86/include/asm/kvm_host.h |   3 +
 arch/x86/kvm/svm.c  |   9 +++
 arch/x86/kvm/vmx.c  | 138 ++--
 arch/x86/kvm/x86.c  |  15 +
 include/uapi/linux/kvm.h|   1 +
 5 files changed, 105 insertions(+), 61 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0ebe659f2802..d7e8f7155d79 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1095,6 +1095,9 @@ struct kvm_x86_ops {
int (*mem_enc_unreg_region)(struct kvm *kvm, struct kvm_enc_region 
*argp);
 
int (*get_msr_feature)(struct kvm_msr_entry *entry);
+
+   int (*nested_enable_evmcs)(struct kvm_vcpu *vcpu,
+  uint16_t *vmcs_version);
 };
 
 struct kvm_arch_async_pf {
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index d9305f1723f5..6dc42c870565 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -7009,6 +7009,13 @@ static int svm_unregister_enc_region(struct kvm *kvm,
return ret;
 }
 
+static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
+  uint16_t *vmcs_version)
+{
+   /* Intel-only feature */
+   return -ENODEV;
+}
+
 static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.cpu_has_kvm_support = has_svm,
.disabled_by_bios = is_disabled,
@@ -7135,6 +7142,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
.mem_enc_op = svm_mem_enc_op,
.mem_enc_reg_region = svm_register_enc_region,
.mem_enc_unreg_region = svm_unregister_enc_region,
+
+   .nested_enable_evmcs = nested_enable_evmcs,
 };
 
 static int __init svm_init(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 48989f78be60..51749207cef1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -648,6 +648,13 @@ struct nested_vmx {
 
bool change_vmcs01_virtual_apic_mode;
 
+   /*
+* Enlightened VMCS has been enabled. It does not mean that L1 has to
+* use it. However, VMX features available to L1 will be limited based
+* on what the enlightened VMCS supports.
+*/
+   bool enlightened_vmcs_enabled;
+
/* L2 must run next, and mustn't decide to exit to L1. */
bool nested_run_pending;
 
@@ -1186,6 +1193,49 @@ DEFINE_STATIC_KEY_FALSE(enable_evmcs);
 
 #define KVM_EVMCS_VERSION 1
 
+/*
+ * Enlightened VMCSv1 doesn't support these:
+ *
+ * POSTED_INTR_NV  = 0x0002,
+ * GUEST_INTR_STATUS   = 0x0810,
+ * APIC_ACCESS_ADDR= 0x2014,
+ * POSTED_INTR_DESC_ADDR   = 0x2016,
+ * EOI_EXIT_BITMAP0= 0x201c,
+ * EOI_EXIT_BITMAP1= 0x201e,
+ * EOI_EXIT_BITMAP2= 0x2020,
+ * EOI_EXIT_BITMAP3= 0x2022,
+ * GUEST_PML_INDEX = 0x0812,
+ * PML_ADDRESS = 0x200e,
+ * VM_FUNCTION_CONTROL = 0x2018,
+ * EPTP_LIST_ADDRESS   = 0x2024,
+ * VMREAD_BITMAP   = 0x2026,
+ * VMWRITE_BITMAP  = 0x2028,
+ *
+ * TSC_MULTIPLIER  = 0x2032,
+ * PLE_GAP = 0x4020,
+ * PLE_WINDOW  = 0x4022,
+ * VMX_PREEMPTION_TIMER_VALUE  = 0x482E,
+ *  GUEST_IA32_PERF_GLOBAL_CTRL = 0x2808,
+ *  HOST_IA32_PERF_GLOBAL_CTRL  = 0x2c04,
+ *
+ * Currently unsupported in KVM:
+ * GUEST_IA32_RTIT_CTL = 0x2814,
+ */
+#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
+   PIN_BASED_VMX_PREEMPTION_TIMER)
+#define EVMCS1_UNSUPPORTED_2NDEXEC \
+   (SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \
+SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |  \
+SECONDARY_EXEC_APIC_REGISTER_VIRT |\
+SECONDARY_EXEC_ENABLE_PML |\
+SECONDARY_EXEC_ENABLE_VMFUNC | \
+SECONDARY_EXEC_SHADOW_VMCS |   \
+SECONDARY_EXEC_TSC_SCALING |   \
+SECONDARY_EXEC_PAUSE_LOOP_EXITING)
+#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
+#define