Skip to content

Commit 7cf95ae

Browse files
Marc Zyngierpm215
Marc Zyngier
authored andcommitted
target/arm: Fix ISR_EL1 tracking when executing at EL2
The ARMv8 ARM states when executing at EL2, EL3 or Secure EL1, ISR_EL1 shows the pending status of the physical IRQ, FIQ, or SError interrupts. Unfortunately, QEMU's implementation only considers the HCR_EL2 bits, and ignores the current exception level. This means a hypervisor trying to look at its own interrupt state actually sees the guest state, which is unexpected and breaks KVM as of Linux 5.3. Instead, check for the running EL and return the physical bits if not running in a virtualized context. Fixes: 636540e Cc: [email protected] Reported-by: Quentin Perret <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Message-id: [email protected] Reviewed-by: Peter Maydell <[email protected]> Reviewed-by: Edgar E. Iglesias <[email protected]> Signed-off-by: Peter Maydell <[email protected]>
1 parent f013899 commit 7cf95ae

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

target/arm/helper.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -1934,8 +1934,11 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
19341934
CPUState *cs = env_cpu(env);
19351935
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
19361936
uint64_t ret = 0;
1937+
bool allow_virt = (arm_current_el(env) == 1 &&
1938+
(!arm_is_secure_below_el3(env) ||
1939+
(env->cp15.scr_el3 & SCR_EEL2)));
19371940

1938-
if (hcr_el2 & HCR_IMO) {
1941+
if (allow_virt && (hcr_el2 & HCR_IMO)) {
19391942
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
19401943
ret |= CPSR_I;
19411944
}
@@ -1945,7 +1948,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
19451948
}
19461949
}
19471950

1948-
if (hcr_el2 & HCR_FMO) {
1951+
if (allow_virt && (hcr_el2 & HCR_FMO)) {
19491952
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
19501953
ret |= CPSR_F;
19511954
}

0 commit comments

Comments
 (0)