Apple T2 Macs are… special. If you run Proxmox on something like a Mac mini 2018, you’ll eventually touch out-of-tree kernel modules and discover that Linux kernel APIs love change. Running Proxmox on a Mac mini 2018 with T2 chip requires the applesmc_t2_kmod kernel module for proper fan control.

After some research I’ve found the repo MCMrARM/mbp2018-etc which was slighly outdated for 2026, as I faced some issues described below.

Common issues

Missing linux/input-polldev.h - this header was removed years ago. I have to patch the source to remove the #include and any polled-input code.

struct acpi_driver has no member owner - on newer kernels, I have to remove .owner = THIS_MODULE from the ACPI driver initializer.

Kernel header mismatch - for Proxmox, the headers package for kernel could be different than on build machine, for example - 6.8.12-4-pve is proxmox-headers-6.8.12-4 (no -pve suffix).

Building in Docker

Using docker buildx, we can build the module for a specific Proxmox kernel and export only the artifact:

# syntax=docker/dockerfile:1

ARG DEBIAN_VERSION=trixie

FROM public.ecr.aws/debian/debian:${DEBIAN_VERSION} AS builder

ARG DEBIAN_VERSION=trixie
ARG KVER

ENV DEBIAN_FRONTEND=noninteractive
SHELL ["/bin/bash", "-euxo", "pipefail", "-c"]

RUN test -n "${KVER:-}" || (echo "ERROR: set --build-arg KVER=<kernel-version>, e.g. 6.17.4-1-pve or 6.1.0-18-amd64" && exit 2)

RUN apt-get update -qq && apt-get install -yqq --no-install-recommends \
      bc \
      build-essential \
      ca-certificates \
      curl \
      git \
      gnupg \
      libelf-dev \
      pkg-config \
    && \
    rm -rf /var/lib/apt/lists/*

RUN if [[ "${KVER}" == *"-pve"* ]]; then \
      curl -fsSL "https://enterprise.proxmox.com/debian/proxmox-archive-keyring-${DEBIAN_VERSION}.gpg" \
        -o /usr/share/keyrings/proxmox-archive-keyring.gpg; \
      printf '%s\n' \
        'Types: deb' \
        'URIs: http://download.proxmox.com/debian/pve' \
        "Suites: ${DEBIAN_VERSION}" \
        'Components: pve-no-subscription' \
        'Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg' \
        > /etc/apt/sources.list.d/proxmox.sources; \
      apt-get update -qq; \
      apt-get install -yqq --no-install-recommends \
        "proxmox-headers-${KVER%-pve}"; \
    else \
      apt-get update -qq; \
      apt-get install -yqq --no-install-recommends \
        "linux-headers-${KVER}"; \
    fi \
    && rm -rf /var/lib/apt/lists/*

COPY ./src /work/src
WORKDIR /work/src/applesmc

RUN KDIR="/lib/modules/${KVER}/build"; \
    if [[ ! -e "${KDIR}/Makefile" ]]; then \
      if [[ "${KVER}" == *"-pve"* ]]; then \
        KDIR="/usr/src/linux-headers-${KVER%-pve}"; \
      else \
        KDIR="/usr/src/linux-headers-${KVER}"; \
      fi; \
    fi; \
    test -e "${KDIR}/Makefile" || (echo "ERROR: kernel build dir not found: ${KDIR}" && ls -la /lib/modules /usr/src || true && exit 3); \
    make KDIR="${KDIR}" KVER="${KVER}" all

RUN install -D -m 0644 applesmc_t2_kmod.ko /out/applesmc_t2_kmod.ko

# ---- Export-only stage ----
FROM scratch AS artifact
COPY --from=builder /out/applesmc_t2_kmod.ko /applesmc_t2_kmod.ko

Build with:

docker buildx build \
  --build-arg DEBIAN_VERSION=trixie \
  --build-arg KVER=6.17.4-1-pve \
  -t applesmc-t2-builder \
  --output type=local,dest=./out .

The scratch stage ensures only the .ko file is exported to ./out/.

Install on Proxmox host

install -D -m 0644 applesmc_t2_kmod.ko /lib/modules/$(uname -r)/extra/applesmc_t2_kmod.ko
depmod -a
modprobe applesmc_t2_kmod
dmesg | tail -n 20

If you see write_smc_mmio errors in fan control tools (like mbpfan or macfanctld), the firmware is rejecting writes to restricted SMC keys (like fan control). Use dedicated T2 tooling instead.

T2 fan control

The applesmc_t2_kmod module alone doesn’t handle fan control properly. Use the t2-ubuntu-repo which provides fan daemons that respect T2 firmware limitations.

Installation & usage

  • Assumming that you are root

    # Download the repo key
    curl -s --compressed "https://adityagarg8.github.io/t2-ubuntu-repo/KEY.gpg" | gpg --dearmor | tee /etc/apt/trusted.gpg.d/t2-ubuntu-repo.gpg >/dev/null
    # Adding repo configuration
    CODENAME=trixie
    echo "deb [signed-by=/etc/apt/trusted.gpg.d/t2-ubuntu-repo.gpg] https://github.com/AdityaGarg8/t2-ubuntu-repo/releases/download/${CODENAME} ./" | tee -a /etc/apt/sources.list.d/t2.list
    # Update list of packages
    apt update && apt install t2fanrd
    
  • Check the status of service

    systemctl status t2fanrd.service
    

Example of configuration

  • /etc/t2fand.conf

    [Fan1]
    low_temp=55
    high_temp=65
    speed_curve=linear
    always_full_speed=false
    

That’s all.