[1/2,nVMX] : Add a vmentry check for HOST_SYSENTER_ESP and HOST_SYSENTER_EIP fields
diff mbox series

Message ID 20190204171650.6920-2-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • [1/2,nVMX] : Add a vmentry check for HOST_SYSENTER_ESP and HOST_SYSENTER_EIP fields
Related show

Commit Message

Krish Sadhukhan Feb. 4, 2019, 5:16 p.m. UTC
According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
following check is performed on vmentry of L2 guests:

    On processors that support Intel 64 architecture, the IA32_SYSENTER_ESP
    field and the IA32_SYSENTER_EIP field must each contain a canonical
    address.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
---
 arch/x86/kvm/vmx/nested.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Jim Mattson Feb. 4, 2019, 6:22 p.m. UTC | #1
On Mon, Feb 4, 2019 at 9:41 AM Krish Sadhukhan
<krish.sadhukhan@oracle.com> wrote:
>
> According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
> following check is performed on vmentry of L2 guests:
>
>     On processors that support Intel 64 architecture, the IA32_SYSENTER_ESP
>     field and the IA32_SYSENTER_EIP field must each contain a canonical
>     address.
>
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
> ---
>  arch/x86/kvm/vmx/nested.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 7bb5e565f3fa..65b29726ad7a 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -2595,6 +2595,15 @@ static int nested_check_host_control_regs(struct kvm_vcpu *vcpu,
>             !nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
>             !nested_cr3_valid(vcpu, vmcs12->host_cr3))
>                 return -EINVAL;
> +
> +#ifdef CONFIG_X86_64
> +       if (is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_ESP),
> +                                               vcpu) ||
> +           is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_EIP),
> +                                               vcpu))
> +               return -EINVAL;
> +#endif
> +
Shouldn't these checks be against the relevant VMCS12 fields?
Krish Sadhukhan Feb. 5, 2019, 2:13 a.m. UTC | #2
On 02/04/2019 10:22 AM, Jim Mattson wrote:
> On Mon, Feb 4, 2019 at 9:41 AM Krish Sadhukhan
> <krish.sadhukhan@oracle.com> wrote:
>> According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
>> following check is performed on vmentry of L2 guests:
>>
>>      On processors that support Intel 64 architecture, the IA32_SYSENTER_ESP
>>      field and the IA32_SYSENTER_EIP field must each contain a canonical
>>      address.
>>
>> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
>> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
>> ---
>>   arch/x86/kvm/vmx/nested.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
>> index 7bb5e565f3fa..65b29726ad7a 100644
>> --- a/arch/x86/kvm/vmx/nested.c
>> +++ b/arch/x86/kvm/vmx/nested.c
>> @@ -2595,6 +2595,15 @@ static int nested_check_host_control_regs(struct kvm_vcpu *vcpu,
>>              !nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
>>              !nested_cr3_valid(vcpu, vmcs12->host_cr3))
>>                  return -EINVAL;
>> +
>> +#ifdef CONFIG_X86_64
>> +       if (is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_ESP),
>> +                                               vcpu) ||
>> +           is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_EIP),
>> +                                               vcpu))
>> +               return -EINVAL;
>> +#endif
>> +
> Shouldn't these checks be against the relevant VMCS12 fields?

Yes, you are right. Will send a revised one.
Sean Christopherson Feb. 5, 2019, 3:15 a.m. UTC | #3
On Mon, Feb 04, 2019 at 12:16:49PM -0500, Krish Sadhukhan wrote:
> According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
> following check is performed on vmentry of L2 guests:
> 
>     On processors that support Intel 64 architecture, the IA32_SYSENTER_ESP
>     field and the IA32_SYSENTER_EIP field must each contain a canonical
>     address.
> 
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
> ---
>  arch/x86/kvm/vmx/nested.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index 7bb5e565f3fa..65b29726ad7a 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -2595,6 +2595,15 @@ static int nested_check_host_control_regs(struct kvm_vcpu *vcpu,
>  	    !nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
>  	    !nested_cr3_valid(vcpu, vmcs12->host_cr3))
>  		return -EINVAL;
> +
> +#ifdef CONFIG_X86_64

Wrapping this with CONFIG_x86_64 is technically wrong, sort of.  The
checks happen regardless of the target mode, the only dependency is that
the CPU supports long mode.  L1 could directly write a VMCLEAR'd VMCS
and then do VMPTRLD to bypass L0's VMWRITE restriction (to limit VMWRITE
to 32-bits) and load a non-canonical value into the VMCS.  I say "sort
of" because I think you could argue that bits 63:32 don't exist in this
case because we'd be emulating a 32-bit CPU.  But the cost is negligible
with the move to vmcs12, and deferring to is_noncanonical_address() is
more consistent with the rest of the nested code.

> +	if (is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_ESP),
> +						vcpu) ||
> +	    is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_EIP),
> +						vcpu))
> +		return -EINVAL;
> +#endif
> +
>  	/*
>  	 * If the load IA32_EFER VM-exit control is 1, bits reserved in the
>  	 * IA32_EFER MSR must be 0 in the field for that register. In addition,
> -- 
> 2.17.2
>

Patch
diff mbox series

diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 7bb5e565f3fa..65b29726ad7a 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -2595,6 +2595,15 @@  static int nested_check_host_control_regs(struct kvm_vcpu *vcpu,
 	    !nested_host_cr4_valid(vcpu, vmcs12->host_cr4) ||
 	    !nested_cr3_valid(vcpu, vmcs12->host_cr3))
 		return -EINVAL;
+
+#ifdef CONFIG_X86_64
+	if (is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_ESP),
+						vcpu) ||
+	    is_noncanonical_address(vmcs_readl(HOST_IA32_SYSENTER_EIP),
+						vcpu))
+		return -EINVAL;
+#endif
+
 	/*
 	 * If the load IA32_EFER VM-exit control is 1, bits reserved in the
 	 * IA32_EFER MSR must be 0 in the field for that register. In addition,