OpenWrt – Rev 1

Subversion Repositories:
Rev:
From efdde709efccc4f95c7641eea8960dbc31fc58b5 Mon Sep 17 00:00:00 2001
From: P33M <p33m@github.com>
Date: Thu, 15 Feb 2018 11:22:44 +0000
Subject: [PATCH 207/454] dwc_otg: add smp_mb() to prevent driver state
 corruption on boot

Occasional crashes have been seen where the FIQ code dereferences
invalid/random pointers immediately after being set up, leading to
panic on boot.

The crash occurs as the FIQ code races against hcd_init_fiq() and
the hcd_init_fiq() code races against the outstanding memory stores
from dwc_otg_hcd_init(). Use explicit barriers after touching
driver state.
---
 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
@@ -519,6 +519,11 @@ static void hcd_init_fiq(void *cookie)
                DWC_ERROR("Can't get FIQ irq");
                return;
        }
+       /*
+        * We could take an interrupt immediately after enabling the FIQ.
+        * Ensure coherency of hcd->fiq_state.
+        */
+       smp_mb();
        enable_fiq(irq);
        local_fiq_enable();
 #endif
@@ -598,7 +603,11 @@ int hcd_init(dwc_bus_dev_t *_dev)
 
        if (fiq_enable) {
                if (num_online_cpus() > 1) {
-                       /* bcm2709: can run the FIQ on a separate core to IRQs */
+                       /*
+                        * bcm2709: can run the FIQ on a separate core to IRQs.
+                        * Ensure driver state is visible to other cores before setting up the FIQ.
+                        */
+                       smp_mb();
                        smp_call_function_single(1, hcd_init_fiq, otg_dev, 1);
                } else {
                        smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);