For wired IRQs (PPIs/SPIs), passing through a physical IRQ to a guest is done by:
From my limited understanding the above will not work for passthrough LPIs (without GICv4), since:
Someone could argue that you can inject it purely as a virtual IRQ and use a maintenance interrupt to finalize it manually from the hypervisor, but how do you ensure that the LPI won't fire again while the guest is servicing it? From the GICv3 software overview it sounds that just by ACKing the LPI it will go from pending to inactive, but it won't be masked. Does EOI have any effect on LPIs and should you use deactivation (DIR) at all?
The only other choice I can imagine is to ACK the LPI and then disable it, set the maintenance IRQ for the specific LR and when the maintenance IRQ is received, enabled the LPI again. However, this sounds way too expensive since it requires costly INV commands to do so. Am I missing something?
Any help would be welcome, thanks in advance.
You're not missing anything. LPIs have a reduced state machine, meaning that when the hypervisor acknowledges the interrupt it will go from Pending -> Inactive. If the device generates a new MSI after that point the LPI will go back to being Pending. At which point it could become the HPPI for the target PE.
There are different things a hypervisor could do. It could, as you suggested, clear the Enable for LPI - but yes, that's potentially expensive. You need to do an INV on both clearing and setting the Enable. Another option is to do nothing. If the device re-fires you get a new physical interrupt into the hypervisor. The hypervisor can deal with that interrupt in a few different ways. If the previous vLPI hasn't been consumed, it could "merge" the instances (in the same way the GIC does for physical interrupts). If the vLPI has been consumed, it could queue up another instance of the vLPI (again, that's what the physical GIC would have done).
Another option, if the GIC you have supports GICv4, is to use direct-injection.
Indeed, doing nothing other than updating the pending state in the populated LR, is already working in my case, but I had second thoughts about it. Anyway, although it sounds less ideal (compared to normal IRQs), it's still reassuring to get a confirmation on the exact LPI behavior.
Once again, thanks for the quick and informative reply Martin.