diff mbox

KVM: x86: Store multiple cpuid entries for a single function

Message ID 1231757365-15717-3-git-send-email-amit.shah@redhat.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Amit Shah Jan. 12, 2009, 10:49 a.m. UTC
CPUID functions 4, 0xb and 0xd behave differently for different values of ECX.
Store these values if userspace passes them.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 arch/x86/kvm/x86.c |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)

Comments

Muli Ben-Yehuda Jan. 12, 2009, 8:39 p.m. UTC | #1
On Mon, Jan 12, 2009 at 10:49:25AM +0000, Amit Shah wrote:
> CPUID functions 4, 0xb and 0xd behave differently for different values of ECX.
> Store these values if userspace passes them.
> 
> Signed-off-by: Amit Shah <amit.shah@redhat.com>
> ---
>  arch/x86/kvm/x86.c |   18 +++++++++++++++---
>  1 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 06b44fb..8dc4b29 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -1126,7 +1126,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
>  				    struct kvm_cpuid *cpuid,
>  				    struct kvm_cpuid_entry __user *entries)
>  {
> -	int r, i;
> +	int r, i, count;
>  	struct kvm_cpuid_entry *cpuid_entries;
>  
>  	r = -E2BIG;
> @@ -1146,8 +1146,20 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
>  		vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
>  		vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
>  		vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
> -		vcpu->arch.cpuid_entries[i].index = 0;
> -		vcpu->arch.cpuid_entries[i].flags = 0;
> +		switch (cpuid_entries[i].function) {
> +		case 4:
> +		case 0xb:
> +		case 0xd:
> +			vcpu->arch.cpuid_entries[i].index = count++;

Isn't this using count uninitialized?

Cheers,
Muli
Avi Kivity Jan. 13, 2009, 9:27 a.m. UTC | #2
Amit Shah wrote:
> CPUID functions 4, 0xb and 0xd behave differently for different values of ECX.
> Store these values if userspace passes them.
>   

Userspace has no way of knowing whether the kernel contains this fix or not.

Use the SET_CPUID2 interface instead.
Amit Shah Jan. 13, 2009, 9:40 a.m. UTC | #3
On Tue, Jan 13, 2009 at 11:27:07AM +0200, Avi Kivity wrote:
> Amit Shah wrote:
>> CPUID functions 4, 0xb and 0xd behave differently for different values of ECX.
>> Store these values if userspace passes them.
>>   
>
> Userspace has no way of knowing whether the kernel contains this fix or not.
>
> Use the SET_CPUID2 interface instead.

OK; So first attempt to use the SET_CPUID2 interface. If that fails (new
userspace on older kernel), what should we do?

Amit
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Avi Kivity Jan. 13, 2009, 9:45 a.m. UTC | #4
Amit Shah wrote:
>> Use the SET_CPUID2 interface instead.
>>     
>
> OK; So first attempt to use the SET_CPUID2 interface. If that fails (new
> userspace on older kernel), what should we do?
>   

SET_CPUID2 was introduced on 2.6.25; that is now the minimum requirement 
for qemu and kvm-userspace anyway.
Amit Shah Jan. 13, 2009, 9:58 a.m. UTC | #5
On Tue, Jan 13, 2009 at 11:45:55AM +0200, Avi Kivity wrote:
> Amit Shah wrote:
>>> Use the SET_CPUID2 interface instead.
>>>     
>>
>> OK; So first attempt to use the SET_CPUID2 interface. If that fails (new
>> userspace on older kernel), what should we do?
>>   
>
> SET_CPUID2 was introduced on 2.6.25; that is now the minimum requirement  
> for qemu and kvm-userspace anyway.

OK; that's great. I'll respin the patches.

Amit.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 06b44fb..8dc4b29 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1126,7 +1126,7 @@  static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 				    struct kvm_cpuid *cpuid,
 				    struct kvm_cpuid_entry __user *entries)
 {
-	int r, i;
+	int r, i, count;
 	struct kvm_cpuid_entry *cpuid_entries;
 
 	r = -E2BIG;
@@ -1146,8 +1146,20 @@  static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 		vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
 		vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
 		vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
-		vcpu->arch.cpuid_entries[i].index = 0;
-		vcpu->arch.cpuid_entries[i].flags = 0;
+		switch (cpuid_entries[i].function) {
+		case 4:
+		case 0xb:
+		case 0xd:
+			vcpu->arch.cpuid_entries[i].index = count++;
+			vcpu->arch.cpuid_entries[i].flags =
+				KVM_CPUID_FLAG_SIGNIFICANT_INDEX;
+			break;
+		default:
+			vcpu->arch.cpuid_entries[i].index = 0;
+			vcpu->arch.cpuid_entries[i].flags = 0;
+		}
+		if (cpuid_entries[i].function != cpuid_entries[i+1].function)
+			count = 0;
 		vcpu->arch.cpuid_entries[i].padding[0] = 0;
 		vcpu->arch.cpuid_entries[i].padding[1] = 0;
 		vcpu->arch.cpuid_entries[i].padding[2] = 0;