Skip to content

t2bce_audio regression on MacBookAir8,1 since linux-t2 7.1.5: page fault in t2audio_pcm_open #20

Open

Description

@roy-devx

t2bce_audio regression on MacBookAir8,1 since linux-t2 7.1.5: page fault in t2audio_pcm_open

Hardware

  • Model: MacBook Air 2018 (MacBookAir8,1)
  • DMI: Apple Inc. MacBookAir8,1 / Mac-827FAC58A8FDFA22
  • Distribution: Arch Linux
  • Audio: Apple T2 Audio

Problem

Internal T2 audio works correctly with linux-t2 7.1.4-2, but is broken with both:

  • linux-t2 7.1.5-1
  • linux-t2 7.1.6-1

With 7.1.5/7.1.6, WirePlumber hangs while opening the T2 audio PCM device. wpctl status hangs indefinitely and pactl times out.

Downgrading back to linux-t2 7.1.4-2 immediately restores normal audio functionality.

I tested upgrading and downgrading more than once and the behavior follows the kernel version.

Kernel command line

BOOT_IMAGE=/vmlinuz-linux-t2 root=UUID=<redacted> rw intel_iommu=on iommu=pt pm_async=off loglevel=3

Working kernel: 7.1.4-2

$ uname -r
7.1.4-arch1-Watanare-T2-2-t2

wpctl status works normally:

Audio
 ├─ Devices:
 │      50. Apple Audio Device                  [alsa]
 │      51. Internal Audio                      [alsa]
 │
 ├─ Sinks:
 │  *   58. Apple Audio Device Speakers
 │      59. Apple Audio Device Headphones
 │
 ├─ Sources:
 │  *   60. Apple Audio Device BuiltinMic
 │      61. Apple Audio Device HeadsetMic

WirePlumber is also in a normal sleeping state:

$ ps -o pid,state,wchan:32,comm -C wireplumber
PID  S  WCHAN                             COMMAND
1875 S  poll_schedule_timeout.constprop.  wireplumber

ALSA exposes the Speaker PCM correctly:

card: 0
device: 0
subdevice: 0
stream: PLAYBACK
id: Speaker
name: Speaker
subname: subdevice #0
subdevices_count: 1
subdevices_avail: 1

Broken kernel: 7.1.6-1

$ uname -r
7.1.6-arch1-Watanare-T2-1-t2

During initialization t2bce_audio reports:

t2bce_audio: Subdevice not found for BufferStruct device Speaker
t2bce_audio: Subdevice not found for BufferStruct device Codec Output
t2bce_audio: Subdevice not found for BufferStruct device Digital Mic
t2bce_audio: Subdevice not found for BufferStruct device Codec Input
t2bce_audio: Subdevice not found for BufferStruct device Speaker@mcpl\x04

A few seconds later the kernel reports a page fault when WirePlumber attempts to open the PCM device:

#PF: error_code(0x0000) - not-present page
CPU: 0 PID: 745 Comm: wireplumber
Hardware name: Apple Inc. MacBookAir8,1/Mac-827FAC58A8FDFA22
RIP: 0010:t2audio_pcm_open+0x48/0x110 [t2bce_audio]

Relevant stack:

t2audio_pcm_open+0x48/0x110 [t2bce_audio]
snd_pcm_open_substream
snd_pcm_open
snd_pcm_playback_open
do_sys_openat2

After this happens, WirePlumber becomes stuck in uninterruptible sleep:

PID   S  WCHAN                            COMMAND
1826  D  snd_pcm_substream_proc_status_re wireplumber

It cannot be terminated normally, and system shutdown/reboot takes a very long time.

ALSA behavior on 7.1.6

The Apple T2 card itself is detected:

0 [Audio]: - Apple T2 Audio
             Apple T2 Audio
1 [PCH]: HDA-Intel - HDA Intel PCH

However, aplay -l only gets as far as:

card 0: Audio [Apple T2 Audio], device 4: Bridge Loopback [Bridge Loopback]

and then hangs. Even Ctrl+C does not return to the shell.

The device nodes do exist, including:

pcmC0D100c
pcmC0D101p
pcmC0D102p
pcmC0D103c
pcmC0D4c
pcmC0D4p

but /proc/asound/card0/pcm0p/info, which exists and works on 7.1.4, is not present on 7.1.6.

PipeWire symptoms

After the failure:

$ pactl info
Connection failure: Timeout

$ pactl list short sinks
Connection failure: Timeout

wpctl status hangs indefinitely.

pavucontrol remains at:

Establishing connection to PulseAudio. Please wait...

On some boots audio output may initially work, but the PipeWire/WirePlumber control interface still becomes unresponsive.

Regression

The behavior appears to be:

linux-t2 7.1.4-2
    -> works normally

linux-t2 7.1.5-1
    -> broken

downgrade to 7.1.4-2
    -> works normally again

upgrade to 7.1.5-1
    -> broken again

linux-t2 7.1.6-1
    -> still broken

downgrade to 7.1.4-2
    -> works normally again

This looks like a regression in t2bce_audio, possibly related to the mapping/initialization of the audio BufferStruct subdevices.

The page fault in t2audio_pcm_open() appears to occur after the driver has already reported that the Speaker/Codec/Mic BufferStruct subdevices could not be found.

The complete dmesg output from the affected 7.1.6 boot is attached below.

貼り付けられたテキスト(1 点)(20260809-213602).txt

Activity

  1. andokazunori commented on Aug 12, 2026

    @andokazunori

    I believe I am seeing the same t2bce_audio regression on a MacBookAir8,2,
    but I have also found an additional and rather serious symptom: hibernation
    can fail after WirePlumber has initialized the T2 audio device.

    Hardware

    • MacBook Air (Retina, 13-inch, 2019)
    • Model: A1932
    • DMI: MacBookAir8,2
    • Arch Linux

    Kernel

    The affected kernel is:

    7.1.6-arch1-Watanare-T2-1-t2
    

    My previous linux-t2-7.1.4-1 kernel did not show this problem when using my
    T2 BCE reset workaround.

    Audio regression

    I see the same kind of kernel Oops when WirePlumber accesses the T2 audio
    device:

    BUG: kernel NULL pointer dereference, address: 0000000000000000
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    
    CPU: 2 UID: 1000 PID: 775 Comm: wireplumber
    Tainted: G     U   C
    7.1.6-arch1-Watanare-T2-1-t2
    
    RIP: t2audio_pcm_open+0x48/0x110 [t2bce_audio]
    

    The call trace starts with:

    t2audio_pcm_open+0x48/0x110 [t2bce_audio]
    snd_pcm_open_substream
    snd_pcm_open
    snd_pcm_playback_open
    

    This appears to be the same t2audio_pcm_open() failure described in this
    issue.

    Additional symptom: hibernation failure

    I initially thought this was a Hyprland or hibernate problem, but I was
    able to isolate it further.

    A fresh boot directly to a TTY can hibernate and resume repeatedly without
    problems.

    Suspend/resume also works reliably.

    I also tested Weston with my T2 BCE reset workaround and completed four
    consecutive hibernate/resume cycles successfully.

    However, after starting Hyprland and allowing WirePlumber to initialize the
    T2 audio device, hibernation eventually fails. With a minimal Hyprland
    configuration the problem still occurs, so this does not appear to be
    caused by my Hyprland configuration or hypridle.

    As a control test, I masked:

    pipewire.service
    pipewire-pulse.service
    wireplumber.service
    

    before starting Hyprland. With the audio stack completely prevented from
    initializing, I can repeatedly hibernate and resume successfully.

    Interestingly, stopping WirePlumber after it has already initialized the
    T2 audio device is not sufficient. Hibernation can still fail afterwards.
    It appears that the T2 audio driver can be left in a bad state once the
    WirePlumber/ALSA access has occurred.

    T2 BCE errors

    After the failure I also observed messages such as:

    t2bce_dma: command queue timeout
    t2bce_dma: SQ unregister failed
    t2bce_dma: CQ unregister failed
    t2bce_vhci: Possible desync, cmd cancel timed out
    

    I also have a /lib/systemd/system-sleep/t2-bce-reset workaround which
    removes and reloads the T2 BCE modules around suspend/hibernate. This is
    why suspend and some hibernation tests can work reliably.

    Why I think this is related

    The important distinction is:

    Fresh TTY + no WirePlumber
        -> hibernate/resume works repeatedly
    
    Hyprland + WirePlumber/T2 audio initialized
        -> kernel Oops / hibernation failure
    
    Hyprland + PipeWire/WirePlumber masked
        -> hibernate/resume works repeatedly
    

    The NULL pointer dereference occurs directly in t2audio_pcm_open() while
    the process is WirePlumber, so I suspect this is the same underlying
    t2bce_audio regression rather than a separate Hyprland/hibernate issue.

    I have not investigated the kernel source itself, so this is only based on
    the behavioral tests and kernel logs.

    If useful, I can provide the complete dmesg/journal from the failed
    hibernate and the t2-bce-reset script.

  2. RFdeGroot commented on Aug 13, 2026

    @RFdeGroot

    I can confirm this same regression on a MacBookPro16,2 (13", 2020, 4x Thunderbolt 3), also on 7.1.6-arch1-Watanare-T2-1-t2 (and earlier reproduced the same crash on 7.1.6 in general). Same t2audio_pcm_open NULL pointer dereference as reported above and by @andokazunori. Adding a few things I found while digging into it that might help narrow it down:

    1. The driver logs "Subdevice not found" for every PCM device at module load, not just the one that later crashes

    t2bce_audio: module is from the staging directory, the quality is unknown, you have been warned.
    t2bce_audio 0000:e6:00.3: enabling device (0000 -> 0002)
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Speaker
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Codec Output
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Digital Mic
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device SpeakerLoopback
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Codec Input
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Speaker Mic
    t2bce_audio t2bce_audio: t2bce_audio: Subdevice not found for BufferStruct device Digital Micback
    t2bce_audio: module initialized
    

    This happens for all seven declared PCM devices, including ones that otherwise appear to work fine (e.g. plain open()/close() via ALSA without playing audio succeeds on most of them). My guess is the driver is failing to resolve a subdevice pointer from a firmware-provided "BufferStruct" descriptor table for every device (maybe a name-matching mismatch between what the driver expects and what the firmware actually reports), and that unresolved/NULL subdevice pointer is what t2audio_pcm_open() later dereferences without a NULL check — which would explain why the crash isn't tied to one specific PCM device (I saw it happen on "Codec Output" across most boots, but ALSA PCM device numbering on this driver is also not stable across boots, so it may just be whichever device happens to get opened first each time).

    2. Full oops from my system

    BUG: kernel NULL pointer dereference, address: 0000000000000000
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    PGD 0 P4D 0
    Oops: Oops: 0000 [#1] SMP NOPTI
    CPU: 2 UID: 1000 PID: 2285 Comm: wireplumber Tainted: G         C          7.1.6-arch1-Watanare-T2-1-t2 #1 PREEMPT(full)
    Hardware name: Apple Inc. MacBookPro16,2/Mac-5F9802EFE386AA28, BIOS 2103.100.6.0.0 (iBridge: 23.16.15067.0.0,0) 04/18/2026
    RIP: 0010:t2audio_pcm_open+0x48/0x110 [t2bce_audio]
    Code: 69 c9 88 00 00 00 48 8d b4 0a 50 01 00 00 48 8d 94 0a c0 00 00 00 8b 48 3c 48 8b 80 c0 00 00 00 85 c9 48 0f 44 d6 48 8b 52 40 <48> 8b 0a 48 89 88 88 01 00 00 48 8b 4a 08 48 89 88 90 01 00 00 48
    Call Trace:
     <TASK>
     snd_pcm_open_substream+0x575/0x960 [snd_pcm]
     snd_pcm_open+0x13d/0x2f0 [snd_pcm]
     snd_pcm_playback_open+0x41/0x70 [snd_pcm]
     chrdev_open+0xc7/0x270
     do_dentry_open+0x12f/0x4c0
     vfs_open+0x30/0xf0
     path_openat+0x3c3/0x1300
     do_file_open+0x117/0x1d0
     do_sys_openat2+0x7b/0xe0
     __x64_sys_openat+0x61/0xa0
     do_syscall_64+0xaa/0x660
     entry_SYSCALL_64_after_hwframe+0x76/0x7e
     </TASK>
    note: wireplumber[2285] exited with irqs disabled
    

    CR2: 0000000000000000 — dereferencing a NULL pointer, consistent with the "Subdevice not found" warnings above (some field on the device struct never got populated).

    3. Once it happens once, the card is wedged for the rest of the boot

    Matches what @andokazunori described. On my system, after the first oops, every subsequent attempt to open any PCM device on this card (even a completely unrelated one, or even just cat /proc/asound/cardN/pcmXY/subZ/status on an idle device) hangs the calling process in unkillable D-state (snd_pcm_substream_proc_status_read), not just re-triggers the oops. Only a hard reboot clears it — SIGKILL has no effect, and systemctl --user restart on anything touching the card just hangs waiting on the dead process. So it seems like the first crash leaves some driver-internal lock/state permanently taken.

    Workaround

    Can confirm downgrading to linux-t2 7.1.4-2 fixes it completely for me too, same as the original report — no crashes, normal audio, across several reboots. I've pinned it via IgnorePkg in pacman.conf until this is fixed.

    Happy to provide more logs/test patches if useful — this is a fairly reliable local repro (crashes on first real playback attempt basically every time on 7.1.5/7.1.6).

    Disclaimer:

    I'm not a kernel or driver developer by any means (although I am a experienced linux user and systadmin) and used claude to help me troubleshoot this issue and help me write this comment.

  3. Varrah commented on Aug 13, 2026

    @Varrah

    reproduced on another MacBookPro16,2, 7.1.6 - broken, 7.1.4 - works

  4. Varrah commented on Aug 19, 2026

    @Varrah

    Seems to be fixed in linux-t2 7.1.8.arch1-3

  5. RFdeGroot commented on Aug 19, 2026

    @RFdeGroot

    Seems to be fixed in linux-t2 7.1.8.arch1-3

    Can confirm. Just updated to the latest kernel version and it seems to be fixed!

  6. andokazunori commented on Aug 21, 2026

    @andokazunori

    I tested this again with linux-t2 7.1.8-arch1-Watanare-T2-3-t2.

    The original t2bce_audio NULL pointer dereference appears to be fixed. Thank you!

    However, I still have a hibernation/resume problem when WirePlumber has been running under Hyprland.

    I found an important difference:

    1. Boot normally into Hyprland with WirePlumber enabled.

    2. Manually run:

      systemctl --user stop wireplumber

    3. Hibernate with:

      systemctl hibernate

    In this case, I can resume from hibernation repeatedly. I tested it 4 times consecutively without a failure.

    However, if WirePlumber has been running and I hibernate without manually stopping it, resume can fail. The keyboard then becomes unresponsive.

    The dmesg from a failed resume shows:

    t2bce_vhci: Possible desync, cmd cancel timed out
    t2bce_vhci: tq resume set-active failed dev=1 port=5 ep=00 status=-110
    t2bce_vhci: stateful resume queue failed: dev=1 ep=00 status=-110
    t2bce_vhci: stateful resume exit status=-110
    t2bce_vhci: bus_resume exit status=-110 no_state_resume=0
    t2bce_vhci t2bce_vhci: HC died; cleaning up
    usb usb5: PM: dpm_run_callback(): usb_dev_restore returns -110
    usb usb5: PM: failed to restore async: error -110
    

    Interestingly, the hibernation entry itself appears to succeed:

    t2bce_vhci: bus_suspend exit status=0
    

    The failure occurs during resume, when the T2 BCE VHCI USB bus is being restored.

    This makes me suspect that WirePlumber leaving the T2 audio device active before hibernation may affect the state of the T2 BCE/VHCI subsystem, even though the original t2bce_audio kernel NULL pointer dereference is now fixed.

    For reference, this is a MacBook Air 8,2.

    I am currently using Hyprland, but the important difference seems to be whether WirePlumber has been running before hibernation, rather than Hyprland itself.

    I should also clarify that I already have the following in my hypridle configuration:

    before_sleep_cmd = sh -c "loginctl lock-session && sleep 1 && systemctl --user stop wireplumber.service && hyprctl dispatch dpms off && sleep 1"
    

    So I am already attempting to stop WirePlumber before suspend/hibernate when using Hyprland.

    However, this does not reliably prevent the hibernation/resume failure.

    There is an important difference between the two cases:

    • If I manually stop WirePlumber first with systemctl --user stop wireplumber.service and then run systemctl hibernate, I can resume from hibernation repeatedly (4 consecutive tests so far).
    • If WirePlumber is stopped by the hypridle before_sleep_cmd, hibernation can still fail during resume.

    This may indicate a timing/order issue between hypridle, systemd's sleep handling, and the T2 BCE drivers.

    I will continue testing, but I wanted to report this additional finding because manually stopping WirePlumber before hibernation makes the problem disappear in my testing.

  7. roy-devx commented on Aug 21, 2026

    @roy-devx
    Author

    Tested on MacBookAir8,1 with 7.1.8-arch1-Watanare-T2-1-t2.

    The original audio regression appears to be fixed on my system as well.

    • t2bce_audio initializes without Subdevice not found errors
    • no t2audio_pcm_open() NULL pointer dereference
    • wpctl status responds normally
    • WirePlumber remains in a normal sleeping state
    • internal speakers are working normally

    I previously reproduced the issue consistently on 7.1.5 and 7.1.6, with 7.1.4 working normally, so this looks fixed in 7.1.8 on MacBookAir8,1 as well.

    Thanks!

  8. andokazunori commented on Aug 21, 2026

    @andokazunori

    I have another important finding.

    I changed my hypridle before_sleep_cmd so that WirePlumber is stopped first, before locking the session or turning off the display:

    before_sleep_cmd = sh -c "systemctl --user stop wireplumber.service && loginctl lock-session && sleep 1 && hyprctl dispatch dpms off && sleep 3"
    

    With this ordering, I was able to resume from hibernation 4 times consecutively without any failure.

    Previously, my command was:

    before_sleep_cmd = sh -c "loginctl lock-session && sleep 1 && systemctl --user stop wireplumber.service && hyprctl dispatch dpms off && sleep 1"
    

    With the previous ordering, hibernation/resume could still fail.

    So it appears that the timing/order of stopping WirePlumber is important. Stopping WirePlumber as the very first operation in before_sleep_cmd seems to give it enough time to shut down before the system proceeds with hibernation.

    For comparison:

    • WirePlumber running → hibernation/resume can fail.
    • Manually run systemctl --user stop wireplumber.service before systemctl hibernate → hibernation/resume works repeatedly (4 consecutive tests).
    • Stop WirePlumber first in hypridle's before_sleep_cmd → hibernation/resume also works repeatedly (4 consecutive tests).

    This makes me think the remaining issue may be a timing/order interaction between WirePlumber, hypridle/systemd sleep handling, and the T2 BCE audio/VHCI drivers, rather than Hyprland itself.

    This appears to be resolved for my setup now.

    The original t2bce_audio NULL pointer dereference is fixed in 7.1.8, and I also found a reliable workaround for the remaining hibernation issue: stopping WirePlumber as the first operation in hypridle's before_sleep_cmd.

    With this ordering, I have successfully resumed from hibernation 4 times consecutively.

    I will close this issue for now. Thank you for the fix and for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions