Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 176 additions & 1 deletion base/comps/kernel/kernel.comp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Comment thread
ellie-di marked this conversation as resolved.
Comment thread
ellie-di marked this conversation as resolved.

# Download the source tarball from the AzureLinux kernel repo
[[components.kernel.source-files]]
Expand All @@ -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" }
Comment thread
ellie-di marked this conversation as resolved.

# 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"
Expand Down Expand Up @@ -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-<name>.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 <kmod include> + 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"""
4 changes: 4 additions & 0 deletions base/comps/kernel/kmod-nvidia-open-modprobe.conf
Original file line number Diff line number Diff line change
@@ -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
143 changes: 143 additions & 0 deletions base/comps/kernel/kmod-nvidia-open.inc
Original file line number Diff line number Diff line change
@@ -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}
Comment thread
ellie-di marked this conversation as resolved.

%ifarch x86_64 aarch64
%package -n kmod-%{_kmod_name}-%{nvidia_open_version}
Summary: NVIDIA open GPU kernel modules (driver %{nvidia_open_version})
Comment thread
ellie-di marked this conversation as resolved.
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-<nvidia_driver_version>-<KVERREL>) 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
Comment thread
ellie-di marked this conversation as resolved.
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 \
Comment thread
ellie-di marked this conversation as resolved.
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
Comment thread
ellie-di marked this conversation as resolved.
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} || :
Comment thread
ellie-di marked this conversation as resolved.

%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
Loading
Loading