lkml.org 
[lkml]   [2020]   [Dec]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 417/453] soc: qcom: smp2p: Safely acquire spinlock without IRQs
    Date
    From: Evan Green <evgreen@chromium.org>

    commit fc3e62e25c3896855b7c3d72df19ca6be3459c9f upstream.

    smp2p_update_bits() should disable interrupts when it acquires its
    spinlock. This is important because without the _irqsave, a priority
    inversion can occur.

    This function is called both with interrupts enabled in
    qcom_q6v5_request_stop(), and with interrupts disabled in
    ipa_smp2p_panic_notifier(). IRQ handling of spinlocks should be
    consistent to avoid the panic notifier deadlocking because it's
    sitting on the thread that's already got the lock via _request_stop().

    Found via lockdep.

    Cc: stable@vger.kernel.org
    Fixes: 50e99641413e7 ("soc: qcom: smp2p: Qualcomm Shared Memory Point to Point")
    Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
    Reviewed-by: Stephen Boyd <swboyd@chromium.org>
    Signed-off-by: Evan Green <evgreen@chromium.org>
    Link: https://lore.kernel.org/r/20200929133040.RESEND.1.Ideabf6dcdfc577cf39ce3d95b0e4aa1ac8b38f0c@changeid
    Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/soc/qcom/smp2p.c | 5 +++--
    1 file changed, 3 insertions(+), 2 deletions(-)

    --- a/drivers/soc/qcom/smp2p.c
    +++ b/drivers/soc/qcom/smp2p.c
    @@ -318,15 +318,16 @@ static int qcom_smp2p_inbound_entry(stru
    static int smp2p_update_bits(void *data, u32 mask, u32 value)
    {
    struct smp2p_entry *entry = data;
    + unsigned long flags;
    u32 orig;
    u32 val;

    - spin_lock(&entry->lock);
    + spin_lock_irqsave(&entry->lock, flags);
    val = orig = readl(entry->value);
    val &= ~mask;
    val |= value;
    writel(val, entry->value);
    - spin_unlock(&entry->lock);
    + spin_unlock_irqrestore(&entry->lock, flags);

    if (val != orig)
    qcom_smp2p_kick(entry->smp2p);

    \
     
     \ /
      Last update: 2020-12-28 14:58    [W:2.083 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site