diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/cpu/amd.c | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/microcode/amd.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/fpu/core.c | 3 | 
3 files changed, 33 insertions, 2 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index ccaa51ce63f6..8e36964a7721 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -516,7 +516,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)  			setup_force_cpu_cap(X86_FEATURE_ZEN5);  			break;  		case 0x50 ... 0x5f: -		case 0x90 ... 0xaf: +		case 0x80 ... 0xaf:  		case 0xc0 ... 0xcf:  			setup_force_cpu_cap(X86_FEATURE_ZEN6);  			break; @@ -1035,8 +1035,18 @@ static void init_amd_zen4(struct cpuinfo_x86 *c)  	}  } +static const struct x86_cpu_id zen5_rdseed_microcode[] = { +	ZEN_MODEL_STEP_UCODE(0x1a, 0x02, 0x1, 0x0b00215a), +	ZEN_MODEL_STEP_UCODE(0x1a, 0x11, 0x0, 0x0b101054), +}; +  static void init_amd_zen5(struct cpuinfo_x86 *c)  { +	if (!x86_match_min_microcode_rev(zen5_rdseed_microcode)) { +		clear_cpu_cap(c, X86_FEATURE_RDSEED); +		msr_clear_bit(MSR_AMD64_CPUID_FN_7, 18); +		pr_emerg_once("RDSEED32 is broken. Disabling the corresponding CPUID bit.\n"); +	}  }  static void init_amd(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 28ed8c089024..b7c797dc94f4 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -233,13 +233,31 @@ static bool need_sha_check(u32 cur_rev)  	return true;  } +static bool cpu_has_entrysign(void) +{ +	unsigned int fam   = x86_family(bsp_cpuid_1_eax); +	unsigned int model = x86_model(bsp_cpuid_1_eax); + +	if (fam == 0x17 || fam == 0x19) +		return true; + +	if (fam == 0x1a) { +		if (model <= 0x2f || +		    (0x40 <= model && model <= 0x4f) || +		    (0x60 <= model && model <= 0x6f)) +			return true; +	} + +	return false; +} +  static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsigned int len)  {  	struct patch_digest *pd = NULL;  	u8 digest[SHA256_DIGEST_SIZE];  	int i; -	if (x86_family(bsp_cpuid_1_eax) < 0x17) +	if (!cpu_has_entrysign())  		return true;  	if (!need_sha_check(cur_rev)) diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 1f71cc135e9a..e88eacb1b5bb 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -825,6 +825,9 @@ void fpu__clear_user_states(struct fpu *fpu)  	    !fpregs_state_valid(fpu, smp_processor_id()))  		os_xrstor_supervisor(fpu->fpstate); +	/* Ensure XFD state is in sync before reloading XSTATE */ +	xfd_update_state(fpu->fpstate); +  	/* Reset user states in registers. */  	restore_fpregs_from_init_fpstate(XFEATURE_MASK_USER_RESTORE);  | 
