Platform: FVP_Base_RevC-2xAEMvA
I set HCR_EL2.IMO/FMO to 1 to route interrupts to EL2 first for some check, and because I want this interrupt still be handled by EL1 kernel, I set interrupt mask in SPSR_EL2 and the corresponding EL1 vector entry to ELR_EL2.
However, by using signal instruction debug tool of Development Studio, I found after "eret" to EL1, and the PE trap to EL2 again, which looks like the mask is not effective and the pending interrupt is signaled again.
Thank you for any reply!
Lijian Huang said:I set HCR_EL2.IMO/FMO to 1 to route interrupts to EL2 first for some check, and because I want this interrupt still be handled by EL1 kernel, I set interrupt mask in SPSR_EL2 and the corresponding EL1 vector entry to ELR_EL2.
Hmm, I don't think that will work the way you want.
In AArch64, exceptions routed to a higher Exception level (EL) cannot be masked(*). Meaning that if IRQs/FIQs are routed to EL2, while in EL1 those exceptions are unmasked regardless of the value of PSTATE.I/F. That's why you see a new exception straight after your ERET.
Also, if you are using GICv3/4 then you'll have another problem. If HCR_EL3.IMO/FMO are set, then EL1 accesses to GIC registers will be virtual - accesses go to the ICV variant instead of the ICC. Therefore when EL1 tries to acknowledge the interrupt it thinks it has just taken, it'll be talking to the GIC's virtual interface - which won't know about the physical interrupt that belongs to EL2.
If you don't mind me asking, what are you trying to do?
A more typical flow for taking interrupts to EL2 and then delegating some back to EL1 looks like:
(*EL0 is something of special case)
Thank you very much for your detailed reply!
I apologize for the incomplete information about my environment. I am using FVP (GICv3) and QEMU (GICv2), and it may transition to JUNO (GICv2) and N1 SDP (GICv3) in the future. The SCR_EL3.IRQ/FIQ are set to 0.
I am trying to implement something like process-level stage 2 page table management in the kernel, using a dedicated stage 2 page table for specific processes.
In my EL2, there is a lightweight hypervisor that only handles HVC calls and stage 2 page table management, with no interrupt handlers implemented. Interrupts can be problematic for me since I have to switch the stage 2 page table for the interrupt handler when an interrupt occurs in specific processes. Therefore, I am trying to perform a check in EL2 if an IRQ/FIQ occurs and switch the stage 2 page table if necessary.
Based on your detailed typical flow, I have summarized two plans for my work:
1. Like KVM Guest:
2. The Flow You Suggested
Thank you again for your patience.