Hi all,
I'm currently virtualizing the GICv2 and some doubts came out during its design. Scenario encompasses the same instance of an hypervisor running in two different CPUs (CPU0 and CPU1). Also, There is one guest running on top of two vCPUs. Each vCPU is dedicated to each CPU. CPU0 runs vCPU0 and vCPU1 runs the CPU1.
Let's suppose that there is an interrupt, an SPI, which targets CPU0 and CPU1. For some reason and asynchronously, this SPI is asserted, and consequently its state gets pending in its GIC. Since GIC uses the 1-N model only one CPU will acknowledge successfully the interrupt by transiting its state from pending to active and the other will get a spurious interrupt. Let's say that it was the CPU0 who performed it successfully and it realizes that this physical interrupt targets the vCPU1 which are running the CPU1.
- Is it possible for an implementation the following case: the CPU0 performs the ack of the hardware interrupt as well as its priority drop in the GIC interface0 and then it sends a message to CPU1 in order to inject a virtual interrupt related with the same hardware interrupt in the virtual interface control 1 of the vCPU1 (an LR with hw bit set to 1). When the virtual interrupt got an EOI from the vCPU1 the physical interrupt will also get deactivated?
Thanks in advance,
Jorge
Ok, at least the two hypervisors must have consent which vCPU should handle the peripheral. Unless you do not virtualize the peripheral, I'd say it is a design error if the interrupt is directed to both CPUs. Anyway, from what I understand from the programmer guide, it is important the the CPU which did acknowledge the interrupt also write EOIR (IHI0048B_gic_architecture_specification.pdf, 4.4.5):
"For every read of a valid Interrupt ID from the GICC_IAR, the connected processor must perform a matching write to the GICC_EOIR. The value written to the GICC_EOIR must be the interrupt ID read from the GICC_IAR."
This sounds like you have to send a message to CPU0 to write EOIR on behalf of vCPU1.
Yes, you're right, but what want to say is,
In my design I have the GICC.EOImode set to 1. So, when the physical interrupt is asserted, I do a read in GICC_IAR (the IRQ gets active) and then a write in GICC_EOIR (to perform a priority drop) in CPU0. At this point, note that the physical IRQ is still active but with the lowest priority. What I want to do is, instead of injecting the associated virtual interrupt to the vCPU0 running in the current CPU. I want to send a message to CPU1 in order to inject it in the vCPU1.
It is unclear for me, whether after the injection of the respective virtual interrupt (somehow linked to the physical interrupt) in the vCPU1, when the vCPU1 deactivates the virtual interrupt using its virtual interface (GICV_EOIR), it will also deactivate the physical one in the distributer.
Did you get my point?
Ok, now get your point. To my understanding, the interrupt is still active in CPU0 after you wrote to CPU1.GICV_EOIR. You need to send a message back to CPU0 to notify the hypervisor that you did handle the interrupt and it should be de-activated.