I am working on hypervisor with raspberry pi 4B board.when I study interrupt virtualization, I encounter a problem, I am follow this documenthttps://developer.arm.com/documentation ... exceptions
There are two mechanisms for generating virtual interrupts:1 Internally by the core, using controls in HCR_EL2.2 Using a GICv2, or later, interrupt controller.
I use method 1. Everything worked fine, I can route IRQ to my EL2 code, and I can forward it to EL1 Linux kernel.But, when I tested, I tried to disable IRQ from EL1, use "msr daifset, #0xf", after this, IRQ will not trigger to EL2 also.I am confused, because the document above said pstate.I will only affect vIRQ(for EL1) not pIRQ(EL2). I tested a GPIO interrupt and IPI interrupt, both failed.I search the web, there are few article on this topic, and can't find any additional settings.All document I found, said set I bit in EL1, will not affect EL2/3.
Thanks, if anyone can help.
Raspberry PI4 datasheet[1] shows that it uses GIC-400, which is GICv2.
Do you run the PI4 from the bare-mental code to design your EL2 hypervisor?
Or you just reuse the PI 4 OS that runs in Linux OS and you enable the KVM feature as the host OS?
The information we got is not enough for further check, but we'd recommend you to:
[1]: https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
[2]: GIC-400 TRM https://developer.arm.com/documentation/ddi0471/b
Thanks for your reply.
I did not use KVM code, I implement my own bare metal hypervisor code.
I use GPIO pins to trigger a IRQ, it should be a pIRQ. I have my own interrupt handler in EL2, it is called when IRQ occurs, and I will set VI bit to send the IRQ to linux kernel. This works fine at normal time. But, as I test, when I set daif to disable interrupt in linux kernel, which run in EL1, my EL2 IRQ handler will not be called again, and, after that, if I clear diaf, everything just works fine again.
Thanks.
To signal virtual interrupts to EL0/1, a hypervisor must set the corresponding routing bit in HCR_EL2. For example, to enable vIRQ signaling, a hypervisor must set HCR_EL2.IMO. This setting routes physical IRQ exceptions to EL2, and enables signaling of the virtual exception to EL1.
HCR_EL2
HCR_EL2.IMO
Please take a look for the Virtualization Exception https://developer.arm.com/documentation/102142/latest/Virtualizating-exceptions
and Handling Interrupts https://developer.arm.com/documentation/198123/0300/Handling-interrupts
Maybe I did not clearly my problem.
Now I can handle interrupt in EL2 in my hypervisor code, and also can forward them to linux kernel, normally it works well, the system works fine, just like no hypervisor. But as I test, I set daif bit to disable interrupt in linux kernel which run in EL1, I believe this will only mask the irq to EL1, and my hypervisor code in EL2 will still get the IRQ, surprisingly, it didn't.
I do not use the function of VGIC, I use arm virtualization. I set hcr.imo to 1, this leads the irq routed to EL2, in EL2 IRQ handler, I recorded the irqs and set hcr.vi to interrupt kernel, at same time, I will trap any access of GIC cpu interface from EL1 to EL2, and simulate the actions. All these are going well normally. The only problem is when I mask irq in EL1, EL2 also can't get any interrupt.