# Commit 60fa12dbf1d4d2c4ffe1ef34b495b24aa7e41aa0
# Date 2021-06-07 15:43:35 +0100
# Author Andrew Cooper <andrew.cooper3@citrix.com>
# Committer Andrew Cooper <andrew.cooper3@citrix.com>
x86/cpuid: Fix HLE and RTM handling (again)

For reasons which are my fault, but I don't recall why, the
FDP_EXCP_ONLY/NO_FPU_SEL adjustment uses the whole special_features[] array
element, not the two relevant bits.

HLE and RTM were recently added to the list of special features, causing them
to be always set in guest view, irrespective of the toolstacks choice on the
matter.

Rewrite the logic to refer to the features specifically, rather than relying
on the contents of the special_features[] array.

Fixes: 8fe24090d9 ("x86/cpuid: Rework HLE and RTM handling")
Reported-by: Edwin Török <edvin.torok@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Mon, 7 Jun 2021 13:38:53 +0100
Subject: x86/cpuid: Drop special_features[]

While the ! annotation is useful to indicate that something special is
happening, an array of bits is not.  Drop it, to prevent mistakes.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 69e1472d21cf7e5cf0795ef38b99d00de78a910e)

x86/cpuid: Half revert "x86/cpuid: Drop special_features[]"

xen-cpuid does print out the list of special features, and this is helpful to
keep.

Fixes: 69e1472d21cf ("x86/cpuid: Drop special_features[]")
Reported-by: Jan Beulich <JBeulich@suse.com>
Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
(cherry picked from commit 0ba0663b1b32d9351890dfd02bdebb3d238897bd)

--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -12,7 +12,6 @@
 #include <asm/xstate.h>
 
 const uint32_t known_features[] = INIT_KNOWN_FEATURES;
-const uint32_t special_features[] = INIT_SPECIAL_FEATURES;
 
 static const uint32_t pv_featuremask[] = INIT_PV_FEATURES;
 static const uint32_t hvm_shadow_featuremask[] = INIT_HVM_SHADOW_FEATURES;
@@ -698,9 +697,11 @@ void recalculate_cpuid_policy(struct dom
     sanitise_featureset(fs);
 
     /* Fold host's FDP_EXCP_ONLY and NO_FPU_SEL into guest's view. */
-    fs[FEATURESET_7b0] &= ~special_features[FEATURESET_7b0];
+    fs[FEATURESET_7b0] &= ~(cpufeat_mask(X86_FEATURE_FDP_EXCP_ONLY) |
+                            cpufeat_mask(X86_FEATURE_NO_FPU_SEL));
     fs[FEATURESET_7b0] |= (host_policy.feat._7b0 &
-                           special_features[FEATURESET_7b0]);
+                           (cpufeat_mask(X86_FEATURE_FDP_EXCP_ONLY) |
+                            cpufeat_mask(X86_FEATURE_NO_FPU_SEL)));
 
     cpuid_featureset_to_policy(fs, p);
 
@@ -1153,7 +1154,6 @@ void guest_cpuid(const struct vcpu *v, u
 static void __init __maybe_unused build_assertions(void)
 {
     BUILD_BUG_ON(ARRAY_SIZE(known_features) != FSCAPINTS);
-    BUILD_BUG_ON(ARRAY_SIZE(special_features) != FSCAPINTS);
     BUILD_BUG_ON(ARRAY_SIZE(pv_featuremask) != FSCAPINTS);
     BUILD_BUG_ON(ARRAY_SIZE(hvm_shadow_featuremask) != FSCAPINTS);
     BUILD_BUG_ON(ARRAY_SIZE(hvm_hap_featuremask) != FSCAPINTS);
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -24,7 +24,6 @@
 #include <public/sysctl.h>
 
 extern const uint32_t known_features[FSCAPINTS];
-extern const uint32_t special_features[FSCAPINTS];
 
 void init_guest_cpuid(void);
 
