Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6a95517 authored by Marc Zyngier's avatar Marc Zyngier Committed by Christoffer Dall
Browse files

arm64: KVM: check ordering of all system register tables



We now have multiple tables for the various system registers
we trap. Make sure we check the order of all of them, as it is
critical that we get the order right (been there, done that...).

Reviewed-by: default avatarAnup Patel <anup.patel@linaro.org>
Reviewed-by: default avatarChristoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent a9866ba0
Loading
Loading
Loading
Loading
+20 −2
Original line number Original line Diff line number Diff line
@@ -1308,14 +1308,32 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
	return write_demux_regids(uindices);
	return write_demux_regids(uindices);
}
}


static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n)
{
	unsigned int i;

	for (i = 1; i < n; i++) {
		if (cmp_sys_reg(&table[i-1], &table[i]) >= 0) {
			kvm_err("sys_reg table %p out of order (%d)\n", table, i - 1);
			return 1;
		}
	}

	return 0;
}

void kvm_sys_reg_table_init(void)
void kvm_sys_reg_table_init(void)
{
{
	unsigned int i;
	unsigned int i;
	struct sys_reg_desc clidr;
	struct sys_reg_desc clidr;


	/* Make sure tables are unique and in order. */
	/* Make sure tables are unique and in order. */
	for (i = 1; i < ARRAY_SIZE(sys_reg_descs); i++)
	BUG_ON(check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs)));
		BUG_ON(cmp_sys_reg(&sys_reg_descs[i-1], &sys_reg_descs[i]) >= 0);
	BUG_ON(check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs)));
	BUG_ON(check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs)));
	BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs)));
	BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs)));
	BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs)));


	/* We abuse the reset function to overwrite the table itself. */
	/* We abuse the reset function to overwrite the table itself. */
	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)
	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)