Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Anup Patel <anup.patel@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

authored by

Marc Zyngier and committed by
Christoffer Dall
e6a95517 a9866ba0

+20 -2
+20 -2
arch/arm64/kvm/sys_regs.c
··· 1308 1308 return write_demux_regids(uindices); 1309 1309 } 1310 1310 1311 + static int check_sysreg_table(const struct sys_reg_desc *table, unsigned int n) 1312 + { 1313 + unsigned int i; 1314 + 1315 + for (i = 1; i < n; i++) { 1316 + if (cmp_sys_reg(&table[i-1], &table[i]) >= 0) { 1317 + kvm_err("sys_reg table %p out of order (%d)\n", table, i - 1); 1318 + return 1; 1319 + } 1320 + } 1321 + 1322 + return 0; 1323 + } 1324 + 1311 1325 void kvm_sys_reg_table_init(void) 1312 1326 { 1313 1327 unsigned int i; 1314 1328 struct sys_reg_desc clidr; 1315 1329 1316 1330 /* Make sure tables are unique and in order. */ 1317 - for (i = 1; i < ARRAY_SIZE(sys_reg_descs); i++) 1318 - BUG_ON(cmp_sys_reg(&sys_reg_descs[i-1], &sys_reg_descs[i]) >= 0); 1331 + BUG_ON(check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs))); 1332 + BUG_ON(check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs))); 1333 + BUG_ON(check_sysreg_table(cp14_64_regs, ARRAY_SIZE(cp14_64_regs))); 1334 + BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs))); 1335 + BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs))); 1336 + BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs))); 1319 1337 1320 1338 /* We abuse the reset function to overwrite the table itself. */ 1321 1339 for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)