Skip to content

Commit d7a0f3b

Browse files
ellie-dichristopherco
authored andcommitted
feat(kernel): add kmod-nvidia-open subpackage framework
1 parent ebdfae9 commit d7a0f3b

9 files changed

Lines changed: 528 additions & 4 deletions

File tree

base/comps/kernel/kernel.comp.toml

Lines changed: 178 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ without = [
1414

1515
[components.kernel.build.defines]
1616
# RPM release number for the Azure Linux kernel package
17-
azl_pkgrelease = "1"
17+
azl_pkgrelease = "2"
1818
# 4th version component from the AZL kernel source (6.18.29.1). Included in specrelease so it appears
19-
# in the RPM Release tag, uname -r, and /lib/modules/ path (e.g. 6.18.29-1.1.azl4.aarch64).
19+
# in the RPM Release tag, uname -r, and /lib/modules/ path (e.g. 6.18.29-1.2.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"
23+
nvidia_open_branch = "595"
2124

2225
# Download the source tarball from the AzureLinux kernel repo
2326
[[components.kernel.source-files]]
@@ -26,6 +29,13 @@ hash = "9c71dec3ea3897107c176c89014134ab31aba0c3a669af549993e1134cf2896c7d6f6b75
2629
hash-type = "SHA512"
2730
origin = { type = "download", uri = "https://github.com/microsoft/CBL-Mariner-Linux-Kernel/archive/rolling-lts/azl4/6.18.29.1.tar.gz" }
2831

32+
# Download the NVIDIA open GPU kernel module source tarball
33+
[[components.kernel.source-files]]
34+
filename = "open-gpu-kernel-modules-595.58.03.tar.gz"
35+
hash = "e0c4659ddf15e4f4e19cee05b49f88c9ba08ef3add0dfe08249798f58d0fe75e"
36+
hash-type = "SHA256"
37+
origin = { type = "download", uri = "https://github.com/NVIDIA/open-gpu-kernel-modules/archive/refs/tags/595.58.03.tar.gz" }
38+
2939
# 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
3040
[[components.kernel.overlays]]
3141
description = "Set specrpmversion to 6.18.29"
@@ -164,3 +174,169 @@ lines = [
164174
"cd ../..",
165175
"%endif",
166176
]
177+
178+
# ============================================================================
179+
# kmod subpackage framework — modular kmod builds alongside the kernel
180+
#
181+
# This framework allows building out-of-tree kernel modules as subpackages of
182+
# the kernel RPM. Each kmod is defined in its own .inc file (e.g.
183+
# kmod-nvidia-open.inc) with phase-gated sections that run at each RPM build
184+
# phase (%description, %prep, %build, %install, %files).
185+
#
186+
# To add a new kmod:
187+
# 1. Create kmod-<name>.inc with phase-gated sections
188+
# 2. Add file-add overlays for .inc and any extra source files
189+
# 3. Add spec-insert-tag overlays to register sources (Source6xxx range)
190+
# 4. Add spec-search-replace overlays targeting the AZL-KMOD-*-ANCHOR
191+
# sentinels for each phase (the anchor survives replacement so the
192+
# next kmod can chain onto it)
193+
# ============================================================================
194+
195+
# --- kmod-nvidia-open: source file registration ---
196+
# Registers the NVIDIA open GPU kernel module sources and configuration files.
197+
# Source numbers 6000-6099 are reserved for nvidia-open.
198+
199+
[[components.kernel.overlays]]
200+
description = "Add kmod-nvidia-open.inc subpackage definition to sources"
201+
type = "file-add"
202+
file = "kmod-nvidia-open.inc"
203+
source = "kmod-nvidia-open.inc"
204+
205+
[[components.kernel.overlays]]
206+
description = "Add NVIDIA modprobe config file for kmod-nvidia-open subpackage"
207+
type = "file-add"
208+
file = "kmod-nvidia-open-modprobe.conf"
209+
source = "kmod-nvidia-open-modprobe.conf"
210+
211+
[[components.kernel.overlays]]
212+
description = "Register NVIDIA open-gpu-kernel-modules tarball as Source6000"
213+
type = "spec-insert-tag"
214+
tag = "Source6000"
215+
value = "open-gpu-kernel-modules-%{nvidia_open_version}.tar.gz"
216+
217+
[[components.kernel.overlays]]
218+
description = "Register NVIDIA modprobe config as Source6001"
219+
type = "spec-insert-tag"
220+
tag = "Source6001"
221+
value = "kmod-nvidia-open-modprobe.conf"
222+
223+
[[components.kernel.overlays]]
224+
description = "Register kmod-nvidia-open.inc as Source6002"
225+
type = "spec-insert-tag"
226+
tag = "Source6002"
227+
value = "kmod-nvidia-open.inc"
228+
229+
# --- kmod framework: phase anchor insertion ---
230+
# These overlays insert unique sentinel comments at unconditional locations in
231+
# the upstream spec. Per-kmod overlays below target these sentinels with
232+
# spec-search-replace, replacing SENTINEL with <kmod include> + SENTINEL so
233+
# each sentinel survives for the next kmod to chain onto.
234+
235+
[[components.kernel.overlays]]
236+
description = "Insert kmod package anchor after main %description — unconditional location for kmod subpackage declarations"
237+
type = "spec-append-lines"
238+
section = "%description"
239+
lines = [
240+
"",
241+
"# AZL-KMOD-PACKAGE-ANCHOR — do not remove (kmod overlays chain here)",
242+
]
243+
244+
[[components.kernel.overlays]]
245+
description = "Insert kmod prep anchor at end of %prep — unconditional location for kmod source extraction"
246+
type = "spec-append-lines"
247+
section = "%prep"
248+
lines = [
249+
"",
250+
"# AZL-KMOD-PREP-ANCHOR — do not remove (kmod overlays chain here)",
251+
]
252+
253+
[[components.kernel.overlays]]
254+
description = "Insert kmod build anchor before modsign macros — unconditional location at the end of the active %build body"
255+
type = "spec-search-replace"
256+
regex = '# Module signing \(modsign\)'
257+
replacement = """# AZL-KMOD-BUILD-ANCHOR — do not remove (kmod overlays chain here)
258+
259+
# Module signing (modsign)"""
260+
261+
[[components.kernel.overlays]]
262+
description = "Insert kmod install anchor before ### clean — unconditional location at the end of the active %install body"
263+
type = "spec-search-replace"
264+
regex = '### clean'
265+
replacement = """# AZL-KMOD-INSTALL-ANCHOR — do not remove (kmod overlays chain here)
266+
267+
###
268+
### clean"""
269+
270+
[[components.kernel.overlays]]
271+
description = "Insert kmod files anchor after %files modules-extra-matched — unconditional location for kmod file lists"
272+
type = "spec-append-lines"
273+
section = "%files"
274+
package = "modules-extra-matched"
275+
lines = [
276+
"",
277+
"# AZL-KMOD-FILES-ANCHOR — do not remove (kmod overlays chain here)",
278+
]
279+
280+
# --- kmod-nvidia-open: phase injection ---
281+
# RPM %include is a preprocessor directive — it must appear directly in the spec
282+
# text (not inside a %define macro). Each phase sets _kmod_phase and _kmod_name
283+
# globals, then includes the kmod .inc file. The .inc file's %if guards select
284+
# the correct section for that phase.
285+
#
286+
# To add a new kmod: duplicate the phase blocks below, changing _kmod_name and
287+
# the %include path. Each block targets the framework anchor for its phase.
288+
289+
[[components.kernel.overlays]]
290+
description = "Run kmod 'package' phase at package anchor — declares kmod subpackages"
291+
type = "spec-search-replace"
292+
regex = '# AZL-KMOD-PACKAGE-ANCHOR'
293+
replacement = """# AZL: kmod subpackage declarations (nvidia-open)
294+
%global _kmod_phase package
295+
%global _kmod_name nvidia-open
296+
%include %{_sourcedir}/kmod-nvidia-open.inc
297+
298+
# AZL-KMOD-PACKAGE-ANCHOR"""
299+
300+
[[components.kernel.overlays]]
301+
description = "Run kmod 'prep' phase at prep anchor — extracts kmod source tarballs"
302+
type = "spec-search-replace"
303+
regex = '# AZL-KMOD-PREP-ANCHOR'
304+
replacement = """# AZL: Prepare kmod subpackage sources (nvidia-open)
305+
%global _kmod_phase prep
306+
%global _kmod_name nvidia-open
307+
%include %{_sourcedir}/kmod-nvidia-open.inc
308+
309+
# AZL-KMOD-PREP-ANCHOR"""
310+
311+
[[components.kernel.overlays]]
312+
description = "Run kmod 'build' phase at build anchor — compiles NVIDIA modules against the just-built kernel"
313+
type = "spec-search-replace"
314+
regex = '# AZL-KMOD-BUILD-ANCHOR'
315+
replacement = """# AZL: Build kmod subpackage modules (nvidia-open)
316+
%global _kmod_phase build
317+
%global _kmod_name nvidia-open
318+
%include %{_sourcedir}/kmod-nvidia-open.inc
319+
320+
# AZL-KMOD-BUILD-ANCHOR"""
321+
322+
[[components.kernel.overlays]]
323+
description = "Run kmod 'install' phase at install anchor — installs NVIDIA modules, configs, and licenses"
324+
type = "spec-search-replace"
325+
regex = '# AZL-KMOD-INSTALL-ANCHOR'
326+
replacement = """# AZL: Install kmod subpackage files (nvidia-open)
327+
%global _kmod_phase install
328+
%global _kmod_name nvidia-open
329+
%include %{_sourcedir}/kmod-nvidia-open.inc
330+
331+
# AZL-KMOD-INSTALL-ANCHOR"""
332+
333+
[[components.kernel.overlays]]
334+
description = "Run kmod 'files' phase at files anchor — adds %post/%postun/%files for NVIDIA kmod subpackage"
335+
type = "spec-search-replace"
336+
regex = '# AZL-KMOD-FILES-ANCHOR'
337+
replacement = """# AZL: kmod subpackage file lists and scriptlets (nvidia-open)
338+
%global _kmod_phase files
339+
%global _kmod_name nvidia-open
340+
%include %{_sourcedir}/kmod-nvidia-open.inc
341+
342+
# 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

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:c4c7b3f134a8c08404a7ba7337df797dd45b5b1bbd3a8a5ab08f9896c3eafd86'
5+
input-fingerprint = 'sha256:f292b1b40de5b622186952a120f8824b27b5e1d8c5fcca14a91ed67bf5e073f5'
66
resolution-input-hash = 'sha256:466421704711c4fd3c71f0b2ed715a0e61d49e3e26f3a2637fee755795849c8e'

specs/k/kernel/kernel.azl.macros

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

0 commit comments

Comments
 (0)