diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2022-10-04 07:11:57 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2022-10-04 14:16:20 +0200 |
commit | 0fa6831811f62cfc10415d731bcf9fde2647ad81 (patch) | |
tree | 396e7da30b261132d749317a00e7fc0d5673545b /arch/powerpc/kernel | |
parent | powerpc/64s/interrupt: Change must-hard-mask interrupt check from BUG to WARN (diff) | |
download | linux-0fa6831811f62cfc10415d731bcf9fde2647ad81.tar.xz linux-0fa6831811f62cfc10415d731bcf9fde2647ad81.zip |
powerpc/64: Fix msr_check_and_set/clear MSR[EE] race
irq soft-masking means that when Linux irqs are disabled, the MSR[EE]
value can change from 1 to 0 asynchronously: if a masked interrupt of
the PACA_IRQ_MUST_HARD_MASK variety fires while irqs are disabled,
the masked handler will return with MSR[EE]=0.
This means a sequence like mtmsr(mfmsr() | MSR_FP) is racy if it can
be called with local irqs disabled, unless a hard_irq_disable has been
done.
Reported-by: Sachin Sant <sachinp@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221004051157.308999-2-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/process.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0fbda89cd1bb..37df0428e4fb 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -127,7 +127,7 @@ unsigned long notrace msr_check_and_set(unsigned long bits) newmsr |= MSR_VSX; if (oldmsr != newmsr) - mtmsr_isync(newmsr); + newmsr = mtmsr_isync_irqsafe(newmsr); return newmsr; } @@ -145,7 +145,7 @@ void notrace __msr_check_and_clear(unsigned long bits) newmsr &= ~MSR_VSX; if (oldmsr != newmsr) - mtmsr_isync(newmsr); + mtmsr_isync_irqsafe(newmsr); } EXPORT_SYMBOL(__msr_check_and_clear); |