I have a quod Cortex-A53 system based on Xilinx Zynqmp SoC, and it uses Linux GiC_V2 driver.
I have configured the system to have the 2 cores running Linux, and the other 2 cores running custom software at EL3. I try to generate an SGI from the non-Linux running core to a Linux core but it does not work. I use 5.15 kernel.
I have tried to create a driver that is using similar functionality for IPI as seen on smp.c file of the arm64 arch directory. The driver registers correctly an IRQ outside the Linux IPI range The SGI id I use is 15 and I send the event to core0 - When I send the SGI event message from the non-linux to Linux I get a kernel panic:
Kernel panic - not syncing: FIQ taken without a root FIQ handler
If I send an SGI event the is within the Linux IPI range, I don't get any kernel Panic, but the IRQ IPI stats do not increase for the specific linux IPI event.
The deployed GIC_V2 has security features too.
I think something with the IRQ masks may be wrong. Is there any common practice to use SGI in Linux in a heterogeneous ArmV8 system?
Any ideas what or where to check would be very much appreciated.
I suspect the Group of the SGI is set to G0.
In GICv2 all interrupts are assigned a "Group", either G0 or G1. For a core with two Security states (TrustZone), G0 are Secure interrupts and G1 are Non-secure interrupts. G0 interrupts are signalled as FIQs to the CPU, G1 interrupts are signalled as IRQs (note: this changes in GICv3)
So the fact that the error message is talking about a FIQ handler makes me think that the SGI you're sending is set as set as G0.
Group is configured by software using the GICD_IGROUPR<n> registers, for SGIs you want GICD_IGROUPR0 - bits 15:0. But... SGIs are banked per-CPU, that is, you have a copy of this register per connected core and each core only sees "its" copy. The register is also Secure access only (given it controls which Security state an interrupt belongs to). Which means something on the receiving CPU must write that registers to mark the SGI you're sending as being G1, and the code doing the writes will need to be running in Secure state.
Thank you for the reply. I will apply the changes - and post the result here
The issue was the NSATT bit on GICD_SGIR register, I set it to 1 from the secured core and it works now. I didn't change the GICD_IGROUP0, but the answer from Martin helped a lot. Thank you