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:
parent
a4b591727a
commit
b8f1753d64
4 changed files with 16 additions and 1 deletions
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue