Skip to content

Commit e71f493

Browse files
committed
feat(kernel): add kmod-nvidia-open subpackage framework
1 parent e57cc92 commit e71f493

3 files changed

Lines changed: 330 additions & 1 deletion

File tree

base/comps/kernel/kernel.comp.toml

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

1515
[components.kernel.build.defines]
1616
# RPM release number for the Azure Linux kernel package
17-
azl_pkgrelease = "18"
17+
azl_pkgrelease = "19"
1818
# 4th version component from the AZL kernel source (6.18.5.1). Included in specrelease so it appears
1919
# in the RPM Release tag, uname -r, and /lib/modules/ path (e.g. 6.18.5-1.3.azl4.aarch64).
2020
kextraversion = "1"
2121
# CBL-Mariner branch number (used in tarball path)
2222
azurelinux_version = "3"
23+
# NVIDIA open GPU kernel module version (built as a subpackage of the kernel)
24+
nvidia_open_version = "595.58.03"
25+
nvidia_open_branch = "595"
2326

2427
# Download the source tarball from the AzureLinux kernel repo
2528
[[components.kernel.source-files]]
@@ -28,6 +31,13 @@ hash = "0d8c755e02857704eb4c4396657ad30b22b474296233b8681365aeaa2fc16926afe31f55
2831
hash-type = "SHA512"
2932
origin = { type = "download", uri = "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/mariner-3/6.18.5.1.tar.gz" }
3033

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

0 commit comments

Comments
 (0)