Skip to content
  • Lukas Wunner's avatar
    x86/quirks: Add early quirk to reset Apple AirPort card · abb2bafd
    Lukas Wunner authored
    The EFI firmware on Macs contains a full-fledged network stack for
    downloading OS X images from osrecovery.apple.com. Unfortunately
    on Macs introduced 2011 and 2012, EFI brings up the Broadcom 4331
    wireless card on every boot and leaves it enabled even after
    ExitBootServices has been called. The card continues to assert its IRQ
    line, causing spurious interrupts if the IRQ is shared. It also corrupts
    memory by DMAing received packets, allowing for remote code execution
    over the air. This only stops when a driver is loaded for the wireless
    card, which may be never if the driver is not installed or blacklisted.
    
    The issue seems to be constrained to the Broadcom 4331. Chris Milsted
    has verified that the newer Broadcom 4360 built into the MacBookPro11,3
    (2013/2014) does not exhibit this behaviour. The chances that Apple will
    ever supply a firmware fix for the older machines appear to be zero.
    
    The solution is to reset the card on boot by writing to a reset bit in
    its mmio space. This must be done as an early quirk and not as a plain
    vanilla PCI quirk to successfully combat memory corruption by DMAed
    packets: Matthew Garrett found out in 2012 that the packets are written
    to EfiBootServicesData memory (http://mjg59.dreamwidth.org/11235.html).
    This type of memory is made available to the page allocator by
    efi_free_boot_services(). Plain vanilla PCI quirks run much later, in
    subsys initcall level. In-between a time window would be open for memory
    corruption. Random crashes occurring in this time window and attributed
    to DMAed packets have indeed been observed in the wild by Chris
    Bainbridge.
    
    When Matthew Garrett analyzed the memory corruption issue in 2012, he
    sought to fix it with a grub quirk which transitions the card to D3hot:
    http://git.savannah.gnu.org/cgit/grub.git/commit/?id=9d34bb85da56
    
    This approach does not help users with other bootloaders and while it
    may prevent DMAed packets, it does not cure the spurious interrupts
    emanating from the card. Unfortunately the card's mmio space is
    inaccessible in D3hot, so to reset it, we have to undo the effect of
    Matthew's grub patch and transition the card back to D0.
    
    Note that the quirk takes a few shortcuts to reduce the amount of code:
    The size of BAR 0 and the location of the PM capability is identical
    on all affected machines and therefore hardcoded. Only the address of
    BAR 0 differs between models. Also, it is assumed that the BCMA core
    currently mapped is the 802.11 core. The EFI driver seems to always take
    care of this.
    
    Michael Büsch, Bjorn Helgaas and Matt Fleming contributed feedback
    towards finding the best solution to this problem.
    
    The following should be a comprehensive list of affected models:
        iMac13,1        2012  21.5"       [Root Port 00:1c.3 = 8086:1e16]
        iMac13,2        2012  27"         [Root Port 00:1c.3 = 8086:1e16]
        Macmini5,1      2011  i5 2.3 GHz  [Root Port 00:1c.1 = 8086:1c12]
        Macmini5,2      2011  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1c12]
        Macmini5,3      2011  i7 2.0 GHz  [Root Port 00:1c.1 = 8086:1c12]
        Macmini6,1      2012  i5 2.5 GHz  [Root Port 00:1c.1 = 8086:1e12]
        Macmini6,2      2012  i7 2.3 GHz  [Root Port 00:1c.1 = 8086:1e12]
        MacBookPro8,1   2011  13"         [Root Port 00:1c.1 = 8086:1c12]
        MacBookPro8,2   2011  15"         [Root Port 00:1c.1 = 8086:1c12]
        MacBookPro8,3   2011  17"         [Root Port 00:1c.1 = 8086:1c12]
        MacBookPro9,1   2012  15"         [Root Port 00:1c.1 = 8086:1e12]
        MacBookPro9,2   2012  13"         [Root Port 00:1c.1 = 8086:1e12]
        MacBookPro10,1  2012  15"         [Root Port 00:1c.1 = 8086:1e12]
        MacBookPro10,2  2012  13"         [Root Port 00:1c.1 = 8086:1e12]
    
    For posterity, spurious interrupts caused by the Broadcom 4331 wireless
    card resulted in splats like this (stacktrace omitted):
    
        irq 17: nobody cared (try booting with the "irqpoll" option)
        handlers:
        [<ffffffff81374370>] pcie_isr
        [<ffffffffc0704550>] sdhci_irq [sdhci] threaded [<ffffffffc07013c0>] sdhci_thread_irq [sdhci]
        [<ffffffffc0a0b960>] azx_interrupt [snd_hda_codec]
        Disabling IRQ #17
    
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=79301
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=111781
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=728916
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=895951#c16
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1009819
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1098621
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1149632#c5
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1279130
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1332732
    
    
    Tested-by: Konstantin Simanov <k.simanov@stlk.ru>        # [MacBookPro8,1]
    Tested-by: Lukas Wunner <lukas@wunner.de>                # [MacBookPro9,1]
    Tested-by: Bryan Paradis <bryan.paradis@gmail.com>       # [MacBookPro9,2]
    Tested-by: Andrew Worsley <amworsley@gmail.com>          # [MacBookPro10,1]
    Tested-by: Chris Bainbridge <chris.bainbridge@gmail.com> # [MacBookPro10,2]
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Acked-by: default avatarRafał Miłecki <zajec5@gmail.com>
    Acked-by: default avatarMatt Fleming <matt@codeblueprint.co.uk>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Bjorn Helgaas <bhelgaas@google.com>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Chris Milsted <cmilsted@redhat.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Josh Poimboeuf <jpoimboe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Matthew Garrett <mjg59@srcf.ucam.org>
    Cc: Michael Buesch <m@bues.ch>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Yinghai Lu <yinghai@kernel.org>
    Cc: b43-dev@lists.infradead.org
    Cc: linux-pci@vger.kernel.org
    Cc: linux-wireless@vger.kernel.org
    Cc: stable@vger.kernel.org
    Cc: stable@vger.kernel.org # 123456789abc: x86/quirks: Apply nvidia_bugs quirk only on root bus
    Cc: stable@vger.kernel.org # 123456789abc: x86/quirks: Reintroduce scanning of secondary buses
    Link: http://lkml.kernel.org/r/48d0972ac82a53d460e5fce77a07b2560db95203.1465690253.git.lukas@wunner.de
    
    
    [ Did minor readability edits. ]
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    abb2bafd