diff --git a/base/comps/kernel/kernel.comp.toml b/base/comps/kernel/kernel.comp.toml index 3dd315e7c68..e18c63372e2 100644 --- a/base/comps/kernel/kernel.comp.toml +++ b/base/comps/kernel/kernel.comp.toml @@ -14,10 +14,12 @@ without = [ [components.kernel.build.defines] # RPM release number for the Azure Linux kernel package -azl_pkgrelease = "3" +azl_pkgrelease = "4" # 4th version component from the AZL kernel source (6.18.31.1). Included in specrelease so it appears # in the RPM Release tag, uname -r, and /lib/modules/ path (e.g. 6.18.31-1.1.azl4.aarch64). kextraversion = "1" +# NVIDIA open GPU kernel module version (built as a subpackage of the kernel) +nvidia_open_version = "595.58.03" # Download the source tarball from the AzureLinux kernel repo [[components.kernel.source-files]] @@ -26,6 +28,13 @@ hash = "1bf684812ff3fc38974dc99b3e2309cb46dc5af93ac794e79a4a4f3dd17debfadb14510a hash-type = "SHA512" origin = { type = "download", uri = "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/azl4/6.18.31.1.tar.gz" } +# Download the NVIDIA open GPU kernel module source tarball +[[components.kernel.source-files]] +filename = "open-gpu-kernel-modules-595.58.03.tar.gz" +hash = "a422b6935209d590f57fa6766f59bb207d9130f8a6777af9245c4ff8cd0f4c4ccef4602a0b26d543e1e8efba24241180992fdb749ea4e5d2aa5218a584b85101" +hash-type = "SHA512" +origin = { type = "download", uri = "https://github.com/NVIDIA/open-gpu-kernel-modules/archive/refs/tags/595.58.03.tar.gz" } + # Insert version and release information from the component defines into the spec file, and update the source URL to match the AzureLinux kernel source structure [[components.kernel.overlays]] description = "Set specrpmversion to 6.18.31" @@ -164,3 +173,169 @@ lines = [ "cd ../..", "%endif", ] + +# ============================================================================ +# kmod subpackage framework — modular kmod builds alongside the kernel +# +# This framework allows building out-of-tree kernel modules as subpackages of +# the kernel RPM. Each kmod is defined in its own .inc file (e.g. +# kmod-nvidia-open.inc) with phase-gated sections that run at each RPM build +# phase (%description, %prep, %build, %install, %files). +# +# To add a new kmod: +# 1. Create kmod-.inc with phase-gated sections +# 2. Add file-add overlays for .inc and any extra source files +# 3. Add spec-insert-tag overlays to register sources (Source6xxx range) +# 4. Add spec-search-replace overlays targeting the AZL-KMOD-*-ANCHOR +# sentinels for each phase (the anchor survives replacement so the +# next kmod can chain onto it) +# ============================================================================ + +# --- kmod-nvidia-open: source file registration --- +# Registers the NVIDIA open GPU kernel module sources and configuration files. +# Source numbers 6000-6099 are reserved for nvidia-open. + +[[components.kernel.overlays]] +description = "Add kmod-nvidia-open.inc subpackage definition to sources" +type = "file-add" +file = "kmod-nvidia-open.inc" +source = "kmod-nvidia-open.inc" + +[[components.kernel.overlays]] +description = "Add NVIDIA modprobe config file for kmod-nvidia-open subpackage" +type = "file-add" +file = "kmod-nvidia-open-modprobe.conf" +source = "kmod-nvidia-open-modprobe.conf" + +[[components.kernel.overlays]] +description = "Register NVIDIA open-gpu-kernel-modules tarball as Source6000" +type = "spec-insert-tag" +tag = "Source6000" +value = "open-gpu-kernel-modules-%{nvidia_open_version}.tar.gz" + +[[components.kernel.overlays]] +description = "Register NVIDIA modprobe config as Source6001" +type = "spec-insert-tag" +tag = "Source6001" +value = "kmod-nvidia-open-modprobe.conf" + +[[components.kernel.overlays]] +description = "Register kmod-nvidia-open.inc as Source6002" +type = "spec-insert-tag" +tag = "Source6002" +value = "kmod-nvidia-open.inc" + +# --- kmod framework: phase anchor insertion --- +# These overlays insert unique sentinel comments at unconditional locations in +# the upstream spec. Per-kmod overlays below target these sentinels with +# spec-search-replace, replacing SENTINEL with + SENTINEL so +# each sentinel survives for the next kmod to chain onto. + +[[components.kernel.overlays]] +description = "Insert kmod package anchor after main %description — unconditional location for kmod subpackage declarations" +type = "spec-append-lines" +section = "%description" +lines = [ + "", + "# AZL-KMOD-PACKAGE-ANCHOR — do not remove (kmod overlays chain here)", +] + +[[components.kernel.overlays]] +description = "Insert kmod prep anchor at end of %prep — unconditional location for kmod source extraction" +type = "spec-append-lines" +section = "%prep" +lines = [ + "", + "# AZL-KMOD-PREP-ANCHOR — do not remove (kmod overlays chain here)", +] + +[[components.kernel.overlays]] +description = "Insert kmod build anchor before modsign macros — unconditional location at the end of the active %build body" +type = "spec-search-replace" +regex = '# Module signing \(modsign\)' +replacement = """# AZL-KMOD-BUILD-ANCHOR — do not remove (kmod overlays chain here) + +# Module signing (modsign)""" + +[[components.kernel.overlays]] +description = "Insert kmod install anchor before ### clean — unconditional location at the end of the active %install body" +type = "spec-search-replace" +regex = '### clean' +replacement = """# AZL-KMOD-INSTALL-ANCHOR — do not remove (kmod overlays chain here) + +### +### clean""" + +[[components.kernel.overlays]] +description = "Insert kmod files anchor after %files modules-extra-matched — unconditional location for kmod file lists" +type = "spec-append-lines" +section = "%files" +package = "modules-extra-matched" +lines = [ + "", + "# AZL-KMOD-FILES-ANCHOR — do not remove (kmod overlays chain here)", +] + +# --- kmod-nvidia-open: phase injection --- +# RPM %include is a preprocessor directive — it must appear directly in the spec +# text (not inside a %define macro). Each phase sets _kmod_phase and _kmod_name +# globals, then includes the kmod .inc file. The .inc file's %if guards select +# the correct section for that phase. +# +# To add a new kmod: duplicate the phase blocks below, changing _kmod_name and +# the %include path. Each block targets the framework anchor for its phase. + +[[components.kernel.overlays]] +description = "Run kmod 'package' phase at package anchor — declares kmod subpackages" +type = "spec-search-replace" +regex = '# AZL-KMOD-PACKAGE-ANCHOR' +replacement = """# AZL: kmod subpackage declarations (nvidia-open) +%global _kmod_phase package +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-PACKAGE-ANCHOR""" + +[[components.kernel.overlays]] +description = "Run kmod 'prep' phase at prep anchor — extracts kmod source tarballs" +type = "spec-search-replace" +regex = '# AZL-KMOD-PREP-ANCHOR' +replacement = """# AZL: Prepare kmod subpackage sources (nvidia-open) +%global _kmod_phase prep +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-PREP-ANCHOR""" + +[[components.kernel.overlays]] +description = "Run kmod 'build' phase at build anchor — compiles NVIDIA modules against the just-built kernel" +type = "spec-search-replace" +regex = '# AZL-KMOD-BUILD-ANCHOR' +replacement = """# AZL: Build kmod subpackage modules (nvidia-open) +%global _kmod_phase build +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-BUILD-ANCHOR""" + +[[components.kernel.overlays]] +description = "Run kmod 'install' phase at install anchor — installs NVIDIA modules, configs, and licenses" +type = "spec-search-replace" +regex = '# AZL-KMOD-INSTALL-ANCHOR' +replacement = """# AZL: Install kmod subpackage files (nvidia-open) +%global _kmod_phase install +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-INSTALL-ANCHOR""" + +[[components.kernel.overlays]] +description = "Run kmod 'files' phase at files anchor — adds %post/%postun/%files for NVIDIA kmod subpackage" +type = "spec-search-replace" +regex = '# AZL-KMOD-FILES-ANCHOR' +replacement = """# AZL: kmod subpackage file lists and scriptlets (nvidia-open) +%global _kmod_phase files +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-FILES-ANCHOR""" diff --git a/base/comps/kernel/kmod-nvidia-open-modprobe.conf b/base/comps/kernel/kmod-nvidia-open-modprobe.conf new file mode 100644 index 00000000000..5dded2d82d0 --- /dev/null +++ b/base/comps/kernel/kmod-nvidia-open-modprobe.conf @@ -0,0 +1,4 @@ +# kmod-nvidia-open modprobe configuration +# Blacklist nouveau to prevent conflicts with NVIDIA open kernel modules +blacklist nouveau +options nouveau modeset=0 diff --git a/base/comps/kernel/kmod-nvidia-open.inc b/base/comps/kernel/kmod-nvidia-open.inc new file mode 100644 index 00000000000..8e861753aab --- /dev/null +++ b/base/comps/kernel/kmod-nvidia-open.inc @@ -0,0 +1,143 @@ +# kmod-nvidia-open.inc — NVIDIA open GPU kernel module subpackage +# +# Phases: package, prep, build, install, files +# Activated by: setting _kmod_phase global + include from kernel.comp.toml overlays +# +# Requires these defines/sources in kernel.spec (injected via comp.toml overlays): +# nvidia_open_version — NVIDIA driver version (e.g. 595.58.03) +# SOURCE6000 — open-gpu-kernel-modules tarball +# SOURCE6001 — kmod-nvidia-open-modprobe.conf + +# ========================================================================= +# Phase: package — subpackage declaration +# ========================================================================= +%if "%{_kmod_phase}" == "package" && %{with_up_base} + +%ifarch x86_64 aarch64 +%package -n kmod-%{_kmod_name}-%{nvidia_open_version} +Summary: NVIDIA open GPU kernel modules (driver %{nvidia_open_version}) +AutoReq: no +# NOTE: Version is inherited from kernel (%{version}), NOT nvidia_open_version. +# Track the actual NVIDIA driver version via Provides for dependency resolution. +Provides: nvidia-open-kmod-version = %{nvidia_open_version} +provides: nvidia-kmod = %{nvidia_open_version} +Provides: kmod-%{_kmod_name} = %{version}-%{release} +# Mark this kmod as install-only so multiple versions can coexist alongside +# their matching kernels (dnf/dnf5 default installonlypkgs includes the +# 'installonlypkg(kernel-module)' token). +Provides: installonlypkg(kernel-module) +Requires: %{name}-core-uname-r = %{KVERREL} +Requires(post): kmod +Requires(postun): kmod +Conflicts: nvidia-closed-kmod + +%description -n kmod-%{_kmod_name}-%{nvidia_open_version} +Open-source NVIDIA GPU kernel modules (driver version %{nvidia_open_version}) +built from the official NVIDIA/open-gpu-kernel-modules repository for +kernel %{KVERREL}. + +These modules support CUDA workloads on NVIDIA GPUs (Turing and later). + +Each kernel version produces a separate kmod package +(kmod-nvidia-open--) so that multiple kernel versions +can coexist with their own NVIDIA modules. +Use 'Requires: nvidia-open-kmod-version = %{nvidia_open_version}' to depend on a +specific NVIDIA driver version, or 'Requires: kmod-nvidia-open' for any version. +%endif + +%endif + +# ========================================================================= +# Phase: prep — extract NVIDIA source tarball +# ========================================================================= +%if "%{_kmod_phase}" == "prep" && %{with_up_base} + +%ifarch x86_64 aarch64 +pushd %{_builddir} +tar -xf %{SOURCE6000} +popd +%endif + +%endif + +# ========================================================================= +# Phase: build — compile NVIDIA kernel modules +# ========================================================================= +%if "%{_kmod_phase}" == "build" && %{with_up_base} + +%ifarch x86_64 aarch64 +%{log_msg "Building NVIDIA open GPU kernel modules %{nvidia_open_version} for %{KVERREL}"} +pushd %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version} +# Unset LDFLAGS — NVIDIA kbuild invokes ld directly, not via gcc +unset LDFLAGS +# IGNORE_CC_MISMATCH=1: kmod is a kernel subpackage built in the same +# mock chroot with the same GCC. The flag suppresses NVIDIA's compiler-string +# comparison which can false-positive on path or version-string formatting +# differences even when the toolchain is identical. +# CONFIG_OBJTOOL_WERROR=: NVIDIA's precompiled binary blob (nv-kernel.o_binary) +# contains bare 'ret' instructions that fail objtool's rethunk validation when +# CONFIG_MITIGATION_RETHUNK=y. Clearing this config on the make command line +# propagates through GNU make's recursive $(MAKE) into kbuild, turning the +# objtool errors into non-fatal warnings. The kernel itself is already fully +# built and validated with objtool by this point. +# Ref: https://forums.developer.nvidia.com/t/360610 +make %{?_smp_mflags} modules \ + KERNEL_UNAME="%{KVERREL}" \ + SYSSRC="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \ + SYSOUT="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \ + IGNORE_CC_MISMATCH=1 \ + IGNORE_XEN_PRESENCE=1 \ + IGNORE_PREEMPT_RT_PRESENCE=1 \ + NV_EXCLUDE_BUILD_MODULES="" \ + CONFIG_OBJTOOL_WERROR= +popd +%endif + +%endif + +# ========================================================================= +# Phase: install — install modules, config, and license +# ========================================================================= +%if "%{_kmod_phase}" == "install" && %{with_up_base} + +%ifarch x86_64 aarch64 +%{log_msg "Installing NVIDIA open GPU kernel modules for %{KVERREL}"} +install -d %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia +for mod in nvidia nvidia-modeset nvidia-drm nvidia-uvm nvidia-peermem; do + ko="%{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/kernel-open/${mod}.ko" + install -m 0644 "${ko}" %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia/ +done +# Install modprobe config to blacklist conflicting modules. Lives under +# %{_modprobedir} (/usr/lib/modprobe.d) — vendor-supplied config, not +# admin-editable, so it is owned by the package without %config(noreplace). +install -D -m 0644 %{SOURCE6001} %{buildroot}%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf +# Install NVIDIA license file +install -D -m 0644 %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/COPYING \ + %{buildroot}%{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING +%endif + +%endif + +# ========================================================================= +# Phase: files — scriptlets and file list +# ========================================================================= +%if "%{_kmod_phase}" == "files" && %{with_up_base} + +%ifarch x86_64 aarch64 +%post -n kmod-%{_kmod_name}-%{nvidia_open_version} +%{_sbindir}/depmod -a %{KVERREL} || : + +%postun -n kmod-%{_kmod_name}-%{nvidia_open_version} +%{_sbindir}/depmod -a %{KVERREL} || : + +%files -n kmod-%{_kmod_name}-%{nvidia_open_version} +%license %{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING +/lib/modules/%{KVERREL}/extra/nvidia/nvidia.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-modeset.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-drm.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-uvm.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-peermem.ko.%{compext} +%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf +%endif + +%endif diff --git a/docs/oss-kmod-packaging-strategy.md b/docs/oss-kmod-packaging-strategy.md new file mode 100644 index 00000000000..d480412c666 --- /dev/null +++ b/docs/oss-kmod-packaging-strategy.md @@ -0,0 +1,205 @@ +# Open Source Out-of-Tree Kernel Module Packaging Strategy — Azure Linux 4.0 + +## Overview + +Azure Linux 4.0 builds out-of-tree kernel modules (kmods) as **subpackages of the kernel RPM** rather than as standalone packages. This ensures tight coupling between the kernel binary and its companion modules — eliminating version skew, simplifying dependency resolution, and guaranteeing that modules are always compiled against the exact kernel headers they will run on. + +## Architecture +consider kmod-nvidia-open as an example: +``` +kernel.comp.toml +├── build.defines.nvidia_open_version = "595.58.03" +├── source-files[] → kernel tarball, NVIDIA tarball +├── overlays +│ ├── [nvidia-open sources] .inc, modprobe.conf (Source6000-6002) +│ └── [nvidia-open phases] spec-append-lines × 5 phases +│ +└── Resulting kernel.spec (after overlays) + ├── %description → %include kmod-nvidia-open.inc (phase=package) + ├── %prep → %include kmod-nvidia-open.inc (phase=prep) + ├── %build → %include kmod-nvidia-open.inc (phase=build) + ├── %install → %include kmod-nvidia-open.inc (phase=install) + └── %files → %include kmod-nvidia-open.inc (phase=files) +``` + +### Key Files + +| File | Purpose | +|------|---------| +| `kmod-.inc` | Self-contained subpackage definition with phase-gated `%if` blocks | +| `kmod--modprobe.conf` | Module loading configuration (blacklists, options) | +| `kernel.comp.toml` | Overlay definitions that wire everything together | + +## Phase-Gated Include Pattern + +RPM's `%include` directive is a preprocessor operation — it injects file contents literally into the spec at parse time. Since `%include` cannot appear inside macro bodies, we use a **phase-gating** pattern: + +```spec +# At each build phase, set the phase variable then include the kmod file: +%global _kmod_phase build +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc +``` + +Inside the `.inc` file, each section is guarded: + +```spec +%if "%{_kmod_phase}" == "build" +# ... build commands ... +%endif +``` + +This allows a single `.inc` file to contain all phases of a kmod's lifecycle while only activating the relevant section at each point in the spec. + +### Phase Execution Order + +| Phase | Injection Point | Purpose | +|-------|----------------|---------| +| `package` | After `%description` | Declare `%package -n kmod--`, Provides, Requires | +| `prep` | End of `%prep` | Extract kmod source tarball | +| `build` | End of `%build` | Compile modules against kernel build tree | +| `install` | End of `%install` | Install `.ko` files, configs, licenses | +| `files` | After `%files modules-extra-matched` | `%post`/`%postun` scriptlets and file list | + +## Naming and Versioning Strategy + +The driver version is embedded directly in the kmod subpackage name (e.g., `kmod-nvidia-open-595.58.03`). + +The subpackage is declared as: + +```spec +%package -n kmod-%{_kmod_name}-%{nvidia_open_version} +``` + +The RPM Version/Release is inherited from the **kernel** (e.g., `kmod-nvidia-open-595.58.03-6.18.5-1.8.azl4.x86_64.rpm`). The driver version is also exposed via virtual Provides so that consumers can depend on it without pinning the kernel version: + +```spec +Provides: nvidia-open-kmod-version = %{nvidia_open_version} +Provides: nvidia-kmod = %{nvidia_open_version} +Provides: kmod-nvidia-open = %{version}-%{release} +``` + +This means: +- `Requires: kmod-nvidia-open` → gets any driver version that matches the installed kernel +- `Requires: kmod-nvidia-open-595.58.03` → pins to that specific driver version's RPM name +- `Requires: nvidia-open-kmod-version = 595.58.03` → pins to a specific driver version via virtual Provides + +Consumer packages (e.g., `nvidia-cuda-driver`) should use the virtual Provides, not the RPM version directly. + +## Adding a New kmod + +### 1. Create the `.inc` file + +``` +base/comps/kernel/kmod-.inc +``` + +Use `kmod-nvidia-open.inc` as a template. Implement all 5 phases with `%if "%{_kmod_phase}" == ""` guards. + +### 2. Create supporting files + +- `kmod--modprobe.conf` — module loading config (blacklists, options) +- Any patches specific to the kmod + +### 3. Add build defines for version + +In `kernel.comp.toml`, add the driver version define: + +```toml +[components.kernel.build.defines] +_version = "1.0.0" # driver version — becomes part of the RPM name +``` + +The driver version is embedded directly in the subpackage name (e.g., `kmod-foo-1.0.0`), enabling multiple driver versions to coexist (e.g., `kmod-foo-1.0.0` and `kmod-foo-2.0.0`). + +### 4. Add source-files entry (if external tarball needed) + +```toml +[[components.kernel.source-files]] +filename = "my-module-1.0.tar.gz" +hash = "..." +hash-type = "SHA256" +origin = { type = "download", uri = "https://..." } +``` + +### 5. Add overlays to `kernel.comp.toml` + +```toml +# Source registration (use Source6100+ range for the new kmod) +[[components.kernel.overlays]] +description = "Add kmod-.inc to sources" +type = "file-add" +file = "kmod-.inc" +source = "kmod-.inc" + +[[components.kernel.overlays]] +description = "Register kmod- tarball as Sourcexxxx" +type = "spec-insert-tag" +tag = "Sourcexxxx" +value = "my-module-1.0.tar.gz" + +[[components.kernel.overlays]] +description = "Register kmod-.inc as Sourcexxxx++" +type = "spec-insert-tag" +tag = "Sourcexxx++" +value = "kmod-.inc" + +# Phase injection (repeat for each phase) +[[components.kernel.overlays]] +description = "Run kmod- 'package' phase" +type = "spec-append-lines" +section = "%description" +lines = [ + "", + "%global _kmod_phase package", + "%global _kmod_name ", + "%include %{_sourcedir}/kmod-.inc", +] + +# ... repeat for prep, build, install, files ... +``` + +### 6. Validate + +```bash +azldev comp render -p kernel # Check overlays apply cleanly +azldev comp build -p kernel # Full build + kmod compilation +``` + +## Source Number Allocation + +| Range | Reserved For | +|-------|-------------| +| 5000–5099 | AZL kernel configs and certificates | +| 6000–6099 | kmod-nvidia-open | +| 6100–6199 | (next kmod) | +| 6200–6299 | (next kmod) | + +## RPM Output + +A successful kernel build produces (among others) the following RPMs, consider kmod-nvidia-open as an example: + +``` +kernel-6.18.5-1.8.azl4.x86_64.rpm +kernel-core-6.18.5-1.8.azl4.x86_64.rpm +kernel-modules-6.18.5-1.8.azl4.x86_64.rpm +kmod-nvidia-open-595.58.03-6.18.5-1.8.azl4.x86_64.rpm ← kmod subpackage (driver 595.58.03) +``` + +The kmod RPM contains: +- `/lib/modules/%{KVERREL}/extra/nvidia/*.ko.xz` — compressed kernel modules +- `/etc/modprobe.d/kmod-nvidia-open-595.58.03.conf` — blacklist conflicting modules +- `/etc/depmod.d/kmod-nvidia-open-595.58.03.conf` — depmod override configuration +- `/usr/share/licenses/kmod-nvidia-open-595.58.03/COPYING` — license file + +## Constraints and Limitations + +1. **RPM `%include` is a preprocessor directive** — it cannot be used inside `%define`/`%global` macro bodies, generated from Lua, or made conditional at the `%include` line itself (the `%if` must be inside the included file). + +2. **No parametric dispatch** — each kmod requires explicit `%global` + `%include` lines per phase. You cannot loop over kmod names with a single macro call due to the `%include` limitation above. + +3. **Build time** — each additional kmod adds compilation time to the kernel build. The NVIDIA open modules add ~5-10 minutes to a ~25 minute kernel build. + +4. **Module compression** — the kernel spec's `%post` processing compresses `.ko` files to `.ko.xz`. The `%files` section must reference the compressed names. + +5. **Architecture restrictions** — use `%ifarch x86_64 aarch64` guards in prep/build/install phases to skip kmod work on architectures where the module is not supported. diff --git a/locks/kernel.lock b/locks/kernel.lock index 206b46f3d54..dd0689d4d8b 100644 --- a/locks/kernel.lock +++ b/locks/kernel.lock @@ -2,5 +2,5 @@ version = 1 import-commit = '5271a1b047ef402ddee40242e02eda23fc273044' upstream-commit = '5271a1b047ef402ddee40242e02eda23fc273044' -input-fingerprint = 'sha256:3712f583962a018083cfb0e5582c296fbed51633b1bbe0e92a940e5dd3653549' +input-fingerprint = 'sha256:bc03956c16315556bb81a4b7557cf78a94a8f6b352bdb0de97af7227ca2bd0b5' resolution-input-hash = 'sha256:466421704711c4fd3c71f0b2ed715a0e61d49e3e26f3a2637fee755795849c8e' diff --git a/specs/k/kernel/kernel.azl.macros b/specs/k/kernel/kernel.azl.macros index 445fb585f12..fe9ba800b5b 100644 --- a/specs/k/kernel/kernel.azl.macros +++ b/specs/k/kernel/kernel.azl.macros @@ -2,5 +2,6 @@ # Do not edit manually; changes will be overwritten. %_without_debug 1 %_without_selftests 1 -%azl_pkgrelease 3 +%azl_pkgrelease 4 %kextraversion 1 +%nvidia_open_version 595.58.03 diff --git a/specs/k/kernel/kernel.spec b/specs/k/kernel/kernel.spec index edf84d8ad00..f55e26dbf95 100644 --- a/specs/k/kernel/kernel.spec +++ b/specs/k/kernel/kernel.spec @@ -1174,6 +1174,9 @@ Source9999: kernel.azl.macros Source5000: 6.18-x86_64-azl.config Source5001: 6.18-aarch64-azl.config Source5002: azurelinux-ca-20230216.pem +Source6000: open-gpu-kernel-modules-%{nvidia_open_version}.tar.gz +Source6001: kmod-nvidia-open-modprobe.conf +Source6002: kmod-nvidia-open.inc ## Patches needed for building this package @@ -1224,6 +1227,13 @@ AutoProv: yes\ %{nil} + +# AZL: kmod subpackage declarations (nvidia-open) +%global _kmod_phase package +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-PACKAGE-ANCHOR — do not remove (kmod overlays chain here) %package doc Summary: Various documentation bits found in the kernel source Group: Documentation @@ -2245,6 +2255,13 @@ OPTS="-w -n -c" SPECPACKAGE_NAME=%{name} RHJOBS=$RPM_BUILD_NCPUS ./process_configs.sh $OPTS %{specrpmversion} cd ../.. %endif + +# AZL: Prepare kmod subpackage sources (nvidia-open) +%global _kmod_phase prep +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-PREP-ANCHOR — do not remove (kmod overlays chain here) %build %{log_msg "Start of build stage"} @@ -3377,6 +3394,13 @@ find Documentation -type d | xargs chmod u+w %{log_msg "end install docs"} %endif +# AZL: Build kmod subpackage modules (nvidia-open) +%global _kmod_phase build +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-BUILD-ANCHOR — do not remove (kmod overlays chain here) + # Module signing (modsign) # # This must be run _after_ find-debuginfo.sh runs, otherwise that will strip @@ -3877,6 +3901,14 @@ find -type f ! -executable -exec install -D -m644 {} %{buildroot}%{_libexecdir}/ popd %endif +### +# AZL: Install kmod subpackage files (nvidia-open) +%global _kmod_phase install +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-INSTALL-ANCHOR — do not remove (kmod overlays chain here) + ### ### clean ### @@ -4538,6 +4570,13 @@ fi\ # and build. # # + +# AZL: kmod subpackage file lists and scriptlets (nvidia-open) +%global _kmod_phase files +%global _kmod_name nvidia-open +%include %{_sourcedir}/kmod-nvidia-open.inc + +# AZL-KMOD-FILES-ANCHOR — do not remove (kmod overlays chain here) %changelog * Thu Feb 19 2026 Augusto Caringi [6.18.13-0] - Linux v6.18.13 diff --git a/specs/k/kernel/kmod-nvidia-open-modprobe.conf b/specs/k/kernel/kmod-nvidia-open-modprobe.conf new file mode 100644 index 00000000000..5dded2d82d0 --- /dev/null +++ b/specs/k/kernel/kmod-nvidia-open-modprobe.conf @@ -0,0 +1,4 @@ +# kmod-nvidia-open modprobe configuration +# Blacklist nouveau to prevent conflicts with NVIDIA open kernel modules +blacklist nouveau +options nouveau modeset=0 diff --git a/specs/k/kernel/kmod-nvidia-open.inc b/specs/k/kernel/kmod-nvidia-open.inc new file mode 100644 index 00000000000..8e861753aab --- /dev/null +++ b/specs/k/kernel/kmod-nvidia-open.inc @@ -0,0 +1,143 @@ +# kmod-nvidia-open.inc — NVIDIA open GPU kernel module subpackage +# +# Phases: package, prep, build, install, files +# Activated by: setting _kmod_phase global + include from kernel.comp.toml overlays +# +# Requires these defines/sources in kernel.spec (injected via comp.toml overlays): +# nvidia_open_version — NVIDIA driver version (e.g. 595.58.03) +# SOURCE6000 — open-gpu-kernel-modules tarball +# SOURCE6001 — kmod-nvidia-open-modprobe.conf + +# ========================================================================= +# Phase: package — subpackage declaration +# ========================================================================= +%if "%{_kmod_phase}" == "package" && %{with_up_base} + +%ifarch x86_64 aarch64 +%package -n kmod-%{_kmod_name}-%{nvidia_open_version} +Summary: NVIDIA open GPU kernel modules (driver %{nvidia_open_version}) +AutoReq: no +# NOTE: Version is inherited from kernel (%{version}), NOT nvidia_open_version. +# Track the actual NVIDIA driver version via Provides for dependency resolution. +Provides: nvidia-open-kmod-version = %{nvidia_open_version} +provides: nvidia-kmod = %{nvidia_open_version} +Provides: kmod-%{_kmod_name} = %{version}-%{release} +# Mark this kmod as install-only so multiple versions can coexist alongside +# their matching kernels (dnf/dnf5 default installonlypkgs includes the +# 'installonlypkg(kernel-module)' token). +Provides: installonlypkg(kernel-module) +Requires: %{name}-core-uname-r = %{KVERREL} +Requires(post): kmod +Requires(postun): kmod +Conflicts: nvidia-closed-kmod + +%description -n kmod-%{_kmod_name}-%{nvidia_open_version} +Open-source NVIDIA GPU kernel modules (driver version %{nvidia_open_version}) +built from the official NVIDIA/open-gpu-kernel-modules repository for +kernel %{KVERREL}. + +These modules support CUDA workloads on NVIDIA GPUs (Turing and later). + +Each kernel version produces a separate kmod package +(kmod-nvidia-open--) so that multiple kernel versions +can coexist with their own NVIDIA modules. +Use 'Requires: nvidia-open-kmod-version = %{nvidia_open_version}' to depend on a +specific NVIDIA driver version, or 'Requires: kmod-nvidia-open' for any version. +%endif + +%endif + +# ========================================================================= +# Phase: prep — extract NVIDIA source tarball +# ========================================================================= +%if "%{_kmod_phase}" == "prep" && %{with_up_base} + +%ifarch x86_64 aarch64 +pushd %{_builddir} +tar -xf %{SOURCE6000} +popd +%endif + +%endif + +# ========================================================================= +# Phase: build — compile NVIDIA kernel modules +# ========================================================================= +%if "%{_kmod_phase}" == "build" && %{with_up_base} + +%ifarch x86_64 aarch64 +%{log_msg "Building NVIDIA open GPU kernel modules %{nvidia_open_version} for %{KVERREL}"} +pushd %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version} +# Unset LDFLAGS — NVIDIA kbuild invokes ld directly, not via gcc +unset LDFLAGS +# IGNORE_CC_MISMATCH=1: kmod is a kernel subpackage built in the same +# mock chroot with the same GCC. The flag suppresses NVIDIA's compiler-string +# comparison which can false-positive on path or version-string formatting +# differences even when the toolchain is identical. +# CONFIG_OBJTOOL_WERROR=: NVIDIA's precompiled binary blob (nv-kernel.o_binary) +# contains bare 'ret' instructions that fail objtool's rethunk validation when +# CONFIG_MITIGATION_RETHUNK=y. Clearing this config on the make command line +# propagates through GNU make's recursive $(MAKE) into kbuild, turning the +# objtool errors into non-fatal warnings. The kernel itself is already fully +# built and validated with objtool by this point. +# Ref: https://forums.developer.nvidia.com/t/360610 +make %{?_smp_mflags} modules \ + KERNEL_UNAME="%{KVERREL}" \ + SYSSRC="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \ + SYSOUT="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \ + IGNORE_CC_MISMATCH=1 \ + IGNORE_XEN_PRESENCE=1 \ + IGNORE_PREEMPT_RT_PRESENCE=1 \ + NV_EXCLUDE_BUILD_MODULES="" \ + CONFIG_OBJTOOL_WERROR= +popd +%endif + +%endif + +# ========================================================================= +# Phase: install — install modules, config, and license +# ========================================================================= +%if "%{_kmod_phase}" == "install" && %{with_up_base} + +%ifarch x86_64 aarch64 +%{log_msg "Installing NVIDIA open GPU kernel modules for %{KVERREL}"} +install -d %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia +for mod in nvidia nvidia-modeset nvidia-drm nvidia-uvm nvidia-peermem; do + ko="%{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/kernel-open/${mod}.ko" + install -m 0644 "${ko}" %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia/ +done +# Install modprobe config to blacklist conflicting modules. Lives under +# %{_modprobedir} (/usr/lib/modprobe.d) — vendor-supplied config, not +# admin-editable, so it is owned by the package without %config(noreplace). +install -D -m 0644 %{SOURCE6001} %{buildroot}%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf +# Install NVIDIA license file +install -D -m 0644 %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/COPYING \ + %{buildroot}%{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING +%endif + +%endif + +# ========================================================================= +# Phase: files — scriptlets and file list +# ========================================================================= +%if "%{_kmod_phase}" == "files" && %{with_up_base} + +%ifarch x86_64 aarch64 +%post -n kmod-%{_kmod_name}-%{nvidia_open_version} +%{_sbindir}/depmod -a %{KVERREL} || : + +%postun -n kmod-%{_kmod_name}-%{nvidia_open_version} +%{_sbindir}/depmod -a %{KVERREL} || : + +%files -n kmod-%{_kmod_name}-%{nvidia_open_version} +%license %{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING +/lib/modules/%{KVERREL}/extra/nvidia/nvidia.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-modeset.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-drm.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-uvm.ko.%{compext} +/lib/modules/%{KVERREL}/extra/nvidia/nvidia-peermem.ko.%{compext} +%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf +%endif + +%endif diff --git a/specs/k/kernel/sources b/specs/k/kernel/sources index c28e276d013..84ea812b65b 100644 --- a/specs/k/kernel/sources +++ b/specs/k/kernel/sources @@ -2,3 +2,4 @@ SHA512 (linux-6.18.13.tar.xz) = a1d1b27391ed55ae2b17dd25841037d3399e4d87900eb098 SHA512 (kernel-abi-stablelists-6.18.13.tar.xz) = 69bbcdd86ae7999b19de306c29bc5cef442e309a8b033900c10a206a97d61b8b4e6d7c6baf6d356daf14e85766bd6a31120b54cfd1eb1c773450e44bae5d2d9b SHA512 (kernel-kabi-dw-6.18.13.tar.xz) = 6473ea636d813e602a59d7332255c4b4597032501a2ed0507985800500451065618a0b6909663e3dc8db2b75c6f4ba10d498dbc41a3b42758cae38f30ca13115 SHA512 (kernel-6.18.31.1.tar.gz) = 1bf684812ff3fc38974dc99b3e2309cb46dc5af93ac794e79a4a4f3dd17debfadb14510aeaaa7fa2d4c6254876a9f8bc67b900a1951c8dda5d94e5f5028a7557 +SHA512 (open-gpu-kernel-modules-595.58.03.tar.gz) = a422b6935209d590f57fa6766f59bb207d9130f8a6777af9245c4ff8cd0f4c4ccef4602a0b26d543e1e8efba24241180992fdb749ea4e5d2aa5218a584b85101