diff mbox

x86/levelling: Fix breakage on older Intel boxes from c/s 08e7738

Message ID 1472754419-12135-1-git-send-email-andrew.cooper3@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andrew Cooper Sept. 1, 2016, 6:26 p.m. UTC
cpufeat_mask() yields an unsigned integer constant.  As a result, taking its
complement causes zero extention rather than sign extention.

The result is that, when a guest OS has OXSAVE disabled, all features in 1d
are hidden from native CPUID.  Amongst other things, this causes the early
code in Linux to find no LAPIC, but for everything to appear fine later when
userspace is up and running.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>

I wonder whether a better fix might be to put an explicit (int) cast in
cpufeat_mask() to yield an signed constant?
---
 xen/arch/x86/cpu/intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Jan Beulich Sept. 2, 2016, 10:20 a.m. UTC | #1
>>> On 01.09.16 at 20:26, <andrew.cooper3@citrix.com> wrote:
> I wonder whether a better fix might be to put an explicit (int) cast in
> cpufeat_mask() to yield an signed constant?

That's an option, but will make us use implementation defined
behavior (due to the unsigned -> signed conversion of a non-
representable type when the bit in question is bit 31).

Jan
diff mbox

Patch

diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index a9355cbf..7b60aaa 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -192,7 +192,7 @@  static void intel_ctxt_switch_levelling(const struct vcpu *next)
 		 */
 		if (next && is_pv_vcpu(next) && !is_idle_vcpu(next) &&
 		    !(next->arch.pv_vcpu.ctrlreg[4] & X86_CR4_OSXSAVE))
-			val &= ~cpufeat_mask(X86_FEATURE_OSXSAVE);
+			val &= ~(uint64_t)cpufeat_mask(X86_FEATURE_OSXSAVE);
 
 		if (unlikely(these_masks->_1cd != val)) {
 			wrmsrl(msr_basic, val);