Skip to content

Commit 59af011

Browse files
author
Marc Zyngier
committed
KVM: arm64: Honor guest requested traps in GICv3 emulation
On platforms that require emulation of the CPU interface, we still need to honor the traps requested by the guest (ICH_HCR_EL2 as well as the FGTs for ICC_IGRPEN{0,1}_EL1. Check for these bits early and lail out if any trap applies. Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 15a1ba8 commit 59af011

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

arch/arm64/kvm/hyp/vgic-v3-sr.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,75 @@ static void __vgic_v3_write_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
10421042
write_gicreg(vmcr, ICH_VMCR_EL2);
10431043
}
10441044

1045+
static bool __vgic_v3_check_trap_forwarding(struct kvm_vcpu *vcpu,
1046+
u32 sysreg, bool is_read)
1047+
{
1048+
u64 ich_hcr;
1049+
1050+
if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
1051+
return false;
1052+
1053+
ich_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
1054+
1055+
switch (sysreg) {
1056+
case SYS_ICC_IGRPEN0_EL1:
1057+
if (is_read &&
1058+
(__vcpu_sys_reg(vcpu, HFGRTR_EL2) & HFGxTR_EL2_ICC_IGRPENn_EL1))
1059+
return true;
1060+
1061+
if (!is_read &&
1062+
(__vcpu_sys_reg(vcpu, HFGWTR_EL2) & HFGxTR_EL2_ICC_IGRPENn_EL1))
1063+
return true;
1064+
1065+
fallthrough;
1066+
1067+
case SYS_ICC_AP0Rn_EL1(0):
1068+
case SYS_ICC_AP0Rn_EL1(1):
1069+
case SYS_ICC_AP0Rn_EL1(2):
1070+
case SYS_ICC_AP0Rn_EL1(3):
1071+
case SYS_ICC_BPR0_EL1:
1072+
case SYS_ICC_EOIR0_EL1:
1073+
case SYS_ICC_HPPIR0_EL1:
1074+
case SYS_ICC_IAR0_EL1:
1075+
return ich_hcr & ICH_HCR_TALL0;
1076+
1077+
case SYS_ICC_IGRPEN1_EL1:
1078+
if (is_read &&
1079+
(__vcpu_sys_reg(vcpu, HFGRTR_EL2) & HFGxTR_EL2_ICC_IGRPENn_EL1))
1080+
return true;
1081+
1082+
if (!is_read &&
1083+
(__vcpu_sys_reg(vcpu, HFGWTR_EL2) & HFGxTR_EL2_ICC_IGRPENn_EL1))
1084+
return true;
1085+
1086+
fallthrough;
1087+
1088+
case SYS_ICC_AP1Rn_EL1(0):
1089+
case SYS_ICC_AP1Rn_EL1(1):
1090+
case SYS_ICC_AP1Rn_EL1(2):
1091+
case SYS_ICC_AP1Rn_EL1(3):
1092+
case SYS_ICC_BPR1_EL1:
1093+
case SYS_ICC_EOIR1_EL1:
1094+
case SYS_ICC_HPPIR1_EL1:
1095+
case SYS_ICC_IAR1_EL1:
1096+
return ich_hcr & ICH_HCR_TALL1;
1097+
1098+
case SYS_ICC_DIR_EL1:
1099+
if (ich_hcr & ICH_HCR_TDIR)
1100+
return true;
1101+
1102+
fallthrough;
1103+
1104+
case SYS_ICC_RPR_EL1:
1105+
case SYS_ICC_CTLR_EL1:
1106+
case SYS_ICC_PMR_EL1:
1107+
return ich_hcr & ICH_HCR_TC;
1108+
1109+
default:
1110+
return false;
1111+
}
1112+
}
1113+
10451114
int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
10461115
{
10471116
int rt;
@@ -1065,6 +1134,9 @@ int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
10651134

10661135
is_read = (esr & ESR_ELx_SYS64_ISS_DIR_MASK) == ESR_ELx_SYS64_ISS_DIR_READ;
10671136

1137+
if (__vgic_v3_check_trap_forwarding(vcpu, sysreg, is_read))
1138+
return 0;
1139+
10681140
switch (sysreg) {
10691141
case SYS_ICC_IAR0_EL1:
10701142
case SYS_ICC_IAR1_EL1:

0 commit comments

Comments
 (0)