// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Transactional Synchronization Extensions (TSX) control.
 *
 * Copyright (C) 2019-2021 Intel Corporation
 *
 * Author:
 *	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
 */

#include <linux/cpufeature.h>

#include <asm/cmdline.h>

#include "cpu.h"

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

enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED;

static void tsx_disable(void)
{
	u64 tsx;

	rdmsrl(MSR_IA32_TSX_CTRL, tsx);

	/* Force all transactions to immediately abort */
	tsx |= TSX_CTRL_RTM_DISABLE;

	/*
	 * Ensure TSX support is not enumerated in CPUID.
	 * This is visible to userspace and will ensure they
	 * do not waste resources trying TSX transactions that
	 * will always abort.
	 */
	tsx |= TSX_CTRL_CPUID_CLEAR;

	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
}

static void tsx_enable(void)
{
	u64 tsx;

	rdmsrl(MSR_IA32_TSX_CTRL, tsx);

	/* Enable the RTM feature in the cpu */
	tsx &= ~TSX_CTRL_RTM_DISABLE;

	/*
	 * Ensure TSX support is enumerated in CPUID.
	 * This is visible to userspace and will ensure they
	 * can enumerate and use the TSX feature.
	 */
	tsx &= ~TSX_CTRL_CPUID_CLEAR;

	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
}

static bool tsx_ctrl_is_supported(void)
{
	u64 ia32_cap = x86_read_arch_cap_msr();

	/*
	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
	 *
	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
	 * tsx= cmdline requests will do nothing on CPUs without
	 * MSR_IA32_TSX_CTRL support.
	 */
	return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
}

static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
{
	if (boot_cpu_has_bug(X86_BUG_TAA))
		return TSX_CTRL_DISABLE;

	return TSX_CTRL_ENABLE;
}

/*
 * Disabling TSX is not a trivial business.
 *
 * First of all, there's a CPUID bit: X86_FEATURE_RTM_ALWAYS_ABORT
 * which says that TSX is practically disabled (all transactions are
 * aborted by default). When that bit is set, the kernel unconditionally
 * disables TSX.
 *
 * In order to do that, however, it needs to dance a bit:
 *
 * 1. The first method to disable it is through MSR_TSX_FORCE_ABORT and
 * the MSR is present only when *two* CPUID bits are set:
 *
 * - X86_FEATURE_RTM_ALWAYS_ABORT
 * - X86_FEATURE_TSX_FORCE_ABORT
 *
 * 2. The second method is for CPUs which do not have the above-mentioned
 * MSR: those use a different MSR - MSR_IA32_TSX_CTRL and disable TSX
 * through that one. Those CPUs can also have the initially mentioned
 * CPUID bit X86_FEATURE_RTM_ALWAYS_ABORT set and for those the same strategy
 * applies: TSX gets disabled unconditionally.
 *
 * When either of the two methods are present, the kernel disables TSX and
 * clears the respective RTM and HLE feature flags.
 *
 * An additional twist in the whole thing presents late microcode loading
 * which, when done, may cause for the X86_FEATURE_RTM_ALWAYS_ABORT CPUID
 * bit to be set after the update.
 *
 * A subsequent hotplug operation on any logical CPU except the BSP will
 * cause for the supported CPUID feature bits to get re-detected and, if
 * RTM and HLE get cleared all of a sudden, but, userspace did consult
 * them before the update, then funny explosions will happen. Long story
 * short: the kernel doesn't modify CPUID feature bits after booting.
 *
 * That's why, this function's call in init_intel() doesn't clear the
 * feature flags.
 */
static void tsx_clear_cpuid(void)
{
	u64 msr;

	/*
	 * MSR_TFA_TSX_CPUID_CLEAR bit is only present when both CPUID
	 * bits RTM_ALWAYS_ABORT and TSX_FORCE_ABORT are present.
	 */
	if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT) &&
	    boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) {
		rdmsrl(MSR_TSX_FORCE_ABORT, msr);
		msr |= MSR_TFA_TSX_CPUID_CLEAR;
		wrmsrl(MSR_TSX_FORCE_ABORT, msr);
	} else if (tsx_ctrl_is_supported()) {
		rdmsrl(MSR_IA32_TSX_CTRL, msr);
		msr |= TSX_CTRL_CPUID_CLEAR;
		wrmsrl(MSR_IA32_TSX_CTRL, msr);
	}
}

/*
 * Disable TSX development mode
 *
 * When the microcode released in Feb 2022 is applied, TSX will be disabled by
 * default on some processors. MSR 0x122 (TSX_CTRL) and MSR 0x123
 * (IA32_MCU_OPT_CTRL) can be used to re-enable TSX for development, doing so is
 * not recommended for production deployments. In particular, applying MD_CLEAR
 * flows for mitigation of the Intel TSX Asynchronous Abort (TAA) transient
 * execution attack may not be effective on these processors when Intel TSX is
 * enabled with updated microcode.
 */
static void tsx_dev_mode_disable(void)
{
	u64 mcu_opt_ctrl;

	/* Check if RTM_ALLOW exists */
	if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() ||
	    !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
		return;

	rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_opt_ctrl);

	if (mcu_opt_ctrl & RTM_ALLOW) {
		mcu_opt_ctrl &= ~RTM_ALLOW;
		wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_opt_ctrl);
		setup_force_cpu_cap(X86_FEATURE_RTM_ALWAYS_ABORT);
	}
}

void __init tsx_init(void)
{
	char arg[5] = {};
	int ret;

	tsx_dev_mode_disable();

	/*
	 * Hardware will always abort a TSX transaction when the CPUID bit
	 * RTM_ALWAYS_ABORT is set. In this case, it is better not to enumerate
	 * CPUID.RTM and CPUID.HLE bits. Clear them here.
	 */
	if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT)) {
		tsx_ctrl_state = TSX_CTRL_RTM_ALWAYS_ABORT;
		tsx_clear_cpuid();
		setup_clear_cpu_cap(X86_FEATURE_RTM);
		setup_clear_cpu_cap(X86_FEATURE_HLE);
		return;
	}

	if (!tsx_ctrl_is_supported()) {
		tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
		return;
	}

	ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg));
	if (ret >= 0) {
		if (!strcmp(arg, "on")) {
			tsx_ctrl_state = TSX_CTRL_ENABLE;
		} else if (!strcmp(arg, "off")) {
			tsx_ctrl_state = TSX_CTRL_DISABLE;
		} else if (!strcmp(arg, "auto")) {
			tsx_ctrl_state = x86_get_tsx_auto_mode();
		} else {
			tsx_ctrl_state = TSX_CTRL_DISABLE;
			pr_err("invalid option, defaulting to off\n");
		}
	} else {
		/* tsx= not provided */
		if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_AUTO))
			tsx_ctrl_state = x86_get_tsx_auto_mode();
		else if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_OFF))
			tsx_ctrl_state = TSX_CTRL_DISABLE;
		else
			tsx_ctrl_state = TSX_CTRL_ENABLE;
	}

	if (tsx_ctrl_state == TSX_CTRL_DISABLE) {
		tsx_disable();

		/*
		 * tsx_disable() will change the state of the RTM and HLE CPUID
		 * bits. Clear them here since they are now expected to be not
		 * set.
		 */
		setup_clear_cpu_cap(X86_FEATURE_RTM);
		setup_clear_cpu_cap(X86_FEATURE_HLE);
	} else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {

		/*
		 * HW defaults TSX to be enabled at bootup.
		 * We may still need the TSX enable support
		 * during init for special cases like
		 * kexec after TSX is disabled.
		 */
		tsx_enable();

		/*
		 * tsx_enable() will change the state of the RTM and HLE CPUID
		 * bits. Force them here since they are now expected to be set.
		 */
		setup_force_cpu_cap(X86_FEATURE_RTM);
		setup_force_cpu_cap(X86_FEATURE_HLE);
	}
}

void tsx_ap_init(void)
{
	tsx_dev_mode_disable();

	if (tsx_ctrl_state == TSX_CTRL_ENABLE)
		tsx_enable();
	else if (tsx_ctrl_state == TSX_CTRL_DISABLE)
		tsx_disable();
	else if (tsx_ctrl_state == TSX_CTRL_RTM_ALWAYS_ABORT)
		/* See comment over that function for more details. */
		tsx_clear_cpuid();
}
