Commit 6c1f42fe83bf9bc14a7a6cc5afd8dad83ee25c74

Authored by Andre Przywara
Committed by Anthony Liguori
1 parent f441bee8

fix KVMs GET_SUPPORTED_CPUID feature usage

If we want to trim the user provided CPUID bits for KVM to be not greater
than that of the host, we should not remove the bits _after_ we sent
them to the kernel.
This fixes the masking of features that are not present on the host by
moving the trim function and it's call from helper.c to kvm.c.
It helps to use -cpu host.

Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
target-i386/helper.c
@@ -92,20 +92,6 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, @@ -92,20 +92,6 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
92 } 92 }
93 } 93 }
94 94
95 -static void kvm_trim_features(uint32_t *features, uint32_t supported,  
96 - const char *names[])  
97 -{  
98 - int i;  
99 - uint32_t mask;  
100 -  
101 - for (i = 0; i < 32; ++i) {  
102 - mask = 1U << i;  
103 - if ((*features & mask) && !(supported & mask)) {  
104 - *features &= ~mask;  
105 - }  
106 - }  
107 -}  
108 -  
109 typedef struct x86_def_t { 95 typedef struct x86_def_t {
110 const char *name; 96 const char *name;
111 uint32_t level; 97 uint32_t level;
@@ -1773,21 +1759,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model) @@ -1773,21 +1759,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
1773 1759
1774 qemu_init_vcpu(env); 1760 qemu_init_vcpu(env);
1775 1761
1776 - if (kvm_enabled()) {  
1777 - kvm_trim_features(&env->cpuid_features,  
1778 - kvm_arch_get_supported_cpuid(env, 1, R_EDX),  
1779 - feature_name);  
1780 - kvm_trim_features(&env->cpuid_ext_features,  
1781 - kvm_arch_get_supported_cpuid(env, 1, R_ECX),  
1782 - ext_feature_name);  
1783 - kvm_trim_features(&env->cpuid_ext2_features,  
1784 - kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX),  
1785 - ext2_feature_name);  
1786 - kvm_trim_features(&env->cpuid_ext3_features,  
1787 - kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX),  
1788 - ext3_feature_name);  
1789 - }  
1790 -  
1791 return env; 1762 return env;
1792 } 1763 }
1793 1764
target-i386/kvm.c
@@ -117,6 +117,19 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) @@ -117,6 +117,19 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
117 117
118 #endif 118 #endif
119 119
  120 +static void kvm_trim_features(uint32_t *features, uint32_t supported)
  121 +{
  122 + int i;
  123 + uint32_t mask;
  124 +
  125 + for (i = 0; i < 32; ++i) {
  126 + mask = 1U << i;
  127 + if ((*features & mask) && !(supported & mask)) {
  128 + *features &= ~mask;
  129 + }
  130 + }
  131 +}
  132 +
120 int kvm_arch_init_vcpu(CPUState *env) 133 int kvm_arch_init_vcpu(CPUState *env)
121 { 134 {
122 struct { 135 struct {
@@ -128,6 +141,15 @@ int kvm_arch_init_vcpu(CPUState *env) @@ -128,6 +141,15 @@ int kvm_arch_init_vcpu(CPUState *env)
128 141
129 env->mp_state = KVM_MP_STATE_RUNNABLE; 142 env->mp_state = KVM_MP_STATE_RUNNABLE;
130 143
  144 + kvm_trim_features(&env->cpuid_features,
  145 + kvm_arch_get_supported_cpuid(env, 1, R_EDX));
  146 + kvm_trim_features(&env->cpuid_ext_features,
  147 + kvm_arch_get_supported_cpuid(env, 1, R_ECX));
  148 + kvm_trim_features(&env->cpuid_ext2_features,
  149 + kvm_arch_get_supported_cpuid(env, 0x80000001, R_EDX));
  150 + kvm_trim_features(&env->cpuid_ext3_features,
  151 + kvm_arch_get_supported_cpuid(env, 0x80000001, R_ECX));
  152 +
131 cpuid_i = 0; 153 cpuid_i = 0;
132 154
133 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); 155 cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);