• Will Deacon's avatar
    arm64: spectre: Prevent lockdep splat on v4 mitigation enable path · a2c42bba
    Will Deacon authored
    The Spectre-v4 workaround is re-configured when resuming from suspend,
    as the firmware may have re-enabled the mitigation despite the user
    previously asking for it to be disabled.
    
    Enabling or disabling the workaround can result in an undefined
    instruction exception on CPUs which implement PSTATE.SSBS but only allow
    it to be configured by adjusting the SPSR on exception return. We handle
    this by installing an 'undef hook' which effectively emulates the access.
    
    Installing this hook requires us to take a couple of spinlocks both to
    avoid corrupting the internal list of hooks but also to ensure that we
    don't run into an unhandled exception. Unfortunately, when resuming from
    suspend, we haven't yet called rcu_idle_exit() and so lockdep gets angry
    about "suspicious RCU usage". In doing so, it tries to print a warning,
    which leads it to get even more suspicious, this time about itself:
    
     |  rcu_scheduler_active = 2, debug_locks = 1
     |  RCU used illegally from extended quiescent state!
     |  1 lock held by swapper/0:
     |   #0: (logbuf_lock){-.-.}-{2:2}, at: vprintk_emit+0x88/0x198
     |
     |  Call trace:
     |   dump_backtrace+0x0/0x1d8
     |   show_stack+0x18/0x24
     |   dump_stack+0xe0/0x17c
     |   lockdep_rcu_suspicious+0x11c/0x134
     |   trace_lock_release+0xa0/0x160
     |   lock_release+0x3c/0x290
     |   _raw_spin_unlock+0x44/0x80
     |   vprintk_emit+0xbc/0x198
     |   vprintk_default+0x44/0x6c
     |   vprintk_func+0x1f4/0x1fc
     |   printk+0x54/0x7c
     |   lockdep_rcu_suspicious+0x30/0x134
     |   trace_lock_acquire+0xa0/0x188
     |   lock_acquire+0x50/0x2fc
     |   _raw_spin_lock+0x68/0x80
     |   spectre_v4_enable_mitigation+0xa8/0x30c
     |   __cpu_suspend_exit+0xd4/0x1a8
     |   cpu_suspend+0xa0/0x104
     |   psci_cpu_suspend_enter+0x3c/0x5c
     |   psci_enter_idle_state+0x44/0x74
     |   cpuidle_enter_state+0x148/0x2f8
     |   cpuidle_enter+0x38/0x50
     |   do_idle+0x1f0/0x2b4
    
    Prevent these splats by running __cpu_suspend_exit() with RCU watching.
    
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Boqun Feng <boqun.feng@gmail.com>
    Cc: Marc Zyngier <maz@kernel.org>
    Cc: Saravana Kannan <saravanak@google.com>
    Suggested-by: default avatar"Paul E . McKenney" <paulmck@kernel.org>
    Reported-by: default avatarSami Tolvanen <samitolvanen@google.com>
    Fixes: c2876207 ("arm64: Rewrite Spectre-v4 mitigation code")
    Cc: <stable@vger.kernel.org>
    Acked-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    Acked-by: default avatarMarc Zyngier <maz@kernel.org>
    Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
    Link: https://lore.kernel.org/r/20210218140346.5224-1-will@kernel.orgSigned-off-by: default avatarWill Deacon <will@kernel.org>
    a2c42bba
suspend.c 3.98 KB