From efdde709efccc4f95c7641eea8960dbc31fc58b5 Mon Sep 17 00:00:00 2001 From: P33M 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);