Commit da8d120f authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: Add get_reg_by_id() as a sys_reg_desc retrieving helper



find_reg_by_id() requires a sys_reg_param as input, which most
users provide as a on-stack variable, but don't make any use of
the result.

Provide a helper that doesn't have this requirement and simplify
the callers (all but one).

Reviewed-by: default avatarReiji Watanabe <reijiw@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent a111daf0
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -2650,21 +2650,29 @@ const struct sys_reg_desc *find_reg_by_id(u64 id,
	return find_reg(params, table, num);
}

const struct sys_reg_desc *get_reg_by_id(u64 id,
					 const struct sys_reg_desc table[],
					 unsigned int num)
{
	struct sys_reg_params params;

	if (!index_to_params(id, &params))
		return NULL;

	return find_reg(&params, table, num);
}

/* Decode an index value, and find the sys_reg_desc entry. */
static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu,
						    u64 id)
{
	const struct sys_reg_desc *r;
	struct sys_reg_params params;

	/* We only do sys_reg for now. */
	if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM64_SYSREG)
		return NULL;

	if (!index_to_params(id, &params))
		return NULL;

	r = find_reg(&params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
	r = get_reg_by_id(id, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));

	/* Not saved in the sys_reg array and not otherwise accessible? */
	if (r && !(r->reg || r->get_user))
@@ -2723,10 +2731,9 @@ static int reg_to_user(void __user *uaddr, const u64 *val, u64 id)

static int get_invariant_sys_reg(u64 id, void __user *uaddr)
{
	struct sys_reg_params params;
	const struct sys_reg_desc *r;

	r = find_reg_by_id(id, &params, invariant_sys_regs,
	r = get_reg_by_id(id, invariant_sys_regs,
			  ARRAY_SIZE(invariant_sys_regs));
	if (!r)
		return -ENOENT;
@@ -2736,12 +2743,11 @@ static int get_invariant_sys_reg(u64 id, void __user *uaddr)

static int set_invariant_sys_reg(u64 id, void __user *uaddr)
{
	struct sys_reg_params params;
	const struct sys_reg_desc *r;
	int err;
	u64 val = 0; /* Make sure high bits are 0 for 32-bit regs */

	r = find_reg_by_id(id, &params, invariant_sys_regs,
	r = get_reg_by_id(id, invariant_sys_regs,
			  ARRAY_SIZE(invariant_sys_regs));
	if (!r)
		return -ENOENT;
+4 −0
Original line number Diff line number Diff line
@@ -195,6 +195,10 @@ const struct sys_reg_desc *find_reg_by_id(u64 id,
					  const struct sys_reg_desc table[],
					  unsigned int num);

const struct sys_reg_desc *get_reg_by_id(u64 id,
					 const struct sys_reg_desc table[],
					 unsigned int num);

#define AA32(_x)	.aarch32_map = AA32_##_x
#define Op0(_x) 	.Op0 = _x
#define Op1(_x) 	.Op1 = _x
+2 −6
Original line number Diff line number Diff line
@@ -263,13 +263,9 @@ static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
				u64 *reg)
{
	struct sys_reg_params params;
	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;

	params.regval = *reg;
	params.is_write = is_write;

	if (find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
	if (get_reg_by_id(sysreg, gic_v3_icc_reg_descs,
			  ARRAY_SIZE(gic_v3_icc_reg_descs)))
		return 0;