Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edb18f8a authored by Suresh Siddha's avatar Suresh Siddha Committed by H. Peter Anvin
Browse files

x86, cpu: Make init_scattered_cpuid_features() consider cpuid subleaves



Some cpuid features (like xsaveopt) are enumerated using cpuid
subleaves.

Extend init_scattered_cpuid_features() to take subleaf into account.

Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
LKML-Reference: <20100719230205.439900717@sbs-t61.sc.intel.com>
Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent bdc802dc
Loading
Loading
Loading
Loading
+13 −12
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ struct cpuid_bit {
	u8 reg;
	u8 bit;
	u32 level;
	u32 sub_leaf;
};

enum cpuid_regs {
@@ -30,16 +31,16 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
	const struct cpuid_bit *cb;

	static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
		{ X86_FEATURE_IDA,   		CR_EAX, 1, 0x00000006 },
		{ X86_FEATURE_ARAT,  		CR_EAX, 2, 0x00000006 },
		{ X86_FEATURE_APERFMPERF,	CR_ECX, 0, 0x00000006 },
		{ X86_FEATURE_EPB,		CR_ECX, 3, 0x00000006 },
		{ X86_FEATURE_CPB,   		CR_EDX, 9, 0x80000007 },
		{ X86_FEATURE_NPT,   		CR_EDX, 0, 0x8000000a },
		{ X86_FEATURE_LBRV,  		CR_EDX, 1, 0x8000000a },
		{ X86_FEATURE_SVML,  		CR_EDX, 2, 0x8000000a },
		{ X86_FEATURE_NRIPS, 		CR_EDX, 3, 0x8000000a },
		{ 0, 0, 0, 0 }
		{ X86_FEATURE_IDA,		CR_EAX, 1, 0x00000006, 0 },
		{ X86_FEATURE_ARAT,		CR_EAX, 2, 0x00000006, 0 },
		{ X86_FEATURE_APERFMPERF,	CR_ECX, 0, 0x00000006, 0 },
		{ X86_FEATURE_EPB,		CR_ECX, 3, 0x00000006, 0 },
		{ X86_FEATURE_CPB,		CR_EDX, 9, 0x80000007, 0 },
		{ X86_FEATURE_NPT,		CR_EDX, 0, 0x8000000a, 0 },
		{ X86_FEATURE_LBRV,		CR_EDX, 1, 0x8000000a, 0 },
		{ X86_FEATURE_SVML,		CR_EDX, 2, 0x8000000a, 0 },
		{ X86_FEATURE_NRIPS,		CR_EDX, 3, 0x8000000a, 0 },
		{ 0, 0, 0, 0, 0 }
	};

	for (cb = cpuid_bits; cb->feature; cb++) {
@@ -50,8 +51,8 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
		    max_level > (cb->level | 0xffff))
			continue;

		cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
			&regs[CR_ECX], &regs[CR_EDX]);
		cpuid_count(cb->level, cb->sub_leaf, &regs[CR_EAX],
			    &regs[CR_EBX], &regs[CR_ECX], &regs[CR_EDX]);

		if (regs[cb->reg] & (1 << cb->bit))
			set_cpu_cap(c, cb->feature);