This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ICH_EISR_EL2 use-cases

Is there any use case where this register (ICH_EISR_EL2) can report more than one outstanding EOI?

I don't really understand why we have 16-bit wide register (one bit per LR) if there is no use-case. I'm sure I'm missing something.




  • (i) It seems in terms of HW implementation this feature could be implemented by having some combinational logic between LRs and the bits of EISR.

    EISR_Bit 0 = (LR.Inactive is true) & (LR.HW is false) & (LR.EOI is true);

    This would make the update of the register nearly immediately with some combinational logic.

    (ii) Now I'm looking for a case by each ICV_EOI/DIR propagation to update the ICH_LR takes longer than handling a next IRQ. When the maintenance IRQ is generated there will be 2 EOId vIRQs set in the LRs and not 1.

    (iii) Next, lets assume, the EISR bit gets true nearly immediately, the LR.Status update very fast as well. Is it possible for an implementation to have a certain timeout on the maintenance IRQ that would give the vCPU time to handle more than vIRQ (LR.EOI=1) before getting the maintenance IRQ?


    @Martin Weidmann need your expertise here. 

  • Sharing some experiments: 

    do {
    		u32 irqstat = gic_read_iar();
    		u32 irqnr = gic_iar_irqnr(irqstat);
    		if (irqnr != GICC_INT_SPURIOUS) {
    
    			... delay ...
    			
    			gic_write_eoir(irqstat);
    		} else {
    			break;
    		}
    	
    } while (1);


    - This example running on a vCPU is able to trigger more than one bit on EISR. when delay is small it sets two bits on EISR before generating the maintenance IRQ. Note that EOIR is performing both priority drop and deactivation.

    Delay has to be a small delay. I wonder how many instructions can we execute :)

    do {
    	u32 irqstat = gic_read_iar();
    	u32 irqnr = gic_iar_irqnr(irqstat);
    	if (irqnr != GICC_INT_SPURIOUS) {
    
    		< IRQ Handling >
    
    		gic_write_eoir(irqstat);
    	} else {
    		break;
    	}
    
    } while (1);
    
    MSR(ICC_DIR_EL1, 7);
    MSR(ICC_DIR_EL1, 6);
    MSR(ICC_DIR_EL1, 5);
    MSR(ICC_DIR_EL1, 4);


    - This example uses separation of the priority drop from deactivation, I inject 4 LRs at the same time with EOI bit set to 1 (vIRQ 7, 6, 5, 4). Then I handle all of the vIRQs (in the guest )with IAR (inactive to active) and EOIR (priority drop) in a loop, and after all do 4 sequencial deactivations with ICC_DIR_EL1 (active to inactive) of the handled vIRQs.

    - In this last case, I observe 4 bits of ICH_ EISR_EL2 are set when receiving the maintenance IRQ on the hypervisor.

    These two examples were tested on NVIDIA Jetson Orin that supports 4 LRs.