Patchwork [08/20] target-i386: move kvm_check_features_against_host() check to realize time

login
register
mail settings
Submitter Igor Mammedov
Date Dec. 27, 2012, 2:59 p.m.
Message ID <1356620376-23501-9-git-send-email-imammedo@redhat.com>
Download mbox | patch
Permalink /patch/208316/
State New
Headers show

Comments

Igor Mammedov - Dec. 27, 2012, 2:59 p.m.
kvm_check_features_against_host() should be called when features can't be changed
and when features are convereted to properties it would be possible to change them
until realize time, so correct way is to call kvm_check_features_against_host() in
x86_cpu_realize()

 - calling kvm_check_features_against_host() makes sense only when qemu is compiled
   --enable-kvm, so move it inside CONFIG_KVM ifdef and compile it and
   other kvm specific functions only if CONFIG_KVM is defined to avoid *-user target
   build breakage.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 v2:
   - squash in ifdef-ing kvm specific functions into this patch
---
 target-i386/cpu.c |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)
Eduardo Habkost - Dec. 27, 2012, 6:55 p.m.
On Thu, Dec 27, 2012 at 03:59:24PM +0100, Igor Mammedov wrote:
> kvm_check_features_against_host() should be called when features can't be changed
> and when features are convereted to properties it would be possible to change them
> until realize time, so correct way is to call kvm_check_features_against_host() in
> x86_cpu_realize()
> 
>  - calling kvm_check_features_against_host() makes sense only when qemu is compiled
>    --enable-kvm, so move it inside CONFIG_KVM ifdef and compile it and
>    other kvm specific functions only if CONFIG_KVM is defined to avoid *-user target
>    build breakage.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Commit message has more than 80 columns.

But considering that the code changes look OK:

Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>

We can probably #ifdef-out the whole host_cpuid() function as well. But
that can be done in a separate patch, as it requires more testing to
make sure it won't cause unexpected build errors on some configurations
(as the function is not static).


> ---
>  v2:
>    - squash in ifdef-ing kvm specific functions into this patch
> ---
>  target-i386/cpu.c |   27 +++++++++++++++------------
>  1 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 97cce89..d93bf5a 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -862,7 +862,6 @@ static int cpu_x86_fill_model_id(char *str)
>      }
>      return 0;
>  }
> -#endif
>  
>  /* Fill a x86_def_t struct with information about the host CPU, and
>   * the CPU features supported by the host hardware + host kernel
> @@ -871,7 +870,6 @@ static int cpu_x86_fill_model_id(char *str)
>   */
>  static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
>  {
> -#ifdef CONFIG_KVM
>      KVMState *s = kvm_state;
>      uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
>  
> @@ -930,7 +928,6 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
>       * unsupported ones later.
>       */
>      x86_cpu_def->svm_features = -1;
> -#endif /* CONFIG_KVM */
>  }
>  
>  static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
> @@ -954,19 +951,20 @@ static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
>   *
>   * This function may be called only if KVM is enabled.
>   */
> -static int kvm_check_features_against_host(x86_def_t *guest_def)
> +static int kvm_check_features_against_host(X86CPU *cpu)
>  {
> +    CPUX86State *env = &cpu->env;
>      x86_def_t host_def;
>      uint32_t mask;
>      int rv, i;
>      struct model_features_t ft[] = {
> -        {&guest_def->features, &host_def.features,
> +        {&env->cpuid_features, &host_def.features,
>              ~0, feature_name, 0x00000000},
> -        {&guest_def->ext_features, &host_def.ext_features,
> +        {&env->cpuid_ext_features, &host_def.ext_features,
>              ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
> -        {&guest_def->ext2_features, &host_def.ext2_features,
> +        {&env->cpuid_ext2_features, &host_def.ext2_features,
>              ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
> -        {&guest_def->ext3_features, &host_def.ext3_features,
> +        {&env->cpuid_ext3_features, &host_def.ext3_features,
>              ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
>  
>      assert(kvm_enabled());
> @@ -981,6 +979,7 @@ static int kvm_check_features_against_host(x86_def_t *guest_def)
>                  }
>      return rv;
>  }
> +#endif /* CONFIG_KVM */
>  
>  static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
>                                           const char *name, Error **errp)
> @@ -1273,7 +1272,9 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
>          }
>      }
>      if (kvm_enabled() && name && strcmp(name, "host") == 0) {
> +#ifdef CONFIG_KVM
>          kvm_cpu_fill_host(x86_cpu_def);
> +#endif
>      } else if (!def) {
>          return -1;
>      } else {
> @@ -1428,10 +1429,6 @@ static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
>      x86_cpu_def->kvm_features &= ~minus_kvm_features;
>      x86_cpu_def->svm_features &= ~minus_svm_features;
>      x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
> -    if (check_cpuid && kvm_enabled()) {
> -        if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
> -            goto error;
> -    }
>      return 0;
>  
>  error:
> @@ -2106,6 +2103,12 @@ void x86_cpu_realize(Object *obj, Error **errp)
>          env->cpuid_svm_features &= TCG_SVM_FEATURES;
>      } else {
>  #ifdef CONFIG_KVM
> +        if (check_cpuid && kvm_check_features_against_host(cpu)
> +            && enforce_cpuid) {
> +            error_setg(errp, "Host's CPU doesn't support requested features");
> +            return;
> +        }
> +
>          filter_features_for_kvm(cpu);
>  #endif
>      }
> -- 
> 1.7.1
>

Patch

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 97cce89..d93bf5a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -862,7 +862,6 @@  static int cpu_x86_fill_model_id(char *str)
     }
     return 0;
 }
-#endif
 
 /* Fill a x86_def_t struct with information about the host CPU, and
  * the CPU features supported by the host hardware + host kernel
@@ -871,7 +870,6 @@  static int cpu_x86_fill_model_id(char *str)
  */
 static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
 {
-#ifdef CONFIG_KVM
     KVMState *s = kvm_state;
     uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
 
@@ -930,7 +928,6 @@  static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
      * unsupported ones later.
      */
     x86_cpu_def->svm_features = -1;
-#endif /* CONFIG_KVM */
 }
 
 static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
@@ -954,19 +951,20 @@  static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
  *
  * This function may be called only if KVM is enabled.
  */
-static int kvm_check_features_against_host(x86_def_t *guest_def)
+static int kvm_check_features_against_host(X86CPU *cpu)
 {
+    CPUX86State *env = &cpu->env;
     x86_def_t host_def;
     uint32_t mask;
     int rv, i;
     struct model_features_t ft[] = {
-        {&guest_def->features, &host_def.features,
+        {&env->cpuid_features, &host_def.features,
             ~0, feature_name, 0x00000000},
-        {&guest_def->ext_features, &host_def.ext_features,
+        {&env->cpuid_ext_features, &host_def.ext_features,
             ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
-        {&guest_def->ext2_features, &host_def.ext2_features,
+        {&env->cpuid_ext2_features, &host_def.ext2_features,
             ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
-        {&guest_def->ext3_features, &host_def.ext3_features,
+        {&env->cpuid_ext3_features, &host_def.ext3_features,
             ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
 
     assert(kvm_enabled());
@@ -981,6 +979,7 @@  static int kvm_check_features_against_host(x86_def_t *guest_def)
                 }
     return rv;
 }
+#endif /* CONFIG_KVM */
 
 static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
                                          const char *name, Error **errp)
@@ -1273,7 +1272,9 @@  static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
         }
     }
     if (kvm_enabled() && name && strcmp(name, "host") == 0) {
+#ifdef CONFIG_KVM
         kvm_cpu_fill_host(x86_cpu_def);
+#endif
     } else if (!def) {
         return -1;
     } else {
@@ -1428,10 +1429,6 @@  static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
     x86_cpu_def->kvm_features &= ~minus_kvm_features;
     x86_cpu_def->svm_features &= ~minus_svm_features;
     x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
-    if (check_cpuid && kvm_enabled()) {
-        if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
-            goto error;
-    }
     return 0;
 
 error:
@@ -2106,6 +2103,12 @@  void x86_cpu_realize(Object *obj, Error **errp)
         env->cpuid_svm_features &= TCG_SVM_FEATURES;
     } else {
 #ifdef CONFIG_KVM
+        if (check_cpuid && kvm_check_features_against_host(cpu)
+            && enforce_cpuid) {
+            error_setg(errp, "Host's CPU doesn't support requested features");
+            return;
+        }
+
         filter_features_for_kvm(cpu);
 #endif
     }