Bug 871265

Summary: lahf_lm flag is not recognized by guest kernel
Product: Red Hat Enterprise Linux 6 Reporter: Suqin Huang <shuang>
Component: qemu-kvmAssignee: Eduardo Habkost <ehabkost>
Status: CLOSED WONTFIX QA Contact: Virtualization Bugs <virt-bugs>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.4CC: acathrow, areis, bsarathy, dyasny, mkenneth, virt-maint
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Known Issue
Doc Text:
AMD Opteron G1, G2 or G3 CPU models on qemu-kvm use the family and models values as follows: family=15 and model=6. If these values are larger than 20, the lahfm_lm CPU feature is ignored by Linux guests, even when the feature is enabled. To work around this problem, use a different CPU model, for example AMD Opteron G4.
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-11-20 13:47:28 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Suqin Huang 2012-10-30 05:29:33 UTC
Description of problem:

same kernel for host and guest, 
lahf_lm is shown on host /proc/cpuinfo
but is not shown on guest /proc/cpuinfo

lahf_lm cpuid is enabled from guest x86info

Version-Release number of selected component (if applicable):
qemu-kvm-0.12.1.2-2.329.el6.x86_64
2.6.32-337.el6.x86_64

How reproducible:
100%

Steps to Reproduce:
1. boot guest with Opteron_G3 on Opteron_G3 host
2.
3.
  
Actual results:


Expected results:


Additional info:
1. guest flag: (no lahf_lm)
flags		: fpu de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx lm rep_good extd_apicid unfair_spinlock pni cx16 x2apic popcnt hypervisor abm sse4a misalignsse

2. host flag: (there is lahf_lm)
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs npt lbrv svm_lock

3. lahf_lm is definded in cpuid.c
static const char *ext3_feature_name[] = {
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
    "3dnowprefetch", "osvw", "ibs", "xop",
    "skinit", "wdt", NULL, NULL,
    "fma4", NULL, "cvt16", "nodeid_msr",

4. guest x86info
eax in: 0x00000000, eax = 00000005 ebx = 68747541 ecx = 444d4163 edx = 69746e65
eax in: 0x00000001, eax = 00000f61 ebx = 01000800 ecx = 80a02001 edx = 078bf3fd
eax in: 0x00000002, eax = 00000001 ebx = 00000000 ecx = 00000000 edx = 002c307d
eax in: 0x00000003, eax = 00000000 ebx = 00000000 ecx = 00000000 edx = 00000000
eax in: 0x00000004, eax = 00000121 ebx = 01c0003f ecx = 0000003f edx = 00000001
eax in: 0x00000005, eax = 00000000 ebx = 00000000 ecx = 00000003 edx = 00000000

eax in: 0x80000000, eax = 80000008 ebx = 68747541 ecx = 444d4163 edx = 69746e65
eax in: 0x80000001, eax = 00000f61 ebx = 00000000 ecx = 000000e1 edx = 2193fbfd
eax in: 0x80000002, eax = 20444d41 ebx = 6574704f ecx = 206e6f72 edx = 78783332
eax in: 0x80000003, eax = 65472820 ebx = 2033206e ecx = 73616c43 edx = 704f2073
eax in: 0x80000004, eax = 6f726574 ebx = 0000296e ecx = 00000000 edx = 00000000
eax in: 0x80000005, eax = 01ff01ff ebx = 01ff01ff ecx = 40020140 edx = 40020140
eax in: 0x80000006, eax = 00000000 ebx = 42004200 ecx = 02008140 edx = 00000000
eax in: 0x80000007, eax = 00000000 ebx = 00000000 ecx = 00000000 edx = 00000000
eax in: 0x80000008, eax = 00003030 ebx = 00000000 ecx = 00000000 edx = 00000000

5. guest & host kernel
2.6.32-337.el6.x86_64

Comment 2 Eduardo Habkost 2012-11-20 13:45:03 UTC
The bit is set on the CPUID info:
eax in: 0x80000001, eax = 00000f61 ebx = 00000000 ecx = 000000e1 edx = 2193fbfd

(it's bit 0 on CPUID[0x80000001].ECX)

The guest chooses to ignore it because of the low model value. This is the guest-side kernel code:

       /* On C+ stepping K8 rep microcode works well for copy/memset */
        if (c->x86 == 0xf) {
                u32 level;

                level = cpuid_eax(1);
                if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
                        set_cpu_cap(c, X86_FEATURE_REP_GOOD);

                /*
                 * Some BIOSes incorrectly force this feature, but only K8
                 * revision D (model = 0x14) and later actually support it.
                 * (AMD Erratum #110, docId: 25759).
                 */
                if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
                        u64 val;

                        clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
                        if (!rdmsrl_amd_safe(0xc001100d, &val)) {
                                val &= ~(1ULL << 32);
                                wrmsrl_amd_safe(0xc001100d, val);
                        }
                }

        }

The only way to fix it would be to update the Opteron_G* models to use a higher family/model value instead of family=15,model=6.