linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: restrict maximal physical address
@ 2016-11-25 14:51 Radim Krčmář
  2016-11-25 15:11 ` David Hildenbrand
  2016-11-25 16:10 ` Paolo Bonzini
  0 siblings, 2 replies; 8+ messages in thread
From: Radim Krčmář @ 2016-11-25 14:51 UTC (permalink / raw)
  To: linux-kernel, kvm; +Cc: Paolo Bonzini

The guest could have configured a maximal physical address that exceeds
the host.  Prevent that situation as it could easily lead to a bug.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 arch/x86/kvm/cpuid.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 25f0f15fab1a..aed910e9fbed 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
 		((best->eax & 0xff00) >> 8) != 0)
 		return -EINVAL;
 
-	/* Update physical-address width */
+
+	/*
+	 * Update physical-address width.
+	 * Make sure that it does not exceed hardware capabilities.
+	 */
+	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)
+		return -EINVAL;
 	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
 
 	kvm_pmu_refresh(vcpu);
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 14:51 [PATCH] KVM: x86: restrict maximal physical address Radim Krčmář
@ 2016-11-25 15:11 ` David Hildenbrand
  2016-11-25 16:14   ` Radim Krčmář
  2016-11-25 16:10 ` Paolo Bonzini
  1 sibling, 1 reply; 8+ messages in thread
From: David Hildenbrand @ 2016-11-25 15:11 UTC (permalink / raw)
  To: Radim Krčmář, linux-kernel, kvm; +Cc: Paolo Bonzini

Am 25.11.2016 um 15:51 schrieb Radim Krčmář:
> The guest could have configured a maximal physical address that exceeds
> the host.  Prevent that situation as it could easily lead to a bug.
>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  arch/x86/kvm/cpuid.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 25f0f15fab1a..aed910e9fbed 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
>  		((best->eax & 0xff00) >> 8) != 0)
>  		return -EINVAL;
>
> -	/* Update physical-address width */
> +
> +	/*
> +	 * Update physical-address width.
> +	 * Make sure that it does not exceed hardware capabilities.
> +	 */
> +	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)

The name maxphyaddr is really misleading. But that is a different story. 
This check is correct.

However, I wonder if there is any way for user space to query this 
property? On s390x, there is a kvm capability to export this information 
to user space. So QEMU can fail (e.g. migration) with a nice error 
message about missing hardware support.

(most probably we still want to block this case, as migration will seem 
to work but than simply fail due to missing hardware support I guess). 
Maybe there is also already a nice check in QEMU that I am not yet aware 
of :)

> +		return -EINVAL;
>  	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
>
>  	kvm_pmu_refresh(vcpu);
>


-- 

David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 14:51 [PATCH] KVM: x86: restrict maximal physical address Radim Krčmář
  2016-11-25 15:11 ` David Hildenbrand
@ 2016-11-25 16:10 ` Paolo Bonzini
  2016-11-25 16:57   ` Radim Krčmář
  1 sibling, 1 reply; 8+ messages in thread
From: Paolo Bonzini @ 2016-11-25 16:10 UTC (permalink / raw)
  To: Radim Krčmář, linux-kernel, kvm



On 25/11/2016 15:51, Radim Krčmář wrote:
> The guest could have configured a maximal physical address that exceeds
> the host.  Prevent that situation as it could easily lead to a bug.
> 
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  arch/x86/kvm/cpuid.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 25f0f15fab1a..aed910e9fbed 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
>  		((best->eax & 0xff00) >> 8) != 0)
>  		return -EINVAL;
>  
> -	/* Update physical-address width */
> +
> +	/*
> +	 * Update physical-address width.
> +	 * Make sure that it does not exceed hardware capabilities.
> +	 */
> +	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)
> +		return -EINVAL;
>  	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
>  
>  	kvm_pmu_refresh(vcpu);
> 

Not possible unfortunately, this would break most versions of QEMU that
hard-code 40 for MAXPHYADDR.

Also, "wider" physical addresses in the guest are actually possible with
shadow paging.

Paolo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 15:11 ` David Hildenbrand
@ 2016-11-25 16:14   ` Radim Krčmář
  2016-11-25 16:43     ` David Hildenbrand
  0 siblings, 1 reply; 8+ messages in thread
From: Radim Krčmář @ 2016-11-25 16:14 UTC (permalink / raw)
  To: David Hildenbrand; +Cc: linux-kernel, kvm, Paolo Bonzini

2016-11-25 16:11+0100, David Hildenbrand:
> Am 25.11.2016 um 15:51 schrieb Radim Krčmář:
>> The guest could have configured a maximal physical address that exceeds
>> the host.  Prevent that situation as it could easily lead to a bug.
>> 
>> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
>> ---
>>  arch/x86/kvm/cpuid.c | 8 +++++++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>> index 25f0f15fab1a..aed910e9fbed 100644
>> --- a/arch/x86/kvm/cpuid.c
>> +++ b/arch/x86/kvm/cpuid.c
>> @@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
>>  		((best->eax & 0xff00) >> 8) != 0)
>>  		return -EINVAL;
>> 
>> -	/* Update physical-address width */
>> +
>> +	/*
>> +	 * Update physical-address width.
>> +	 * Make sure that it does not exceed hardware capabilities.
>> +	 */
>> +	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)
> 
> The name maxphyaddr is really misleading. But that is a different story.

Yes, I'll rename it, thanks.

> This check is correct.
> 
> However, I wonder if there is any way for user space to query this property?

Do you mean boot_cpu_data.x86_phys_bits?
Userspace can execute CPUID instruction and read the value; QEMU does.

> On s390x, there is a kvm capability to export this information to user
> space. So QEMU can fail (e.g. migration) with a nice error message about
> missing hardware support.
> 
> (most probably we still want to block this case, as migration will seem to
> work but than simply fail due to missing hardware support I guess). Maybe
> there is also already a nice check in QEMU that I am not yet aware of :)

This patch is bad.  It would break QEMU on all old machines, because
QEMU sets 40 by default.

Heh, QEMU doesn't check at all -- it even allows migration with
"host-phys-bits" feature and will happily change phys-bits when
migrating to another machine.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 16:14   ` Radim Krčmář
@ 2016-11-25 16:43     ` David Hildenbrand
  2016-11-29 16:53       ` Radim Krčmář
  0 siblings, 1 reply; 8+ messages in thread
From: David Hildenbrand @ 2016-11-25 16:43 UTC (permalink / raw)
  To: Radim Krčmář; +Cc: linux-kernel, kvm, Paolo Bonzini


>> This check is correct.
>>
>> However, I wonder if there is any way for user space to query this property?
>
> Do you mean boot_cpu_data.x86_phys_bits?
> Userspace can execute CPUID instruction and read the value; QEMU does.

Thanks, good to know. I remember that on s390x we explicitly decided to 
query the maximum address from KVM (KVM_S390_VM_MEM_LIMIT_SIZE) for two 
reasons. One of them was "just because our CPU supports it doesn't mean 
KVM supports it". Just like with all CPU features.

However, this applies only for configuring hardware virtualization. The 
value that is exposed to the guest comes from the cpu model (with s390x 
cpu model support). So it will also not change during migration.

But if this will never be relevant for x86 (KVM will always support host 
x86_phys_bits), fine.

>
>> On s390x, there is a kvm capability to export this information to user
>> space. So QEMU can fail (e.g. migration) with a nice error message about
>> missing hardware support.
>>
>> (most probably we still want to block this case, as migration will seem to
>> work but than simply fail due to missing hardware support I guess). Maybe
>> there is also already a nice check in QEMU that I am not yet aware of :)
>
> This patch is bad.  It would break QEMU on all old machines, because
> QEMU sets 40 by default.

Not sure if rounding that value down (so it is at least consistent in 
KVM) makes sense (and documenting this behavior "may be rounded down"). 
And then implementing appropriate checks in QEMU (if not already present).

>
> Heh, QEMU doesn't check at all -- it even allows migration with
> "host-phys-bits" feature and will happily change phys-bits when
> migrating to another machine.
>

Either migrate that value (hmmm... ) or glue it to a command line 
parameter, so it won't change while migrating. E.g.

- cpu models (if this value was always the same for a CPU generation - 
no expert on x86 cpu models).
- "-cpu maxmem..." - could be a fit when thinking about "maximum VM size 
== max phys bits for our guest". But depends how this value is actually 
interpreted by guests.

-- 

David

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 16:10 ` Paolo Bonzini
@ 2016-11-25 16:57   ` Radim Krčmář
  2016-11-25 17:21     ` Paolo Bonzini
  0 siblings, 1 reply; 8+ messages in thread
From: Radim Krčmář @ 2016-11-25 16:57 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: linux-kernel, kvm

2016-11-25 17:10+0100, Paolo Bonzini:
> On 25/11/2016 15:51, Radim Krčmář wrote:
>> The guest could have configured a maximal physical address that exceeds
>> the host.  Prevent that situation as it could easily lead to a bug.
>> 
>> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
>> ---
>>  arch/x86/kvm/cpuid.c | 8 +++++++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>> index 25f0f15fab1a..aed910e9fbed 100644
>> --- a/arch/x86/kvm/cpuid.c
>> +++ b/arch/x86/kvm/cpuid.c
>> @@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
>>  		((best->eax & 0xff00) >> 8) != 0)
>>  		return -EINVAL;
>>  
>> -	/* Update physical-address width */
>> +
>> +	/*
>> +	 * Update physical-address width.
>> +	 * Make sure that it does not exceed hardware capabilities.
>> +	 */
>> +	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)
>> +		return -EINVAL;
>>  	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
>>  
>>  	kvm_pmu_refresh(vcpu);
>> 
> 
> Not possible unfortunately, this would break most versions of QEMU that
> hard-code 40 for MAXPHYADDR.
> 
> Also, "wider" physical addresses in the guest are actually possible with
> shadow paging.

We don't disable EPT in that case, though.  I guess that situations
where QEMU configures mem slot into high physical addresses are not hit
in production ...

Is any solution better than ignoring this situation?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 16:57   ` Radim Krčmář
@ 2016-11-25 17:21     ` Paolo Bonzini
  0 siblings, 0 replies; 8+ messages in thread
From: Paolo Bonzini @ 2016-11-25 17:21 UTC (permalink / raw)
  To: Radim Krčmář; +Cc: linux-kernel, kvm



On 25/11/2016 17:57, Radim Krčmář wrote:
> 2016-11-25 17:10+0100, Paolo Bonzini:
>> On 25/11/2016 15:51, Radim Krčmář wrote:
>>> The guest could have configured a maximal physical address that exceeds
>>> the host.  Prevent that situation as it could easily lead to a bug.
>>>
>>> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
>>> ---
>>>  arch/x86/kvm/cpuid.c | 8 +++++++-
>>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
>>> index 25f0f15fab1a..aed910e9fbed 100644
>>> --- a/arch/x86/kvm/cpuid.c
>>> +++ b/arch/x86/kvm/cpuid.c
>>> @@ -136,7 +136,13 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
>>>  		((best->eax & 0xff00) >> 8) != 0)
>>>  		return -EINVAL;
>>>  
>>> -	/* Update physical-address width */
>>> +
>>> +	/*
>>> +	 * Update physical-address width.
>>> +	 * Make sure that it does not exceed hardware capabilities.
>>> +	 */
>>> +	if (cpuid_query_maxphyaddr(vcpu) > boot_cpu_data.x86_phys_bits)
>>> +		return -EINVAL;
>>>  	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
>>>  
>>>  	kvm_pmu_refresh(vcpu);
>>>
>>
>> Not possible unfortunately, this would break most versions of QEMU that
>> hard-code 40 for MAXPHYADDR.
>>
>> Also, "wider" physical addresses in the guest are actually possible with
>> shadow paging.
> 
> We don't disable EPT in that case, though.  I guess that situations
> where QEMU configures mem slot into high physical addresses are not hit
> in production ...
> 
> Is any solution better than ignoring this situation?

We've hit it at least once a year (I can remember me, Nadav, Eduardo, 
Dave Gilbert and you) and always decided that ultimately there is no 
satisfactory solution.

Both GAW < HAW (AW = address width) and GAW > HAW have problems.  If 
GAW is smaller, bits that ought to be reserved aren't.  This is 
arguably worse than configuring memory into addresses above GAW.  
However most Intel chips in the wild have 36 or 46 physical bits 
respectively client or server, so in reality it's unlikely to have a 
mismatch.

The sad thing, and one that is new since the last time we discussed the 
issue, is that apparently Intel did have plans to support GAW < HAW:

    commit 0307b7b8c275e65552f6022a18ad91902ae25d42
    Author: Zhang Xiantao <xiantao.zhang@intel.com>
    Date:   Wed Dec 5 01:55:14 2012 +0800

    kvm: remove unnecessary bit checking for ept violation
    
    Bit 6 in EPT vmexit's exit qualification is not defined in SDM, so 
    remove it.
    
    Signed-off-by: Zhang Xiantao <xiantao.zhang@intel.com>
    Signed-off-by: Gleb Natapov <gleb@redhat.com>

    diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
    index 2fd2046dc94c..d2248b3dbb61 100644
    --- a/arch/x86/kvm/vmx.c
    +++ b/arch/x86/kvm/vmx.c
    @@ -4863,11 +4863,6 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
     
            exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
     
    -       if (exit_qualification & (1 << 6)) {
    -               printk(KERN_ERR "EPT: GPA exceeds GAW!\n");
    -               return -EINVAL;
    -       }
    -
            gla_validity = (exit_qualification >> 7) & 0x3;
            if (gla_validity != 0x3 && gla_validity != 0x1 && gla_validity != 0) {
                    printk(KERN_ERR "EPT: Handling EPT violation failed!\n");

Oh well. :(

Paolo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] KVM: x86: restrict maximal physical address
  2016-11-25 16:43     ` David Hildenbrand
@ 2016-11-29 16:53       ` Radim Krčmář
  0 siblings, 0 replies; 8+ messages in thread
From: Radim Krčmář @ 2016-11-29 16:53 UTC (permalink / raw)
  To: David Hildenbrand; +Cc: linux-kernel, kvm, Paolo Bonzini

2016-11-25 17:43+0100, David Hildenbrand:
>> > This check is correct.
>> > 
>> > However, I wonder if there is any way for user space to query this property?
>> 
>> Do you mean boot_cpu_data.x86_phys_bits?
>> Userspace can execute CPUID instruction and read the value; QEMU does.
> 
> Thanks, good to know. I remember that on s390x we explicitly decided to
> query the maximum address from KVM (KVM_S390_VM_MEM_LIMIT_SIZE) for two
> reasons. One of them was "just because our CPU supports it doesn't mean KVM
> supports it". Just like with all CPU features.
> 
> However, this applies only for configuring hardware virtualization. The
> value that is exposed to the guest comes from the cpu model (with s390x cpu
> model support). So it will also not change during migration.
> 
> But if this will never be relevant for x86 (KVM will always support host
> x86_phys_bits), fine.
> 
>> 
>> > On s390x, there is a kvm capability to export this information to user
>> > space. So QEMU can fail (e.g. migration) with a nice error message about
>> > missing hardware support.
>> > 
>> > (most probably we still want to block this case, as migration will seem to
>> > work but than simply fail due to missing hardware support I guess). Maybe
>> > there is also already a nice check in QEMU that I am not yet aware of :)
>> 
>> This patch is bad.  It would break QEMU on all old machines, because
>> QEMU sets 40 by default.
> 
> Not sure if rounding that value down (so it is at least consistent in KVM)
> makes sense (and documenting this behavior "may be rounded down"). And then
> implementing appropriate checks in QEMU (if not already present).

Silently rouding down doesn't fix bugs that we introduce to the guest,
just makes them behave differently and changing the value while the
guest is running could introduce more bugs. :(

I slightly prefer doing nothing for the case I was writing this patch
for:  VMX checks for CR3 reserved bits -- doing nothing means that the
guest gets killed; rouding down would make the guest misbehave, which a
bit harder to debug.

Changing QEMU makes sense even if KVM stays the same.  I'd touch QEMU
first, actually and after few years (decades), we could just apply this
patch. :)

>> Heh, QEMU doesn't check at all -- it even allows migration with
>> "host-phys-bits" feature and will happily change phys-bits when
>> migrating to another machine.
>> 
> 
> Either migrate that value (hmmm... ) or glue it to a command line parameter,
> so it won't change while migrating. E.g.
> - cpu models (if this value was always the same for a CPU generation - no
> expert on x86 cpu models).
> - "-cpu maxmem..." - could be a fit when thinking about "maximum VM size ==
> max phys bits for our guest". But depends how this value is actually
> interpreted by guests.

Yes, the host value has to be migrated in that case.  QEMU also has
"phys-bits=N" feature and the default protected by machine types is 40,
so both work as expected on migration.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-11-29 16:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-25 14:51 [PATCH] KVM: x86: restrict maximal physical address Radim Krčmář
2016-11-25 15:11 ` David Hildenbrand
2016-11-25 16:14   ` Radim Krčmář
2016-11-25 16:43     ` David Hildenbrand
2016-11-29 16:53       ` Radim Krčmář
2016-11-25 16:10 ` Paolo Bonzini
2016-11-25 16:57   ` Radim Krčmář
2016-11-25 17:21     ` 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).