// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2019 Arm Ltd.

#include <linux/arm-smccc.h>
#include <linux/kvm_host.h>

#include <asm/kvm_emulate.h>

#include <kvm/arm_hypercalls.h>
#include <kvm/arm_psci.h>

#define KVM_ARM_SMCCC_STD_FEATURES				\
	GENMASK(KVM_REG_ARM_STD_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_STD_HYP_FEATURES				\
	GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES			\
	GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2			\
	GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT - 1, 0)

static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
{
	struct system_time_snapshot systime_snapshot;
	u64 cycles = ~0UL;
	u32 feature;

	/*
	 * system time and counter value must captured at the same
	 * time to keep consistency and precision.
	 */
	ktime_get_snapshot(&systime_snapshot);

	/*
	 * This is only valid if the current clocksource is the
	 * architected counter, as this is the only one the guest
	 * can see.
	 */
	if (systime_snapshot.cs_id != CSID_ARM_ARCH_COUNTER)
		return;

	/*
	 * The guest selects one of the two reference counters
	 * (virtual or physical) with the first argument of the SMCCC
	 * call. In case the identifier is not supported, error out.
	 */
	feature = smccc_get_arg1(vcpu);
	switch (feature) {
	case KVM_PTP_VIRT_COUNTER:
		cycles = systime_snapshot.cycles - vcpu->kvm->arch.timer_data.voffset;
		break;
	case KVM_PTP_PHYS_COUNTER:
		cycles = systime_snapshot.cycles - vcpu->kvm->arch.timer_data.poffset;
		break;
	default:
		return;
	}

	/*
	 * This relies on the top bit of val[0] never being set for
	 * valid values of system time, because that is *really* far
	 * in the future (about 292 years from 1970, and at that stage
	 * nobody will give a damn about it).
	 */
	val[0] = upper_32_bits(systime_snapshot.real);
	val[1] = lower_32_bits(systime_snapshot.real);
	val[2] = upper_32_bits(cycles);
	val[3] = lower_32_bits(cycles);
}

static bool kvm_smccc_default_allowed(u32 func_id)
{
	switch (func_id) {
	/*
	 * List of function-ids that are not gated with the bitmapped
	 * feature firmware registers, and are to be allowed for
	 * servicing the call by default.
	 */
	case ARM_SMCCC_VERSION_FUNC_ID:
	case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
		return true;
	default:
		/* PSCI 0.2 and up is in the 0:0x1f range */
		if (ARM_SMCCC_OWNER_NUM(func_id) == ARM_SMCCC_OWNER_STANDARD &&
		    ARM_SMCCC_FUNC_NUM(func_id) <= 0x1f)
			return true;

		/*
		 * KVM's PSCI 0.1 doesn't comply with SMCCC, and has
		 * its own function-id base and range
		 */
		if (func_id >= KVM_PSCI_FN(0) && func_id <= KVM_PSCI_FN(3))
			return true;

		return false;
	}
}

static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
{
	struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;

	switch (func_id) {
	case ARM_SMCCC_TRNG_VERSION:
	case ARM_SMCCC_TRNG_FEATURES:
	case ARM_SMCCC_TRNG_GET_UUID:
	case ARM_SMCCC_TRNG_RND32:
	case ARM_SMCCC_TRNG_RND64:
		return test_bit(KVM_REG_ARM_STD_BIT_TRNG_V1_0,
				&smccc_feat->std_bmap);
	case ARM_SMCCC_HV_PV_TIME_FEATURES:
	case ARM_SMCCC_HV_PV_TIME_ST:
		return test_bit(KVM_REG_ARM_STD_HYP_BIT_PV_TIME,
				&smccc_feat->std_hyp_bmap);
	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
	case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID:
		return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT,
				&smccc_feat->vendor_hyp_bmap);
	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
		return test_bit(KVM_REG_ARM_VENDOR_HYP_BIT_PTP,
				&smccc_feat->vendor_hyp_bmap);
	default:
		return false;
	}
}

#define SMC32_ARCH_RANGE_BEGIN	ARM_SMCCC_VERSION_FUNC_ID
#define SMC32_ARCH_RANGE_END	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
						   ARM_SMCCC_SMC_32,		\
						   0, ARM_SMCCC_FUNC_MASK)

#define SMC64_ARCH_RANGE_BEGIN	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
						   ARM_SMCCC_SMC_64,		\
						   0, 0)
#define SMC64_ARCH_RANGE_END	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,		\
						   ARM_SMCCC_SMC_64,		\
						   0, ARM_SMCCC_FUNC_MASK)

static int kvm_smccc_filter_insert_reserved(struct kvm *kvm)
{
	int r;

	/*
	 * Prevent userspace from handling any SMCCC calls in the architecture
	 * range, avoiding the risk of misrepresenting Spectre mitigation status
	 * to the guest.
	 */
	r = mtree_insert_range(&kvm->arch.smccc_filter,
			       SMC32_ARCH_RANGE_BEGIN, SMC32_ARCH_RANGE_END,
			       xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
			       GFP_KERNEL_ACCOUNT);
	if (r)
		goto out_destroy;

	r = mtree_insert_range(&kvm->arch.smccc_filter,
			       SMC64_ARCH_RANGE_BEGIN, SMC64_ARCH_RANGE_END,
			       xa_mk_value(KVM_SMCCC_FILTER_HANDLE),
			       GFP_KERNEL_ACCOUNT);
	if (r)
		goto out_destroy;

	return 0;
out_destroy:
	mtree_destroy(&kvm->arch.smccc_filter);
	return r;
}

static bool kvm_smccc_filter_configured(struct kvm *kvm)
{
	return !mtree_empty(&kvm->arch.smccc_filter);
}

static int kvm_smccc_set_filter(struct kvm *kvm, struct kvm_smccc_filter __user *uaddr)
{
	const void *zero_page = page_to_virt(ZERO_PAGE(0));
	struct kvm_smccc_filter filter;
	u32 start, end;
	int r;

	if (copy_from_user(&filter, uaddr, sizeof(filter)))
		return -EFAULT;

	if (memcmp(filter.pad, zero_page, sizeof(filter.pad)))
		return -EINVAL;

	start = filter.base;
	end = start + filter.nr_functions - 1;

	if (end < start || filter.action >= NR_SMCCC_FILTER_ACTIONS)
		return -EINVAL;

	mutex_lock(&kvm->arch.config_lock);

	if (kvm_vm_has_ran_once(kvm)) {
		r = -EBUSY;
		goto out_unlock;
	}

	if (!kvm_smccc_filter_configured(kvm)) {
		r = kvm_smccc_filter_insert_reserved(kvm);
		if (WARN_ON_ONCE(r))
			goto out_unlock;
	}

	r = mtree_insert_range(&kvm->arch.smccc_filter, start, end,
			       xa_mk_value(filter.action), GFP_KERNEL_ACCOUNT);
out_unlock:
	mutex_unlock(&kvm->arch.config_lock);
	return r;
}

static u8 kvm_smccc_filter_get_action(struct kvm *kvm, u32 func_id)
{
	unsigned long idx = func_id;
	void *val;

	if (!kvm_smccc_filter_configured(kvm))
		return KVM_SMCCC_FILTER_HANDLE;

	/*
	 * But where's the error handling, you say?
	 *
	 * mt_find() returns NULL if no entry was found, which just so happens
	 * to match KVM_SMCCC_FILTER_HANDLE.
	 */
	val = mt_find(&kvm->arch.smccc_filter, &idx, idx);
	return xa_to_value(val);
}

static u8 kvm_smccc_get_action(struct kvm_vcpu *vcpu, u32 func_id)
{
	/*
	 * Intervening actions in the SMCCC filter take precedence over the
	 * pseudo-firmware register bitmaps.
	 */
	u8 action = kvm_smccc_filter_get_action(vcpu->kvm, func_id);
	if (action != KVM_SMCCC_FILTER_HANDLE)
		return action;

	if (kvm_smccc_test_fw_bmap(vcpu, func_id) ||
	    kvm_smccc_default_allowed(func_id))
		return KVM_SMCCC_FILTER_HANDLE;

	return KVM_SMCCC_FILTER_DENY;
}

static void kvm_prepare_hypercall_exit(struct kvm_vcpu *vcpu, u32 func_id)
{
	u8 ec = ESR_ELx_EC(kvm_vcpu_get_esr(vcpu));
	struct kvm_run *run = vcpu->run;
	u64 flags = 0;

	if (ec == ESR_ELx_EC_SMC32 || ec == ESR_ELx_EC_SMC64)
		flags |= KVM_HYPERCALL_EXIT_SMC;

	if (!kvm_vcpu_trap_il_is32bit(vcpu))
		flags |= KVM_HYPERCALL_EXIT_16BIT;

	run->exit_reason = KVM_EXIT_HYPERCALL;
	run->hypercall = (typeof(run->hypercall)) {
		.nr	= func_id,
		.flags	= flags,
	};
}

int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
{
	struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
	u32 func_id = smccc_get_function(vcpu);
	u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
	u32 feature;
	u8 action;
	gpa_t gpa;
	uuid_t uuid;

	action = kvm_smccc_get_action(vcpu, func_id);
	switch (action) {
	case KVM_SMCCC_FILTER_HANDLE:
		break;
	case KVM_SMCCC_FILTER_DENY:
		goto out;
	case KVM_SMCCC_FILTER_FWD_TO_USER:
		kvm_prepare_hypercall_exit(vcpu, func_id);
		return 0;
	default:
		WARN_RATELIMIT(1, "Unhandled SMCCC filter action: %d\n", action);
		goto out;
	}

	switch (func_id) {
	case ARM_SMCCC_VERSION_FUNC_ID:
		val[0] = ARM_SMCCC_VERSION_1_1;
		break;
	case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
		feature = smccc_get_arg1(vcpu);
		switch (feature) {
		case ARM_SMCCC_ARCH_WORKAROUND_1:
			switch (arm64_get_spectre_v2_state()) {
			case SPECTRE_VULNERABLE:
				break;
			case SPECTRE_MITIGATED:
				val[0] = SMCCC_RET_SUCCESS;
				break;
			case SPECTRE_UNAFFECTED:
				val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
				break;
			}
			break;
		case ARM_SMCCC_ARCH_WORKAROUND_2:
			switch (arm64_get_spectre_v4_state()) {
			case SPECTRE_VULNERABLE:
				break;
			case SPECTRE_MITIGATED:
				/*
				 * SSBS everywhere: Indicate no firmware
				 * support, as the SSBS support will be
				 * indicated to the guest and the default is
				 * safe.
				 *
				 * Otherwise, expose a permanent mitigation
				 * to the guest, and hide SSBS so that the
				 * guest stays protected.
				 */
				if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
					break;
				fallthrough;
			case SPECTRE_UNAFFECTED:
				val[0] = SMCCC_RET_NOT_REQUIRED;
				break;
			}
			break;
		case ARM_SMCCC_ARCH_WORKAROUND_3:
			switch (arm64_get_spectre_bhb_state()) {
			case SPECTRE_VULNERABLE:
				break;
			case SPECTRE_MITIGATED:
				val[0] = SMCCC_RET_SUCCESS;
				break;
			case SPECTRE_UNAFFECTED:
				val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED;
				break;
			}
			break;
		case ARM_SMCCC_HV_PV_TIME_FEATURES:
			if (test_bit(KVM_REG_ARM_STD_HYP_BIT_PV_TIME,
				     &smccc_feat->std_hyp_bmap))
				val[0] = SMCCC_RET_SUCCESS;
			break;
		}
		break;
	case ARM_SMCCC_HV_PV_TIME_FEATURES:
		val[0] = kvm_hypercall_pv_features(vcpu);
		break;
	case ARM_SMCCC_HV_PV_TIME_ST:
		gpa = kvm_init_stolen_time(vcpu);
		if (gpa != INVALID_GPA)
			val[0] = gpa;
		break;
	case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID:
		uuid = ARM_SMCCC_VENDOR_HYP_UID_KVM;
		val[0] = smccc_uuid_to_reg(&uuid, 0);
		val[1] = smccc_uuid_to_reg(&uuid, 1);
		val[2] = smccc_uuid_to_reg(&uuid, 2);
		val[3] = smccc_uuid_to_reg(&uuid, 3);
		break;
	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
		val[0] = smccc_feat->vendor_hyp_bmap;
		/* Function numbers 2-63 are reserved for pKVM for now */
		val[2] = smccc_feat->vendor_hyp_bmap_2;
		break;
	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
		kvm_ptp_get_time(vcpu, val);
		break;
	case ARM_SMCCC_TRNG_VERSION:
	case ARM_SMCCC_TRNG_FEATURES:
	case ARM_SMCCC_TRNG_GET_UUID:
	case ARM_SMCCC_TRNG_RND32:
	case ARM_SMCCC_TRNG_RND64:
		return kvm_trng_call(vcpu);
	default:
		return kvm_psci_call(vcpu);
	}

out:
	smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
	return 1;
}

static const u64 kvm_arm_fw_reg_ids[] = {
	KVM_REG_ARM_PSCI_VERSION,
	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3,
	KVM_REG_ARM_STD_BMAP,
	KVM_REG_ARM_STD_HYP_BMAP,
	KVM_REG_ARM_VENDOR_HYP_BMAP,
	KVM_REG_ARM_VENDOR_HYP_BMAP_2,
};

void kvm_arm_init_hypercalls(struct kvm *kvm)
{
	struct kvm_smccc_features *smccc_feat = &kvm->arch.smccc_feat;

	smccc_feat->std_bmap = KVM_ARM_SMCCC_STD_FEATURES;
	smccc_feat->std_hyp_bmap = KVM_ARM_SMCCC_STD_HYP_FEATURES;
	smccc_feat->vendor_hyp_bmap = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;

	mt_init(&kvm->arch.smccc_filter);
}

void kvm_arm_teardown_hypercalls(struct kvm *kvm)
{
	mtree_destroy(&kvm->arch.smccc_filter);
}

int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
{
	return ARRAY_SIZE(kvm_arm_fw_reg_ids);
}

int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) {
		if (put_user(kvm_arm_fw_reg_ids[i], uindices++))
			return -EFAULT;
	}

	return 0;
}

#define KVM_REG_FEATURE_LEVEL_MASK	GENMASK(3, 0)

/*
 * Convert the workaround level into an easy-to-compare number, where higher
 * values mean better protection.
 */
static int get_kernel_wa_level(struct kvm_vcpu *vcpu, u64 regid)
{
	switch (regid) {
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
		switch (arm64_get_spectre_v2_state()) {
		case SPECTRE_VULNERABLE:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
		case SPECTRE_MITIGATED:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL;
		case SPECTRE_UNAFFECTED:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED;
		}
		return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
		switch (arm64_get_spectre_v4_state()) {
		case SPECTRE_MITIGATED:
			/*
			 * As for the hypercall discovery, we pretend we
			 * don't have any FW mitigation if SSBS is there at
			 * all times.
			 */
			if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP))
				return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
			fallthrough;
		case SPECTRE_UNAFFECTED:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
		case SPECTRE_VULNERABLE:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
		}
		break;
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
		switch (arm64_get_spectre_bhb_state()) {
		case SPECTRE_VULNERABLE:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
		case SPECTRE_MITIGATED:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL;
		case SPECTRE_UNAFFECTED:
			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED;
		}
		return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL;
	}

	return -EINVAL;
}

int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
{
	struct kvm_smccc_features *smccc_feat = &vcpu->kvm->arch.smccc_feat;
	void __user *uaddr = (void __user *)(long)reg->addr;
	u64 val;

	switch (reg->id) {
	case KVM_REG_ARM_PSCI_VERSION:
		val = kvm_psci_version(vcpu);
		break;
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
		val = get_kernel_wa_level(vcpu, reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
		break;
	case KVM_REG_ARM_STD_BMAP:
		val = READ_ONCE(smccc_feat->std_bmap);
		break;
	case KVM_REG_ARM_STD_HYP_BMAP:
		val = READ_ONCE(smccc_feat->std_hyp_bmap);
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP:
		val = READ_ONCE(smccc_feat->vendor_hyp_bmap);
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		val = READ_ONCE(smccc_feat->vendor_hyp_bmap_2);
		break;
	default:
		return -ENOENT;
	}

	if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
		return -EFAULT;

	return 0;
}

static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
{
	int ret = 0;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_smccc_features *smccc_feat = &kvm->arch.smccc_feat;
	unsigned long *fw_reg_bmap, fw_reg_features;

	switch (reg_id) {
	case KVM_REG_ARM_STD_BMAP:
		fw_reg_bmap = &smccc_feat->std_bmap;
		fw_reg_features = KVM_ARM_SMCCC_STD_FEATURES;
		break;
	case KVM_REG_ARM_STD_HYP_BMAP:
		fw_reg_bmap = &smccc_feat->std_hyp_bmap;
		fw_reg_features = KVM_ARM_SMCCC_STD_HYP_FEATURES;
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP:
		fw_reg_bmap = &smccc_feat->vendor_hyp_bmap;
		fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		fw_reg_bmap = &smccc_feat->vendor_hyp_bmap_2;
		fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2;
		break;
	default:
		return -ENOENT;
	}

	/* Check for unsupported bit */
	if (val & ~fw_reg_features)
		return -EINVAL;

	mutex_lock(&kvm->arch.config_lock);

	if (kvm_vm_has_ran_once(kvm) && val != *fw_reg_bmap) {
		ret = -EBUSY;
		goto out;
	}

	WRITE_ONCE(*fw_reg_bmap, val);
out:
	mutex_unlock(&kvm->arch.config_lock);
	return ret;
}

int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
{
	void __user *uaddr = (void __user *)(long)reg->addr;
	u64 val;
	int wa_level;

	if (KVM_REG_SIZE(reg->id) != sizeof(val))
		return -ENOENT;
	if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
		return -EFAULT;

	switch (reg->id) {
	case KVM_REG_ARM_PSCI_VERSION:
	{
		bool wants_02;

		wants_02 = vcpu_has_feature(vcpu, KVM_ARM_VCPU_PSCI_0_2);

		switch (val) {
		case KVM_ARM_PSCI_0_1:
			if (wants_02)
				return -EINVAL;
			vcpu->kvm->arch.psci_version = val;
			return 0;
		case KVM_ARM_PSCI_0_2:
		case KVM_ARM_PSCI_1_0:
		case KVM_ARM_PSCI_1_1:
		case KVM_ARM_PSCI_1_2:
		case KVM_ARM_PSCI_1_3:
			if (!wants_02)
				return -EINVAL;
			vcpu->kvm->arch.psci_version = val;
			return 0;
		}
		break;
	}

	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3:
		if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
			return -EINVAL;

		if (get_kernel_wa_level(vcpu, reg->id) < val)
			return -EINVAL;

		return 0;

	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
		if (val & ~(KVM_REG_FEATURE_LEVEL_MASK |
			    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED))
			return -EINVAL;

		/* The enabled bit must not be set unless the level is AVAIL. */
		if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) &&
		    (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL)
			return -EINVAL;

		/*
		 * Map all the possible incoming states to the only two we
		 * really want to deal with.
		 */
		switch (val & KVM_REG_FEATURE_LEVEL_MASK) {
		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
			break;
		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
			break;
		default:
			return -EINVAL;
		}

		/*
		 * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
		 * other way around.
		 */
		if (get_kernel_wa_level(vcpu, reg->id) < wa_level)
			return -EINVAL;

		return 0;
	case KVM_REG_ARM_STD_BMAP:
	case KVM_REG_ARM_STD_HYP_BMAP:
	case KVM_REG_ARM_VENDOR_HYP_BMAP:
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
	default:
		return -ENOENT;
	}

	return -EINVAL;
}

int kvm_vm_smccc_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
{
	switch (attr->attr) {
	case KVM_ARM_VM_SMCCC_FILTER:
		return 0;
	default:
		return -ENXIO;
	}
}

int kvm_vm_smccc_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
{
	void __user *uaddr = (void __user *)attr->addr;

	switch (attr->attr) {
	case KVM_ARM_VM_SMCCC_FILTER:
		return kvm_smccc_set_filter(kvm, uaddr);
	default:
		return -ENXIO;
	}
}
