Search code examples
arm64memory-barriers

Why a DSB SY is required after updating ARM gic ICC_PMR register?


In the linux kernel, updating SYS_ICC_PMR_EL1 is followed with a DSB SY if ICC_CTLR_EL1.PMHE == 0b1.

./arch/arm64/include/asm/irqflags.h:
45              write_sysreg_s(GIC_PRIO_IRQON, SYS_ICC_PMR_EL1);
   0xffff80008069ff90 <+156>:   mov     x0, #0xe0                       // #224
   0xffff80008069ff94 <+160>:   msr     s3_0_c4_c6_0, x0

46              pmr_sync();
   0xffff80008069ff98 <+164>:   dsb     sy

The explanation in commit msg is:

When Priority Mask Hint Enable (PMHE) == 0b1, the GIC may use the PMR value to determine whether to signal an IRQ to a PE, and consequently after a change to the PMR value, a DSB SY may be required to ensure that interrupts are signalled to a CPU in finite time.

But DSB is a memory barrier, why it's required for updating a system register here? since it's not a mem op. And how can it "ensure that interrupts are signalled to a CPU in finite time"?


Solution

  • DSB is much more than just a memory barrier. ARMv8 uses it as kind of a "synchronize everything" hammer. The Architecture Reference Manual says:

    In addition, no instruction that appears in program order after the DSB instruction can alter any state of the system or perform any part of its functionality until the DSB completes other than:

    • Being fetched from memory and decoded.
    • Reading the general-purpose, SIMD and floating-point, SVE vector or predicate, Special-purpose, or System registers that are directly or indirectly read without causing side-effects.
    • If FEAT_ETS is not implemented, having any virtual addresses of loads and stores translated.

    There are a number of other system-type instructions with text like "guaranteed to be complete after a DSB". For instance, DSB waits for all in-flight cache maintenance instructions to complete.

    In particular, DSB is defined to have certain effects with respect to the interrupt controller. This is documented in the ARM Generic Interrupt Controller spec, section 12.1.6 (in issue H).

    Architectural execution of a DSB instruction guarantees that

    — The last value written to ICC_PMR_EL1 or GICC_PMR is observed by the associated Redistributor. PMR values are only observable by the Redistributor when ICC_CTLR_ELx.PMHE==1, and observation by the Redistributor does not affect masking of interrupts within the CPU interface.

    — The last value written to ICC_SGI0R_EL1 or ICC_SGI1R_EL1 is observed by the associated Redistributor.

    [... and many more similar statements ...]