Commit 556c1ad6 authored by Pawan Gupta's avatar Pawan Gupta Committed by Dave Hansen
Browse files

x86/vmscape: Enable the mitigation



Enable the previously added mitigation for VMscape. Add the cmdline
vmscape={off|ibpb|force} and sysfs reporting.

Signed-off-by: default avatarPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
parent 2f8f1734
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -586,6 +586,7 @@ What: /sys/devices/system/cpu/vulnerabilities
		/sys/devices/system/cpu/vulnerabilities/srbds
		/sys/devices/system/cpu/vulnerabilities/tsa
		/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
		/sys/devices/system/cpu/vulnerabilities/vmscape
Date:		January 2018
Contact:	Linux kernel mailing list <linux-kernel@vger.kernel.org>
Description:	Information about CPU vulnerabilities
+11 −0
Original line number Diff line number Diff line
@@ -3829,6 +3829,7 @@
					       srbds=off [X86,INTEL]
					       ssbd=force-off [ARM64]
					       tsx_async_abort=off [X86]
					       vmscape=off [X86]

				Exceptions:
					       This does not have any effect on
@@ -8041,6 +8042,16 @@
	vmpoff=		[KNL,S390] Perform z/VM CP command after power off.
			Format: <command>

	vmscape=	[X86] Controls mitigation for VMscape attacks.
			VMscape attacks can leak information from a userspace
			hypervisor to a guest via speculative side-channels.

			off		- disable the mitigation
			ibpb		- use Indirect Branch Prediction Barrier
					  (IBPB) mitigation (default)
			force		- force vulnerability detection even on
					  unaffected processors

	vsyscall=	[X86-64,EARLY]
			Controls the behavior of vsyscalls (i.e. calls to
			fixed addresses of 0xffffffffff600x00 from legacy
+9 −0
Original line number Diff line number Diff line
@@ -2701,6 +2701,15 @@ config MITIGATION_TSA
	  security vulnerability on AMD CPUs which can lead to forwarding of
	  invalid info to subsequent instructions and thus can affect their
	  timing and thereby cause a leakage.

config MITIGATION_VMSCAPE
	bool "Mitigate VMSCAPE"
	depends on KVM
	default y
	help
	  Enable mitigation for VMSCAPE attacks. VMSCAPE is a hardware security
	  vulnerability on Intel and AMD CPUs that may allow a guest to do
	  Spectre v2 style attacks on userspace hypervisor.
endif

config ARCH_HAS_ADD_PAGES
+90 −0
Original line number Diff line number Diff line
@@ -96,6 +96,9 @@ static void __init its_update_mitigation(void);
static void __init its_apply_mitigation(void);
static void __init tsa_select_mitigation(void);
static void __init tsa_apply_mitigation(void);
static void __init vmscape_select_mitigation(void);
static void __init vmscape_update_mitigation(void);
static void __init vmscape_apply_mitigation(void);

/* The base value of the SPEC_CTRL MSR without task-specific bits set */
u64 x86_spec_ctrl_base;
@@ -270,6 +273,7 @@ void __init cpu_select_mitigations(void)
	its_select_mitigation();
	bhi_select_mitigation();
	tsa_select_mitigation();
	vmscape_select_mitigation();

	/*
	 * After mitigations are selected, some may need to update their
@@ -301,6 +305,7 @@ void __init cpu_select_mitigations(void)
	bhi_update_mitigation();
	/* srso_update_mitigation() depends on retbleed_update_mitigation(). */
	srso_update_mitigation();
	vmscape_update_mitigation();

	spectre_v1_apply_mitigation();
	spectre_v2_apply_mitigation();
@@ -318,6 +323,7 @@ void __init cpu_select_mitigations(void)
	its_apply_mitigation();
	bhi_apply_mitigation();
	tsa_apply_mitigation();
	vmscape_apply_mitigation();
}

/*
@@ -3322,6 +3328,77 @@ static void __init srso_apply_mitigation(void)
	}
}

#undef pr_fmt
#define pr_fmt(fmt)	"VMSCAPE: " fmt

enum vmscape_mitigations {
	VMSCAPE_MITIGATION_NONE,
	VMSCAPE_MITIGATION_AUTO,
	VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER,
	VMSCAPE_MITIGATION_IBPB_ON_VMEXIT,
};

static const char * const vmscape_strings[] = {
	[VMSCAPE_MITIGATION_NONE]		= "Vulnerable",
	/* [VMSCAPE_MITIGATION_AUTO] */
	[VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER]	= "Mitigation: IBPB before exit to userspace",
	[VMSCAPE_MITIGATION_IBPB_ON_VMEXIT]	= "Mitigation: IBPB on VMEXIT",
};

static enum vmscape_mitigations vmscape_mitigation __ro_after_init =
	IS_ENABLED(CONFIG_MITIGATION_VMSCAPE) ? VMSCAPE_MITIGATION_AUTO : VMSCAPE_MITIGATION_NONE;

static int __init vmscape_parse_cmdline(char *str)
{
	if (!str)
		return -EINVAL;

	if (!strcmp(str, "off")) {
		vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
	} else if (!strcmp(str, "ibpb")) {
		vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER;
	} else if (!strcmp(str, "force")) {
		setup_force_cpu_bug(X86_BUG_VMSCAPE);
		vmscape_mitigation = VMSCAPE_MITIGATION_AUTO;
	} else {
		pr_err("Ignoring unknown vmscape=%s option.\n", str);
	}

	return 0;
}
early_param("vmscape", vmscape_parse_cmdline);

static void __init vmscape_select_mitigation(void)
{
	if (cpu_mitigations_off() ||
	    !boot_cpu_has_bug(X86_BUG_VMSCAPE) ||
	    !boot_cpu_has(X86_FEATURE_IBPB)) {
		vmscape_mitigation = VMSCAPE_MITIGATION_NONE;
		return;
	}

	if (vmscape_mitigation == VMSCAPE_MITIGATION_AUTO)
		vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER;
}

static void __init vmscape_update_mitigation(void)
{
	if (!boot_cpu_has_bug(X86_BUG_VMSCAPE))
		return;

	if (retbleed_mitigation == RETBLEED_MITIGATION_IBPB ||
	    srso_mitigation == SRSO_MITIGATION_IBPB_ON_VMEXIT)
		vmscape_mitigation = VMSCAPE_MITIGATION_IBPB_ON_VMEXIT;

	pr_info("%s\n", vmscape_strings[vmscape_mitigation]);
}

static void __init vmscape_apply_mitigation(void)
{
	if (vmscape_mitigation == VMSCAPE_MITIGATION_IBPB_EXIT_TO_USER)
		setup_force_cpu_cap(X86_FEATURE_IBPB_EXIT_TO_USER);
}

#undef pr_fmt
#define pr_fmt(fmt) fmt

@@ -3570,6 +3647,11 @@ static ssize_t tsa_show_state(char *buf)
	return sysfs_emit(buf, "%s\n", tsa_strings[tsa_mitigation]);
}

static ssize_t vmscape_show_state(char *buf)
{
	return sysfs_emit(buf, "%s\n", vmscape_strings[vmscape_mitigation]);
}

static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
			       char *buf, unsigned int bug)
{
@@ -3636,6 +3718,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
	case X86_BUG_TSA:
		return tsa_show_state(buf);

	case X86_BUG_VMSCAPE:
		return vmscape_show_state(buf);

	default:
		break;
	}
@@ -3727,6 +3812,11 @@ ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *bu
{
	return cpu_show_common(dev, attr, buf, X86_BUG_TSA);
}

ssize_t cpu_show_vmscape(struct device *dev, struct device_attribute *attr, char *buf)
{
	return cpu_show_common(dev, attr, buf, X86_BUG_VMSCAPE);
}
#endif

void __warn_thunk(void)
+3 −0
Original line number Diff line number Diff line
@@ -603,6 +603,7 @@ CPU_SHOW_VULN_FALLBACK(ghostwrite);
CPU_SHOW_VULN_FALLBACK(old_microcode);
CPU_SHOW_VULN_FALLBACK(indirect_target_selection);
CPU_SHOW_VULN_FALLBACK(tsa);
CPU_SHOW_VULN_FALLBACK(vmscape);

static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
@@ -622,6 +623,7 @@ static DEVICE_ATTR(ghostwrite, 0444, cpu_show_ghostwrite, NULL);
static DEVICE_ATTR(old_microcode, 0444, cpu_show_old_microcode, NULL);
static DEVICE_ATTR(indirect_target_selection, 0444, cpu_show_indirect_target_selection, NULL);
static DEVICE_ATTR(tsa, 0444, cpu_show_tsa, NULL);
static DEVICE_ATTR(vmscape, 0444, cpu_show_vmscape, NULL);

static struct attribute *cpu_root_vulnerabilities_attrs[] = {
	&dev_attr_meltdown.attr,
@@ -642,6 +644,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
	&dev_attr_old_microcode.attr,
	&dev_attr_indirect_target_selection.attr,
	&dev_attr_tsa.attr,
	&dev_attr_vmscape.attr,
	NULL
};

Loading