static bool plic_cpuhp_setup_done __ro_after_init;
 static DEFINE_PER_CPU(struct plic_handler, plic_handlers);
 
-static inline void plic_toggle(struct plic_handler *handler,
-                               int hwirq, int enable)
+static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable)
 {
-       u32 __iomem *reg = handler->enable_base + (hwirq / 32) * sizeof(u32);
+       u32 __iomem *reg = enable_base + (hwirq / 32) * sizeof(u32);
        u32 hwirq_mask = 1 << (hwirq % 32);
 
-       raw_spin_lock(&handler->enable_lock);
        if (enable)
                writel(readl(reg) | hwirq_mask, reg);
        else
                writel(readl(reg) & ~hwirq_mask, reg);
+}
+
+static void plic_toggle(struct plic_handler *handler, int hwirq, int enable)
+{
+       raw_spin_lock(&handler->enable_lock);
+       __plic_toggle(handler->enable_base, hwirq, enable);
        raw_spin_unlock(&handler->enable_lock);
 }
 
                 * Skip contexts other than external interrupts for our
                 * privilege level.
                 */
-               if (parent.args[0] != RV_IRQ_EXT)
+               if (parent.args[0] != RV_IRQ_EXT) {
+                       /* Disable S-mode enable bits if running in M-mode. */
+                       if (IS_ENABLED(CONFIG_RISCV_M_MODE)) {
+                               void __iomem *enable_base = priv->regs +
+                                       CONTEXT_ENABLE_BASE +
+                                       i * CONTEXT_ENABLE_SIZE;
+
+                               for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
+                                       __plic_toggle(enable_base, hwirq, 0);
+                       }
                        continue;
+               }
 
                hartid = riscv_of_parent_hartid(parent.np);
                if (hartid < 0) {