[PATCH 1/2] target/i386: pass X86CPU to x86_cpu_get_supported_feature_word

Paolo Bonzini posted 2 patches 5 months ago
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Marcelo Tosatti <mtosatti@redhat.com>
[PATCH 1/2] target/i386: pass X86CPU to x86_cpu_get_supported_feature_word
Posted by Paolo Bonzini 5 months ago
This allows modifying the bits in "-cpu max"/"-cpu host" depending on
the guest CPU vendor (which, at least by default, is the host vendor in
the case of KVM).

For example, machine check architecture differs between Intel and AMD,
and bits from AMD should be dropped when configuring the guest for
an Intel model.

Cc: Xiaoyao Li <xiaoyao.li@intel.com>
Cc: John Allen <john.allen@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.h         |  3 +--
 target/i386/cpu.c         | 13 ++++++-------
 target/i386/kvm/kvm-cpu.c |  2 +-
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 29daf370485..9bea7142bf4 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -666,8 +666,7 @@ typedef enum FeatureWord {
 } FeatureWord;
 
 typedef uint64_t FeatureWordArray[FEATURE_WORDS];
-uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
-                                            bool migratable_only);
+uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
 
 /* cpuid_features bits */
 #define CPUID_FP87 (1U << 0)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 4c2e6f3a71e..deb58670651 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6035,8 +6035,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
 
 #endif /* !CONFIG_USER_ONLY */
 
-uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
-                                            bool migratable_only)
+uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
 {
     FeatureWordInfo *wi = &feature_word_info[w];
     uint64_t r = 0;
@@ -6076,9 +6075,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
             ? CPUID_EXT2_LM & ~CPUID_EXT2_KERNEL_FEATURES
             : CPUID_EXT2_LM;
         r &= ~unavail;
-    }
+        break;
 #endif
-    if (migratable_only) {
+    if (cpu && cpu->migratable) {
         r &= x86_cpu_get_migratable_flags(w);
     }
     return r;
@@ -7371,7 +7370,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
              * by the user.
              */
             env->features[w] |=
-                x86_cpu_get_supported_feature_word(w, cpu->migratable) &
+                x86_cpu_get_supported_feature_word(cpu, w) &
                 ~env->user_features[w] &
                 ~feature_word_info[w].no_autoenable_flags;
         }
@@ -7497,7 +7496,7 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
 
     for (w = 0; w < FEATURE_WORDS; w++) {
         uint64_t host_feat =
-            x86_cpu_get_supported_feature_word(w, false);
+            x86_cpu_get_supported_feature_word(NULL, w);
         uint64_t requested_features = env->features[w];
         uint64_t unavailable_features = requested_features & ~host_feat;
         mark_unavailable_features(cpu, w, unavailable_features, prefix);
@@ -7617,7 +7616,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
         env->features[FEAT_PERF_CAPABILITIES] & PERF_CAP_LBR_FMT;
     if (requested_lbr_fmt && kvm_enabled()) {
         uint64_t host_perf_cap =
-            x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES, false);
+            x86_cpu_get_supported_feature_word(NULL, FEAT_PERF_CAPABILITIES);
         unsigned host_lbr_fmt = host_perf_cap & PERF_CAP_LBR_FMT;
 
         if (!cpu->enable_pmu) {
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index f9b99b5f50d..b2735d6efee 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -136,7 +136,7 @@ static void kvm_cpu_xsave_init(void)
         if (!esa->size) {
             continue;
         }
-        if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits)
+        if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits)
             != esa->bits) {
             continue;
         }
-- 
2.45.2
Re: [PATCH 1/2] target/i386: pass X86CPU to x86_cpu_get_supported_feature_word
Posted by Xiaoyao Li 4 months, 4 weeks ago
On 6/27/2024 10:06 PM, Paolo Bonzini wrote:
> This allows modifying the bits in "-cpu max"/"-cpu host" depending on
> the guest CPU vendor (which, at least by default, is the host vendor in
> the case of KVM).
> 
> For example, machine check architecture differs between Intel and AMD,
> and bits from AMD should be dropped when configuring the guest for
> an Intel model.
> 
> Cc: Xiaoyao Li <xiaoyao.li@intel.com>
> Cc: John Allen <john.allen@amd.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   target/i386/cpu.h         |  3 +--
>   target/i386/cpu.c         | 13 ++++++-------
>   target/i386/kvm/kvm-cpu.c |  2 +-
>   3 files changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> index 29daf370485..9bea7142bf4 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -666,8 +666,7 @@ typedef enum FeatureWord {
>   } FeatureWord;
>   
>   typedef uint64_t FeatureWordArray[FEATURE_WORDS];
> -uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
> -                                            bool migratable_only);
> +uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
>   
>   /* cpuid_features bits */
>   #define CPUID_FP87 (1U << 0)
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 4c2e6f3a71e..deb58670651 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -6035,8 +6035,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
>   
>   #endif /* !CONFIG_USER_ONLY */
>   
> -uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
> -                                            bool migratable_only)
> +uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
>   {
>       FeatureWordInfo *wi = &feature_word_info[w];
>       uint64_t r = 0;
> @@ -6076,9 +6075,9 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
>               ? CPUID_EXT2_LM & ~CPUID_EXT2_KERNEL_FEATURES
>               : CPUID_EXT2_LM;
>           r &= ~unavail;
> -    }
> +        break;

It seems some leftover when spliting from next patch. Need to remove it.

Other than it,

Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>

>   #endif
> -    if (migratable_only) {
> +    if (cpu && cpu->migratable) {
>           r &= x86_cpu_get_migratable_flags(w);
>       }
>       return r;
> @@ -7371,7 +7370,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
>                * by the user.
>                */
>               env->features[w] |=
> -                x86_cpu_get_supported_feature_word(w, cpu->migratable) &
> +                x86_cpu_get_supported_feature_word(cpu, w) &
>                   ~env->user_features[w] &
>                   ~feature_word_info[w].no_autoenable_flags;
>           }
> @@ -7497,7 +7496,7 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
>   
>       for (w = 0; w < FEATURE_WORDS; w++) {
>           uint64_t host_feat =
> -            x86_cpu_get_supported_feature_word(w, false);
> +            x86_cpu_get_supported_feature_word(NULL, w);
>           uint64_t requested_features = env->features[w];
>           uint64_t unavailable_features = requested_features & ~host_feat;
>           mark_unavailable_features(cpu, w, unavailable_features, prefix);
> @@ -7617,7 +7616,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
>           env->features[FEAT_PERF_CAPABILITIES] & PERF_CAP_LBR_FMT;
>       if (requested_lbr_fmt && kvm_enabled()) {
>           uint64_t host_perf_cap =
> -            x86_cpu_get_supported_feature_word(FEAT_PERF_CAPABILITIES, false);
> +            x86_cpu_get_supported_feature_word(NULL, FEAT_PERF_CAPABILITIES);
>           unsigned host_lbr_fmt = host_perf_cap & PERF_CAP_LBR_FMT;
>   
>           if (!cpu->enable_pmu) {
> diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
> index f9b99b5f50d..b2735d6efee 100644
> --- a/target/i386/kvm/kvm-cpu.c
> +++ b/target/i386/kvm/kvm-cpu.c
> @@ -136,7 +136,7 @@ static void kvm_cpu_xsave_init(void)
>           if (!esa->size) {
>               continue;
>           }
> -        if ((x86_cpu_get_supported_feature_word(esa->feature, false) & esa->bits)
> +        if ((x86_cpu_get_supported_feature_word(NULL, esa->feature) & esa->bits)
>               != esa->bits) {
>               continue;
>           }