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

arm64: KVM: Handle traps of ICC_SRE_EL1 as RAZ/WI

When running on a system with a GICv3, we currenly don't allow the guest
to access the system register interface of the GICv3. We do this by
clearing the ICC_SRE_EL2.Enable, which causes all guest accesses to
ICC_SRE_EL1 to trap to EL2 and causes all guest accesses to other ICC_
registers to cause an undefined exception in the guest.

However, we currently don't handle the trap of guest accesses to
ICC_SRE_EL1 and will spill out a warning. The trap just needs to handle
the access as RAZ/WI, and a guest that tries to prod this register and
set ICC_SRE_EL1.SRE=1, must read back the value (which Linux already
does) to see if it succeeded, and will thus observe that ICC_SRE_EL1.SRE
was not set.

Add the simple trap handler in the sorted table of the system registers.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
[ardb: added cp15 handling]
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Christoffer Dall and committed by
Paolo Bonzini
db7dedd0 7cbb87d6

+9
+9
arch/arm64/kvm/sys_regs.c
··· 424 424 /* VBAR_EL1 */ 425 425 { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b0000), Op2(0b000), 426 426 NULL, reset_val, VBAR_EL1, 0 }, 427 + 428 + /* ICC_SRE_EL1 */ 429 + { Op0(0b11), Op1(0b000), CRn(0b1100), CRm(0b1100), Op2(0b101), 430 + trap_raz_wi }, 431 + 427 432 /* CONTEXTIDR_EL1 */ 428 433 { Op0(0b11), Op1(0b000), CRn(0b1101), CRm(0b0000), Op2(0b001), 429 434 access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 }, ··· 695 690 { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR }, 696 691 { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 }, 697 692 { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 }, 693 + 694 + /* ICC_SRE */ 695 + { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi }, 696 + 698 697 { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID }, 699 698 }; 700 699