ipi: add missing barrier and enforce completion

- dmb() no longer works for GICv3, and consequently
a stronger barrier like dsb() has to be used. A weaker
variant of dsb is used to ensure the observability of
complete stores in the same inner-shareable domain.

Signed-off-by: JorgeMVP <jorgepereira89@gmail.com>
This commit is contained in:
JorgeMVP 2023-04-14 19:44:35 +02:00 committed by Kent McLeod
parent a4b591727a
commit b8f1753d64
4 changed files with 16 additions and 1 deletions

View file

@ -22,7 +22,11 @@ typedef word_t vm_fault_type_t;
#define IPI_MEM_BARRIER \
do { \
dmb(); \
/* This can be relaxed for GICv2 but for GICv3 dmb() no longer works */ \
/* since the way IPI is triggered is different (memory-mapped or MSR inst.) */ \
/* and dmb() is not able to avoid re-ordering between memory accesses and */ \
/* instructions. In order to support both GICv2 and v3 dsb() is required. */ \
dsb_ishst(); \
} while (0)
#endif /* __ASSEMBLER__ */

View file

@ -19,6 +19,11 @@ static inline void dsb(void)
asm volatile("dsb" ::: "memory");
}
static inline void dsb_ishst(void)
{
asm volatile("dsb ishst" ::: "memory");
}
static inline void dmb(void)
{
asm volatile("dmb" ::: "memory");

View file

@ -16,6 +16,11 @@ static inline void dsb(void)
asm volatile("dsb sy" ::: "memory");
}
static inline void dsb_ishst(void)
{
asm volatile("dsb ishst" ::: "memory");
}
static inline void dmb(void)
{
asm volatile("dmb sy" ::: "memory");

View file

@ -131,6 +131,7 @@ void generic_ipi_send_mask(irq_t ipi, word_t mask, bool_t isBlocking)
target_cores[nr_target_cores] = index;
nr_target_cores++;
} else {
IPI_MEM_BARRIER;
ipi_send_target(ipi, cpuIndexToID(index));
}
mask &= ~BIT(index);