How to know the interrupt ID which is signaled currently without acknowledging it

At EL2, all the interrupts are trapped to EL2. Based on the interrupt ID I want to switch to guest to further handle.

Is it safe to rely on ICC_HPPIR1_EL1 to peek the highest pending interrupt and based on the INT ID switch to guest to which the interrupt is assigned?

I don't want to acknowledge the interrupt in EL2 by reading ICC_IAR1_EL1.

  • ICC_HPPIR1_EL1 will tell you the HPPI at the moment in time when you read it.  So, yes, you can use it to peek a the current HPPI.

    The issue is that interrupts are asynchronous events.   The HPPI changes depending on what interrupts are currently Pending (and a bunch of SW controlled config).  Meaning that just because INTID X was the HPPI when you read ICC_HPPIR1_EL1 doesn't mean that a read of ICC_IAR1_EL1 won't return INTID Y.

    If you want to control which interrupts are presented to which guest, the standard flow is something like:

    • Take Physical IRQ to EL2
    • Ack physical interrupt by reading ICC_IAR1_EL1
      • Physical interrupt goes from Pending --> Active (or Active & Pending if Level)
    • Determine what to do with interrupt (handle in EL2, inject to current vPE, ...)
      • Assume we're injecting into current vPE
    • Create new Virtual Interrupt in the List Registers
      • Virtual interrupt is now Pending, Physical Interrupt unchanged
    • Return to Guest
    • Take Virtual IRQ to EL1
    • Ack virtual interrupt by reading ICV_IAR1_EL1
      • Virtual interrupt goes from Pending --> Active 
    • Handle virtual interrupt
    • Deactivate virtual interrupt by writing to ICV_EOIR or ICV_DIR
      • Virtual interrupt goes from Active --> Idle
      • If HW=1, physical interrupt goes from Active --> Idle