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

Commit 1b86883c authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk Committed by Thomas Gleixner
Browse files

x86/bugs: Read SPEC_CTRL MSR during boot and re-use reserved bits

The 336996-Speculative-Execution-Side-Channel-Mitigations.pdf refers to all
the other bits as reserved. The Intel SDM glossary defines reserved as
implementation specific - aka unknown.

As such at bootup this must be taken it into account and proper masking for
the bits in use applied.

A copy of this document is available at
https://bugzilla.kernel.org/show_bug.cgi?id=199511



[ tglx: Made x86_spec_ctrl_base __ro_after_init ]

Suggested-by: default avatarJon Masters <jcm@redhat.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarIngo Molnar <mingo@kernel.org>
parent d1059518
Loading
Loading
Loading
Loading
+20 −4
Original line number Original line Diff line number Diff line
@@ -217,6 +217,17 @@ enum spectre_v2_mitigation {
	SPECTRE_V2_IBRS,
	SPECTRE_V2_IBRS,
};
};


/*
 * The Intel specification for the SPEC_CTRL MSR requires that we
 * preserve any already set reserved bits at boot time (e.g. for
 * future additions that this kernel is not currently aware of).
 * We then set any additional mitigation bits that we want
 * ourselves and always use this as the base for SPEC_CTRL.
 * We also use this when handling guest entry/exit as below.
 */
extern void x86_spec_ctrl_set(u64);
extern u64 x86_spec_ctrl_get_default(void);

extern char __indirect_thunk_start[];
extern char __indirect_thunk_start[];
extern char __indirect_thunk_end[];
extern char __indirect_thunk_end[];


@@ -254,8 +265,9 @@ void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)


static inline void indirect_branch_prediction_barrier(void)
static inline void indirect_branch_prediction_barrier(void)
{
{
	alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB,
	u64 val = PRED_CMD_IBPB;
			      X86_FEATURE_USE_IBPB);

	alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB);
}
}


/*
/*
@@ -266,14 +278,18 @@ static inline void indirect_branch_prediction_barrier(void)
 */
 */
#define firmware_restrict_branch_speculation_start()			\
#define firmware_restrict_branch_speculation_start()			\
do {									\
do {									\
	u64 val = x86_spec_ctrl_get_default() | SPEC_CTRL_IBRS;		\
									\
	preempt_disable();						\
	preempt_disable();						\
	alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS,	\
	alternative_msr_write(MSR_IA32_SPEC_CTRL, val,			\
			      X86_FEATURE_USE_IBRS_FW);			\
			      X86_FEATURE_USE_IBRS_FW);			\
} while (0)
} while (0)


#define firmware_restrict_branch_speculation_end()			\
#define firmware_restrict_branch_speculation_end()			\
do {									\
do {									\
	alternative_msr_write(MSR_IA32_SPEC_CTRL, 0,			\
	u64 val = x86_spec_ctrl_get_default();				\
									\
	alternative_msr_write(MSR_IA32_SPEC_CTRL, val,			\
			      X86_FEATURE_USE_IBRS_FW);			\
			      X86_FEATURE_USE_IBRS_FW);			\
	preempt_enable();						\
	preempt_enable();						\
} while (0)
} while (0)
+28 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,12 @@


static void __init spectre_v2_select_mitigation(void);
static void __init spectre_v2_select_mitigation(void);


/*
 * Our boot-time value of the SPEC_CTRL MSR. We read it once so that any
 * writes to SPEC_CTRL contain whatever reserved bits have been set.
 */
static u64 __ro_after_init x86_spec_ctrl_base;

void __init check_bugs(void)
void __init check_bugs(void)
{
{
	identify_boot_cpu();
	identify_boot_cpu();
@@ -37,6 +43,13 @@ void __init check_bugs(void)
		print_cpu_info(&boot_cpu_data);
		print_cpu_info(&boot_cpu_data);
	}
	}


	/*
	 * Read the SPEC_CTRL MSR to account for reserved bits which may
	 * have unknown values.
	 */
	if (boot_cpu_has(X86_FEATURE_IBRS))
		rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base);

	/* Select the proper spectre mitigation before patching alternatives */
	/* Select the proper spectre mitigation before patching alternatives */
	spectre_v2_select_mitigation();
	spectre_v2_select_mitigation();


@@ -95,6 +108,21 @@ static const char *spectre_v2_strings[] = {


static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;


void x86_spec_ctrl_set(u64 val)
{
	if (val & ~SPEC_CTRL_IBRS)
		WARN_ONCE(1, "SPEC_CTRL MSR value 0x%16llx is unknown.\n", val);
	else
		wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base | val);
}
EXPORT_SYMBOL_GPL(x86_spec_ctrl_set);

u64 x86_spec_ctrl_get_default(void)
{
	return x86_spec_ctrl_base;
}
EXPORT_SYMBOL_GPL(x86_spec_ctrl_get_default);

#ifdef RETPOLINE
#ifdef RETPOLINE
static bool spectre_v2_bad_module;
static bool spectre_v2_bad_module;