debuggers.hg

changeset 22278:eb964c4b4f31

x86-64: workaround for BIOSes wrongly enabling LAHF_LM feature indicator

This workaround is taken from Linux, and the main motivation (besides
such workarounds indeed belonging in the hypervisor rather than each
kernel) is to suppress the warnings in the Xen log each Linux guest
would cause due to the disallowed wrmsr.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir@xen.org>
date Mon Oct 11 09:02:36 2010 +0100 (2010-10-11)
parents a1405385db77
children 1a3b8b84e58b
files xen/arch/x86/cpu/amd.c
line diff
     1.1 --- a/xen/arch/x86/cpu/amd.c	Mon Oct 11 09:01:45 2010 +0100
     1.2 +++ b/xen/arch/x86/cpu/amd.c	Mon Oct 11 09:02:36 2010 +0100
     1.3 @@ -43,6 +43,47 @@ static inline void wrmsr_amd(unsigned in
     1.4  	);
     1.5  }
     1.6  
     1.7 +static inline int rdmsr_amd_safe(unsigned int msr, unsigned int *lo,
     1.8 +				 unsigned int *hi)
     1.9 +{
    1.10 +	int err;
    1.11 +
    1.12 +	asm volatile("1: rdmsr\n2:\n"
    1.13 +		     ".section .fixup,\"ax\"\n"
    1.14 +		     "3: movl %6,%2\n"
    1.15 +		     "   jmp 2b\n"
    1.16 +		     ".previous\n"
    1.17 +		     ".section __ex_table,\"a\"\n"
    1.18 +		     __FIXUP_ALIGN "\n"
    1.19 +		     __FIXUP_WORD " 1b,3b\n"
    1.20 +		     ".previous\n"
    1.21 +		     : "=a" (*lo), "=d" (*hi), "=r" (err)
    1.22 +		     : "c" (msr), "D" (0x9c5a203a), "2" (0), "i" (-EFAULT));
    1.23 +
    1.24 +	return err;
    1.25 +}
    1.26 +
    1.27 +static inline int wrmsr_amd_safe(unsigned int msr, unsigned int lo,
    1.28 +				 unsigned int hi)
    1.29 +{
    1.30 +	int err;
    1.31 +
    1.32 +	asm volatile("1: wrmsr\n2:\n"
    1.33 +		     ".section .fixup,\"ax\"\n"
    1.34 +		     "3: movl %6,%0\n"
    1.35 +		     "   jmp 2b\n"
    1.36 +		     ".previous\n"
    1.37 +		     ".section __ex_table,\"a\"\n"
    1.38 +		     __FIXUP_ALIGN "\n"
    1.39 +		     __FIXUP_WORD " 1b,3b\n"
    1.40 +		     ".previous\n"
    1.41 +		     : "=r" (err)
    1.42 +		     : "c" (msr), "a" (lo), "d" (hi), "D" (0x9c5a203a),
    1.43 +		       "0" (0), "i" (-EFAULT));
    1.44 +
    1.45 +	return err;
    1.46 +}
    1.47 +
    1.48  /*
    1.49   * Mask the features and extended features returned by CPUID.  Parameters are
    1.50   * set from the boot line via two methods:
    1.51 @@ -329,6 +370,24 @@ static void __devinit init_amd(struct cp
    1.52  	   3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
    1.53  	clear_bit(0*32+31, c->x86_capability);
    1.54  	
    1.55 +#ifdef CONFIG_X86_64
    1.56 +	if (c->x86 == 0xf && c->x86_model < 0x14
    1.57 +	    && cpu_has(c, X86_FEATURE_LAHF_LM)) {
    1.58 +		/*
    1.59 +		 * Some BIOSes incorrectly force this feature, but only K8
    1.60 +		 * revision D (model = 0x14) and later actually support it.
    1.61 +		 * (AMD Erratum #110, docId: 25759).
    1.62 +		 */
    1.63 +		unsigned int lo, hi;
    1.64 +
    1.65 +		clear_bit(X86_FEATURE_LAHF_LM, c->x86_capability);
    1.66 +		if (!rdmsr_amd_safe(0xc001100d, &lo, &hi)) {
    1.67 +			hi &= ~1;
    1.68 +			wrmsr_amd_safe(0xc001100d, lo, hi);
    1.69 +		}
    1.70 +	}
    1.71 +#endif
    1.72 +
    1.73  	r = get_model_name(c);
    1.74  
    1.75  	switch(c->x86)