Le 30/08/2022 à 07:15, Nicholas Piggin a écrit : > On Wed Aug 24, 2022 at 2:39 AM AEST, Christophe Leroy wrote: >> In ppc, compiler based sanitizer will generate instrument instructions >> around statement WRITE_ONCE(local_paca->irq_soft_mask, mask): >>
[...] >> >> If there is a context switch before "stb r9,2354(r31)", r31 may >> not equal to r13, in such case, irq soft mask will not work. >> >> The same problem occurs in irq_soft_mask_return() with >> READ_ONCE(local_paca->irq_soft_mask). > > WRITE_ONCE doesn't require address generation to be atomic with the > store so this is a bug without sanitizer too. I have seen gcc put r13 > into a nvgpr before. > > READ_ONCE maybe could be argued is safe in this case because data > could be stale when you use it anyway, but pointless and risky > in some cases (imagine cpu offline -> store poison value to irq soft > mask. > >> This patch partially reverts commit ef5b570d3700 ("powerpc/irq: Don't >> open code irq_soft_mask helpers") with a more modern inline assembly. >> >> Reported-by: Zhouyi Zhou <zhouzho...@gmail.com> >> Fixes: ef5b570d3700 ("powerpc/irq: Don't open code irq_soft_mask helpers") >> Signed-off-by: Christophe Leroy <christophe.le...@csgroup.eu> >> --- >> v2: Use =m constraint for stb instead of m constraint >> --- >> arch/powerpc/include/asm/hw_irq.h | 9 ++++++--- >> 1 file changed, 6 insertions(+), 3 deletions(-) >> >> diff --git a/arch/powerpc/include/asm/hw_irq.h >> b/arch/powerpc/include/asm/hw_irq.h >> index 26ede09c521d..815420988ef3 100644 >> --- a/arch/powerpc/include/asm/hw_irq.h >> +++ b/arch/powerpc/include/asm/hw_irq.h >> @@ -113,7 +113,11 @@ static inline void __hard_RI_enable(void) >> >> static inline notrace unsigned long irq_soft_mask_return(void) >> { >> - return READ_ONCE(local_paca->irq_soft_mask); >> + unsigned long flags; >> + >> + asm volatile("lbz%X1 %0,%1" : "=r" (flags) : "m" >> (local_paca->irq_soft_mask)); >> + >> + return flags; >> } >> >> /* >> @@ -140,8 +144,7 @@ static inline notrace void irq_soft_mask_set(unsigned >> long mask) >> if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) >> WARN_ON(mask && !(mask & IRQS_DISABLED)); >> >> - WRITE_ONCE(local_paca->irq_soft_mask, mask); >> - barrier(); >> + asm volatile("stb%X0 %1,%0" : "=m" (local_paca->irq_soft_mask) : "r" >> (mask) : "memory"); > > This is still slightly concerning to me. Is there any guarantee that the > compiler would not use a different sequence for the address here? > > Maybe explicit r13 is required. > local_paca is defined as: register struct paca_struct *local_paca asm("r13"); Why would the compiler use another register ? If so, do we also have an issue with the use of current_stack_pointer in irq.c ? Segher ?