// SPDX-License-Identifier: GPL-2.0
/*
 * Early cpufeature override framework
 *
 * Copyright (C) 2020 Google LLC
 * Author: Marc Zyngier <maz@kernel.org>
 */

#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/libfdt.h>

#include <asm/cacheflush.h>
#include <asm/cpufeature.h>
#include <asm/setup.h>

#define FTR_DESC_NAME_LEN	20
#define FTR_DESC_FIELD_LEN	10
#define FTR_ALIAS_NAME_LEN	30
#define FTR_ALIAS_OPTION_LEN	80

struct ftr_set_desc {
	char 				name[FTR_DESC_NAME_LEN];
	struct arm64_ftr_override	*override;
	struct {
		char			name[FTR_DESC_FIELD_LEN];
		u8			shift;
		bool			(*filter)(u64 val);
	} 				fields[];
};

static bool __init mmfr1_vh_filter(u64 val)
{
	/*
	 * If we ever reach this point while running VHE, we're
	 * guaranteed to be on one of these funky, VHE-stuck CPUs. If
	 * the user was trying to force nVHE on us, proceed with
	 * attitude adjustment.
	 */
	return !(is_kernel_in_hyp_mode() && val == 0);
}

static const struct ftr_set_desc mmfr1 __initconst = {
	.name		= "id_aa64mmfr1",
	.override	= &id_aa64mmfr1_override,
	.fields		= {
		{ "vh", ID_AA64MMFR1_VHE_SHIFT, mmfr1_vh_filter },
		{}
	},
};

static const struct ftr_set_desc pfr1 __initconst = {
	.name		= "id_aa64pfr1",
	.override	= &id_aa64pfr1_override,
	.fields		= {
	        { "bt", ID_AA64PFR1_BT_SHIFT },
		{ "mte", ID_AA64PFR1_MTE_SHIFT},
		{}
	},
};

static const struct ftr_set_desc isar1 __initconst = {
	.name		= "id_aa64isar1",
	.override	= &id_aa64isar1_override,
	.fields		= {
	        { "gpi", ID_AA64ISAR1_GPI_SHIFT },
	        { "gpa", ID_AA64ISAR1_GPA_SHIFT },
	        { "api", ID_AA64ISAR1_API_SHIFT },
	        { "apa", ID_AA64ISAR1_APA_SHIFT },
		{}
	},
};

extern struct arm64_ftr_override kaslr_feature_override;

static const struct ftr_set_desc kaslr __initconst = {
	.name		= "kaslr",
#ifdef CONFIG_RANDOMIZE_BASE
	.override	= &kaslr_feature_override,
#endif
	.fields		= {
		{ "disabled", 0 },
		{}
	},
};

static const struct ftr_set_desc * const regs[] __initconst = {
	&mmfr1,
	&pfr1,
	&isar1,
	&kaslr,
};

static const struct {
	char	alias[FTR_ALIAS_NAME_LEN];
	char	feature[FTR_ALIAS_OPTION_LEN];
} aliases[] __initconst = {
	{ "kvm-arm.mode=nvhe",		"id_aa64mmfr1.vh=0" },
	{ "kvm-arm.mode=protected",	"id_aa64mmfr1.vh=0" },
	{ "arm64.nobti",		"id_aa64pfr1.bt=0" },
	{ "arm64.nopauth",
	  "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
	  "id_aa64isar1.api=0 id_aa64isar1.apa=0"	   },
	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
	{ "nokaslr",			"kaslr.disabled=1" },
};

static int __init find_field(const char *cmdline,
			     const struct ftr_set_desc *reg, int f, u64 *v)
{
	char opt[FTR_DESC_NAME_LEN + FTR_DESC_FIELD_LEN + 2];
	int len;

	len = snprintf(opt, ARRAY_SIZE(opt), "%s.%s=",
		       reg->name, reg->fields[f].name);

	if (!parameqn(cmdline, opt, len))
		return -1;

	return kstrtou64(cmdline + len, 0, v);
}

static void __init match_options(const char *cmdline)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(regs); i++) {
		int f;

		if (!regs[i]->override)
			continue;

		for (f = 0; strlen(regs[i]->fields[f].name); f++) {
			u64 shift = regs[i]->fields[f].shift;
			u64 mask = 0xfUL << shift;
			u64 v;

			if (find_field(cmdline, regs[i], f, &v))
				continue;

			/*
			 * If an override gets filtered out, advertise
			 * it by setting the value to 0xf, but
			 * clearing the mask... Yes, this is fragile.
			 */
			if (regs[i]->fields[f].filter &&
			    !regs[i]->fields[f].filter(v)) {
				regs[i]->override->val  |= mask;
				regs[i]->override->mask &= ~mask;
				continue;
			}

			regs[i]->override->val  &= ~mask;
			regs[i]->override->val  |= (v << shift) & mask;
			regs[i]->override->mask |= mask;

			return;
		}
	}
}

static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
{
	do {
		char buf[256];
		size_t len;
		int i;

		cmdline = skip_spaces(cmdline);

		for (len = 0; cmdline[len] && !isspace(cmdline[len]); len++);
		if (!len)
			return;

		len = min(len, ARRAY_SIZE(buf) - 1);
		strncpy(buf, cmdline, len);
		buf[len] = 0;

		if (strcmp(buf, "--") == 0)
			return;

		cmdline += len;

		match_options(buf);

		for (i = 0; parse_aliases && i < ARRAY_SIZE(aliases); i++)
			if (parameq(buf, aliases[i].alias))
				__parse_cmdline(aliases[i].feature, false);
	} while (1);
}

static __init const u8 *get_bootargs_cmdline(void)
{
	const u8 *prop;
	void *fdt;
	int node;

	fdt = get_early_fdt_ptr();
	if (!fdt)
		return NULL;

	node = fdt_path_offset(fdt, "/chosen");
	if (node < 0)
		return NULL;

	prop = fdt_getprop(fdt, node, "bootargs", NULL);
	if (!prop)
		return NULL;

	return strlen(prop) ? prop : NULL;
}

static __init void parse_cmdline(void)
{
	const u8 *prop = get_bootargs_cmdline();

	if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
		__parse_cmdline(CONFIG_CMDLINE, true);

	if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && prop)
		__parse_cmdline(prop, true);
}

/* Keep checkers quiet */
void init_feature_override(void);

asmlinkage void __init init_feature_override(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(regs); i++) {
		if (regs[i]->override) {
			regs[i]->override->val  = 0;
			regs[i]->override->mask = 0;
		}
	}

	parse_cmdline();

	for (i = 0; i < ARRAY_SIZE(regs); i++) {
		if (regs[i]->override)
			dcache_clean_inval_poc((unsigned long)regs[i]->override,
					    (unsigned long)regs[i]->override +
					    sizeof(*regs[i]->override));
	}
}
