Skip to content

Commit 455e0c5

Browse files
committed
feat(kernel): add kmod-nvidia-open subpackage framework
1 parent 1d68dfa commit 455e0c5

9 files changed

Lines changed: 513 additions & 3 deletions

File tree

base/comps/kernel/kernel.comp.toml

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ without = [
1414

1515
[components.kernel.build.defines]
1616
# RPM release number for the Azure Linux kernel package
17-
azl_pkgrelease = "3"
17+
azl_pkgrelease = "4"
1818
# 4th version component from the AZL kernel source (6.18.31.1). Included in specrelease so it appears
1919
# in the RPM Release tag, uname -r, and /lib/modules/ path (e.g. 6.18.31-1.1.azl4.aarch64).
2020
kextraversion = "1"
21+
# NVIDIA open GPU kernel module version (built as a subpackage of the kernel)
22+
nvidia_open_version = "595.58.03"
2123

2224
# Download the source tarball from the AzureLinux kernel repo
2325
[[components.kernel.source-files]]
@@ -26,6 +28,13 @@ hash = "1bf684812ff3fc38974dc99b3e2309cb46dc5af93ac794e79a4a4f3dd17debfadb14510a
2628
hash-type = "SHA512"
2729
origin = { type = "download", uri = "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/azl4/6.18.31.1.tar.gz" }
2830

31+
# Download the NVIDIA open GPU kernel module source tarball
32+
[[components.kernel.source-files]]
33+
filename = "open-gpu-kernel-modules-595.58.03.tar.gz"
34+
hash = "a422b6935209d590f57fa6766f59bb207d9130f8a6777af9245c4ff8cd0f4c4ccef4602a0b26d543e1e8efba24241180992fdb749ea4e5d2aa5218a584b85101"
35+
hash-type = "SHA512"
36+
origin = { type = "download", uri = "https://github.com/NVIDIA/open-gpu-kernel-modules/archive/refs/tags/595.58.03.tar.gz" }
37+
2938
# 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
3039
[[components.kernel.overlays]]
3140
description = "Set specrpmversion to 6.18.31"
@@ -164,3 +173,169 @@ lines = [
164173
"cd ../..",
165174
"%endif",
166175
]
176+
177+
# ============================================================================
178+
# kmod subpackage framework — modular kmod builds alongside the kernel
179+
#
180+
# This framework allows building out-of-tree kernel modules as subpackages of
181+
# the kernel RPM. Each kmod is defined in its own .inc file (e.g.
182+
# kmod-nvidia-open.inc) with phase-gated sections that run at each RPM build
183+
# phase (%description, %prep, %build, %install, %files).
184+
#
185+
# To add a new kmod:
186+
# 1. Create kmod-<name>.inc with phase-gated sections
187+
# 2. Add file-add overlays for .inc and any extra source files
188+
# 3. Add spec-insert-tag overlays to register sources (Source6xxx range)
189+
# 4. Add spec-search-replace overlays targeting the AZL-KMOD-*-ANCHOR
190+
# sentinels for each phase (the anchor survives replacement so the
191+
# next kmod can chain onto it)
192+
# ============================================================================
193+
194+
# --- kmod-nvidia-open: source file registration ---
195+
# Registers the NVIDIA open GPU kernel module sources and configuration files.
196+
# Source numbers 6000-6099 are reserved for nvidia-open.
197+
198+
[[components.kernel.overlays]]
199+
description = "Add kmod-nvidia-open.inc subpackage definition to sources"
200+
type = "file-add"
201+
file = "kmod-nvidia-open.inc"
202+
source = "kmod-nvidia-open.inc"
203+
204+
[[components.kernel.overlays]]
205+
description = "Add NVIDIA modprobe config file for kmod-nvidia-open subpackage"
206+
type = "file-add"
207+
file = "kmod-nvidia-open-modprobe.conf"
208+
source = "kmod-nvidia-open-modprobe.conf"
209+
210+
[[components.kernel.overlays]]
211+
description = "Register NVIDIA open-gpu-kernel-modules tarball as Source6000"
212+
type = "spec-insert-tag"
213+
tag = "Source6000"
214+
value = "open-gpu-kernel-modules-%{nvidia_open_version}.tar.gz"
215+
216+
[[components.kernel.overlays]]
217+
description = "Register NVIDIA modprobe config as Source6001"
218+
type = "spec-insert-tag"
219+
tag = "Source6001"
220+
value = "kmod-nvidia-open-modprobe.conf"
221+
222+
[[components.kernel.overlays]]
223+
description = "Register kmod-nvidia-open.inc as Source6002"
224+
type = "spec-insert-tag"
225+
tag = "Source6002"
226+
value = "kmod-nvidia-open.inc"
227+
228+
# --- kmod framework: phase anchor insertion ---
229+
# These overlays insert unique sentinel comments at unconditional locations in
230+
# the upstream spec. Per-kmod overlays below target these sentinels with
231+
# spec-search-replace, replacing SENTINEL with <kmod include> + SENTINEL so
232+
# each sentinel survives for the next kmod to chain onto.
233+
234+
[[components.kernel.overlays]]
235+
description = "Insert kmod package anchor after main %description — unconditional location for kmod subpackage declarations"
236+
type = "spec-append-lines"
237+
section = "%description"
238+
lines = [
239+
"",
240+
"# AZL-KMOD-PACKAGE-ANCHOR — do not remove (kmod overlays chain here)",
241+
]
242+
243+
[[components.kernel.overlays]]
244+
description = "Insert kmod prep anchor at end of %prep — unconditional location for kmod source extraction"
245+
type = "spec-append-lines"
246+
section = "%prep"
247+
lines = [
248+
"",
249+
"# AZL-KMOD-PREP-ANCHOR — do not remove (kmod overlays chain here)",
250+
]
251+
252+
[[components.kernel.overlays]]
253+
description = "Insert kmod build anchor before modsign macros — unconditional location at the end of the active %build body"
254+
type = "spec-search-replace"
255+
regex = '# Module signing \(modsign\)'
256+
replacement = """# AZL-KMOD-BUILD-ANCHOR — do not remove (kmod overlays chain here)
257+
258+
# Module signing (modsign)"""
259+
260+
[[components.kernel.overlays]]
261+
description = "Insert kmod install anchor before ### clean — unconditional location at the end of the active %install body"
262+
type = "spec-search-replace"
263+
regex = '### clean'
264+
replacement = """# AZL-KMOD-INSTALL-ANCHOR — do not remove (kmod overlays chain here)
265+
266+
###
267+
### clean"""
268+
269+
[[components.kernel.overlays]]
270+
description = "Insert kmod files anchor after %files modules-extra-matched — unconditional location for kmod file lists"
271+
type = "spec-append-lines"
272+
section = "%files"
273+
package = "modules-extra-matched"
274+
lines = [
275+
"",
276+
"# AZL-KMOD-FILES-ANCHOR — do not remove (kmod overlays chain here)",
277+
]
278+
279+
# --- kmod-nvidia-open: phase injection ---
280+
# RPM %include is a preprocessor directive — it must appear directly in the spec
281+
# text (not inside a %define macro). Each phase sets _kmod_phase and _kmod_name
282+
# globals, then includes the kmod .inc file. The .inc file's %if guards select
283+
# the correct section for that phase.
284+
#
285+
# To add a new kmod: duplicate the phase blocks below, changing _kmod_name and
286+
# the %include path. Each block targets the framework anchor for its phase.
287+
288+
[[components.kernel.overlays]]
289+
description = "Run kmod 'package' phase at package anchor — declares kmod subpackages"
290+
type = "spec-search-replace"
291+
regex = '# AZL-KMOD-PACKAGE-ANCHOR'
292+
replacement = """# AZL: kmod subpackage declarations (nvidia-open)
293+
%global _kmod_phase package
294+
%global _kmod_name nvidia-open
295+
%include %{_sourcedir}/kmod-nvidia-open.inc
296+
297+
# AZL-KMOD-PACKAGE-ANCHOR"""
298+
299+
[[components.kernel.overlays]]
300+
description = "Run kmod 'prep' phase at prep anchor — extracts kmod source tarballs"
301+
type = "spec-search-replace"
302+
regex = '# AZL-KMOD-PREP-ANCHOR'
303+
replacement = """# AZL: Prepare kmod subpackage sources (nvidia-open)
304+
%global _kmod_phase prep
305+
%global _kmod_name nvidia-open
306+
%include %{_sourcedir}/kmod-nvidia-open.inc
307+
308+
# AZL-KMOD-PREP-ANCHOR"""
309+
310+
[[components.kernel.overlays]]
311+
description = "Run kmod 'build' phase at build anchor — compiles NVIDIA modules against the just-built kernel"
312+
type = "spec-search-replace"
313+
regex = '# AZL-KMOD-BUILD-ANCHOR'
314+
replacement = """# AZL: Build kmod subpackage modules (nvidia-open)
315+
%global _kmod_phase build
316+
%global _kmod_name nvidia-open
317+
%include %{_sourcedir}/kmod-nvidia-open.inc
318+
319+
# AZL-KMOD-BUILD-ANCHOR"""
320+
321+
[[components.kernel.overlays]]
322+
description = "Run kmod 'install' phase at install anchor — installs NVIDIA modules, configs, and licenses"
323+
type = "spec-search-replace"
324+
regex = '# AZL-KMOD-INSTALL-ANCHOR'
325+
replacement = """# AZL: Install kmod subpackage files (nvidia-open)
326+
%global _kmod_phase install
327+
%global _kmod_name nvidia-open
328+
%include %{_sourcedir}/kmod-nvidia-open.inc
329+
330+
# AZL-KMOD-INSTALL-ANCHOR"""
331+
332+
[[components.kernel.overlays]]
333+
description = "Run kmod 'files' phase at files anchor — adds %post/%postun/%files for NVIDIA kmod subpackage"
334+
type = "spec-search-replace"
335+
regex = '# AZL-KMOD-FILES-ANCHOR'
336+
replacement = """# AZL: kmod subpackage file lists and scriptlets (nvidia-open)
337+
%global _kmod_phase files
338+
%global _kmod_name nvidia-open
339+
%include %{_sourcedir}/kmod-nvidia-open.inc
340+
341+
# AZL-KMOD-FILES-ANCHOR"""
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# kmod-nvidia-open modprobe configuration
2+
# Blacklist nouveau to prevent conflicts with NVIDIA open kernel modules
3+
blacklist nouveau
4+
options nouveau modeset=0
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# kmod-nvidia-open.inc — NVIDIA open GPU kernel module subpackage
2+
#
3+
# Phases: package, prep, build, install, files
4+
# Activated by: setting _kmod_phase global + include from kernel.comp.toml overlays
5+
#
6+
# Requires these defines/sources in kernel.spec (injected via comp.toml overlays):
7+
# nvidia_open_version — NVIDIA driver version (e.g. 595.58.03)
8+
# SOURCE6000 — open-gpu-kernel-modules tarball
9+
# SOURCE6001 — kmod-nvidia-open-modprobe.conf
10+
11+
# =========================================================================
12+
# Phase: package — subpackage declaration
13+
# =========================================================================
14+
%if "%{_kmod_phase}" == "package" && %{with_up_base}
15+
16+
%ifarch x86_64 aarch64
17+
%package -n kmod-%{_kmod_name}-%{nvidia_open_version}
18+
Summary: NVIDIA open GPU kernel modules (driver %{nvidia_open_version})
19+
AutoReq: no
20+
# NOTE: Version is inherited from kernel (%{version}), NOT nvidia_open_version.
21+
# Track the actual NVIDIA driver version via Provides for dependency resolution.
22+
Provides: nvidia-open-kmod-version = %{nvidia_open_version}
23+
provides: nvidia-kmod = %{nvidia_open_version}
24+
Provides: kmod-%{_kmod_name} = %{version}-%{release}
25+
# Mark this kmod as install-only so multiple versions can coexist alongside
26+
# their matching kernels (dnf/dnf5 default installonlypkgs includes the
27+
# 'installonlypkg(kernel-module)' token).
28+
Provides: installonlypkg(kernel-module)
29+
Requires: %{name}-core-uname-r = %{KVERREL}
30+
Requires(post): kmod
31+
Requires(postun): kmod
32+
Conflicts: nvidia-closed-kmod
33+
34+
%description -n kmod-%{_kmod_name}-%{nvidia_open_version}
35+
Open-source NVIDIA GPU kernel modules (driver version %{nvidia_open_version})
36+
built from the official NVIDIA/open-gpu-kernel-modules repository for
37+
kernel %{KVERREL}.
38+
39+
These modules support CUDA workloads on NVIDIA GPUs (Turing and later).
40+
41+
Each kernel version produces a separate kmod package
42+
(kmod-nvidia-open-<nvidia_driver_version>-<KVERREL>) so that multiple kernel versions
43+
can coexist with their own NVIDIA modules.
44+
Use 'Requires: nvidia-open-kmod-version = %{nvidia_open_version}' to depend on a
45+
specific NVIDIA driver version, or 'Requires: kmod-nvidia-open' for any version.
46+
%endif
47+
48+
%endif
49+
50+
# =========================================================================
51+
# Phase: prep — extract NVIDIA source tarball
52+
# =========================================================================
53+
%if "%{_kmod_phase}" == "prep" && %{with_up_base}
54+
55+
%ifarch x86_64 aarch64
56+
pushd %{_builddir}
57+
tar -xf %{SOURCE6000}
58+
popd
59+
%endif
60+
61+
%endif
62+
63+
# =========================================================================
64+
# Phase: build — compile NVIDIA kernel modules
65+
# =========================================================================
66+
%if "%{_kmod_phase}" == "build" && %{with_up_base}
67+
68+
%ifarch x86_64 aarch64
69+
%{log_msg "Building NVIDIA open GPU kernel modules %{nvidia_open_version} for %{KVERREL}"}
70+
pushd %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}
71+
# Unset LDFLAGS — NVIDIA kbuild invokes ld directly, not via gcc
72+
unset LDFLAGS
73+
# IGNORE_CC_MISMATCH=1: kmod is a kernel subpackage built in the same
74+
# mock chroot with the same GCC. The flag suppresses NVIDIA's compiler-string
75+
# comparison which can false-positive on path or version-string formatting
76+
# differences even when the toolchain is identical.
77+
# CONFIG_OBJTOOL_WERROR=: NVIDIA's precompiled binary blob (nv-kernel.o_binary)
78+
# contains bare 'ret' instructions that fail objtool's rethunk validation when
79+
# CONFIG_MITIGATION_RETHUNK=y. Clearing this config on the make command line
80+
# propagates through GNU make's recursive $(MAKE) into kbuild, turning the
81+
# objtool errors into non-fatal warnings. The kernel itself is already fully
82+
# built and validated with objtool by this point.
83+
# Ref: https://forums.developer.nvidia.com/t/360610
84+
make %{?_smp_mflags} modules \
85+
KERNEL_UNAME="%{KVERREL}" \
86+
SYSSRC="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \
87+
SYSOUT="%{_builddir}/kernel-%{tarfile_release}/linux-%{KVERREL}" \
88+
IGNORE_CC_MISMATCH=1 \
89+
IGNORE_XEN_PRESENCE=1 \
90+
IGNORE_PREEMPT_RT_PRESENCE=1 \
91+
NV_EXCLUDE_BUILD_MODULES="" \
92+
CONFIG_OBJTOOL_WERROR=
93+
popd
94+
%endif
95+
96+
%endif
97+
98+
# =========================================================================
99+
# Phase: install — install modules, config, and license
100+
# =========================================================================
101+
%if "%{_kmod_phase}" == "install" && %{with_up_base}
102+
103+
%ifarch x86_64 aarch64
104+
%{log_msg "Installing NVIDIA open GPU kernel modules for %{KVERREL}"}
105+
install -d %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia
106+
for mod in nvidia nvidia-modeset nvidia-drm nvidia-uvm nvidia-peermem; do
107+
ko="%{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/kernel-open/${mod}.ko"
108+
install -m 0644 "${ko}" %{buildroot}/lib/modules/%{KVERREL}/extra/nvidia/
109+
done
110+
# Install modprobe config to blacklist conflicting modules. Lives under
111+
# %{_modprobedir} (/usr/lib/modprobe.d) — vendor-supplied config, not
112+
# admin-editable, so it is owned by the package without %config(noreplace).
113+
install -D -m 0644 %{SOURCE6001} %{buildroot}%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf
114+
# Install NVIDIA license file
115+
install -D -m 0644 %{_builddir}/open-gpu-kernel-modules-%{nvidia_open_version}/COPYING \
116+
%{buildroot}%{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING
117+
%endif
118+
119+
%endif
120+
121+
# =========================================================================
122+
# Phase: files — scriptlets and file list
123+
# =========================================================================
124+
%if "%{_kmod_phase}" == "files" && %{with_up_base}
125+
126+
%ifarch x86_64 aarch64
127+
%post -n kmod-%{_kmod_name}-%{nvidia_open_version}
128+
%{_sbindir}/depmod -a %{KVERREL} || :
129+
130+
%postun -n kmod-%{_kmod_name}-%{nvidia_open_version}
131+
%{_sbindir}/depmod -a %{KVERREL} || :
132+
133+
%files -n kmod-%{_kmod_name}-%{nvidia_open_version}
134+
%license %{_datadir}/licenses/kmod-%{_kmod_name}-%{nvidia_open_version}/COPYING
135+
/lib/modules/%{KVERREL}/extra/nvidia/nvidia.ko.%{compext}
136+
/lib/modules/%{KVERREL}/extra/nvidia/nvidia-modeset.ko.%{compext}
137+
/lib/modules/%{KVERREL}/extra/nvidia/nvidia-drm.ko.%{compext}
138+
/lib/modules/%{KVERREL}/extra/nvidia/nvidia-uvm.ko.%{compext}
139+
/lib/modules/%{KVERREL}/extra/nvidia/nvidia-peermem.ko.%{compext}
140+
%{_modprobedir}/kmod-%{_kmod_name}-%{nvidia_open_version}.conf
141+
%endif
142+
143+
%endif

locks/kernel.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
version = 1
33
import-commit = '5271a1b047ef402ddee40242e02eda23fc273044'
44
upstream-commit = '5271a1b047ef402ddee40242e02eda23fc273044'
5-
input-fingerprint = 'sha256:3712f583962a018083cfb0e5582c296fbed51633b1bbe0e92a940e5dd3653549'
5+
input-fingerprint = 'sha256:bc03956c16315556bb81a4b7557cf78a94a8f6b352bdb0de97af7227ca2bd0b5'
66
resolution-input-hash = 'sha256:466421704711c4fd3c71f0b2ed715a0e61d49e3e26f3a2637fee755795849c8e'

specs/k/kernel/kernel.azl.macros

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
# Do not edit manually; changes will be overwritten.
33
%_without_debug 1
44
%_without_selftests 1
5-
%azl_pkgrelease 3
5+
%azl_pkgrelease 4
66
%kextraversion 1
7+
%nvidia_open_version 595.58.03

0 commit comments

Comments
 (0)