aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-01-21 10:34:35 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2016-02-29 13:34:22 -0500
commitb613f59dd2628937860f37dbfbe315d9edcb1668 (patch)
tree40465df57bf4f1b64d2e6876c67333d65d3b4801 /arch/arm/kvm
parent504bfce18a76c9fb6ad5a5f894750f4fca6cde39 (diff)
ARM: KVM: Enforce sorting of all CP tables
Since we're obviously terrible at sorting the CP tables, make sure we're going to do it properly (or fail to boot). arm64 has had the same mechanism for a while, and nobody ever broke it... Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/coproc.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 9aa462ec9c56..40d6db1ca4a8 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -381,17 +381,26 @@ static const struct coproc_reg cp15_regs[] = {
381 { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar}, 381 { CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
382}; 382};
383 383
384static int check_reg_table(const struct coproc_reg *table, unsigned int n)
385{
386 unsigned int i;
387
388 for (i = 1; i < n; i++) {
389 if (cmp_reg(&table[i-1], &table[i]) >= 0) {
390 kvm_err("reg table %p out of order (%d)\n", table, i - 1);
391 return 1;
392 }
393 }
394
395 return 0;
396}
397
384/* Target specific emulation tables */ 398/* Target specific emulation tables */
385static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS]; 399static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS];
386 400
387void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table) 401void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table)
388{ 402{
389 unsigned int i; 403 BUG_ON(check_reg_table(table->table, table->num));
390
391 for (i = 1; i < table->num; i++)
392 BUG_ON(cmp_reg(&table->table[i-1],
393 &table->table[i]) >= 0);
394
395 target_tables[table->target] = table; 404 target_tables[table->target] = table;
396} 405}
397 406
@@ -1210,8 +1219,8 @@ void kvm_coproc_table_init(void)
1210 unsigned int i; 1219 unsigned int i;
1211 1220
1212 /* Make sure tables are unique and in order. */ 1221 /* Make sure tables are unique and in order. */
1213 for (i = 1; i < ARRAY_SIZE(cp15_regs); i++) 1222 BUG_ON(check_reg_table(cp15_regs, ARRAY_SIZE(cp15_regs)));
1214 BUG_ON(cmp_reg(&cp15_regs[i-1], &cp15_regs[i]) >= 0); 1223 BUG_ON(check_reg_table(invariant_cp15, ARRAY_SIZE(invariant_cp15)));
1215 1224
1216 /* We abuse the reset function to overwrite the table itself. */ 1225 /* We abuse the reset function to overwrite the table itself. */
1217 for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++) 1226 for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++)