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

arm64: KVM: use separate tables for AArch32 32 and 64bit traps

An interesting "feature" of the CP14 encoding is that there is
an overlap between 32 and 64bit registers, meaning they cannot
live in the same table as we did for CP15.

Create separate tables for 64bit CP14 and CP15 registers, and
let the top level handler use the right one.

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
a9866ba0 72564016

+10 -3
+10 -3
arch/arm64/kvm/sys_regs.c
··· 498 498 static const struct sys_reg_desc cp14_regs[] = { 499 499 }; 500 500 501 + /* Trapped cp14 64bit registers */ 502 + static const struct sys_reg_desc cp14_64_regs[] = { 503 + }; 504 + 501 505 /* 502 506 * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding, 503 507 * depending on the way they are accessed (as a 32bit or a 64bit 504 508 * register). 505 509 */ 506 510 static const struct sys_reg_desc cp15_regs[] = { 507 - { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, 508 511 { Op1( 0), CRn( 1), CRm( 0), Op2( 0), access_sctlr, NULL, c1_SCTLR }, 509 512 { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, 510 513 { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, ··· 548 545 { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, 549 546 { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, 550 547 548 + }; 549 + 550 + static const struct sys_reg_desc cp15_64_regs[] = { 551 + { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, 551 552 { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 }, 552 553 }; 553 554 ··· 777 770 778 771 target_specific = get_target_table(vcpu->arch.target, false, &num); 779 772 return kvm_handle_cp_64(vcpu, 780 - cp15_regs, ARRAY_SIZE(cp15_regs), 773 + cp15_64_regs, ARRAY_SIZE(cp15_64_regs), 781 774 target_specific, num); 782 775 } 783 776 ··· 795 788 int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run) 796 789 { 797 790 return kvm_handle_cp_64(vcpu, 798 - cp14_regs, ARRAY_SIZE(cp14_regs), 791 + cp14_64_regs, ARRAY_SIZE(cp14_64_regs), 799 792 NULL, 0); 800 793 } 801 794