From 854a06b7310a3ba35d817e133d5e31e0873fb0b7 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:40:41 +0000 Subject: [PATCH 01/57] conftest: Fix drm_connector_helper_funcs_mode_valid_has_const_mode_arg The return type is expected to be 'enum drm_mode_status', fix that. Signed-off-by: Mathias Krause --- kernel-open/conftest.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 59f3624d1..6ec4973fc 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -4932,8 +4932,9 @@ compile_test() { CODE=" #include - static int conftest_drm_connector_mode_valid(struct drm_connector *connector, - const struct drm_display_mode *mode) { + static enum drm_mode_status + conftest_drm_connector_mode_valid(struct drm_connector *connector, + const struct drm_display_mode *mode) { return 0; } From e251a50c4dc932df2ab7db1e4176bafdf6ead3fb Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:49:51 +0000 Subject: [PATCH 02/57] nvidia: Fix nvswitch_task_dispatch() prototype nvswitch_task_dispatch() is supposed to be of type nv_q_func_t which expects a void pointer argument. Fix that to make it compatible with strongly type-based CFI implementations like RAP, as found in grsecurity. Signed-off-by: Mathias Krause --- kernel-open/nvidia/linux_nvswitch.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel-open/nvidia/linux_nvswitch.c b/kernel-open/nvidia/linux_nvswitch.c index 015de1ca6..be2e0be70 100644 --- a/kernel-open/nvidia/linux_nvswitch.c +++ b/kernel-open/nvidia/linux_nvswitch.c @@ -259,7 +259,7 @@ struct file_operations ctl_fops = static int nvswitch_initialize_device_interrupt(NVSWITCH_DEV *nvswitch_dev); static void nvswitch_shutdown_device_interrupt(NVSWITCH_DEV *nvswitch_dev); static void nvswitch_load_bar_info(NVSWITCH_DEV *nvswitch_dev); -static void nvswitch_task_dispatch(NVSWITCH_DEV *nvswitch_dev); +static void nvswitch_task_dispatch(void *nvswitch_dev); static NvBool nvswitch_is_device_blacklisted @@ -313,7 +313,7 @@ nvswitch_init_background_tasks NV_ATOMIC_SET(nvswitch_dev->task_q_ready, 1); nv_kthread_q_item_init(&nvswitch_dev->task_item, - (nv_q_func_t) &nvswitch_task_dispatch, + &nvswitch_task_dispatch, nvswitch_dev); if (!nv_kthread_q_schedule_q_item(&nvswitch_dev->task_q, @@ -1208,9 +1208,10 @@ nvswitch_isr_thread static void nvswitch_task_dispatch ( - NVSWITCH_DEV *nvswitch_dev + void *_nvswitch_dev ) { + NVSWITCH_DEV *nvswitch_dev = _nvswitch_dev; NvU64 nsec; NvU64 timeout; NvS64 rc; From 3d51bad5ab5dbaf3311025e236f1140304bfc1fe Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 4 Mar 2026 10:05:59 +0000 Subject: [PATCH 03/57] nvidia: Fix TMR_CALLBACK_FUNCTION type The retun type should be 'void' as all users of tmrCtrlCmdEventCreate() pass a 'void (*)(void *)' function pointer. Signed-off-by: Mathias Krause --- src/nvidia/src/kernel/gpu/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/src/kernel/gpu/timer/timer.c b/src/nvidia/src/kernel/gpu/timer/timer.c index 5a28338c0..dba085a76 100644 --- a/src/nvidia/src/kernel/gpu/timer/timer.c +++ b/src/nvidia/src/kernel/gpu/timer/timer.c @@ -1769,7 +1769,7 @@ tmrapiDeregisterEvents_IMPL(TimerApi *pTimerApi) // inner callback and calls it correctly from itself. Hacky but it should work around the // limitations in the SDK (all RM derived types undefined, so TIMEPROC type is impossible). // -typedef NvU32 (*TMR_CALLBACK_FUNCTION)(void *pCallbackData); +typedef void (*TMR_CALLBACK_FUNCTION)(void *pCallbackData); typedef struct { From 319ddfc10af1708d2f4b6a3a10c3849c2feb34f6 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 5 Feb 2026 10:18:03 +0000 Subject: [PATCH 04/57] nvidia: maxwell - Fix aperture type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc warns about the use of the wrong enum type, fix that! .../src/nvidia/src/kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c:1720:76: warning: implicit conversion from ‘GMMU_APERTURE’ to ‘FB_CACHE_MEMTYPE’ [-Wenum-conversion] 1720 | kmemsysCacheOp_HAL(pGpu, GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu), NULL, aperture, FB_CACHE_INVALIDATE); | ^~~~~~~~ .../src/nvidia/generated/g_kern_mem_sys_nvoc.h:632:135: note: in definition of macro ‘kmemsysCacheOp_HAL’ 632 | #define kmemsysCacheOp_HAL(pGpu, pKernelMemorySystem, arg3, arg4, operation) kmemsysCacheOp_DISPATCH(pGpu, pKernelMemorySystem, arg3, arg4, operation) | ^~~~ Signed-off-by: Mathias Krause --- .../kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/src/kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c b/src/nvidia/src/kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c index cc2098b02..476b174e3 100644 --- a/src/nvidia/src/kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c +++ b/src/nvidia/src/kernel/gpu/mem_mgr/arch/maxwell/virt_mem_allocator_gm107.c @@ -1692,7 +1692,7 @@ dmaFreeMapping_GM107 if (pCliMapInfo != NULL && pCliMapInfo->pDmaMappingInfo->bNeedL2InvalidateAtUnmap) { - GMMU_APERTURE aperture = (pCliMapInfo->pDmaMappingInfo->aperture == GMMU_APERTURE_PEER) ? + FB_CACHE_MEMTYPE aperture = (pCliMapInfo->pDmaMappingInfo->aperture == GMMU_APERTURE_PEER) ? FB_CACHE_PEER_MEMORY : FB_CACHE_SYSTEM_MEMORY; kmemsysCacheOp_HAL(pGpu, GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu), NULL, aperture, FB_CACHE_INVALIDATE); From 76c78b096b7ad46c370d25be87cc9a7fffefeada Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 4 Mar 2026 10:09:34 +0000 Subject: [PATCH 05/57] nvidia: Fix stack info leak in tmrCtrlCmdEventCreate() In case tmrEventCreate() fails, we will copy the uninitialized value of the stack local variable 'pEvent' and expose it to the caller. Prevent that by initializing it to NULL, as all other users do. Signed-off-by: Mathias Krause --- src/nvidia/src/kernel/gpu/timer/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/src/kernel/gpu/timer/timer.c b/src/nvidia/src/kernel/gpu/timer/timer.c index dba085a76..b5f41cd84 100644 --- a/src/nvidia/src/kernel/gpu/timer/timer.c +++ b/src/nvidia/src/kernel/gpu/timer/timer.c @@ -1822,7 +1822,7 @@ tmrCtrlCmdEventCreate ) { NV_STATUS rc; - TMR_EVENT *pEvent; + TMR_EVENT *pEvent = NULL; wrapperStorage_t *pWrapper; OBJTMR *pTmr = GPU_GET_TIMER(pGpu); From a32a49cd6f04450cd65a778c814ff899bfe971ee Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 11 Mar 2026 21:19:58 +0100 Subject: [PATCH 06/57] nvidia: Fix cleaning of nv_compiler.h Targets added to 'clean-files' shouldn't have the '$(obj)/' prefix or won't be found for the 'make clean' target. Fix that to ensure 'nv_compiler.h' will be removed on 'make clean'. Signed-off-by: Mathias Krause --- kernel-open/nvidia/nvidia.Kbuild | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index a04d6198b..8b05205d4 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -74,12 +74,12 @@ $(call ASSIGN_PER_OBJ_CFLAGS, $(NVIDIA_OBJECTS), $(NVIDIA_CFLAGS)) # nv-procfs.c requires nv-compiler.h # -NV_COMPILER_VERSION_HEADER = $(obj)/nv_compiler.h +NV_COMPILER_VERSION_HEADER = nv_compiler.h -$(NV_COMPILER_VERSION_HEADER): +$(obj)/$(NV_COMPILER_VERSION_HEADER): @echo \#define NV_COMPILER \"`$(CC) -v 2>&1 | tail -n 1`\" > $@ -$(obj)/nvidia/nv-procfs.o: $(NV_COMPILER_VERSION_HEADER) +$(obj)/nvidia/nv-procfs.o: $(obj)/$(NV_COMPILER_VERSION_HEADER) clean-files += $(NV_COMPILER_VERSION_HEADER) From ac4912325a8e9f7f135622ccd4acdcd15ba51831 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:16:20 +0000 Subject: [PATCH 07/57] nvidia-drm: Fix prototype of nv_drm_connector_mode_valid() The drm_connector_helper_funcs.mode_valid() hook is expected to return a 'enum drm_mode_status' since Linux commit 0993f1d0d8a1 ("drm: Make the connector mode_valid() func return a drm_mode_status enum") merged in v3.14. Add a conftest test for it to fix that without breaking older kernels. The test is slightly evolved as C considers mismatched enum vs. int return types as compatible but they still violate CFI checks for advanced implementations like RAP as found in grsecurity. Signed-off-by: Mathias Krause --- kernel-open/conftest.sh | 32 +++++++++++++++++++ kernel-open/nvidia-drm/nvidia-drm-connector.c | 11 +++++-- kernel-open/nvidia-drm/nvidia-drm-sources.mk | 1 + 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 6ec4973fc..a515909db 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -4919,6 +4919,38 @@ compile_test() { compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_DATE" "" "types" ;; + drm_connector_helper_funcs_mode_valid_has_int_ret_type) + # + # Determine if the return type is 'int' for + # drm_connector_helper_funcs::mode_valid. + # + # It was changed to 'enum drm_mode_status' by commit 0993f1d0d8a1 + # ("drm: Make the connector mode_valid() vfunc return a + # drm_mode_status enum") in v3.14. + # + CODE=" + #include + + #ifndef __same_type + #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) + #endif + + /* BUILD_BUG_ON() from isn't working */ + #define CONF_BUILD_BUG_ON(cond) \ + char conf_bug_on_trigger[0 - !!(cond)] + + /* We exploit the fact, that 'int' and 'enum' are compatible but + * 'enum e1' and 'enum e2' are not to cause a build error if the + * return type of drm_connector_helper_funcs::mode_valid is an enum. + */ + enum conftest_enum { CONFTEST = -1 } conftest_enum; + const struct drm_connector_helper_funcs conftest_func; + CONF_BUILD_BUG_ON(!__same_type(conftest_func.mode_valid(NULL, NULL), conftest_enum)); + " + + compile_check_conftest "$CODE" "NV_DRM_CONNECTOR_HELPER_FUNCS_MODE_VALID_HAS_INT_RET_TYPE" "" "types" + ;; + drm_connector_helper_funcs_mode_valid_has_const_mode_arg) # # Determine if the 'mode' pointer argument is const in diff --git a/kernel-open/nvidia-drm/nvidia-drm-connector.c b/kernel-open/nvidia-drm/nvidia-drm-connector.c index fee5b9109..bb718c67b 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-connector.c +++ b/kernel-open/nvidia-drm/nvidia-drm-connector.c @@ -310,11 +310,16 @@ static int nv_drm_connector_get_modes(struct drm_connector *connector) return count; } -static int nv_drm_connector_mode_valid(struct drm_connector *connector, +#ifdef NV_DRM_CONNECTOR_HELPER_FUNCS_MODE_VALID_HAS_INT_RET_TYPE +static int +#else +static enum drm_mode_status +#endif +nv_drm_connector_mode_valid(struct drm_connector *connector, #if defined(NV_DRM_CONNECTOR_HELPER_FUNCS_MODE_VALID_HAS_CONST_MODE_ARG) - const struct drm_display_mode *mode) + const struct drm_display_mode *mode) #else - struct drm_display_mode *mode) + struct drm_display_mode *mode) #endif { struct drm_device *dev = connector->dev; diff --git a/kernel-open/nvidia-drm/nvidia-drm-sources.mk b/kernel-open/nvidia-drm/nvidia-drm-sources.mk index a2c3a3862..6bdc535cb 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-sources.mk +++ b/kernel-open/nvidia-drm/nvidia-drm-sources.mk @@ -107,5 +107,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_format_info_has_is_yuv NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_gem_prime_mmap NV_CONFTEST_TYPE_COMPILE_TESTS += drm_output_poll_changed NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_date +NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_helper_funcs_mode_valid_has_int_ret_type NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_helper_funcs_mode_valid_has_const_mode_arg NV_CONFTEST_TYPE_COMPILE_TESTS += drm_fb_create_takes_format_info From a421e854fa03a03a65caf5f6a4744056575fcce8 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:52:36 +0000 Subject: [PATCH 08/57] nvidia-uvm: Statically initialize g_exported_uvm_events There is no need to initialize 'g_exported_uvm_events' at runtime, initialize at compile time. Signed-off-by: Mathias Krause --- kernel-open/nvidia-uvm/uvm_global.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel-open/nvidia-uvm/uvm_global.c b/kernel-open/nvidia-uvm/uvm_global.c index 913765809..e346d7738 100644 --- a/kernel-open/nvidia-uvm/uvm_global.c +++ b/kernel-open/nvidia-uvm/uvm_global.c @@ -42,19 +42,19 @@ #include "nv_uvm_interface.h" uvm_global_t g_uvm_global; -static struct UvmEventsLinux g_exported_uvm_events; +static struct UvmEventsLinux g_exported_uvm_events = { + .isrTopHalf = uvm_isr_top_half_entry, + .suspend = uvm_suspend_entry, + .resume = uvm_resume_entry, + .drainP2P = uvm_suspend_and_drainP2P_entry, + .resumeP2P = uvm_resumeP2P_entry, +}; static bool g_ops_registered = false; static NV_STATUS uvm_register_callbacks(void) { NV_STATUS status = NV_OK; - g_exported_uvm_events.isrTopHalf = uvm_isr_top_half_entry; - g_exported_uvm_events.suspend = uvm_suspend_entry; - g_exported_uvm_events.resume = uvm_resume_entry; - g_exported_uvm_events.drainP2P = uvm_suspend_and_drainP2P_entry; - g_exported_uvm_events.resumeP2P = uvm_resumeP2P_entry; - // Register the UVM callbacks with the main GPU driver: status = uvm_rm_locked_call(nvUvmInterfaceRegisterUvmEvents(&g_exported_uvm_events)); if (status != NV_OK) From ecf4da37c67b128d3ff487fc5579307ffc340ec7 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 5 Feb 2026 09:54:13 +0000 Subject: [PATCH 09/57] nvidia-modeset: Fix prototype of NVEvoSubDevRec.scanLockState() Actual implementations of the NVEvoSubDevRec.scanLockState hook want an 'NVEvoLockAction'-typed 'action' argument. Fix that. Signed-off-by: Mathias Krause --- src/nvidia-modeset/include/nvkms-evo-states.h | 19 ----------------- src/nvidia-modeset/include/nvkms-types.h | 21 ++++++++++++++++++- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/nvidia-modeset/include/nvkms-evo-states.h b/src/nvidia-modeset/include/nvkms-evo-states.h index ab34f2a67..cd9a82632 100644 --- a/src/nvidia-modeset/include/nvkms-evo-states.h +++ b/src/nvidia-modeset/include/nvkms-evo-states.h @@ -39,25 +39,6 @@ typedef enum NVEvoLockSignal { NV_EVO_LOCK_SIGNAL_STEREO, } NVEvoLockSignal; -typedef enum NVEvoLockAction { - NV_EVO_PROHIBIT_LOCK, - NV_EVO_PROHIBIT_LOCK_DISABLE, - NV_EVO_LOCK_HEADS, - NV_EVO_UNLOCK_HEADS, - NV_EVO_ADD_FRAME_LOCK_SERVER, - NV_EVO_REM_FRAME_LOCK_SERVER, - NV_EVO_ADD_FRAME_LOCK_HOUSE_SYNC, - NV_EVO_REM_FRAME_LOCK_HOUSE_SYNC, - NV_EVO_ADD_FRAME_LOCK_CLIENT, - NV_EVO_REM_FRAME_LOCK_CLIENT, - NV_EVO_ADD_FRAME_LOCK_REF, - NV_EVO_REM_FRAME_LOCK_REF, - NV_EVO_ADD_SLI_SECONDARY, - NV_EVO_ADD_SLI_LAST_SECONDARY, - NV_EVO_ADD_SLI_PRIMARY, - NV_EVO_REM_SLI, -} NVEvoLockAction; - /* nv_evo.c */ NVEvoLockPin nvEvoGetPinForSignal(const NVDispEvoRec *, diff --git a/src/nvidia-modeset/include/nvkms-types.h b/src/nvidia-modeset/include/nvkms-types.h index 1bc0d328f..de3427a8c 100644 --- a/src/nvidia-modeset/include/nvkms-types.h +++ b/src/nvidia-modeset/include/nvkms-types.h @@ -796,6 +796,25 @@ typedef struct { NvU32 surfaceCount; } NVHsStateOneHeadAllDisps; +typedef enum NVEvoLockAction { + NV_EVO_PROHIBIT_LOCK, + NV_EVO_PROHIBIT_LOCK_DISABLE, + NV_EVO_LOCK_HEADS, + NV_EVO_UNLOCK_HEADS, + NV_EVO_ADD_FRAME_LOCK_SERVER, + NV_EVO_REM_FRAME_LOCK_SERVER, + NV_EVO_ADD_FRAME_LOCK_HOUSE_SYNC, + NV_EVO_REM_FRAME_LOCK_HOUSE_SYNC, + NV_EVO_ADD_FRAME_LOCK_CLIENT, + NV_EVO_REM_FRAME_LOCK_CLIENT, + NV_EVO_ADD_FRAME_LOCK_REF, + NV_EVO_REM_FRAME_LOCK_REF, + NV_EVO_ADD_SLI_SECONDARY, + NV_EVO_ADD_SLI_LAST_SECONDARY, + NV_EVO_ADD_SLI_PRIMARY, + NV_EVO_REM_SLI, +} NVEvoLockAction; + /* Subdevice-specific, channel-independent state */ typedef struct _NVEvoSubDevRec { NvU32 subDeviceInstance; @@ -812,7 +831,7 @@ typedef struct _NVEvoSubDevRec { void *cursorPio[NVKMS_MAX_HEADS_PER_DISP]; NvBool (*scanLockState)(NVDispEvoPtr pDispEvo, NVEvoSubDevPtr pEvoSubDev, - NvU32 action, + NVEvoLockAction action, /* NV_INVALID_HEAD-terminated * array of head indices */ const NvU32 *pHeads); From ef9d43f0d05982c6bc96c0aaf458eb185bb75046 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 09:29:21 -0400 Subject: [PATCH 10/57] kernel-open: RANDSTRUCT kernel config test Test the kernel for having RANDSTRUCT enabled and break the build, if it is as this would otherwise lead to ABI-incompatibilities with the OS-agnostic part that doesn't get compiled with RANDSTRCUT enabled. A visible outcome of this would be calling the wrong callback function via structures that purely consist of function pointers (which RANDSTRUCT randomizes). Signed-off-by: Mathias Krause --- kernel-open/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel-open/Makefile b/kernel-open/Makefile index f7a8db69f..50565d934 100644 --- a/kernel-open/Makefile +++ b/kernel-open/Makefile @@ -68,6 +68,15 @@ else endif endif + # RANDSTRUCT is incompatible with how we build the OS-agnostic part, leading + # to calling the wrong callback functions from pure *ops structures at + # runtime. + ranstruct_enabled=$(firstword $(shell . $(KERNEL_OUTPUT)/.config; \ + echo "$$CONFIG_RANDSTRUCT$$CONFIG_GCC_PLUGIN_RANDSTRUCT")) + ifneq ($(ranstruct_enabled),) + $(error RANDSTRUCT enabled kernel is incompatible with binary objects!)) + endif + CC ?= cc LD ?= ld OBJDUMP ?= objdump From 5ab85101b5bbfc3ce1f163ee94da76599c944303 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 27 Nov 2025 10:28:08 +0000 Subject: [PATCH 11/57] src/: remove system header dependencies Get rid of system header includes in preparation for upcoming kbuild support which prevents their usage via -nostdinc. The change is mostly mechanic, by making use of appropriate substitutes: - stddef.h gets replaced by a new nv-stddef.h header that uses kernel headers when appropriate defines are set or the regular system header otherwise, - stdarg.h gets replaced by nv_stdarg.h, which already uses kernel headers, if needed For softfloat the additional headers get wrapped: - stdbool.h, which makes use of Linux's for kernel builds and the system's otherwise. - stdint.h, which also makes use of Linux's for kernel builds but also provide the missing [u]int_fast*_t typedefs Signed-off-by: Mathias Krause --- src/common/displayport/inc/dp_internal.h | 2 +- src/common/displayport/inc/dp_object.h | 2 +- src/common/modeset/hdmipacket/nvhdmipkt.c | 2 +- .../modeset/hdmipacket/nvhdmipkt_C671.c | 2 +- src/common/modeset/timing/nvt_dsc_pps.c | 2 +- src/common/modeset/timing/nvtiming_pvt.h | 2 +- .../nvswitch/kernel/ls10/discovery_ls10.c | 2 +- src/common/nvswitch/kernel/ls10/tnvl_ls10.c | 2 +- src/common/sdk/nvidia/inc/nv-stddef.h | 38 +++++++++++++++++++ src/common/shared/msgq/msgq.c | 2 +- src/common/softfloat/nvidia/stdbool.h | 10 +++++ src/common/softfloat/nvidia/stdint.h | 38 +++++++++++++++++++ .../utils/interface/nv_mode_timings_utils.h | 2 +- .../common/utils/interface/nv_vasprintf.h | 4 +- src/common/unix/common/utils/unix_rm_handle.c | 2 +- .../nvidia-3d/interface/nvidia-3d-imports.h | 2 +- .../nvidia-push/interface/nvidia-push-types.h | 2 +- .../uproc/os/common/include/libos_log.h | 2 +- .../uproc/os/libos-v3.1.0/lib/libdwarf.c | 2 +- .../uproc/os/libos-v3.1.0/lib/liblogdecode.c | 5 +-- src/nvidia-modeset/include/nvkms-types.h | 2 +- src/nvidia-modeset/lib/nvkms-format.c | 2 +- .../include/nvidia-modeset-os-interface.h | 6 +-- .../os-interface/include/nvkms.h | 6 +-- src/nvidia-modeset/src/nvkms-dma.c | 2 +- src/nvidia/inc/kernel/core/prelude.h | 4 +- .../inc/libraries/nvport/inline/util_valist.h | 2 +- src/nvidia/inc/libraries/nvport/util.h | 2 +- .../deprecated/rmapi_deprecated_allocmemory.c | 2 +- .../deprecated/rmapi_deprecated_control.c | 2 +- .../deprecated/rmapi_deprecated_utils.c | 2 +- .../interface/rmapi/src/g_finn_rm_api.c | 6 ++- src/nvidia/src/kernel/gpu/conf_compute/ccsl.c | 2 +- 33 files changed, 121 insertions(+), 44 deletions(-) create mode 100644 src/common/sdk/nvidia/inc/nv-stddef.h create mode 100644 src/common/softfloat/nvidia/stdbool.h create mode 100644 src/common/softfloat/nvidia/stdint.h diff --git a/src/common/displayport/inc/dp_internal.h b/src/common/displayport/inc/dp_internal.h index 571e90076..f06390a4f 100644 --- a/src/common/displayport/inc/dp_internal.h +++ b/src/common/displayport/inc/dp_internal.h @@ -37,7 +37,7 @@ // #include -#include // size_t +#include // size_t #include "dp_object.h" #include "dp_ringbuffer.h" diff --git a/src/common/displayport/inc/dp_object.h b/src/common/displayport/inc/dp_object.h index 9bb02e805..8da7d6f8d 100644 --- a/src/common/displayport/inc/dp_object.h +++ b/src/common/displayport/inc/dp_object.h @@ -33,7 +33,7 @@ #define INCLUDED_DP_OBJECT_H #include "nvtypes.h" -#include "stddef.h" +#include "nv-stddef.h" #include "dp_hostimp.h" static inline void dpMemCopy(void * target, const void * source, size_t len) diff --git a/src/common/modeset/hdmipacket/nvhdmipkt.c b/src/common/modeset/hdmipacket/nvhdmipkt.c index 88317d0db..58ecc58e5 100644 --- a/src/common/modeset/hdmipacket/nvhdmipkt.c +++ b/src/common/modeset/hdmipacket/nvhdmipkt.c @@ -25,7 +25,7 @@ * Purpose: Provide initialization functions for HDMI library */ -#include +#include #include "nvlimits.h" #include "nvhdmipkt_common.h" #include "nvhdmipkt_class.h" diff --git a/src/common/modeset/hdmipacket/nvhdmipkt_C671.c b/src/common/modeset/hdmipacket/nvhdmipkt_C671.c index abdb91f46..88605af4f 100644 --- a/src/common/modeset/hdmipacket/nvhdmipkt_C671.c +++ b/src/common/modeset/hdmipacket/nvhdmipkt_C671.c @@ -25,7 +25,7 @@ * Purpose: Provides packet write functions for HDMI library for Ampere+ chips */ -#include +#include #include "nvhdmipkt_common.h" #include "nvhdmipkt_class.h" diff --git a/src/common/modeset/timing/nvt_dsc_pps.c b/src/common/modeset/timing/nvt_dsc_pps.c index 3f539ecbe..883cc8116 100644 --- a/src/common/modeset/timing/nvt_dsc_pps.c +++ b/src/common/modeset/timing/nvt_dsc_pps.c @@ -35,7 +35,7 @@ #include "displayport/displayport.h" #include "displayport/displayport2x.h" #include "nvctassert.h" -#include +#include /* ------------------------ Macros ----------------------------------------- */ diff --git a/src/common/modeset/timing/nvtiming_pvt.h b/src/common/modeset/timing/nvtiming_pvt.h index 1a54d0211..8f9002f83 100644 --- a/src/common/modeset/timing/nvtiming_pvt.h +++ b/src/common/modeset/timing/nvtiming_pvt.h @@ -49,7 +49,7 @@ #define nvt_assert(p) ((void)0) #endif // DD_UNITTEST -#include // NULL +#include // NULL #ifdef __cplusplus extern "C" { diff --git a/src/common/nvswitch/kernel/ls10/discovery_ls10.c b/src/common/nvswitch/kernel/ls10/discovery_ls10.c index 01af0303d..3db0c7bc1 100644 --- a/src/common/nvswitch/kernel/ls10/discovery_ls10.c +++ b/src/common/nvswitch/kernel/ls10/discovery_ls10.c @@ -30,7 +30,7 @@ #include "nvswitch/ls10/nxbar_discovery.h" #include "nvswitch/ls10/dev_npg_ip.h" -#include +#include #define VERBOSE_MMIO_DISCOVERY 0 diff --git a/src/common/nvswitch/kernel/ls10/tnvl_ls10.c b/src/common/nvswitch/kernel/ls10/tnvl_ls10.c index 92e3f1eff..ad948105b 100644 --- a/src/common/nvswitch/kernel/ls10/tnvl_ls10.c +++ b/src/common/nvswitch/kernel/ls10/tnvl_ls10.c @@ -39,7 +39,7 @@ #include "nvswitch/ls10/ptop_discovery_ip.h" #include "nvswitch/ls10/dev_minion_ip.h" -#include +#include /* ------------------------ Macros ----------------------------------------- */ #define TNVL_MAX_CERT_CHAIN_SIZE (0x1000) diff --git a/src/common/sdk/nvidia/inc/nv-stddef.h b/src/common/sdk/nvidia/inc/nv-stddef.h new file mode 100644 index 000000000..5ef838b56 --- /dev/null +++ b/src/common/sdk/nvidia/inc/nv-stddef.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _NV_STDDEF_H_ +#define _NV_STDDEF_H_ + +#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(__FreeBSD__) + #include // NULL +#elif defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) + #include // NULL + #include // size_t + #include // SIZE_MAX,... +#else + #include // NULL +#endif + +#endif // _NV_STDDEF_H_ diff --git a/src/common/shared/msgq/msgq.c b/src/common/shared/msgq/msgq.c index 76d9dd361..86d750bfa 100644 --- a/src/common/shared/msgq/msgq.c +++ b/src/common/shared/msgq/msgq.c @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include diff --git a/src/common/softfloat/nvidia/stdbool.h b/src/common/softfloat/nvidia/stdbool.h new file mode 100644 index 000000000..c50698c32 --- /dev/null +++ b/src/common/softfloat/nvidia/stdbool.h @@ -0,0 +1,10 @@ +#ifndef _NV_STDBOOL_H_ +#define _NV_STDBOOL_H_ + +#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) + #include +#else + #include_next +#endif + +#endif // _NV_STDBOOL_H_ diff --git a/src/common/softfloat/nvidia/stdint.h b/src/common/softfloat/nvidia/stdint.h new file mode 100644 index 000000000..5dadb5d31 --- /dev/null +++ b/src/common/softfloat/nvidia/stdint.h @@ -0,0 +1,38 @@ +#ifndef _NV_STDINT_H_ +#define _NV_STDINT_H_ + +#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) + #include + + /* Linux lacks the '*fast/least*_t' variants. */ + typedef int8_t int_fast8_t; + typedef uint8_t uint_fast8_t; + + typedef int16_t int_fast16_t; + typedef uint16_t uint_fast16_t; + + typedef int32_t int_fast32_t; + typedef uint32_t uint_fast32_t; + + typedef int64_t int_fast64_t; + typedef uint64_t uint_fast64_t; + + typedef int8_t int_least8_t; + typedef uint8_t uint_least8_t; + + typedef int16_t int_least16_t; + typedef uint16_t uint_least16_t; + + typedef int32_t int_least32_t; + typedef uint32_t uint_least32_t; + + typedef int64_t int_least64_t; + typedef uint64_t uint_least64_t; + + #define INT64_C(x) S64_C(x) + #define UINT64_C(x) U64_C(x) +#else + #include_next +#endif + +#endif // _NV_STDINT_H_ diff --git a/src/common/unix/common/utils/interface/nv_mode_timings_utils.h b/src/common/unix/common/utils/interface/nv_mode_timings_utils.h index 62ef305c0..6fafaf667 100644 --- a/src/common/unix/common/utils/interface/nv_mode_timings_utils.h +++ b/src/common/unix/common/utils/interface/nv_mode_timings_utils.h @@ -33,7 +33,7 @@ #include "nv_mode_timings.h" #include "timing/nvtiming.h" -#include /* size_t */ +#include /* size_t */ /* * Macros used for printing values divided by 1000 without floating diff --git a/src/common/unix/common/utils/interface/nv_vasprintf.h b/src/common/unix/common/utils/interface/nv_vasprintf.h index ec94beb51..a8023f899 100644 --- a/src/common/unix/common/utils/interface/nv_vasprintf.h +++ b/src/common/unix/common/utils/interface/nv_vasprintf.h @@ -28,8 +28,8 @@ extern "C" { #endif -#include -#include +#include +#include /* * nv_vasprintf() depends on nv_vasprintf_{alloc,free,vsnprintf}(). diff --git a/src/common/unix/common/utils/unix_rm_handle.c b/src/common/unix/common/utils/unix_rm_handle.c index b24d0e05e..bd3b39b58 100644 --- a/src/common/unix/common/utils/unix_rm_handle.c +++ b/src/common/unix/common/utils/unix_rm_handle.c @@ -37,7 +37,7 @@ * [15:00] Handle constant */ -#include +#include #include "unix_rm_handle.h" diff --git a/src/common/unix/nvidia-3d/interface/nvidia-3d-imports.h b/src/common/unix/nvidia-3d/interface/nvidia-3d-imports.h index 839a2da59..a64f93369 100644 --- a/src/common/unix/nvidia-3d/interface/nvidia-3d-imports.h +++ b/src/common/unix/nvidia-3d/interface/nvidia-3d-imports.h @@ -29,7 +29,7 @@ #ifndef __NVIDIA_3D_IMPORTS_H__ #define __NVIDIA_3D_IMPORTS_H__ -#include /* size_t */ +#include /* size_t */ void *nv3dImportAlloc(size_t size); void nv3dImportFree(void *ptr); diff --git a/src/common/unix/nvidia-push/interface/nvidia-push-types.h b/src/common/unix/nvidia-push/interface/nvidia-push-types.h index ef0ce1548..7b3b4ad9d 100644 --- a/src/common/unix/nvidia-push/interface/nvidia-push-types.h +++ b/src/common/unix/nvidia-push/interface/nvidia-push-types.h @@ -29,7 +29,7 @@ #ifndef __NVIDIA_PUSH_TYPES_H__ #define __NVIDIA_PUSH_TYPES_H__ -#include /* size_t */ +#include /* size_t */ diff --git a/src/common/uproc/os/common/include/libos_log.h b/src/common/uproc/os/common/include/libos_log.h index 7e59dd739..25b4aeb20 100644 --- a/src/common/uproc/os/common/include/libos_log.h +++ b/src/common/uproc/os/common/include/libos_log.h @@ -25,7 +25,7 @@ #define LIBOS_LOGGER_H_ #include "nvtypes.h" -#include +#include "nv_stdarg.h" #include "libos_printf_arg.h" #if defined(NVRM) diff --git a/src/common/uproc/os/libos-v3.1.0/lib/libdwarf.c b/src/common/uproc/os/libos-v3.1.0/lib/libdwarf.c index 1ba1acda1..fd0dc32d7 100644 --- a/src/common/uproc/os/libos-v3.1.0/lib/libdwarf.c +++ b/src/common/uproc/os/libos-v3.1.0/lib/libdwarf.c @@ -23,7 +23,7 @@ #ifdef NVRM -# include +# include # include # define printf(fmt, ...) nv_printf(LEVEL_ERROR, fmt, ##__VA_ARGS__) diff --git a/src/common/uproc/os/libos-v3.1.0/lib/liblogdecode.c b/src/common/uproc/os/libos-v3.1.0/lib/liblogdecode.c index e5e79cfc4..406f223df 100644 --- a/src/common/uproc/os/libos-v3.1.0/lib/liblogdecode.c +++ b/src/common/uproc/os/libos-v3.1.0/lib/liblogdecode.c @@ -27,7 +27,7 @@ #ifdef NVRM # include -# include // size_t +# include // size_t #define LIBOS_LOG_DECODE_PRINTF(level, fmt, ...) portDbgExPrintfLevel(level, fmt, ##__VA_ARGS__) @@ -39,6 +39,7 @@ #include "time.h" #endif +# include # include # include # include @@ -75,8 +76,6 @@ #define LIBOS_LOG_DECODE_PRINTF(level, fmt, ...) printf(fmt, ...) #endif -#include - #include "nvtypes.h" #include "nvstatus.h" #include "liblogdecode.h" diff --git a/src/nvidia-modeset/include/nvkms-types.h b/src/nvidia-modeset/include/nvkms-types.h index de3427a8c..3b7f7fbe4 100644 --- a/src/nvidia-modeset/include/nvkms-types.h +++ b/src/nvidia-modeset/include/nvkms-types.h @@ -61,7 +61,7 @@ extern "C" { #include "timing/dpsdp.h" #include "hdmipacket/nvhdmi_frlInterface.h" // HDMI_{SRC,SINK}_CAPS -#include +#include #include "nv_smg.h" diff --git a/src/nvidia-modeset/lib/nvkms-format.c b/src/nvidia-modeset/lib/nvkms-format.c index cb8c8fd1a..fb50558ff 100644 --- a/src/nvidia-modeset/lib/nvkms-format.c +++ b/src/nvidia-modeset/lib/nvkms-format.c @@ -25,7 +25,7 @@ #include "nv_common_utils.h" #include "nvctassert.h" -#include +#include #define RGB_ENTRY(_format, _depth, _bytesPerPixel) \ [NvKmsSurfaceMemoryFormat##_format] = { \ diff --git a/src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h b/src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h index d4d656e76..e97754a8e 100644 --- a/src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h +++ b/src/nvidia-modeset/os-interface/include/nvidia-modeset-os-interface.h @@ -29,11 +29,7 @@ #if !defined(_NVIDIA_MODESET_OS_INTERFACE_H_) #define _NVIDIA_MODESET_OS_INTERFACE_H_ -#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) -#include /* size_t */ -#else -#include /* size_t */ -#endif +#include /* size_t */ #include "nvtypes.h" /* NvU8 */ #include "nvkms.h" diff --git a/src/nvidia-modeset/os-interface/include/nvkms.h b/src/nvidia-modeset/os-interface/include/nvkms.h index d350ef756..55c8abd64 100644 --- a/src/nvidia-modeset/os-interface/include/nvkms.h +++ b/src/nvidia-modeset/os-interface/include/nvkms.h @@ -25,11 +25,7 @@ #define __NV_KMS_H__ #include "nvtypes.h" -#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) -#include /* size_t */ -#else -#include /* size_t */ -#endif +#include /* size_t, NULL */ #include "nvkms-kapi.h" diff --git a/src/nvidia-modeset/src/nvkms-dma.c b/src/nvidia-modeset/src/nvkms-dma.c index a6c0b57b6..b8b3743e7 100644 --- a/src/nvidia-modeset/src/nvkms-dma.c +++ b/src/nvidia-modeset/src/nvkms-dma.c @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include +#include #include "nvkms-dma.h" #include "nvkms-utils.h" diff --git a/src/nvidia/inc/kernel/core/prelude.h b/src/nvidia/inc/kernel/core/prelude.h index 3273c2f58..5c72252d6 100644 --- a/src/nvidia/inc/kernel/core/prelude.h +++ b/src/nvidia/inc/kernel/core/prelude.h @@ -23,12 +23,10 @@ #ifndef __PRELUDE_H__ #define __PRELUDE_H__ -/* ------------------------ C library --------------------------------------- */ -#include // NULL - /* ------------------------ SDK includes ------------------------------------ */ #include "nvtypes.h" +#include "nv-stddef.h" #include "nvrangetypes.h" #include "nvstatus.h" #include "nvmisc.h" diff --git a/src/nvidia/inc/libraries/nvport/inline/util_valist.h b/src/nvidia/inc/libraries/nvport/inline/util_valist.h index 4d293c3fd..fb67c05ac 100644 --- a/src/nvidia/inc/libraries/nvport/inline/util_valist.h +++ b/src/nvidia/inc/libraries/nvport/inline/util_valist.h @@ -27,4 +27,4 @@ */ // We used to have custom implementations in here, but now we just take the standard ones -#include // define va_* +#include // define va_* diff --git a/src/nvidia/inc/libraries/nvport/util.h b/src/nvidia/inc/libraries/nvport/util.h index 6234d618a..194b7a43e 100644 --- a/src/nvidia/inc/libraries/nvport/util.h +++ b/src/nvidia/inc/libraries/nvport/util.h @@ -183,7 +183,7 @@ PORT_UTIL_INLINE NvU32 portUtilCountTrailingZeros32(NvU32 n); /// @} End core functions -#include /* NULL */ +#include /* NULL */ /** * @name Extended Functions diff --git a/src/nvidia/interface/deprecated/rmapi_deprecated_allocmemory.c b/src/nvidia/interface/deprecated/rmapi_deprecated_allocmemory.c index 6a88b6f92..c2502ae30 100644 --- a/src/nvidia/interface/deprecated/rmapi_deprecated_allocmemory.c +++ b/src/nvidia/interface/deprecated/rmapi_deprecated_allocmemory.c @@ -37,7 +37,7 @@ #include "ctrl/ctrl2080/ctrl2080fb.h" // NV2080_CTRL_FB_INFO -#include +#include typedef NV_STATUS RmAllocMemoryFunc( DEPRECATED_CONTEXT *pContext, diff --git a/src/nvidia/interface/deprecated/rmapi_deprecated_control.c b/src/nvidia/interface/deprecated/rmapi_deprecated_control.c index 0a647ed35..0ffdba52a 100644 --- a/src/nvidia/interface/deprecated/rmapi_deprecated_control.c +++ b/src/nvidia/interface/deprecated/rmapi_deprecated_control.c @@ -45,7 +45,7 @@ #include "rmapi/rs_utils.h" #include "rmapi/rmapi.h" -#include // NULL +#include // NULL /** * Kernel-space deprecated control conversion. diff --git a/src/nvidia/interface/deprecated/rmapi_deprecated_utils.c b/src/nvidia/interface/deprecated/rmapi_deprecated_utils.c index 0b2f8bb9b..257bc2358 100644 --- a/src/nvidia/interface/deprecated/rmapi_deprecated_utils.c +++ b/src/nvidia/interface/deprecated/rmapi_deprecated_utils.c @@ -28,7 +28,7 @@ #include "ctrl/ctrl0080/ctrl0080gpu.h" // NV0080_CTRL_CMD_GPU_FIND_SUBDEVICE_HANDLE #include "nvos.h" -#include +#include NV_STATUS RmDeprecatedGetHandleParent diff --git a/src/nvidia/interface/rmapi/src/g_finn_rm_api.c b/src/nvidia/interface/rmapi/src/g_finn_rm_api.c index dfb6812ed..b6368ec09 100644 --- a/src/nvidia/interface/rmapi/src/g_finn_rm_api.c +++ b/src/nvidia/interface/rmapi/src/g_finn_rm_api.c @@ -21,8 +21,10 @@ #include "ctrl/ctrlb06f.h" #if defined(NVRM) /* Kernel Mode */ -#include -#include +#include +#ifndef NV_KERNEL_INTERFACE_LAYER +# include +#endif #include "nvport/nvport.h" #elif defined(NV_LIBOS) /* LIBOS */ #include diff --git a/src/nvidia/src/kernel/gpu/conf_compute/ccsl.c b/src/nvidia/src/kernel/gpu/conf_compute/ccsl.c index f5ab03e26..bf2a26d88 100644 --- a/src/nvidia/src/kernel/gpu/conf_compute/ccsl.c +++ b/src/nvidia/src/kernel/gpu/conf_compute/ccsl.c @@ -31,7 +31,7 @@ #include "nvport/nvport.h" #include "rmapi/rmapi.h" #include "ctrl/ctrlc56f.h" -#include +#include // This guard is here until we fix CONF_COMPUTE and SPDM guards across whole RM #include "kernel/gpu/spdm/libspdm_includes.h" #include From 3f06caf3ee7b686ed5de58c0b1be1ffdcd4fb806 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Mar 2026 11:33:53 +0100 Subject: [PATCH 12/57] nvswitch: use designated initializers Use designated initializers for initializing static nvswitch discovery handler objects to resolve incompatibilities with Linux's RANDSTRUCT gcc plugin. Signed-off-by: Mathias Krause --- .../nvswitch/kernel/lr10/discovery_lr10.c | 32 +++++++++---------- .../nvswitch/kernel/ls10/discovery_ls10.c | 32 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/common/nvswitch/kernel/lr10/discovery_lr10.c b/src/common/nvswitch/kernel/lr10/discovery_lr10.c index f282ba590..63f3d2616 100644 --- a/src/common/nvswitch/kernel/lr10/discovery_lr10.c +++ b/src/common/nvswitch/kernel/lr10/discovery_lr10.c @@ -921,37 +921,37 @@ nvswitch_nxbar_handle_data2_lr10 static NVSWITCH_DISCOVERY_HANDLERS_LR10 discovery_handlers_ptop_lr10 = { - &_nvswitch_ptop_parse_entry_lr10, - &_nvswitch_ptop_parse_enum_lr10, - &_nvswitch_ptop_handle_data1_lr10, - &_nvswitch_ptop_handle_data2_lr10 + .parse_entry = _nvswitch_ptop_parse_entry_lr10, + .parse_enum = _nvswitch_ptop_parse_enum_lr10, + .handle_data1 = _nvswitch_ptop_handle_data1_lr10, + .handle_data2 = _nvswitch_ptop_handle_data2_lr10 }; static NVSWITCH_DISCOVERY_HANDLERS_LR10 discovery_handlers_npg_lr10 = { - &_nvswitch_npg_parse_entry_lr10, - &_nvswitch_npg_parse_enum_lr10, - &_nvswitch_npg_handle_data1_lr10, - &_nvswitch_npg_handle_data2_lr10 + .parse_entry = _nvswitch_npg_parse_entry_lr10, + .parse_enum = _nvswitch_npg_parse_enum_lr10, + .handle_data1 = _nvswitch_npg_handle_data1_lr10, + .handle_data2 = _nvswitch_npg_handle_data2_lr10 }; static NVSWITCH_DISCOVERY_HANDLERS_LR10 discovery_handlers_nvlw_lr10 = { - &nvswitch_nvlw_parse_entry_lr10, - &nvswitch_nvlw_parse_enum_lr10, - &nvswitch_nvlw_handle_data1_lr10, - &nvswitch_nvlw_handle_data2_lr10 + .parse_entry = nvswitch_nvlw_parse_entry_lr10, + .parse_enum = nvswitch_nvlw_parse_enum_lr10, + .handle_data1 = nvswitch_nvlw_handle_data1_lr10, + .handle_data2 = nvswitch_nvlw_handle_data2_lr10 }; static NVSWITCH_DISCOVERY_HANDLERS_LR10 discovery_handlers_nxbar_lr10 = { - &nvswitch_nxbar_parse_entry_lr10, - &nvswitch_nxbar_parse_enum_lr10, - &nvswitch_nxbar_handle_data1_lr10, - &nvswitch_nxbar_handle_data2_lr10 + .parse_entry = nvswitch_nxbar_parse_entry_lr10, + .parse_enum = nvswitch_nxbar_parse_enum_lr10, + .handle_data1 = nvswitch_nxbar_handle_data1_lr10, + .handle_data2 = nvswitch_nxbar_handle_data2_lr10 }; // diff --git a/src/common/nvswitch/kernel/ls10/discovery_ls10.c b/src/common/nvswitch/kernel/ls10/discovery_ls10.c index 3db0c7bc1..33a7d109b 100644 --- a/src/common/nvswitch/kernel/ls10/discovery_ls10.c +++ b/src/common/nvswitch/kernel/ls10/discovery_ls10.c @@ -952,37 +952,37 @@ nvswitch_nxbar_handle_data2_ls10 static NVSWITCH_DISCOVERY_HANDLERS_LS10 discovery_handlers_ptop_ls10 = { - &_nvswitch_ptop_parse_entry_ls10, - &_nvswitch_ptop_parse_enum_ls10, - &_nvswitch_ptop_handle_data1_ls10, - &_nvswitch_ptop_handle_data2_ls10 + .parse_entry = _nvswitch_ptop_parse_entry_ls10, + .parse_enum = _nvswitch_ptop_parse_enum_ls10, + .handle_data1 = _nvswitch_ptop_handle_data1_ls10, + .handle_data2 = _nvswitch_ptop_handle_data2_ls10 }; static NVSWITCH_DISCOVERY_HANDLERS_LS10 discovery_handlers_npg_ls10 = { - &_nvswitch_npg_parse_entry_ls10, - &_nvswitch_npg_parse_enum_ls10, - &_nvswitch_npg_handle_data1_ls10, - &_nvswitch_npg_handle_data2_ls10 + .parse_entry = _nvswitch_npg_parse_entry_ls10, + .parse_enum = _nvswitch_npg_parse_enum_ls10, + .handle_data1 = _nvswitch_npg_handle_data1_ls10, + .handle_data2 = _nvswitch_npg_handle_data2_ls10 }; static NVSWITCH_DISCOVERY_HANDLERS_LS10 discovery_handlers_nvlw_ls10 = { - &nvswitch_nvlw_parse_entry_ls10, - &nvswitch_nvlw_parse_enum_ls10, - &nvswitch_nvlw_handle_data1_ls10, - &nvswitch_nvlw_handle_data2_ls10 + .parse_entry = nvswitch_nvlw_parse_entry_ls10, + .parse_enum = nvswitch_nvlw_parse_enum_ls10, + .handle_data1 = nvswitch_nvlw_handle_data1_ls10, + .handle_data2 = nvswitch_nvlw_handle_data2_ls10 }; static NVSWITCH_DISCOVERY_HANDLERS_LS10 discovery_handlers_nxbar_ls10 = { - &nvswitch_nxbar_parse_entry_ls10, - &nvswitch_nxbar_parse_enum_ls10, - &nvswitch_nxbar_handle_data1_ls10, - &nvswitch_nxbar_handle_data2_ls10 + .parse_entry = nvswitch_nxbar_parse_entry_ls10, + .parse_enum = nvswitch_nxbar_parse_enum_ls10, + .handle_data1 = nvswitch_nxbar_handle_data1_ls10, + .handle_data2 = nvswitch_nxbar_handle_data2_ls10 }; // From 165106dd3782b00cb40b764d86c42036b92a9088 Mon Sep 17 00:00:00 2001 From: PaX Team Date: Thu, 5 Feb 2026 09:24:35 +0000 Subject: [PATCH 13/57] nvidia-3d: use designated initializers Use designated initializers for initializing static Nv3dHal objects to resolve incompatibilities with Linux's RANDSTRUCT gcc plugin. Signed-off-by: PaX Team Signed-off-by: Mathias Krause --- .../unix/nvidia-3d/src/nvidia-3d-init.c | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/common/unix/nvidia-3d/src/nvidia-3d-init.c b/src/common/unix/nvidia-3d/src/nvidia-3d-init.c index a59e54ffa..dca2f2f80 100644 --- a/src/common/unix/nvidia-3d/src/nvidia-3d-init.c +++ b/src/common/unix/nvidia-3d/src/nvidia-3d-init.c @@ -309,30 +309,30 @@ static NvBool GetSpaVersion( } static const Nv3dHal _nv3dHalTuring = { - _nv3dSetSpaVersionKepler, /* setSpaVersion */ - _nv3dInitChannelTuring, /* initChannel */ - _nv3dUploadDataInlineKepler, /* uploadDataInline */ - _nv3dSetProgramOffsetVolta, /* setProgramOffset */ - _nv3dAssignNv3dTexturePascal, /* assignNv3dTexture */ - _nv3dSetVertexStreamEndTuring, /* setVertexStreamEnd */ + .setSpaVersion = _nv3dSetSpaVersionKepler, + .initChannel = _nv3dInitChannelTuring, + .uploadDataInline = _nv3dUploadDataInlineKepler, + .setProgramOffset = _nv3dSetProgramOffsetVolta, + .assignNv3dTexture = _nv3dAssignNv3dTexturePascal, + .setVertexStreamEnd = _nv3dSetVertexStreamEndTuring }; static const Nv3dHal _nv3dHalAmpere = { - _nv3dSetSpaVersionKepler, /* setSpaVersion */ - _nv3dInitChannelTuring, /* initChannel */ - _nv3dUploadDataInlineKepler, /* uploadDataInline */ - _nv3dSetProgramOffsetVolta, /* setProgramOffset */ - _nv3dAssignNv3dTexturePascal, /* assignNv3dTexture */ - _nv3dSetVertexStreamEndTuring, /* setVertexStreamEnd */ + .setSpaVersion = _nv3dSetSpaVersionKepler, + .initChannel = _nv3dInitChannelTuring, + .uploadDataInline = _nv3dUploadDataInlineKepler, + .setProgramOffset = _nv3dSetProgramOffsetVolta, + .assignNv3dTexture = _nv3dAssignNv3dTexturePascal, + .setVertexStreamEnd = _nv3dSetVertexStreamEndTuring }; static const Nv3dHal _nv3dHalHopper = { - _nv3dSetSpaVersionKepler, /* setSpaVersion */ - _nv3dInitChannelHopper, /* initChannel */ - _nv3dUploadDataInlineKepler, /* uploadDataInline */ - _nv3dSetProgramOffsetVolta, /* setProgramOffset */ - _nv3dAssignNv3dTextureHopper, /* assignNv3dTexture */ - _nv3dSetVertexStreamEndTuring, /* setVertexStreamEnd */ + .setSpaVersion = _nv3dSetSpaVersionKepler, + .initChannel = _nv3dInitChannelHopper, + .uploadDataInline = _nv3dUploadDataInlineKepler, + .setProgramOffset = _nv3dSetProgramOffsetVolta, + .assignNv3dTexture = _nv3dAssignNv3dTextureHopper, + .setVertexStreamEnd = _nv3dSetVertexStreamEndTuring }; NvBool nv3dAllocDevice( From fc6cf5307f914b066f1e4f07030ae7a42d2a67ac Mon Sep 17 00:00:00 2001 From: PaX Team Date: Thu, 5 Feb 2026 09:24:35 +0000 Subject: [PATCH 14/57] nvidia-modeset: use designated initializers Use designated initializers for initializing NvKmsNvPushImports to resolve incompatibilities with Linux's RANDSTRUCT gcc plugin. Signed-off-by: PaX Team Signed-off-by: Mathias Krause --- src/nvidia-modeset/src/nvkms-push.c | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/nvidia-modeset/src/nvkms-push.c b/src/nvidia-modeset/src/nvkms-push.c index 4b6094ac3..81bd96d18 100644 --- a/src/nvidia-modeset/src/nvkms-push.c +++ b/src/nvidia-modeset/src/nvkms-push.c @@ -233,24 +233,24 @@ static void NvPushImportLogNvDiss( #endif /* DEBUG */ static const NvPushImports NvKmsNvPushImports = { - NvPushImportRmApiControl, /* rmApiControl */ - NvPushImportRmApiAlloc, /* rmApiAlloc */ - NvPushImportRmApiFree, /* rmApiFree */ - NvPushImportRmApiMapMemoryDma, /* rmApiMapMemoryDma */ - NvPushImportRmApiUnmapMemoryDma, /* rmApiUnmapMemoryDma */ - NvPushImportRmApiAllocMemory64, /* rmApiAllocMemory64 */ - NvPushImportRmApiVidHeapControl, /* rmApiVidHeapControl */ - NvPushImportRmApiMapMemory, /* rmApiMapMemory */ - NvPushImportRmApiUnmapMemory, /* rmApiUnmapMemory */ - NvPushImportGetMilliSeconds, /* getMilliSeconds */ - NvPushImportYield, /* yield */ - NvPushImportWaitForEvent, /* waitForEvent */ - NvPushImportEmptyEventFifo, /* emptyEventFifo */ - NvPushImportChannelErrorOccurred, /* channelErrorOccurred */ - NvPushImportPushbufferWrapped, /* pushbufferWrapped */ - NvPushImportLogError, /* logError */ + .rmApiControl = NvPushImportRmApiControl, + .rmApiAlloc = NvPushImportRmApiAlloc, + .rmApiFree = NvPushImportRmApiFree, + .rmApiMapMemoryDma = NvPushImportRmApiMapMemoryDma, + .rmApiUnmapMemoryDma = NvPushImportRmApiUnmapMemoryDma, + .rmApiAllocMemory64 = NvPushImportRmApiAllocMemory64, + .rmApiVidHeapControl = NvPushImportRmApiVidHeapControl, + .rmApiMapMemory = NvPushImportRmApiMapMemory, + .rmApiUnmapMemory = NvPushImportRmApiUnmapMemory, + .getMilliSeconds = NvPushImportGetMilliSeconds, + .yield = NvPushImportYield, + .waitForEvent = NvPushImportWaitForEvent, + .emptyEventFifo = NvPushImportEmptyEventFifo, + .channelErrorOccurred = NvPushImportChannelErrorOccurred, + .pushbufferWrapped = NvPushImportPushbufferWrapped, + .logError = NvPushImportLogError, #if defined(DEBUG) - NvPushImportLogNvDiss, /* logNvDiss */ + .logNvDiss = NvPushImportLogNvDiss, #endif }; From 1fe68c930b1d1c502aa26fc5376fdb0ca7ceae40 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Mar 2026 11:35:44 +0100 Subject: [PATCH 15/57] nvidia: gpu/mmu - use designated initializers Use designated initializers for initializing static MMU walk callback objects to resolve incompatibilities with Linux's RANDSTRUCT gcc plugin. Signed-off-by: Mathias Krause --- src/nvidia/src/kernel/gpu/mmu/bar2_walk.c | 14 ++++++------ src/nvidia/src/kernel/gpu/mmu/gmmu_trace.c | 26 +++++++++++----------- src/nvidia/src/kernel/gpu/mmu/gmmu_walk.c | 14 ++++++------ 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/nvidia/src/kernel/gpu/mmu/bar2_walk.c b/src/nvidia/src/kernel/gpu/mmu/bar2_walk.c index bae762f39..ebb3b8c43 100644 --- a/src/nvidia/src/kernel/gpu/mmu/bar2_walk.c +++ b/src/nvidia/src/kernel/gpu/mmu/bar2_walk.c @@ -935,11 +935,11 @@ _bar2WalkCBWriteBuffer const MMU_WALK_CALLBACKS g_bar2WalkCallbacks = { - _bar2WalkCBLevelAlloc, - _bar2WalkCBLevelFree, - _bar2WalkCBUpdatePdb, - _bar2WalkCBUpdatePde, - _bar2WalkCBFillEntries, - NULL, - _bar2WalkCBWriteBuffer, + .LevelAlloc = _bar2WalkCBLevelAlloc, + .LevelFree = _bar2WalkCBLevelFree, + .UpdatePdb = _bar2WalkCBUpdatePdb, + .UpdatePde = _bar2WalkCBUpdatePde, + .FillEntries = _bar2WalkCBFillEntries, + .CopyEntries = NULL, + .WriteBuffer = _bar2WalkCBWriteBuffer, }; diff --git a/src/nvidia/src/kernel/gpu/mmu/gmmu_trace.c b/src/nvidia/src/kernel/gpu/mmu/gmmu_trace.c index 17dda40f4..6092316ea 100644 --- a/src/nvidia/src/kernel/gpu/mmu/gmmu_trace.c +++ b/src/nvidia/src/kernel/gpu/mmu/gmmu_trace.c @@ -546,17 +546,17 @@ _gmmuSwToHwLevel const MMU_TRACE_CALLBACKS g_gmmuTraceCallbacks = { - _gmmuIsPte, // isPte - _gmmuGetFmtPde, // getFmtPde - _gmmuGetFmtPte, // getFmtPte - _gmmuGetPdePa, // getPdePa - _gmmuGetPtePa, // getPtePa - _gmmuPrintPdb, // printPdb - _gmmuPrintPde, // printPde - _gmmuPrintPt, // printPt - _gmmuPrintPte, // printPte - _gmmuIsInvalidPdeOk, // isInvalidPdeOk - _gmmuPdeAddrSpace, // pdeAddrSpace - _gmmuPteAddrSpace, // pteAddrSpace - _gmmuSwToHwLevel, // swToHwLevel + .isPte = _gmmuIsPte, + .getFmtPde = _gmmuGetFmtPde, + .getFmtPte = _gmmuGetFmtPte, + .getPdePa = _gmmuGetPdePa, + .getPtePa = _gmmuGetPtePa, + .printPdb = _gmmuPrintPdb, + .printPde = _gmmuPrintPde, + .printPt = _gmmuPrintPt, + .printPte = _gmmuPrintPte, + .isInvalidPdeOk = _gmmuIsInvalidPdeOk, + .pdeAddrSpace = _gmmuPdeAddrSpace, + .pteAddrSpace = _gmmuPteAddrSpace, + .swToHwLevel = _gmmuSwToHwLevel, }; diff --git a/src/nvidia/src/kernel/gpu/mmu/gmmu_walk.c b/src/nvidia/src/kernel/gpu/mmu/gmmu_walk.c index f72063c78..9b735c53b 100644 --- a/src/nvidia/src/kernel/gpu/mmu/gmmu_walk.c +++ b/src/nvidia/src/kernel/gpu/mmu/gmmu_walk.c @@ -1002,11 +1002,11 @@ _gmmuWalkCBCopyEntries const MMU_WALK_CALLBACKS g_gmmuWalkCallbacks = { - _gmmuWalkCBLevelAlloc, - _gmmuWalkCBLevelFree, - _gmmuWalkCBUpdatePdb, - _gmmuWalkCBUpdatePde, - _gmmuWalkCBFillEntries, - _gmmuWalkCBCopyEntries, - NULL, + .LevelAlloc = _gmmuWalkCBLevelAlloc, + .LevelFree = _gmmuWalkCBLevelFree, + .UpdatePdb = _gmmuWalkCBUpdatePdb, + .UpdatePde = _gmmuWalkCBUpdatePde, + .FillEntries = _gmmuWalkCBFillEntries, + .CopyEntries = _gmmuWalkCBCopyEntries, + .WriteBuffer = NULL, }; From 6e5d31985b91ff3d171426bb9020aa2c2027fbb0 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 16:37:52 -0400 Subject: [PATCH 16/57] nvidia: make GPUHWREG use flexible arrays Make the union of GPUHWREG use proper flexible arrays to avoid UBSAN out-of-bounds warnings when accessing hardware registers. Signed-off-by: Mathias Krause --- src/common/sdk/nvidia/inc/nv-stddef.h | 8 ++++++++ src/nvidia/generated/g_gpu_access_nvoc.h | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common/sdk/nvidia/inc/nv-stddef.h b/src/common/sdk/nvidia/inc/nv-stddef.h index 5ef838b56..cc9cb5b46 100644 --- a/src/common/sdk/nvidia/inc/nv-stddef.h +++ b/src/common/sdk/nvidia/inc/nv-stddef.h @@ -35,4 +35,12 @@ #include // NULL #endif +#ifndef __DECLARE_FLEX_ARRAY + #ifdef __cplusplus + #define __DECLARE_FLEX_ARRAY(T, field) T field[0] + #else + #define __DECLARE_FLEX_ARRAY(T, field) T field[] + #endif +#endif + #endif // _NV_STDDEF_H_ diff --git a/src/nvidia/generated/g_gpu_access_nvoc.h b/src/nvidia/generated/g_gpu_access_nvoc.h index e644e0121..b00aa7d47 100644 --- a/src/nvidia/generated/g_gpu_access_nvoc.h +++ b/src/nvidia/generated/g_gpu_access_nvoc.h @@ -69,9 +69,9 @@ typedef NvU32 (*GpuReadRegCallback)(OBJGPU *, void *, NvU32 addr, NvU32 accessSi union GPUHWREG { - volatile NvV8 Reg008[1]; - volatile NvV16 Reg016[1]; - volatile NvV32 Reg032[1]; + volatile __DECLARE_FLEX_ARRAY(NvV8, Reg008); + volatile __DECLARE_FLEX_ARRAY(NvV16, Reg016); + volatile __DECLARE_FLEX_ARRAY(NvV32, Reg032); }; typedef union GPUHWREG GPUHWREG; From 23f1e7c67fbda7ff64b8d12022caff9d321c2237 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 27 Nov 2025 10:26:21 +0000 Subject: [PATCH 17/57] x86emu: drop dependency on Define 'NULL' directly instead of depending on system headers to do so. Signed-off-by: Mathias Krause --- src/nvidia/arch/nvalloc/unix/include/x86emu/x86emui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/arch/nvalloc/unix/include/x86emu/x86emui.h b/src/nvidia/arch/nvalloc/unix/include/x86emu/x86emui.h index 5788558d8..0ce30835d 100644 --- a/src/nvidia/arch/nvalloc/unix/include/x86emu/x86emui.h +++ b/src/nvidia/arch/nvalloc/unix/include/x86emu/x86emui.h @@ -51,7 +51,7 @@ #ifndef NO_SYS_HEADERS #define NO_SYS_HEADERS #endif -#include /* NULL */ +#define NULL ((void *)0) #if defined(__cplusplus) && !defined(_NO_INLINE) #define _INLINE inline #else From 7c70a05a42d16b0194f88d21c8777cf1024aa121 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 26 Feb 2026 20:49:37 +0000 Subject: [PATCH 18/57] kernel-open/Kbuild: fix potential duplicated CFLAGS The ASSIGN_PER_OBJ_CFLAGS helper tries to support older kbuild versions that used the full path as the target-stem by not only assigning the basenamed "CFLAGS_" variable but also one with the full path. However, if the object file's directory part is empty, ASSIGN_PER_OBJ_CFLAGS would add the flags twice, as "$(notdir $(1))" and "$(1)" evaluate to the same. Avoid that by filtering duplicates via $(sort ...). Signed-off-by: Mathias Krause --- kernel-open/Kbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 60181c7f0..9f2d0435a 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -39,7 +39,7 @@ NV_BUILD_TYPE ?= release # ASSIGN_PER_OBJ_CFLAGS = \ $(foreach _cflags_variable, \ - $(notdir $(1)) $(1), \ + $(sort $(notdir $(1)) $(1)), \ $(eval $(addprefix CFLAGS_,$(_cflags_variable)) += $(2))) From 9947da36a262b5d93569c91531a21c7021921aca Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:54:38 +0000 Subject: [PATCH 19/57] kernel-open/Kbuild: CFLAGS_REMOVE support Provide an ASSIGN_PER_OBJ_CFLAGS_REMOVE macro to be able to set per-object-file CFLAGS_REMOVE variables. For it to be effective, move the *.Kbuild include to after setting early cflags, allowing to override these via ASSIGN_PER_OBJ_CFLAGS_REMOVE. Signed-off-by: Mathias Krause --- kernel-open/Kbuild | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 9f2d0435a..1c0e3851e 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -42,6 +42,14 @@ ASSIGN_PER_OBJ_CFLAGS = \ $(sort $(notdir $(1)) $(1)), \ $(eval $(addprefix CFLAGS_,$(_cflags_variable)) += $(2))) +# +# As ASSIGN_PER_OBJ_CFLAGS, just for per-object CFLAGS_REMOVE. +# +ASSIGN_PER_OBJ_CFLAGS_REMOVE = \ + $(foreach _cflags_variable, \ + $(sort $(notdir $(1)) $(1)), \ + $(eval $(addprefix CFLAGS_REMOVE_,$(_cflags_variable)) += $(2))) + # # Include the specifics of the individual NVIDIA kernel modules. @@ -70,13 +78,15 @@ endif quiet_cmd_symlink = SYMLINK $@ cmd_symlink = ln -sf $(abspath $<) $@ +# early flags, which may be filtered for USE_KBUILD=1 builds +ccflags-y += -I$(src)/common/inc +ccflags-y += -I$(src) + $(foreach _module, $(NV_KERNEL_MODULES), \ $(eval include $(src)/$(_module)/$(_module).Kbuild)) -ccflags-y += -I$(src)/common/inc -ccflags-y += -I$(src) ccflags-y += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-format-extra-args ccflags-y += -D__KERNEL__ -DMODULE -DNVRM ccflags-y += -DNV_VERSION_STRING=\"590.48.01\" From 2c1dee51fca52f9e5a90e40c472fa4746fdb5d32 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 10:37:55 +0000 Subject: [PATCH 20/57] kernel-open/Kbuild: NVIDSTRING support Add support for the GENERATE_NVIDSTRING macro for pure kbuild-based builds. Signed-off-by: Mathias Krause --- kernel-open/Kbuild | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 1c0e3851e..20478b072 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -51,6 +51,68 @@ ASSIGN_PER_OBJ_CFLAGS_REMOVE = \ $(eval $(addprefix CFLAGS_REMOVE_,$(_cflags_variable)) += $(2))) +# +# Define rule for generating a source file containing identification information +# for the build. +# +# $(1) string name +# $(2) module name +# $(3) prerequisite object files +############################################################################## + +NV_BUILD_USER ?= $(shell whoami) +NV_BUILD_HOST ?= $(shell hostname) + +ifndef TARGET_OS + TARGET_OS := $(shell uname) +endif + +ifndef TARGET_ARCH + ifneq ($(TARGET_OS),SunOS) + TARGET_ARCH := $(shell uname -m) + else + TARGET_ARCH := $(shell isainfo -n) + endif + TARGET_ARCH := $(subst i386,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i486,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i586,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i686,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst amd64,x86_64,$(TARGET_ARCH)) +endif + +DATE ?= date + +NVIDSTRING ?= g_nvid_string.c + +ifeq ($(NV_BUILD_TYPE),debug) + NVIDSTRING_BUILD_TYPE_STRING = Debug Build +else ifeq ($(NV_BUILD_TYPE),develop) + NVIDSTRING_BUILD_TYPE_STRING = Develop Build +else ifeq ($(NV_BUILD_TYPE),release) + NVIDSTRING_BUILD_TYPE_STRING = Release Build +else + NVIDSTRING_BUILD_TYPE_STRING = Custom '$(NV_BUILD_TYPE)' Build +endif + +# NV_VERSION_STRING is set as preprocessor define +NVIDIA_NVID_VERSION := \"NV_VERSION_STRING\" + +define GENERATE_NVIDSTRING + $(1)_BUILD_NVID := NVIDIA $$(strip $(2)) for $$(TARGET_ARCH) $$(NVIDIA_NVID_VERSION) + $(1)_BUILD_NVID := $$($$(strip $(1))_BUILD_NVID) $$(NVIDSTRING_BUILD_TYPE_STRING) + ifneq ($$(NVIDIA_NVID_EXTRA),) + $(1)_BUILD_NVID := $$($$(strip $(1))_BUILD_NVID) $$(NVIDIA_NVID_EXTRA) + endif + $(1)_BUILD_NVID := $$($$(strip $(1))_BUILD_NVID) ($$(NV_BUILD_USER)@$$(NV_BUILD_HOST)) + # g_nvid_string.c depends on all objects except g_nvid_string.o, and version.mk + # $(NVIDSTRING) evaluated early, to allow reusing it + $$(obj)/$(NVIDSTRING): $$(adprefix $$(obj)/,$$(filter-out $(NVIDSTRING:.c=.o), $(3))) $$(VERSION_MK) + @mkdir -p $$(dir $$@) + @echo "const char $(1)[] = \"nvidia id: $$($$(strip $(1))_BUILD_NVID) `$$(DATE)`\";" > $$@ + @echo "const char *const p$$(strip $(1)) = $(1) + 11;" >> $$@; +endef + + # # Include the specifics of the individual NVIDIA kernel modules. # From 405804c912951e4cf9c2ca5c4d9edba108d138d9 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 26 Feb 2026 20:59:12 +0000 Subject: [PATCH 21/57] kernel-open/Kbuild: LDFLAGS and OBJCOPYFLAGS support Provide ASSIGN_PER_OBJ_LDFLAGS and ASSIGN_PER_OBJ_OBJCOPYFLAGS macros that can be used to to set per-object-file LDFLAGS and OBJCOPYFLAGS variables. Signed-off-by: Mathias Krause --- kernel-open/Kbuild | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 20478b072..2baa133b2 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -50,6 +50,22 @@ ASSIGN_PER_OBJ_CFLAGS_REMOVE = \ $(sort $(notdir $(1)) $(1)), \ $(eval $(addprefix CFLAGS_REMOVE_,$(_cflags_variable)) += $(2))) +# +# As ASSIGN_PER_OBJ_CFLAGS, just for per-object LDFLAGS. +# +ASSIGN_PER_OBJ_LDFLAGS = \ + $(foreach _ldflags_variable, \ + $(sort $(notdir $(1)) $(1)), \ + $(eval $(addprefix LDFLAGS_,$(_ldflags_variable)) += $(2))) + +# +# As ASSIGN_PER_OBJ_CFLAGS, just for per-object OBJCOPYFLAGS. +# +ASSIGN_PER_OBJ_OBJCOPYFLAGS = \ + $(foreach _objcopyflags_variable, \ + $(sort $(notdir $(1)) $(1)i), \ + $(eval $(addprefix OBJCOPYFLAGS_,$(_objcopyflags_variable)) += $(2))) + # # Define rule for generating a source file containing identification information From 6b0c069f94c3b5ee02eaa3e04c3420d0ef77b534 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 10:43:56 +0000 Subject: [PATCH 22/57] kernel-open/Kbuild: stub module support Add rules to work around kbuild's lack of compound object file support for modules. It's implemented by building stub modules composed of the object files intended to group plus kernel-open/common/mod_stub.o for the .modinfo bits which get stripped by an intermediate objcopy call. The stub module should be named $foo.stub.o, the created (and depended on) object file will be called $foo.clean.o. Signed-off-by: Mathias Krause --- kernel-open/Kbuild | 24 ++++++++++++++++++++++++ kernel-open/common/mod_stub.c | 4 ++++ 2 files changed, 28 insertions(+) create mode 100644 kernel-open/common/mod_stub.c diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 2baa133b2..7905c9f13 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -156,6 +156,30 @@ endif quiet_cmd_symlink = SYMLINK $@ cmd_symlink = ln -sf $(abspath $<) $@ +# +# Command to neuter .modinfo section for stub modules which are our hacky +# attempt to make kbuild support nested compound objects. +# +# Intended usage: +# +# # stub module +# obj-m += nv-kernel.stub.o +# nv-kernel.stub-y := ... +# +# # real module wanting to make use of nv-kernel.o +# obj-m += ndidia.o +# nvidia-y += nv-kernel.clean.o ... +# + +MOD_STUB := common/mod_stub.o + +# not really needed, but to have conftest be the very first +NV_OBJECTS_DEPEND_ON_CONFTEST += $(MOD_STUB) + +$(obj)/%.clean.o: OBJCOPYFLAGS += --rename-section .modinfo=.discard.modinfo +$(obj)/%.clean.o: $(obj)/%.stub.o FORCE + $(call if_changed,objcopy) + # early flags, which may be filtered for USE_KBUILD=1 builds ccflags-y += -I$(src)/common/inc ccflags-y += -I$(src) diff --git a/kernel-open/common/mod_stub.c b/kernel-open/common/mod_stub.c new file mode 100644 index 000000000..f3584c952 --- /dev/null +++ b/kernel-open/common/mod_stub.c @@ -0,0 +1,4 @@ +/* Stub module fragment for emulated nested compound object kbuild support */ +#include + +MODULE_LICENSE("Dual MIT/GPL"); From f8481c080aa89c02676e230ed20e5f7318242c7d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 10:48:06 +0000 Subject: [PATCH 23/57] kernel-open: introduce module preparation step Don't build the regular modules during preparation, which is an intermediate step for full kbuild support. Signed-off-by: Mathias Krause --- kernel-open/Makefile | 8 ++++++++ kernel-open/nvidia-drm/nvidia-drm.Kbuild | 2 ++ kernel-open/nvidia-modeset/nvidia-modeset.Kbuild | 2 ++ kernel-open/nvidia-peermem/nvidia-peermem.Kbuild | 2 ++ kernel-open/nvidia-uvm/nvidia-uvm.Kbuild | 2 ++ kernel-open/nvidia/nvidia.Kbuild | 4 ++++ 6 files changed, 20 insertions(+) diff --git a/kernel-open/Makefile b/kernel-open/Makefile index 50565d934..01c3fd936 100644 --- a/kernel-open/Makefile +++ b/kernel-open/Makefile @@ -141,6 +141,14 @@ else KBUILD_PARAMS += NV_KERNEL_MODULES="$(NV_KERNEL_MODULES)" KBUILD_PARAMS += INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)" KBUILD_PARAMS += NV_SPECTRE_V2=$(SPECTRE_V2_RETPOLINE) + ifeq ($(USE_KBUILD),1) + KBUILD_PARAMS += NV_PREPARE_ONLY=$(NV_PREPARE_ONLY) + ifeq ($(NV_PREPARE_ONLY),1) + KBUILD_PARAMS += KBUILD_MODPOST_NOFINAL=1 + KBUILD_PARAMS += MODPOST=/bin/true + KBUILD_PARAMS += objtool-enabled= + endif + endif .PHONY: modules module clean clean_conftest modules_install modules clean modules_install: diff --git a/kernel-open/nvidia-drm/nvidia-drm.Kbuild b/kernel-open/nvidia-drm/nvidia-drm.Kbuild index 892fa4dab..9998773fd 100644 --- a/kernel-open/nvidia-drm/nvidia-drm.Kbuild +++ b/kernel-open/nvidia-drm/nvidia-drm.Kbuild @@ -14,8 +14,10 @@ NVIDIA_DRM_SOURCES += nvidia-drm/nvidia-drm-linux.c NVIDIA_DRM_OBJECTS = $(patsubst %.c,%.o,$(NVIDIA_DRM_SOURCES)) +ifneq ($(NV_PREPARE_ONLY),1) obj-m += nvidia-drm.o nvidia-drm-y := $(NVIDIA_DRM_OBJECTS) +endif NVIDIA_DRM_KO = nvidia-drm/nvidia-drm.ko diff --git a/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild b/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild index 15694fe5d..bb7ca8edc 100644 --- a/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild +++ b/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild @@ -11,8 +11,10 @@ NVIDIA_MODESET_SOURCES += nvidia-modeset/nv-kthread-q.c NVIDIA_MODESET_OBJECTS = $(patsubst %.c,%.o,$(NVIDIA_MODESET_SOURCES)) +ifneq ($(NV_PREPARE_ONLY),1) obj-m += nvidia-modeset.o nvidia-modeset-y := $(NVIDIA_MODESET_OBJECTS) +endif NVIDIA_MODESET_KO = nvidia-modeset/nvidia-modeset.ko diff --git a/kernel-open/nvidia-peermem/nvidia-peermem.Kbuild b/kernel-open/nvidia-peermem/nvidia-peermem.Kbuild index d2bcaf8d0..c52a74ed1 100644 --- a/kernel-open/nvidia-peermem/nvidia-peermem.Kbuild +++ b/kernel-open/nvidia-peermem/nvidia-peermem.Kbuild @@ -11,8 +11,10 @@ NVIDIA_PEERMEM_SOURCES += nvidia-peermem/nvidia-peermem.c NVIDIA_PEERMEM_OBJECTS = $(patsubst %.c,%.o,$(NVIDIA_PEERMEM_SOURCES)) +ifneq ($(NV_PREPARE_ONLY),1) obj-m += nvidia-peermem.o nvidia-peermem-y := $(NVIDIA_PEERMEM_OBJECTS) +endif NVIDIA_PEERMEM_KO = nvidia-peermem/nvidia-peermem.ko diff --git a/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild b/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild index c33f5c2f4..6df0d381c 100644 --- a/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild +++ b/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild @@ -13,8 +13,10 @@ NVIDIA_UVM_OBJECTS = include $(src)/nvidia-uvm/nvidia-uvm-sources.Kbuild NVIDIA_UVM_OBJECTS += $(patsubst %.c,%.o,$(NVIDIA_UVM_SOURCES)) +ifneq ($(NV_PREPARE_ONLY),1) obj-m += nvidia-uvm.o nvidia-uvm-y := $(NVIDIA_UVM_OBJECTS) +endif NVIDIA_UVM_KO = nvidia-uvm/nvidia-uvm.ko diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index 8b05205d4..bd9c0f4ba 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -9,8 +9,10 @@ include $(src)/nvidia/nvidia-sources.Kbuild NVIDIA_OBJECTS = $(patsubst %.c,%.o,$(NVIDIA_SOURCES)) +ifneq ($(NV_PREPARE_ONLY),1) obj-m += nvidia.o nvidia-y := $(NVIDIA_OBJECTS) +endif NVIDIA_KO = nvidia/nvidia.ko @@ -96,8 +98,10 @@ NVIDIA_INTERFACE := nvidia/nv-interface.o # before v5.6 looks at "always"; kernel versions between v5.12 and v5.6 # look at both. +ifneq ($(NV_PREPARE_ONLY),1) always += $(NVIDIA_INTERFACE) always-y += $(NVIDIA_INTERFACE) +endif $(obj)/$(NVIDIA_INTERFACE): $(addprefix $(obj)/,$(NVIDIA_OBJECTS)) $(LD) -r -o $@ $^ From 8eec7471fd67723068a5c960a250a93100cf4410 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 9 Dec 2025 19:41:45 +0000 Subject: [PATCH 24/57] src/nvidia: move CFLAGS to defs.mk Extract compiler flags into defs.mk for reuse by upcomming kbuild support. Signed-off-by: Mathias Krause --- src/nvidia/Makefile | 78 +++---------------------------------------- src/nvidia/defs.mk | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 74 deletions(-) create mode 100644 src/nvidia/defs.mk diff --git a/src/nvidia/Makefile b/src/nvidia/Makefile index d1d6d8663..686d36c3b 100644 --- a/src/nvidia/Makefile +++ b/src/nvidia/Makefile @@ -9,6 +9,7 @@ VERSION_MK_DIR = ../../ include ../../utils.mk include srcs.mk +include defs.mk ############################################################################## # Helper functions to determine the compiler type @@ -22,54 +23,17 @@ GET_COMPILER_TYPE = \ ALL_SRCS = $(SRCS) $(SRCS_CXX) ALL_SRCS += $(NVIDSTRING) -SRC_COMMON = ../common CONDITIONAL_CFLAGS := -CFLAGS += -include $(SRC_COMMON)/sdk/nvidia/inc/cpuopsys.h - -CFLAGS += -I kernel/inc -CFLAGS += -I interface -CFLAGS += -I $(SRC_COMMON)/sdk/nvidia/inc -CFLAGS += -I $(SRC_COMMON)/sdk/nvidia/inc/hw -CFLAGS += -I arch/nvalloc/common/inc -CFLAGS += -I arch/nvalloc/common/inc/gsp -CFLAGS += -I arch/nvalloc/common/inc/deprecated -CFLAGS += -I arch/nvalloc/unix/include -CFLAGS += -I inc -CFLAGS += -I inc/os -CFLAGS += -I $(SRC_COMMON)/shared/inc -CFLAGS += -I $(SRC_COMMON)/shared/msgq/inc -CFLAGS += -I $(SRC_COMMON)/inc - -CFLAGS += -I $(SRC_COMMON)/uproc/os/libos-v2.0.0/include -CFLAGS += -I $(SRC_COMMON)/uproc/os/common/include -CFLAGS += -I $(SRC_COMMON)/inc/swref -CFLAGS += -I $(SRC_COMMON)/inc/swref/published - -CFLAGS += -I generated -CFLAGS += -I $(SRC_COMMON)/nvswitch/kernel/inc -CFLAGS += -I $(SRC_COMMON)/nvswitch/interface -CFLAGS += -I $(SRC_COMMON)/nvswitch/common/inc/ -CFLAGS += -I $(SRC_COMMON)/inc/displayport -CFLAGS += -I $(SRC_COMMON)/nvlink/interface/ -CFLAGS += -I $(SRC_COMMON)/nvlink/inband/interface -CFLAGS += -I src/mm/uvm/interface -CFLAGS += -I inc/libraries -CFLAGS += -I src/libraries -CFLAGS += -I inc/kernel +CFLAGS += $(addprefix -include ,$(NV_INCLUDE)) +CFLAGS += $(addprefix -I ,$(NV_INCDIRS)) +CFLAGS += $(NV_DEFINES) # Libspdm source requires additional include paths and build flags. include src/libraries/libspdm/nvidia/openspdm.mk $(call BUILD_OBJECT_LIST,$(LIBSPDM_SOURCES)): CFLAGS += $(addprefix -I ,$(LIBSPDM_INCLUDES)) $(call BUILD_OBJECT_LIST,$(LIBSPDM_SOURCES)): CFLAGS += $(addprefix -D,$(LIBSPDM_DEFINES)) -#if NV_USE_MBEDTLS -MBEDTLS_VERSION ?= 3.6.2 -CFLAGS += -I $(SRC_COMMON)/mbedtls/$(MBEDTLS_VERSION)/include -CFLAGS += -I $(SRC_COMMON)/mbedtls/$(MBEDTLS_VERSION)/nvidia -CFLAGS += -D"MBEDTLS_USER_CONFIG_FILE=" -#endif - CFLAGS += -Werror-implicit-function-declaration CFLAGS += -Wwrite-strings CFLAGS += -Wundef @@ -104,40 +68,6 @@ endif CFLAGS += -fno-pic -CFLAGS += -D_LANGUAGE_C -CFLAGS += -D__NO_CTYPE -CFLAGS += -DNVRM -CFLAGS += -DLOCK_VAL_ENABLED=0 -CFLAGS += -DPORT_ATOMIC_64_BIT_SUPPORTED=1 -CFLAGS += -DPORT_IS_KERNEL_BUILD=1 -CFLAGS += -DPORT_IS_CHECKED_BUILD=0 -CFLAGS += -DPORT_MODULE_atomic=1 -CFLAGS += -DPORT_MODULE_core=1 -CFLAGS += -DPORT_MODULE_cpu=1 -CFLAGS += -DPORT_MODULE_crypto=1 -CFLAGS += -DPORT_MODULE_debug=1 -CFLAGS += -DPORT_MODULE_memory=1 -CFLAGS += -DPORT_MODULE_safe=1 -CFLAGS += -DPORT_MODULE_string=1 -CFLAGS += -DPORT_MODULE_sync=1 -CFLAGS += -DPORT_MODULE_thread=1 -CFLAGS += -DPORT_MODULE_util=1 -CFLAGS += -DPORT_MODULE_example=0 -CFLAGS += -DPORT_MODULE_mmio=0 -CFLAGS += -DPORT_MODULE_time=0 -CFLAGS += -DRS_STANDALONE=0 -CFLAGS += -DRS_STANDALONE_TEST=0 -CFLAGS += -DRS_COMPATABILITY_MODE=1 -CFLAGS += -DRS_PROVIDES_API_STATE=0 -CFLAGS += -DNV_CONTAINERS_NO_TEMPLATES - -CFLAGS += -DINCLUDE_NVLINK_LIB -CFLAGS += -DINCLUDE_NVSWITCH_LIB - -CFLAGS += -DNV_PRINTF_STRINGS_ALLOWED=1 -CFLAGS += -DNV_ASSERT_FAILED_USES_STRINGS=1 -CFLAGS += -DPORT_ASSERT_FAILED_USES_STRINGS=1 - ifeq ($(DEBUG),1) CFLAGS += -gsplit-dwarf endif diff --git a/src/nvidia/defs.mk b/src/nvidia/defs.mk new file mode 100644 index 000000000..96af68db9 --- /dev/null +++ b/src/nvidia/defs.mk @@ -0,0 +1,81 @@ +# shared make defines for Makefile and Kbuild + +SRC_COMMON := ../common + +NV_INCLUDE := +NV_INCDIRS := +NV_DEFINES := + +NV_INCLUDE += $(SRC_COMMON)/sdk/nvidia/inc/cpuopsys.h + +NV_INCDIRS += kernel/inc +NV_INCDIRS += interface +NV_INCDIRS += $(SRC_COMMON)/sdk/nvidia/inc +NV_INCDIRS += $(SRC_COMMON)/sdk/nvidia/inc/hw +NV_INCDIRS += arch/nvalloc/common/inc +NV_INCDIRS += arch/nvalloc/common/inc/gsp +NV_INCDIRS += arch/nvalloc/common/inc/deprecated +NV_INCDIRS += arch/nvalloc/unix/include +NV_INCDIRS += inc +NV_INCDIRS += inc/os +NV_INCDIRS += $(SRC_COMMON)/shared/inc +NV_INCDIRS += $(SRC_COMMON)/shared/msgq/inc +NV_INCDIRS += $(SRC_COMMON)/inc + +NV_INCDIRS += $(SRC_COMMON)/uproc/os/libos-v2.0.0/include +NV_INCDIRS += $(SRC_COMMON)/uproc/os/common/include +NV_INCDIRS += $(SRC_COMMON)/inc/swref +NV_INCDIRS += $(SRC_COMMON)/inc/swref/published + +NV_INCDIRS += generated +NV_INCDIRS += $(SRC_COMMON)/nvswitch/kernel/inc +NV_INCDIRS += $(SRC_COMMON)/nvswitch/interface +NV_INCDIRS += $(SRC_COMMON)/nvswitch/common/inc/ +NV_INCDIRS += $(SRC_COMMON)/inc/displayport +NV_INCDIRS += $(SRC_COMMON)/nvlink/interface/ +NV_INCDIRS += $(SRC_COMMON)/nvlink/inband/interface +NV_INCDIRS += src/mm/uvm/interface +NV_INCDIRS += inc/libraries +NV_INCDIRS += src/libraries +NV_INCDIRS += inc/kernel + +#if NV_USE_MBEDTLS +MBEDTLS_VERSION ?= 3.6.2 +NV_INCDIRS += $(SRC_COMMON)/mbedtls/$(MBEDTLS_VERSION)/include +NV_INCDIRS += $(SRC_COMMON)/mbedtls/$(MBEDTLS_VERSION)/nvidia +NV_DEFINES += -D"MBEDTLS_USER_CONFIG_FILE=" +#endif + +NV_DEFINES += -D_LANGUAGE_C +NV_DEFINES += -D__NO_CTYPE +NV_DEFINES += -DNVRM +NV_DEFINES += -DLOCK_VAL_ENABLED=0 +NV_DEFINES += -DPORT_ATOMIC_64_BIT_SUPPORTED=1 +NV_DEFINES += -DPORT_IS_KERNEL_BUILD=1 +NV_DEFINES += -DPORT_IS_CHECKED_BUILD=0 +NV_DEFINES += -DPORT_MODULE_atomic=1 +NV_DEFINES += -DPORT_MODULE_core=1 +NV_DEFINES += -DPORT_MODULE_cpu=1 +NV_DEFINES += -DPORT_MODULE_crypto=1 +NV_DEFINES += -DPORT_MODULE_debug=1 +NV_DEFINES += -DPORT_MODULE_memory=1 +NV_DEFINES += -DPORT_MODULE_safe=1 +NV_DEFINES += -DPORT_MODULE_string=1 +NV_DEFINES += -DPORT_MODULE_sync=1 +NV_DEFINES += -DPORT_MODULE_thread=1 +NV_DEFINES += -DPORT_MODULE_util=1 +NV_DEFINES += -DPORT_MODULE_example=0 +NV_DEFINES += -DPORT_MODULE_mmio=0 +NV_DEFINES += -DPORT_MODULE_time=0 +NV_DEFINES += -DRS_STANDALONE=0 +NV_DEFINES += -DRS_STANDALONE_TEST=0 +NV_DEFINES += -DRS_COMPATABILITY_MODE=1 +NV_DEFINES += -DRS_PROVIDES_API_STATE=0 +NV_DEFINES += -DNV_CONTAINERS_NO_TEMPLATES + +NV_DEFINES += -DINCLUDE_NVLINK_LIB +NV_DEFINES += -DINCLUDE_NVSWITCH_LIB + +NV_DEFINES += -DNV_PRINTF_STRINGS_ALLOWED=1 +NV_DEFINES += -DNV_ASSERT_FAILED_USES_STRINGS=1 +NV_DEFINES += -DPORT_ASSERT_FAILED_USES_STRINGS=1 From fb77ed328a60fc4e1ad470bdbeaef1a59327eeff Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 26 Feb 2026 21:03:02 +0000 Subject: [PATCH 25/57] src/nvidia: move LINKER_SCRIPT and EXPORTS_LINK_COMMAND to srcs.mk Move the definitions of LINKER_SCRIPT and EXPORTS_LINK_COMMAND to srcs.mk. Signed-off-by: Mathias Krause --- src/nvidia/Makefile | 3 --- src/nvidia/srcs.mk | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nvidia/Makefile b/src/nvidia/Makefile index 686d36c3b..9a8aef1e9 100644 --- a/src/nvidia/Makefile +++ b/src/nvidia/Makefile @@ -80,7 +80,6 @@ endif CFLAGS += -ffunction-sections CFLAGS += -fdata-sections NV_KERNEL_O_LDFLAGS += --gc-sections -EXPORTS_LINK_COMMAND = exports_link_command.txt ifeq ($(TARGET_ARCH),x86_64) COMPILER_TYPE := $(call GET_COMPILER_TYPE, $(CC)) @@ -137,8 +136,6 @@ NV_KERNEL_O = $(OUTPUTDIR)/nv-kernel.o .PHONY: all all: $(NV_KERNEL_O) -LINKER_SCRIPT = nv-kernel.ld - NV_KERNEL_O_LDFLAGS += $(LDFLAGS) $(NV_KERNEL_O): $(OBJS) $(EXPORTS_LINK_COMMAND) $(LINKER_SCRIPT) diff --git a/src/nvidia/srcs.mk b/src/nvidia/srcs.mk index 675167f37..3e42a15e4 100644 --- a/src/nvidia/srcs.mk +++ b/src/nvidia/srcs.mk @@ -1017,3 +1017,6 @@ SRCS += src/libraries/utils/nvassert.c SRCS += ../common/uproc/os/libos-v3.1.0/lib/libdwarf.c SRCS += ../common/uproc/os/libos-v3.1.0/lib/libelf.c SRCS += ../common/uproc/os/libos-v3.1.0/lib/liblogdecode.c + +LINKER_SCRIPT := nv-kernel.ld +EXPORTS_LINK_COMMAND := exports_link_command.txt From 3b6a3b31f8feebd06b0e559280f5a2f51c3156fe Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:08:07 +0000 Subject: [PATCH 26/57] src/nvidia: preliminary kbuild support Provide a Kbuild file to be able to build src/nvidia/ using Linux's kbuild. It's meant to be included by kernel-open/nvidia/. Signed-off-by: Mathias Krause --- src/nvidia/nvidia.Kbuild | 92 ++++++++++++++++++++++++++++++++++++++++ src/nvidia/srcs.mk | 4 +- 2 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/nvidia/nvidia.Kbuild diff --git a/src/nvidia/nvidia.Kbuild b/src/nvidia/nvidia.Kbuild new file mode 100644 index 000000000..90787377a --- /dev/null +++ b/src/nvidia/nvidia.Kbuild @@ -0,0 +1,92 @@ +########################################################################### +# nvidia.Kbuild, included by kernel-open/nvidia/nvidia.Kbuild +########################################################################### + +nvidia_src ?= . + +NV_KERNEL_O = nv-kernel.clean.o +NV_KERNEL_O_OBJS = $(nv-kernel-objs) + +include $(src)/$(nvidia_src)/srcs.mk +include $(src)/$(nvidia_src)/defs.mk + +# The source files for nv-kernel.o are all SRCS and SRCS_CXX defined in +# srcs.mk, and the NVIDIA ID string +SRCS := $(addprefix $(nvidia_src)/,$(SRCS)) +SRCS_CXX := $(addprefix $(nvidia_src)/,$(SRCS_CXX)) +NVIDSTRING := $(addprefix $(nvidia_src)/,g_nvid_string.c) + +nv-kernel-objs := $(SRCS:.c=.o) +nv-kernel-objs += $(SRCS_CXX:.cpp=.o) +nv-kernel-objs += $(NVIDSTRING:.c=.o) + +# Hack to create a relocatable intermediate object file to avoid '/bin/sh: +# Argument list too long' errors for the real module. +ifeq ($(NV_PREPARE_ONLY),1) +obj-m += nv-kernel.stub.o +nv-kernel.stub-y := $(nv-kernel-objs) $(MOD_STUB) +endif + +# for the 'clean' target +targets += $(nv-kernel-objs) +# ensure to use "our" NVIDSTRING +$(eval targets += $(NVIDSTRING)) + +# Define how to generate the NVIDIA ID string -- intentionally deviates from +# the OS-agnostic build +$(eval $(call GENERATE_NVIDSTRING, \ + NVRM_ID, \ + Linux Open Kernel Module, $(nv-kernel-objs))) + +# now compile the final ccflags +nv-kernel-cflags := $(addprefix -include $(src)/$(nvidia_src)/,$(NV_INCLUDE)) +nv-kernel-cflags += $(addprefix -I $(src)/$(nvidia_src)/,$(NV_INCDIRS)) +nv-kernel-cflags += $(NV_DEFINES) + +# quite some implicit fall-through cases +nv-kernel-cflags += -Wno-implicit-fallthrough +# lots of missing prototypes, all accross the board +nv-kernel-cflags-remove := -Wmissing-declarations -Wmissing-prototypes + +# Define how to perform dead code elimination: place each symbol in its own +# section at compile time, and garbage collect unreachable sections at link +# time. exports_link_command.txt tells the linker which symbols need to be +# exported from $(NV_KERNEL_O) so the linker can determine which symbols are +# unreachable. +nv-kernel-cflags += -ffunction-sections +nv-kernel-cflags += -fdata-sections + +nv-kernel-ldflags := --gc-sections +nv-kernel-ldflags += @$(src)/$(nvidia_src)/$(EXPORTS_LINK_COMMAND) +nv-kernel-ldflags += -T $(src)/$(nvidia_src)/$(LINKER_SCRIPT) + +nv-kernel-objcopyflags := --localize-symbol=memset +nv-kernel-objcopyflags += --localize-symbol=memcpy +#nv-kernel-objcopyflags += --remove-section=.note.gnu.property + +# move early -I... flags to after ours -- what a hack! +ccflags-includes := $(filter -I$(src)%,$(ccflags-y)) +nv-kernel-cflags += $(patsubst -I%,-I %,$(ccflags-includes)) +nv-kernel-cflags-remove += $(ccflags-includes) + +$(call ASSIGN_PER_OBJ_CFLAGS_REMOVE, $(nv-kernel-objs), $(nv-kernel-cflags-remove)) +$(call ASSIGN_PER_OBJ_CFLAGS, $(nv-kernel-objs), $(nv-kernel-cflags)) +$(call ASSIGN_PER_OBJ_LDFLAGS, nv-kernel.stub.o, $(nv-kernel-ldflags)) +$(call ASSIGN_PER_OBJ_OBJCOPYFLAGS, nv-kernel.clean.o, $(nv-kernel-objcopyflags)) + +$(obj)/nv-kernel.stub.o: $(addprefix $(obj)/$(nvidia_src)/,\ + $(EXPORTS_LINK_COMMAND) $(LINKER_SCRIPT)) + +## Libspdm source requires additional include paths and build flags. +include $(src)/$(nvidia_src)/src/libraries/libspdm/nvidia/openspdm.mk +# is sufficient to get all required defines and types +LIBSPDM_DEFINES += "LIBSPDM_STDINT_ALT=" +LIBSPDM_DEFINES += "LIBSPDM_STDBOOL_ALT=" +LIBSPDM_DEFINES += "LIBSPDM_STDDEF_ALT=" + +libspdm-objs := $(addprefix $(nvidia_src)/,$(LIBSPDM_SOURCES:.c=.o)) + +libspdm-cflags := $(addprefix -I $(src)/$(nvidia_src)/,$(LIBSPDM_INCLUDES)) +libspdm-cflags += $(addprefix -D,$(LIBSPDM_DEFINES)) + +$(call ASSIGN_PER_OBJ_CFLAGS, $(libspdm-objs), $(libspdm-cflags)) diff --git a/src/nvidia/srcs.mk b/src/nvidia/srcs.mk index 3e42a15e4..17acb032c 100644 --- a/src/nvidia/srcs.mk +++ b/src/nvidia/srcs.mk @@ -1,5 +1,5 @@ -SRCS ?= -SRCS_CXX ?= +SRCS := +SRCS_CXX := SRCS += generated/g_access_cntr_buffer_nvoc.c SRCS += generated/g_all_dcl_pb.c From e3cdae8395b48f77c070ddc6d202e5f215c5ef90 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:56:46 +0000 Subject: [PATCH 27/57] kernel-open/nvidia: Kbuild support Support building the dependent src/nv-kernel.o using Linux's kbuild. Signed-off-by: Mathias Krause --- kernel-open/nvidia/nvidia.Kbuild | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index bd9c0f4ba..498d23eba 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -14,6 +14,17 @@ obj-m += nvidia.o nvidia-y := $(NVIDIA_OBJECTS) endif +ifeq ($(USE_KBUILD),1) +# build nv-kernel.o using Linux's kbuild system +nvidia_src := ../src/nvidia +include $(src)/$(nvidia_src)/nvidia.Kbuild + +nvidia-y += $(NV_KERNEL_O) + +NV_OBJECTS_DEPEND_ON_CONFTEST += $(NV_KERNEL_O_OBJS) + +else # !USE_KBUILD + NVIDIA_KO = nvidia/nvidia.ko @@ -48,6 +59,7 @@ $(obj)/$(NVIDIA_BINARY_OBJECT_O): $(NVIDIA_BINARY_OBJECT) FORCE $(call if_changed,symlink) nvidia-y += $(NVIDIA_BINARY_OBJECT_O) +endif # From 17ce643814ae99be99ba6731a18f7476121a8c84 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:38:49 +0000 Subject: [PATCH 28/57] kernel-open: pass C++ compiler variable to sub-make Try to deduce a fitting C++ compiler from the kernel's config and pass it as CXX to the kernel's make file. This is required for the upcomming kbuild support. Signed-off-by: Mathias Krause --- kernel-open/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel-open/Makefile b/kernel-open/Makefile index 01c3fd936..0ddea676f 100644 --- a/kernel-open/Makefile +++ b/kernel-open/Makefile @@ -64,6 +64,7 @@ else from CONFIG_CC_VERSION_TEXT in the kernel configuration.) else CC=$(cc_version_text) + CXX=$(subst cc,++,$(cc_version_text)) endif endif endif @@ -79,6 +80,7 @@ else CC ?= cc LD ?= ld + CXX ?= c++ OBJDUMP ?= objdump AWK ?= awk # Bake the following awk program in a string. The program is needed to add C++ @@ -152,7 +154,7 @@ else .PHONY: modules module clean clean_conftest modules_install modules clean modules_install: - @$(MAKE) "LD=$(LD)" "CC=$(CC)" "OBJDUMP=$(OBJDUMP)" \ + @$(MAKE) "LD=$(LD)" "CC=$(CC)" "CXX=$(CXX)" "OBJDUMP=$(OBJDUMP)" \ $(PAHOLE_VARIABLES) $(KBUILD_PARAMS) $@ @if [ "$@" = "modules" ]; then \ for module in $(NV_KERNEL_MODULES); do \ From b60c08e4f1d25d0bdebba59c90b09c5ff6cdae9e Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Mon, 9 Feb 2026 21:33:27 +0000 Subject: [PATCH 29/57] Make nv-stddef.h C++-aware and use it in nvdp-host.cpp Wrap C++-defined types and keywords prior to including Linux kernel headers to avoid clashing with the ones defined there. This is required for the upcoming kbuild support which cannot make use of standard system headers but has to rely on kernel headers. Signed-off-by: Mathias Krause --- src/common/sdk/nvidia/inc/nv-stddef.h | 18 ++++++++++++++++++ src/nvidia-modeset/src/dp/nvdp-host.cpp | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/common/sdk/nvidia/inc/nv-stddef.h b/src/common/sdk/nvidia/inc/nv-stddef.h index cc9cb5b46..009f40ac7 100644 --- a/src/common/sdk/nvidia/inc/nv-stddef.h +++ b/src/common/sdk/nvidia/inc/nv-stddef.h @@ -28,9 +28,27 @@ #if defined(NV_KERNEL_INTERFACE_LAYER) && defined(__FreeBSD__) #include // NULL #elif defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) + #ifdef __cplusplus + // Hack to prevent from redefining 'bool' + #define _Bool int + #define bool LINUX_bool + #define true LINUX_true + #define false LINUX_false + #endif #include // NULL #include // size_t #include // SIZE_MAX,... + #ifdef __cplusplus + #undef _Bool + #undef bool + #undef true + #undef false + // XXX: no fallback for pre-C++11 but we enforce it via -std=gnu++11 + #if __cplusplus >= 201103L + #undef NULL + #define NULL nullptr + #endif + #endif #else #include // NULL #endif diff --git a/src/nvidia-modeset/src/dp/nvdp-host.cpp b/src/nvidia-modeset/src/dp/nvdp-host.cpp index eb1128b06..18c7019fd 100644 --- a/src/nvidia-modeset/src/dp/nvdp-host.cpp +++ b/src/nvidia-modeset/src/dp/nvdp-host.cpp @@ -23,7 +23,7 @@ /* DisplayPort management routines */ -#include +#include #include "nvkms-utils.h" From 58f5ca350506813d90d12be26dfd8e06efc9b474 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Mon, 9 Feb 2026 21:34:10 +0000 Subject: [PATCH 30/57] nvidia-3d: always define XZ_INTERNAL_CRC32 Make sure to always declare xz_crc32_init() in xz.h as nvidia-3d-fermi.c unconditionally makes use of it. Signed-off-by: Mathias Krause --- src/common/unix/nvidia-3d/src/nvidia-3d-fermi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/unix/nvidia-3d/src/nvidia-3d-fermi.c b/src/common/unix/nvidia-3d/src/nvidia-3d-fermi.c index 6e28df205..d561a7e92 100644 --- a/src/common/unix/nvidia-3d/src/nvidia-3d-fermi.c +++ b/src/common/unix/nvidia-3d/src/nvidia-3d-fermi.c @@ -33,6 +33,7 @@ #include #include +#define XZ_INTERNAL_CRC32 1 #include #if NV_PUSH_ALLOW_FLOAT From cf4a56d19b6769b24905a1a26b30c3f3bb69ee8b Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 11:00:53 -0400 Subject: [PATCH 31/57] dp/connectorimpl: always define DP_OPTION_AUTO_ENABLE_MST_STREAM_ENCR The preprocessor symbol DP_OPTION_AUTO_ENABLE_MST_STREAM_ENCR doesn't get defined by the build system, causing build errors under '-Werror=undef'. Fix that by providing a default definition of 0 for it. Signed-off-by: Mathias Krause --- src/common/displayport/inc/dp_connectorimpl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/displayport/inc/dp_connectorimpl.h b/src/common/displayport/inc/dp_connectorimpl.h index c46bf265c..bdc955d9b 100644 --- a/src/common/displayport/inc/dp_connectorimpl.h +++ b/src/common/displayport/inc/dp_connectorimpl.h @@ -44,6 +44,10 @@ #include "dp_deviceimpl.h" #include "./dptestutil/dp_testmessage.h" +#ifndef DP_OPTION_AUTO_ENABLE_MST_STREAM_ENCR + #define DP_OPTION_AUTO_ENABLE_MST_STREAM_ENCR 0 +#endif + // HDCP abort codes #define HDCP_FLAGS_ABORT_DEVICE_REVOKED 0x00000800 // Abort due to a revoked device in DP1.2 topology #define HDCP_FLAGS_ABORT_DEVICE_INVALID 0x00080000 // Abort due to an invalid device in DP1.2 topology From daf2363f910080c37f16677938137d3e939fa25f Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:32:46 +0000 Subject: [PATCH 32/57] src/nvidia-modeset: move CFLAGS to defs.mk, shaders to srcs.mk Extract compiler flags into defs.mk as well as shaders to srcs.mk for reuse by upcomming kbuild support. Signed-off-by: Mathias Krause --- src/nvidia-modeset/Makefile | 66 +++---------------------------------- src/nvidia-modeset/defs.mk | 62 ++++++++++++++++++++++++++++++++++ src/nvidia-modeset/srcs.mk | 7 ++++ 3 files changed, 74 insertions(+), 61 deletions(-) create mode 100644 src/nvidia-modeset/defs.mk diff --git a/src/nvidia-modeset/Makefile b/src/nvidia-modeset/Makefile index b54138cc4..a46354212 100644 --- a/src/nvidia-modeset/Makefile +++ b/src/nvidia-modeset/Makefile @@ -8,6 +8,7 @@ VERSION_MK_DIR = ../../ include ../../utils.mk include srcs.mk +include defs.mk ############################################################################## # Helper functions to determine the compiler type @@ -21,51 +22,11 @@ GET_COMPILER_TYPE = \ ALL_SRCS = $(SRCS) $(SRCS_CXX) ALL_SRCS += $(NVIDSTRING) -SRC_COMMON = ../common - CONDITIONAL_CFLAGS := -CFLAGS += -include $(SRC_COMMON)/sdk/nvidia/inc/cpuopsys.h - -CFLAGS += -I $(SRC_COMMON)/sdk/nvidia/inc -CFLAGS += -I $(SRC_COMMON)/sdk/nvidia/inc/hw -CFLAGS += -I $(SRC_COMMON)/shared/inc -CFLAGS += -I $(SRC_COMMON)/inc -CFLAGS += -I $(SRC_COMMON)/softfloat/nvidia -CFLAGS += -I $(SRC_COMMON)/softfloat/source/include -CFLAGS += -I $(SRC_COMMON)/softfloat/source/8086-SSE -CFLAGS += -I $(SRC_COMMON)/unix/common/utils/interface -CFLAGS += -I $(SRC_COMMON)/unix/common/inc -CFLAGS += -I $(SRC_COMMON)/modeset -CFLAGS += -I os-interface/include -CFLAGS += -I kapi/interface -CFLAGS += -I ../nvidia/arch/nvalloc/unix/include -CFLAGS += -I interface -CFLAGS += -I include -CFLAGS += -I kapi/include -CFLAGS += -I generated -CFLAGS += -I $(SRC_COMMON)/displayport/inc -CFLAGS += -I $(SRC_COMMON)/displayport/inc/dptestutil -CFLAGS += -I $(SRC_COMMON)/inc/displayport - -CFLAGS += -DNDEBUG -CFLAGS += -D_LANGUAGE_C -CFLAGS += -D__NO_CTYPE - -CFLAGS += -DNV_CPU_INTRINSICS_KERNEL -CFLAGS += -DNVHDMIPKT_RM_CALLS_INTERNAL=0 -CFLAGS += -DNVHDMIPKT_NVKMS - -# XXX it would be nice to only define these for appropriate files... -CFLAGS += -DSOFTFLOAT_ROUND_ODD -CFLAGS += -DSOFTFLOAT_FAST_DIV32TO16 -CFLAGS += -DSOFTFLOAT_FAST_DIV64TO32 - -# Tell nvtiming to use nvkms import functions -CFLAGS += -DNVT_USE_NVKMS - -# Tell SMG we're being compiled into kernel -CFLAGS += -DNV_SMG_IN_NVKMS +CFLAGS += $(addprefix -include ,$(NV_INCLUDE)) +CFLAGS += $(addprefix -I ,$(NV_INCDIRS)) +CFLAGS += $(NV_DEFINES) CFLAGS += -Wformat CFLAGS += -Wreturn-type @@ -172,19 +133,6 @@ CXX_ONLY_CFLAGS += -fcheck-new SHADER_OBJS = -CFLAGS += -I $(SRC_COMMON)/unix/nvidia-3d/interface -CFLAGS += -I $(SRC_COMMON)/unix/nvidia-push/interface -CFLAGS += -I $(SRC_COMMON)/unix/nvidia-3d/include -CFLAGS += -I $(SRC_COMMON)/unix/nvidia-push/include -CFLAGS += -I $(SRC_COMMON)/unix/xzminidec/interface -CFLAGS += -I $(SRC_COMMON)/unix/nvidia-headsurface -CFLAGS += -I src/shaders - -CFLAGS += -DNV_PUSH_IN_KERNEL -CFLAGS += -DNV_XZ_CUSTOM_MEM_HOOKS -CFLAGS += -DNV_XZ_USE_NVTYPES -CFLAGS += -DXZ_DEC_SINGLE - # Compress the shaders and embed in ELF object files. define COMPRESS_SHADERS $$(OUTPUTDIR)/$(1)_shaders.xz: src/shaders/g_$(1)_shaders @@ -196,11 +144,7 @@ $$(eval $$(call READ_ONLY_OBJECT_FROM_FILE_RULE,$$(OUTPUTDIR)/$(1)_shaders.xz)) SHADER_OBJS += $$(OUTPUTDIR)/$(1)_shaders.xz.o endef -$(eval $(call COMPRESS_SHADERS,turing)) -$(eval $(call COMPRESS_SHADERS,ampere)) -$(eval $(call COMPRESS_SHADERS,hopper)) -$(eval $(call COMPRESS_SHADERS,blackwell)) -$(eval $(call COMPRESS_SHADERS,gb20x)) +$(foreach shader, $(SHADERS), $(eval $(call COMPRESS_SHADERS,$(shader)))) OBJS = $(call BUILD_OBJECT_LIST,$(ALL_SRCS)) OBJS += $(SHADER_OBJS) diff --git a/src/nvidia-modeset/defs.mk b/src/nvidia-modeset/defs.mk new file mode 100644 index 000000000..a3471756d --- /dev/null +++ b/src/nvidia-modeset/defs.mk @@ -0,0 +1,62 @@ +# shared make defines for Makefile and Kbuild + +SRC_COMMON := ../common + +NV_INCLUDE := +NV_INCDIRS := +NV_DEFINES := + +NV_INCLUDE += $(SRC_COMMON)/sdk/nvidia/inc/cpuopsys.h + +NV_INCDIRS += $(SRC_COMMON)/sdk/nvidia/inc +NV_INCDIRS += $(SRC_COMMON)/sdk/nvidia/inc/hw +NV_INCDIRS += $(SRC_COMMON)/shared/inc +NV_INCDIRS += $(SRC_COMMON)/inc +NV_INCDIRS += $(SRC_COMMON)/softfloat/nvidia +NV_INCDIRS += $(SRC_COMMON)/softfloat/source/include +NV_INCDIRS += $(SRC_COMMON)/softfloat/source/8086-SSE +NV_INCDIRS += $(SRC_COMMON)/unix/common/utils/interface +NV_INCDIRS += $(SRC_COMMON)/unix/common/inc +NV_INCDIRS += $(SRC_COMMON)/modeset +NV_INCDIRS += os-interface/include +NV_INCDIRS += kapi/interface +NV_INCDIRS += ../nvidia/arch/nvalloc/unix/include +NV_INCDIRS += interface +NV_INCDIRS += include +NV_INCDIRS += kapi/include +NV_INCDIRS += generated +NV_INCDIRS += $(SRC_COMMON)/displayport/inc +NV_INCDIRS += $(SRC_COMMON)/displayport/inc/dptestutil +NV_INCDIRS += $(SRC_COMMON)/inc/displayport + +NV_DEFINES += -DNDEBUG +NV_DEFINES += -D_LANGUAGE_C +NV_DEFINES += -D__NO_CTYPE + +NV_DEFINES += -DNV_CPU_INTRINSICS_KERNEL +NV_DEFINES += -DNVHDMIPKT_RM_CALLS_INTERNAL=0 +NV_DEFINES += -DNVHDMIPKT_NVKMS + +# XXX it would be nice to only define these for appropriate files... +NV_DEFINES += -DSOFTFLOAT_ROUND_ODD +NV_DEFINES += -DSOFTFLOAT_FAST_DIV32TO16 +NV_DEFINES += -DSOFTFLOAT_FAST_DIV64TO32 + +# Tell nvtiming to use nvkms import functions +NV_DEFINES += -DNVT_USE_NVKMS + +# Tell SMG we're being compiled into kernel +NV_DEFINES += -DNV_SMG_IN_NVKMS + +NV_INCDIRS += $(SRC_COMMON)/unix/nvidia-3d/interface +NV_INCDIRS += $(SRC_COMMON)/unix/nvidia-push/interface +NV_INCDIRS += $(SRC_COMMON)/unix/nvidia-3d/include +NV_INCDIRS += $(SRC_COMMON)/unix/nvidia-push/include +NV_INCDIRS += $(SRC_COMMON)/unix/xzminidec/interface +NV_INCDIRS += $(SRC_COMMON)/unix/nvidia-headsurface +NV_INCDIRS += src/shaders + +NV_DEFINES += -DNV_PUSH_IN_KERNEL +NV_DEFINES += -DNV_XZ_CUSTOM_MEM_HOOKS +NV_DEFINES += -DNV_XZ_USE_NVTYPES +NV_DEFINES += -DXZ_DEC_SINGLE diff --git a/src/nvidia-modeset/srcs.mk b/src/nvidia-modeset/srcs.mk index bda977fbc..170edeee9 100644 --- a/src/nvidia-modeset/srcs.mk +++ b/src/nvidia-modeset/srcs.mk @@ -227,3 +227,10 @@ SRCS += ../common/unix/xzminidec/src/xz_crc32.c SRCS += ../common/unix/xzminidec/src/xz_dec_bcj.c SRCS += ../common/unix/xzminidec/src/xz_dec_lzma2.c SRCS += ../common/unix/xzminidec/src/xz_dec_stream.c + +# shaders +SHADERS += turing +SHADERS += ampere +SHADERS += hopper +SHADERS += blackwell +SHADERS += gb20x From 0d5f849612767854ddab4f64d38e6c7f9601c7a5 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:37:55 +0000 Subject: [PATCH 33/57] src/nvidia-modeset: preliminary kbuild support Provide a Kbuild file to be able to build src/nvidia-modeset/ using Linux's kbuild. It's meant to be included by kernel-open/nvidia-modeset/. Signed-off-by: Mathias Krause --- src/nvidia-modeset/nvidia-modeset.Kbuild | 151 +++++++++++++++++++++++ src/nvidia-modeset/srcs.mk | 4 +- 2 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 src/nvidia-modeset/nvidia-modeset.Kbuild diff --git a/src/nvidia-modeset/nvidia-modeset.Kbuild b/src/nvidia-modeset/nvidia-modeset.Kbuild new file mode 100644 index 000000000..aa5898a6d --- /dev/null +++ b/src/nvidia-modeset/nvidia-modeset.Kbuild @@ -0,0 +1,151 @@ +########################################################################### +# nvidia-modeset.Kbuild, included by kernel-open/nvidia-modeset/nvidia-modeset.Kbuild +########################################################################### + +nvidia_modeset_src ?= . + +NV_MODESET_KERNEL_O = nv-modeset-kernel.clean.o +NV_MODESET_KERNEL_O_OBJS = $(nv-modeset-kernel-objs) + +include $(src)/$(nvidia_modeset_src)/srcs.mk +include $(src)/$(nvidia_modeset_src)/defs.mk + +# The source files for nv-modeset-kernel.o are all SRCS and SRCS_CXX defined in +# srcs.mk, the NVIDIA ID string and the shaders +SRCS := $(addprefix $(nvidia_modeset_src)/,$(SRCS)) +SRCS_CXX := $(addprefix $(nvidia_modeset_src)/,$(SRCS_CXX)) +NVIDSTRING := $(addprefix $(nvidia_modeset_src)/,g_nvid_string.c) +ALL_SRCS := $(SRCS) $(SRCS_CXX) $(NVIDSTRING) + +# g_${shader}_shaders -> $[shaders}_shaders.xz.o +SHADER_OBJS := \ + $(addprefix $(nvidia_modeset_src)/src/shaders/,\ + $(addsuffix .xz.o,$(addsuffix _shaders,$(SHADERS)))) + +nv-modeset-kernel-objs := $(SRCS:.c=.o) +nv-modeset-kernel-objs += $(SRCS_CXX:.cpp=.o) +nv-modeset-kernel-objs += $(NVIDSTRING:.c=.o) +nv-modeset-kernel-objs += $(SHADER_OBJS) + +# Hack to create a relocatable intermediate object file to avoid '/bin/sh: +# Argument list too long' errors for the real module. +ifeq ($(NV_PREPARE_ONLY),1) +obj-m += nv-modeset-kernel.stub.o +nv-modeset-kernel.stub-y := $(nv-modeset-kernel-objs) $(MOD_STUB) +endif + +# for the 'clean' target +targets += $(nv-modeset-kernel-objs) +# ensure to use "our" NVIDSTRING +$(eval targets += $(NVIDSTRING)) + +# Define how to generate the NVIDIA ID string -- intentionally deviates from +# the OS-agnostic build +$(eval $(call GENERATE_NVIDSTRING, \ + NV_KMS_ID, \ + Linux Open Kernel Mode Setting Driver, $(nv-modeset-kernel-objs))) + +# now compile the final ccflags +nv-modeset-kernel-cflags := $(addprefix -include $(src)/$(nvidia_modeset_src)/,$(NV_INCLUDE)) +nv-modeset-kernel-cflags += $(addprefix -I $(src)/$(nvidia_modeset_src)/,$(NV_INCDIRS)) +nv-modeset-kernel-cflags += $(NV_DEFINES) + +# suppress some warnings +nv-modeset-kernel-cflags += -Wno-format-zero-length +nv-modeset-kernel-cflags += -Wno-implicit-fallthrough + +# XXX: Using -ffunction-sections / -fdata-sections makes no sense without +# XXX: --gc-sections. However, we cannot make use of --gc-sections as that +# XXX: would also drop crucial sections like .alt_instructions or +# XXX: .return_sites. So just disable these. +#nv-modeset-kernel-cflags += -ffunction-sections +#nv-modeset-kernel-cflags += -fdata-sections + +# move early -I... flags to after ours -- what a hack! +ccflags-includes := $(filter -I$(src)%,$(ccflags-y)) +nv-modeset-kernel-cflags += $(patsubst -I%,-I %,$(ccflags-includes)) +nv-modeset-kernel-cflags-remove += $(ccflags-includes) + +$(call ASSIGN_PER_OBJ_CFLAGS_REMOVE, $(nv-modeset-kernel-objs), $(nv-modeset-kernel-cflags-remove)) +$(call ASSIGN_PER_OBJ_CFLAGS, $(nv-modeset-kernel-objs), $(nv-modeset-kernel-cflags)) + +nv-modeset-kernel-cxxflags := -std=gnu++11 +nv-modeset-kernel-cxxflags += -fno-operator-names +nv-modeset-kernel-cxxflags += -fno-rtti +nv-modeset-kernel-cxxflags += -fno-exceptions +nv-modeset-kernel-cxxflags += -fcheck-new + +# ... referenced in section `__mcount_loc' of ...: defined in discarded section ... :/ +nv-modeset-kernel-cxxflags += -mno-record-mcount + +# --- 8< --- taken from scripts/Makefile.lib, adapted for C++ +# + +# strip C-only options from c_flags +cxx_cflags_filter := -W%implicit +cxx_cflags_filter += -W%implicit-int +cxx_cflags_filter += -W%implicit-function-declaration +cxx_cflags_filter += -W%strict-prototypes +cxx_cflags_filter += -W%missing-prototypes +cxx_cflags_filter += -W%pointer-sign +cxx_cflags_filter += -W%incompatible-pointer-types +cxx_cflags_filter += -W%designated-init +cxx_cflags_filter += -W%override-init +cxx_cflags_filter += -std=gnu11 + +CXX_FLAGS := $(nv-modeset-kernel-cxxflags) + +cxx_flags = $(filter-out $(cxx_cflags_filter),$(c_flags)) $(CXX_FLAGS) +quiet_cmd_cc_o_cxx = CXX $(quiet_modtag) $@ + cmd_cc_o_cxx = $(CXX) $(cxx_flags) -c -o $@ $< \ + $(cmd_ld_single) #\ + $(cmd_objtool) # disabled for now, as .return_sites / .call_sites reference to-be-discarded symbols + +define rule_cc_o_cxx + $(call cmd_and_fixdep,cc_o_cxx) + $(call cmd,checksrc) + $(call cmd,checkdoc) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_c)$(eval # genksyms can only parse C code!) + $(call cmd,record_mcount) + $(call cmd,warn_shared_object) +endef + +$(obj)/%.o: $(obj)/%.cpp $(recordmcount_source) FORCE + $(call if_changed_rule,cc_o_cxx) + $(call cmd,force_checksrc) +# +# --- >8 --- + +# shader rules +# +ld_o_xz-ldflags = -r -z noexecstack --format=binary +ld_o_xz-objcopy = --rename-section .data=.rodata,contents,alloc,load,data,readonly + +# changing into the directory of the .xz is needed to get sane names for the +# _binary_..._start/_end/_size symbols +quiet_cmd_ld_o_xz = LD XZO $@ + cmd_ld_o_xz = (cd $(dir $<) && $(LD) $(ld_o_xz-ldflags) $(notdir $<) -o $@.tmp) && $(OBJCOPY) $(ld_o_xz-objcopy) $@.tmp $@ && rm -f $@.tmp + +$(obj)/%.xz.o: $(obj)/%.xz FORCE + $(call if_changed,ld_o_xz) + +quiet_cmd_shader_xz = XZRAW $@ + cmd_shader_xz = cat $< | $(XZ) -ce -C none > $@ + +# This one is needed because we want to change the basename of the file and '%' +# would match the full path, including directories,prefixing the 'g_' at the +# wrong spot. +define mk_shader_rules +$$(obj)/$(1).xz: $$(obj)/$(dir $(1))/g_$(notdir $(1)) FORCE + $$(call if_changed,shader_xz) + +# for 'make clean' +targets += $(1).xz + +# not really needed, but to have conftest be the very first +NV_OBJECTS_DEPEND_ON_CONFTEST += $(1).xz +endef + +$(foreach shader, $(SHADER_OBJS:.xz.o=), $(eval $(call mk_shader_rules,$(shader)))) + diff --git a/src/nvidia-modeset/srcs.mk b/src/nvidia-modeset/srcs.mk index 170edeee9..ad89faca8 100644 --- a/src/nvidia-modeset/srcs.mk +++ b/src/nvidia-modeset/srcs.mk @@ -1,5 +1,5 @@ -SRCS ?= -SRCS_CXX ?= +SRCS := +SRCS_CXX := SRCS += ../common/shared/nvstatus/nvstatus.c SRCS += ../common/softfloat/source/8086-SSE/s_commonNaNToF16UI.c From 61b6eb0b455a96c4f00ed9c430a3ad06c2238a8c Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 11 Mar 2026 21:05:25 +0100 Subject: [PATCH 34/57] src/nvidia-modeset: collapse C++ comdat sections The C++ code of nv-modeset-kernel.o causes a lot of comdat sections to be generated which interferes badly with objtool trying to instrument / reference these, especially when some of the comdat sections do get dropped during linking of the final module. Resolve this issue by collapsing the comdat sections early and squashing the scattered sections with the help of a linker script. Signed-off-by: Mathias Krause --- src/nvidia-modeset/nv-modeset-kernel.ld | 28 ++++++++++++++++++++++++ src/nvidia-modeset/nvidia-modeset.Kbuild | 10 +++++++++ src/nvidia-modeset/srcs.mk | 2 ++ 3 files changed, 40 insertions(+) create mode 100644 src/nvidia-modeset/nv-modeset-kernel.ld diff --git a/src/nvidia-modeset/nv-modeset-kernel.ld b/src/nvidia-modeset/nv-modeset-kernel.ld new file mode 100644 index 000000000..8305d6d87 --- /dev/null +++ b/src/nvidia-modeset/nv-modeset-kernel.ld @@ -0,0 +1,28 @@ +/* + * nv-modeset-kernel.o linker script + * + * g++ puts inline functions, vtables, template functions, etc, in separate + * ".gnu.linkonce.*" / ".text.*" /... sections even without '-ffunction-sections + * -fdata-sections'. Duplicates will be collapsed at link time via + * '--force-group-allocation'. However, the weird section names will still be + * preserved which just increases module load time. + + * Merge these sections with this little linker script. + * + * C++ symbols/sections get filtered by their common '_Z' prefix, demanded by + * the Itanium ABI. + */ + +SECTIONS { + + .text : { *(.text) *(.text._Z*) *(.gnu.linkonce.t._Z*) } + + .rodata : { *(.rodata) *(.rodata._Z*) *(.gnu.linkonce.r._Z*) } + + .data : { *(.data) *(.data._Z*) } + + .bss : { *(.bss) *(.bss._Z*) } + + /* The rest of the sections ("orphaned sections") will just be copied from + the input to the output */ +} diff --git a/src/nvidia-modeset/nvidia-modeset.Kbuild b/src/nvidia-modeset/nvidia-modeset.Kbuild index aa5898a6d..3e61d1227 100644 --- a/src/nvidia-modeset/nvidia-modeset.Kbuild +++ b/src/nvidia-modeset/nvidia-modeset.Kbuild @@ -54,6 +54,13 @@ nv-modeset-kernel-cflags += $(NV_DEFINES) nv-modeset-kernel-cflags += -Wno-format-zero-length nv-modeset-kernel-cflags += -Wno-implicit-fallthrough +# Get rid of COMDAT groups when linking nv-modeset-kernel.stub.o to not cause +# objtool-generated cross-section linker errors on sections the linker is about +# to drop. Also merge all related C++-specific sections with the help of a +# linker script to reduce them to a sensible number of to-be-loaded sections. +nv-modeset-kernel-ldflags := --force-group-allocation +nv-modeset-kernel-ldflags += -T $(src)/$(nvidia_modeset_src)/$(LINKER_SCRIPT) + # XXX: Using -ffunction-sections / -fdata-sections makes no sense without # XXX: --gc-sections. However, we cannot make use of --gc-sections as that # XXX: would also drop crucial sections like .alt_instructions or @@ -68,6 +75,9 @@ nv-modeset-kernel-cflags-remove += $(ccflags-includes) $(call ASSIGN_PER_OBJ_CFLAGS_REMOVE, $(nv-modeset-kernel-objs), $(nv-modeset-kernel-cflags-remove)) $(call ASSIGN_PER_OBJ_CFLAGS, $(nv-modeset-kernel-objs), $(nv-modeset-kernel-cflags)) +$(call ASSIGN_PER_OBJ_LDFLAGS, nv-modeset-kernel.stub.o, $(nv-modeset-kernel-ldflags)) + +$(obj)/nv-modeset-kernel.stub.o: $(obj)/$(nvidia_modeset_src)/$(LINKER_SCRIPT) nv-modeset-kernel-cxxflags := -std=gnu++11 nv-modeset-kernel-cxxflags += -fno-operator-names diff --git a/src/nvidia-modeset/srcs.mk b/src/nvidia-modeset/srcs.mk index ad89faca8..f44f8edb0 100644 --- a/src/nvidia-modeset/srcs.mk +++ b/src/nvidia-modeset/srcs.mk @@ -234,3 +234,5 @@ SHADERS += ampere SHADERS += hopper SHADERS += blackwell SHADERS += gb20x + +LINKER_SCRIPT := nv-modeset-kernel.ld From 4f7a0d95012dbf95d05f15b5ee1b5373967730c3 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 10 Feb 2026 09:43:16 +0000 Subject: [PATCH 35/57] kernel-open/nvidia-modeset: Kbuild support Support building the dependent src/nvidia-modeset-kernel.o using Linux's kbuild. Signed-off-by: Mathias Krause --- kernel-open/nvidia-modeset/nvidia-modeset.Kbuild | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild b/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild index bb7ca8edc..43b88fd67 100644 --- a/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild +++ b/kernel-open/nvidia-modeset/nvidia-modeset.Kbuild @@ -16,6 +16,17 @@ obj-m += nvidia-modeset.o nvidia-modeset-y := $(NVIDIA_MODESET_OBJECTS) endif +ifeq ($(USE_KBUILD),1) +# build nv-modeset-kernel.o using Linux's kbuild system +nvidia_modeset_src := ../src/nvidia-modeset +include $(src)/$(nvidia_modeset_src)/nvidia-modeset.Kbuild + +nvidia-modeset-y += $(NV_MODESET_KERNEL_O) + +NV_OBJECTS_DEPEND_ON_CONFTEST += $(NV_MODESET_KERNEL_O_OBJS) + +else # !USE_KBUILD + NVIDIA_MODESET_KO = nvidia-modeset/nvidia-modeset.ko NV_KERNEL_MODULE_TARGETS += $(NVIDIA_MODESET_KO) @@ -48,6 +59,7 @@ $(obj)/$(NVIDIA_MODESET_BINARY_OBJECT_O): $(NVIDIA_MODESET_BINARY_OBJECT) FORCE $(call if_changed,symlink) nvidia-modeset-y += $(NVIDIA_MODESET_BINARY_OBJECT_O) +endif # @@ -84,8 +96,10 @@ NVIDIA_MODESET_INTERFACE := nvidia-modeset/nv-modeset-interface.o # before v5.6 looks at "always"; kernel versions between v5.12 and v5.6 # look at both. +ifneq ($(NV_PREPARE_ONLY),1) always += $(NVIDIA_MODESET_INTERFACE) always-y += $(NVIDIA_MODESET_INTERFACE) +endif $(obj)/$(NVIDIA_MODESET_INTERFACE): $(addprefix $(obj)/,$(NVIDIA_MODESET_OBJECTS)) $(LD) -r -o $@ $^ From 69de8b8231184d8141a95fd56b5e2d762f4f08fb Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 16 Dec 2025 22:19:36 +0000 Subject: [PATCH 36/57] Experimental support for Linux's kbuild Add experimental support for using the Linux kernel's kbuild system to not only compile code below kernel-open/ but src/ as well. The build is still done in two phases, as in first building src/, then kernel-open/ as otherwise the build would run into errors, trying to link too many objects, hitting shell command argument limits. Compiling the code below src/ via kbuild is needed to, e.g., support more recent kernel features like IBT or to add required marker locations via objtool for features like RETHUNK. Using kbuild is disabled by default and needs to be explicitly opt-in via `make USE_KBUILD=1`. Signed-off-by: Mathias Krause --- Makefile | 37 ++++++++++++++++++++++++++++--------- README.md | 4 ++++ src/nvidia-modeset/Makefile | 4 ++++ src/nvidia/Makefile | 4 ++++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 449c7f585..38e228c9a 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,19 @@ # To install the build kernel modules: run (as root) `make modules_install` ########################################################################### +# Experimental use of the Linux kernel's kbuild system +USE_KBUILD ?= 0 +export USE_KBUILD + +########################################################################### +# rules +########################################################################### + +.PHONY: all +all: modules + +ifneq ($(USE_KBUILD),1) + ########################################################################### # variables ########################################################################### @@ -16,15 +29,8 @@ nv_kernel_o_binary = kernel-open/nvidia/nv-kernel.o_binary nv_modeset_kernel_o = src/nvidia-modeset/$(OUTPUTDIR)/nv-modeset-kernel.o nv_modeset_kernel_o_binary = kernel-open/nvidia-modeset/nv-modeset-kernel.o_binary -########################################################################### -# rules -########################################################################### - include utils.mk -.PHONY: all -all: modules - ########################################################################### # nv-kernel.o is the OS agnostic portion of nvidia.ko ########################################################################### @@ -48,6 +54,9 @@ $(nv_modeset_kernel_o): $(nv_modeset_kernel_o_binary): $(nv_modeset_kernel_o) cd $(dir $@) && ln -sf ../../$^ $(notdir $@) +# Make the OS agnostic binaries a prerequisite of the modules target +modules: $(nv_kernel_o_binary) $(nv_modeset_kernel_o_binary) +endif ########################################################################### # After the OS agnostic portions are built, descend into kernel-open/ and build @@ -55,7 +64,13 @@ $(nv_modeset_kernel_o_binary): $(nv_modeset_kernel_o) ########################################################################### .PHONY: modules -modules: $(nv_kernel_o_binary) $(nv_modeset_kernel_o_binary) +modules: +ifeq ($(USE_KBUILD),1) +# create nv-kernel.o and nv-modeset-kernel.o by building stub modules -- a +# required hack to overcome kbuild limitations regarding the maximum number +# of object files to link into a module. + $(MAKE) -C kernel-open modules NV_PREPARE_ONLY=1 +endif $(MAKE) -C kernel-open modules ########################################################################### @@ -63,7 +78,7 @@ modules: $(nv_kernel_o_binary) $(nv_modeset_kernel_o_binary) ########################################################################### .PHONY: modules_install -modules_install: +modules_install: modules $(MAKE) -C kernel-open modules_install ########################################################################### @@ -75,11 +90,15 @@ clean: nvidia.clean nvidia-modeset.clean kernel-open.clean .PHONY: nvidia.clean nvidia.clean: +ifneq ($(USE_KBUILD),1) $(MAKE) -C src/nvidia clean +endif .PHONY: nvidia-modeset.clean nvidia-modeset.clean: +ifneq ($(USE_KBUILD),1) $(MAKE) -C src/nvidia-modeset clean +endif .PHONY: kernel-open.clean kernel-open.clean: diff --git a/README.md b/README.md index a89739266..7ddc4653c 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ DEBUG - Set this to "1" to build the kernel modules as debug. By default, the build compiles without debugging information. This also enables various debug log messages in the kernel modules. +USE_KBUILD - Set this to "1" to build all sources using the linux kernel build + system. This is needed to support features like RANDSTRUCT, kCFI or + grsecurity kernels. + These variables can be set on the make command line. E.g., make modules -j$(nproc) NV_VERBOSE=1 diff --git a/src/nvidia-modeset/Makefile b/src/nvidia-modeset/Makefile index a46354212..2ad070a1c 100644 --- a/src/nvidia-modeset/Makefile +++ b/src/nvidia-modeset/Makefile @@ -2,6 +2,10 @@ # Makefile for nv-modeset-kernel.o ########################################################################### +ifeq ($(USE_KBUILD),1) +$(error nv-modeset-kernel.o gets build as part of kernel-open/) +endif + NV_MODULE_LOGGING_NAME ?= nvidia-modeset VERSION_MK_DIR = ../../ diff --git a/src/nvidia/Makefile b/src/nvidia/Makefile index 9a8aef1e9..1a005d1b1 100644 --- a/src/nvidia/Makefile +++ b/src/nvidia/Makefile @@ -2,6 +2,10 @@ # Makefile for nv-kernel.o ########################################################################### +ifeq ($(USE_KBUILD),1) +$(error nv-kernel.o gets build as part of kernel-open/) +endif + NV_MODULE_LOGGING_NAME ?= nvidia VERSION_MK_DIR = ../../ From a1f715b9864c6433cda6140b570659590e25ed5d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 09:29:21 -0400 Subject: [PATCH 37/57] kernel-open: Lift RANDSTRUCT restriction for USE_KBUILD=1 The RANDSTRUCT limitation isn't needed when all sources get compiled with kbuild. Guard it like that. Signed-off-by: Mathias Krause --- kernel-open/Makefile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel-open/Makefile b/kernel-open/Makefile index 0ddea676f..c189f5613 100644 --- a/kernel-open/Makefile +++ b/kernel-open/Makefile @@ -69,13 +69,15 @@ else endif endif - # RANDSTRUCT is incompatible with how we build the OS-agnostic part, leading - # to calling the wrong callback functions from pure *ops structures at - # runtime. - ranstruct_enabled=$(firstword $(shell . $(KERNEL_OUTPUT)/.config; \ - echo "$$CONFIG_RANDSTRUCT$$CONFIG_GCC_PLUGIN_RANDSTRUCT")) - ifneq ($(ranstruct_enabled),) - $(error RANDSTRUCT enabled kernel is incompatible with binary objects!)) + ifneq ($(USE_KBUILD),1) + # RANDSTRUCT is incompatible with how we build the OS-agnostic part, leading + # to calling the wrong callback functions from pure *ops structures at + # runtime. + ranstruct_enabled=$(firstword $(shell . $(KERNEL_OUTPUT)/.config; \ + echo "$$CONFIG_RANDSTRUCT$$CONFIG_GCC_PLUGIN_RANDSTRUCT")) + ifneq ($(ranstruct_enabled),) + $(error RANDSTRUCT enabled kernel is incompatible with binary objects!)) + endif endif CC ?= cc From a1e0c29f0d843a02fdb4ee04a7b4d6e893c69d15 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:46:59 +0000 Subject: [PATCH 38/57] conftest: Add test for vm_operations_struct.access() 'len' type The grsecurity kernel patch changes the return type and 'len' argument type to ssize_t and size_t respectively. Add a test for this to add support for grsecurity. Signed-off-by: Mathias Krause --- kernel-open/conftest.sh | 24 ++++++++++++++++++++++++ kernel-open/nvidia/nv-mmap.c | 11 +++++++++++ kernel-open/nvidia/nvidia.Kbuild | 1 + 3 files changed, 36 insertions(+) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index a515909db..7840bd544 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -2094,6 +2094,30 @@ compile_test() { compile_check_conftest "$CODE" "NV_VM_OPS_FAULT_REMOVED_VMA_ARG" "" "types" ;; + vm_ops_access_size_t_len) + # + # Determine if vma.vm_ops.access takes an int or size_t len arg. + # Acronym key: + # vma: struct vm_area_struct + # vm_ops: struct vm_operations_struct + # + # The type gets changed by the grsecurity kernel patch. + # + CODE=" + #include + static ssize_t conftest_access(struct vm_area_struct *vma, unsigned long addr, + void *buf, size_t len, int write) + { + return -EINVAL; + } + + struct vm_operations_struct vm_ops = { + .access = conftest_access, + };" + + compile_check_conftest "$CODE" "NV_VM_OPS_ACCESS_SIZE_T_LEN" "" "types" + ;; + is_export_symbol_present_*) export_symbol_present_conftest $(echo $1 | cut -f5- -d_) ;; diff --git a/kernel-open/nvidia/nv-mmap.c b/kernel-open/nvidia/nv-mmap.c index 9ce5f4260..f3dc246e9 100644 --- a/kernel-open/nvidia/nv-mmap.c +++ b/kernel-open/nvidia/nv-mmap.c @@ -112,6 +112,16 @@ nvidia_vma_release(struct vm_area_struct *vma) } } +#ifdef NV_VM_OPS_ACCESS_SIZE_T_LEN +static ssize_t +nvidia_vma_access( + struct vm_area_struct *vma, + unsigned long addr, + void *buffer, + size_t length, + int write +) +#else static int nvidia_vma_access( struct vm_area_struct *vma, @@ -120,6 +130,7 @@ nvidia_vma_access( int length, int write ) +#endif { nv_alloc_t *at = NULL; nv_linux_file_private_t *nvlfp = NV_GET_LINUX_FILE_PRIVATE(NV_VMA_FILE(vma)); diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index 498d23eba..78cf15de0 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -239,6 +239,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += has_enum_pidtype_tgid NV_CONFTEST_TYPE_COMPILE_TESTS += bpmp_mrq_has_strap_set NV_CONFTEST_TYPE_COMPILE_TESTS += register_shrinker_has_format_arg NV_CONFTEST_TYPE_COMPILE_TESTS += pci_resize_resource_has_exclude_bars_arg +NV_CONFTEST_TYPE_COMPILE_TESTS += vm_ops_access_size_t_len NV_CONFTEST_GENERIC_COMPILE_TESTS += dom0_kernel_present NV_CONFTEST_GENERIC_COMPILE_TESTS += nvidia_vgpu_kvm_build From dfd59fcb955c23ce6e1f1a7fb07b237701e4c01a Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 11 Dec 2025 14:22:14 +0000 Subject: [PATCH 39/57] conftest: Add test for grsecurity's atomic*_unchecked_t The grsecurity kernel patch makes used of "unchecked" variants of the various atomic* types to lower instrumentation overhead. Add a test for the type and make use of it, where required. Signed-off-by: Mathias Krause --- kernel-open/common/inc/nv-linux.h | 6 ++++++ kernel-open/conftest.sh | 18 ++++++++++++++++++ kernel-open/nvidia-uvm/nvidia-uvm.Kbuild | 1 + kernel-open/nvidia-uvm/uvm_gpu.h | 18 +++++++++--------- kernel-open/nvidia-uvm/uvm_perf_thrashing.c | 8 ++++---- kernel-open/nvidia-uvm/uvm_va_space.h | 2 +- kernel-open/nvidia/nv_uvm_interface.c | 4 ++-- kernel-open/nvidia/nvidia.Kbuild | 1 + 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/kernel-open/common/inc/nv-linux.h b/kernel-open/common/inc/nv-linux.h index 8d0428289..7a04b8dc5 100644 --- a/kernel-open/common/inc/nv-linux.h +++ b/kernel-open/common/inc/nv-linux.h @@ -38,6 +38,12 @@ #include "nv-chardev-numbers.h" #include "nv-platform.h" +#ifndef NV_HAVE_ATOMIC_UNCHECKED_T +#define atomic_unchecked_t atomic_t +#define atomic64_unchecked_t atomic64_t +#define atomic_long_unchecked_t atomic_long_t +#endif + #ifndef AUTOCONF_INCLUDED #if defined(NV_GENERATED_AUTOCONF_H_PRESENT) #include diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 7840bd544..46ff9b3a5 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -2118,6 +2118,24 @@ compile_test() { compile_check_conftest "$CODE" "NV_VM_OPS_ACCESS_SIZE_T_LEN" "" "types" ;; + atomic_unchecked_t) + # + # Determine if atomic_unchecked_t is available. + # + # atomic*_unchecked_t is a grsecurity-specific type extension. + # + CODE=" + #include + + static atomic_unchecked_t a; + + int conftest_atomic_unchecked_t(void) { + return atomic_inc_return(&a); + }" + + compile_check_conftest "$CODE" "NV_HAVE_ATOMIC_UNCHECKED_T" "" "types" + ;; + is_export_symbol_present_*) export_symbol_present_conftest $(echo $1 | cut -f5- -d_) ;; diff --git a/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild b/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild index 6df0d381c..8e1f737ca 100644 --- a/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild +++ b/kernel-open/nvidia-uvm/nvidia-uvm.Kbuild @@ -71,6 +71,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += mmu_interval_notifier NV_CONFTEST_TYPE_COMPILE_TESTS += sg_dma_page_iter NV_CONFTEST_TYPE_COMPILE_TESTS += struct_page_has_zone_device_data NV_CONFTEST_TYPE_COMPILE_TESTS += memory_device_coherent_present +NV_CONFTEST_TYPE_COMPILE_TESTS += atomic_unchecked_t NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_int_active_memcg NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_migrate_vma_setup diff --git a/kernel-open/nvidia-uvm/uvm_gpu.h b/kernel-open/nvidia-uvm/uvm_gpu.h index 8e81d2b42..676e0004e 100644 --- a/kernel-open/nvidia-uvm/uvm_gpu.h +++ b/kernel-open/nvidia-uvm/uvm_gpu.h @@ -398,9 +398,9 @@ typedef struct NvU64 num_duplicate_faults; - atomic64_t num_pages_out; + atomic64_unchecked_t num_pages_out; - atomic64_t num_pages_in; + atomic64_unchecked_t num_pages_in; NvU64 num_replays; @@ -448,9 +448,9 @@ typedef struct NvU64 num_physical_faults; - atomic64_t num_pages_out; + atomic64_unchecked_t num_pages_out; - atomic64_t num_pages_in; + atomic64_unchecked_t num_pages_in; } stats; // Tracker which temporarily holds the work pushed to service faults @@ -551,9 +551,9 @@ struct uvm_access_counter_buffer_struct // Access counter statistics struct { - atomic64_t num_pages_out; + atomic64_unchecked_t num_pages_out; - atomic64_t num_pages_in; + atomic64_unchecked_t num_pages_in; } stats; // Ignoring access counters means that notifications are left in the HW @@ -880,7 +880,7 @@ struct uvm_gpu_struct bool enabled; // Artificially injected error for testing - atomic_t injected_error; + atomic_unchecked_t injected_error; // Direct mapping of the 32-bit part of the hw interrupt tree that has // the NVLINK error bits. @@ -1300,9 +1300,9 @@ struct uvm_parent_gpu_struct NvU64 num_non_replayable_faults; - atomic64_t num_pages_out; + atomic64_unchecked_t num_pages_out; - atomic64_t num_pages_in; + atomic64_unchecked_t num_pages_in; } stats; // Structure to hold nvswitch specific information. In an nvswitch diff --git a/kernel-open/nvidia-uvm/uvm_perf_thrashing.c b/kernel-open/nvidia-uvm/uvm_perf_thrashing.c index 30f147763..dc64cd419 100644 --- a/kernel-open/nvidia-uvm/uvm_perf_thrashing.c +++ b/kernel-open/nvidia-uvm/uvm_perf_thrashing.c @@ -210,16 +210,16 @@ typedef struct struct proc_dir_entry *procfs_file; // Number of times thrashing is detected - atomic64_t num_thrashing; + atomic64_unchecked_t num_thrashing; // Number of times the processor was throttled while thrashing - atomic64_t num_throttle; + atomic64_unchecked_t num_throttle; // Number of times a page was pinned on this processor while thrashing - atomic64_t num_pin_local; + atomic64_unchecked_t num_pin_local; // Number of times a page was pinned on a different processor while thrashing - atomic64_t num_pin_remote; + atomic64_unchecked_t num_pin_remote; } processor_thrashing_stats_t; // Pre-allocated thrashing stats structure for the CPU. This is only valid if diff --git a/kernel-open/nvidia-uvm/uvm_va_space.h b/kernel-open/nvidia-uvm/uvm_va_space.h index 43ec27de4..5dd24357a 100644 --- a/kernel-open/nvidia-uvm/uvm_va_space.h +++ b/kernel-open/nvidia-uvm/uvm_va_space.h @@ -227,7 +227,7 @@ struct uvm_va_space_struct struct list_head list_node; // Monotonically increasing counter for range groups IDs - atomic64_t range_group_id_counter; + atomic64_unchecked_t range_group_id_counter; // Range groups struct radix_tree_root range_groups; diff --git a/kernel-open/nvidia/nv_uvm_interface.c b/kernel-open/nvidia/nv_uvm_interface.c index b008a8480..3aacdf1b8 100644 --- a/kernel-open/nvidia/nv_uvm_interface.c +++ b/kernel-open/nvidia/nv_uvm_interface.c @@ -41,7 +41,7 @@ // This is really a struct UvmEventsLinux *. It needs to be an atomic because it // can be read outside of the g_pNvUvmEventsLock. Use getUvmEvents and // setUvmEvents to access it. -static atomic_long_t g_pNvUvmEvents; +static atomic_long_unchecked_t g_pNvUvmEvents; static struct semaphore g_pNvUvmEventsLock; static struct UvmEventsLinux *getUvmEvents(void) @@ -62,7 +62,7 @@ static struct semaphore g_spLock; #define DEBUG_GLOBAL_STACK 0 #define DEBUG_GLOBAL_STACK_THRESHOLD 2 -static atomic_t g_debugGlobalStackCount = ATOMIC_INIT(0); +static atomic_unchecked_t g_debugGlobalStackCount = ATOMIC_INIT(0); // Called at module load, not by an external client int nv_uvm_init(void) diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index 78cf15de0..885587147 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -240,6 +240,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += bpmp_mrq_has_strap_set NV_CONFTEST_TYPE_COMPILE_TESTS += register_shrinker_has_format_arg NV_CONFTEST_TYPE_COMPILE_TESTS += pci_resize_resource_has_exclude_bars_arg NV_CONFTEST_TYPE_COMPILE_TESTS += vm_ops_access_size_t_len +NV_CONFTEST_TYPE_COMPILE_TESTS += atomic_unchecked_t NV_CONFTEST_GENERIC_COMPILE_TESTS += dom0_kernel_present NV_CONFTEST_GENERIC_COMPILE_TESTS += nvidia_vgpu_kvm_build From 084f8a04a987d77a1078633b5b9dacdaef8ba9db Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 17:20:56 +0000 Subject: [PATCH 40/57] nvidia-uvm: make *ops union compatible with grsecurity Mark the anonumous *ops union of uvm_hal_class_ops_t '__no_const' to fix the build for grsecurity kernels which try to enforce making types of only function pointers const. This won't be possible for uvm_hal_class_ops_t as it has non-function-pointer members too. Signed-off-by: Mathias Krause --- kernel-open/common/inc/nvtypes.h | 11 +++++++++++ kernel-open/nvidia-uvm/uvm_hal.h | 16 ++++++++-------- kernel-open/nvidia-uvm/uvm_mmu.h | 1 - 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/kernel-open/common/inc/nvtypes.h b/kernel-open/common/inc/nvtypes.h index 2965de5bd..41cc84da2 100644 --- a/kernel-open/common/inc/nvtypes.h +++ b/kernel-open/common/inc/nvtypes.h @@ -530,6 +530,17 @@ typedef struct #define NV_ATTRIBUTE_UNUSED #endif +// grsecurity compatibility +#ifndef __no_const +#define __no_const +#endif +#ifndef __do_const +#define __do_const +#endif +#ifndef __mutable_const +#define __mutable_const +#endif + #if defined(_MSC_VER) #if _MSC_VER >= 1310 diff --git a/kernel-open/nvidia-uvm/uvm_hal.h b/kernel-open/nvidia-uvm/uvm_hal.h index 8427b39ed..4fb5786e6 100644 --- a/kernel-open/nvidia-uvm/uvm_hal.h +++ b/kernel-open/nvidia-uvm/uvm_hal.h @@ -837,7 +837,7 @@ struct uvm_host_hal_struct uvm_hal_access_counter_clear_targeted_t access_counter_clear_targeted; uvm_hal_access_counter_query_clear_op_t access_counter_query_clear_op; uvm_hal_get_time_t get_time; -}; +} __mutable_const; struct uvm_ce_hal_struct { @@ -863,7 +863,7 @@ struct uvm_ce_hal_struct uvm_hal_semaphore_reduction_inc_t semaphore_reduction_inc; uvm_hal_ce_encrypt_t encrypt; uvm_hal_ce_decrypt_t decrypt; -}; +} __mutable_const; struct uvm_arch_hal_struct { @@ -872,7 +872,7 @@ struct uvm_arch_hal_struct uvm_hal_mmu_enable_prefetch_faults_t enable_prefetch_faults; uvm_hal_mmu_disable_prefetch_faults_t disable_prefetch_faults; uvm_hal_mmu_client_id_to_utlb_id_t mmu_client_id_to_utlb_id; -}; +} __mutable_const; struct uvm_fault_buffer_hal_struct { @@ -890,7 +890,7 @@ struct uvm_fault_buffer_hal_struct uvm_hal_fault_buffer_entry_size_t entry_size; uvm_hal_fault_buffer_parse_non_replayable_entry_t parse_non_replayable_entry; uvm_hal_fault_buffer_get_fault_type_t get_fault_type; -}; +} __mutable_const; struct uvm_access_counter_buffer_hal_struct { @@ -901,7 +901,7 @@ struct uvm_access_counter_buffer_hal_struct uvm_hal_access_counter_buffer_entry_is_valid_t entry_is_valid; uvm_hal_access_counter_buffer_entry_clear_valid_t entry_clear_valid; uvm_hal_access_counter_buffer_entry_size_t entry_size; -}; +} __mutable_const; struct uvm_sec2_hal_struct { @@ -910,7 +910,7 @@ struct uvm_sec2_hal_struct uvm_hal_semaphore_release_t semaphore_release; uvm_hal_semaphore_timestamp_t semaphore_timestamp; uvm_hal_semaphore_target_is_valid_t semaphore_target_is_valid; -}; +} __mutable_const; typedef struct { @@ -937,8 +937,8 @@ typedef struct // sec2_ops: id is an architecture uvm_sec2_hal_t sec2_ops; - } u; -} uvm_hal_class_ops_t; + } __mutable_const u; +} __mutable_const uvm_hal_class_ops_t; NV_STATUS uvm_hal_init_table(void); NV_STATUS uvm_hal_init_gpu(uvm_parent_gpu_t *parent_gpu); diff --git a/kernel-open/nvidia-uvm/uvm_mmu.h b/kernel-open/nvidia-uvm/uvm_mmu.h index 3453a26d1..6f8806ea3 100644 --- a/kernel-open/nvidia-uvm/uvm_mmu.h +++ b/kernel-open/nvidia-uvm/uvm_mmu.h @@ -24,7 +24,6 @@ #ifndef __UVM_MMU_H__ #define __UVM_MMU_H__ -#include "uvm_forward_decl.h" #include "uvm_hal_types.h" #include "uvm_pmm_gpu.h" #include "uvm_types.h" From aceb4c2b11a36871bc31b01f4bf0a62e16df7747 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 10 Dec 2025 13:47:11 +0000 Subject: [PATCH 41/57] kernel-open: mark nv_kthread_q related types nolocal for grsecurity compatibility grsecurity's private kernel stack feature demands 'struct nv_kthread_q_item' objects to be moved off the stack as different threads cannot access each other's kernel stacks. Signed-off-by: Mathias Krause --- kernel-open/common/inc/nv-kthread-q-os.h | 5 +++-- kernel-open/common/inc/nvtypes.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel-open/common/inc/nv-kthread-q-os.h b/kernel-open/common/inc/nv-kthread-q-os.h index 4d7decfa6..5413f10c6 100644 --- a/kernel-open/common/inc/nv-kthread-q-os.h +++ b/kernel-open/common/inc/nv-kthread-q-os.h @@ -31,6 +31,7 @@ #include #include "conftest.h" +#include "nvtypes.h" struct nv_kthread_q { @@ -45,14 +46,14 @@ struct nv_kthread_q struct task_struct *q_kthread; bool is_unload_flush_ongoing; -}; +} __nolocal; struct nv_kthread_q_item { struct list_head q_list_node; nv_q_func_t function_to_run; void *function_args; -}; +} __nolocal; #ifndef NUMA_NO_NODE diff --git a/kernel-open/common/inc/nvtypes.h b/kernel-open/common/inc/nvtypes.h index 41cc84da2..f7802e780 100644 --- a/kernel-open/common/inc/nvtypes.h +++ b/kernel-open/common/inc/nvtypes.h @@ -540,6 +540,9 @@ typedef struct #ifndef __mutable_const #define __mutable_const #endif +#ifndef __nolocal +#define __nolocal +#endif #if defined(_MSC_VER) From 1d1d3eb8196088a8fba671594bfacb0e5f58eaba Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 19:57:52 +0000 Subject: [PATCH 42/57] src/common: make "HAL" types compatible with grsecurity Make "HAL" types which are either embedded in larger types that often get modified 'no_const' or 'mutable_const' if they're only rarely written to, to fix build errors for grsecurity kernels which try to enforce making instances of these types const otherwise. Signed-off-by: Mathias Krause --- src/common/modeset/hdmipacket/nvhdmipkt.h | 2 +- src/common/nvlink/interface/nvlink.h | 2 +- .../kernel/inc/flcn/haldefs_flcn_nvswitch.h | 2 +- .../kernel/inc/flcn/haldefs_flcnable_nvswitch.h | 2 +- src/common/nvswitch/kernel/inc/haldef_nvswitch.h | 2 +- src/common/sdk/nvidia/inc/nvtypes.h | 14 ++++++++++++++ 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/common/modeset/hdmipacket/nvhdmipkt.h b/src/common/modeset/hdmipacket/nvhdmipkt.h index 7b7cab2c2..19a3df053 100644 --- a/src/common/modeset/hdmipacket/nvhdmipkt.h +++ b/src/common/modeset/hdmipacket/nvhdmipkt.h @@ -282,7 +282,7 @@ typedef struct _tagNVHDMIPKT_CALLBACK const char *filename, const char *function, unsigned int line); -} NVHDMIPKT_CALLBACK; +} __no_const NVHDMIPKT_CALLBACK; /************************************************************************************************ diff --git a/src/common/nvlink/interface/nvlink.h b/src/common/nvlink/interface/nvlink.h index c0fbc5c2f..99bbc1223 100644 --- a/src/common/nvlink/interface/nvlink.h +++ b/src/common/nvlink/interface/nvlink.h @@ -291,7 +291,7 @@ struct nvlink_link_handlers NV_API_CALL void (*get_uphy_load) (struct nvlink_link *link, NvBool* bUnlocked); NV_API_CALL NvlStatus (*get_cci_link_mode) (struct nvlink_link *link, NvU64 *mode); NV_API_CALL NvlStatus (*ali_training) (struct nvlink_link *link); -}; +} __mutable_const; // // Represents an intranode connections in single/multi-node system. diff --git a/src/common/nvswitch/kernel/inc/flcn/haldefs_flcn_nvswitch.h b/src/common/nvswitch/kernel/inc/flcn/haldefs_flcn_nvswitch.h index f649ee27d..8d86978eb 100644 --- a/src/common/nvswitch/kernel/inc/flcn/haldefs_flcn_nvswitch.h +++ b/src/common/nvswitch/kernel/inc/flcn/haldefs_flcn_nvswitch.h @@ -95,7 +95,7 @@ typedef struct { NV_STATUS (*debugBufferDestroy) (struct nvswitch_device *, struct FLCN *); NV_STATUS (*debugBufferDisplay) (struct nvswitch_device *, struct FLCN *); NvBool (*debugBufferIsEmpty) (struct nvswitch_device *, struct FLCN *); -} flcn_hal; +} __mutable_const flcn_hal; void flcnQueueSetupHal(struct FLCN *pFlcn); void flcnRtosSetupHal(struct FLCN *pFlcn); diff --git a/src/common/nvswitch/kernel/inc/flcn/haldefs_flcnable_nvswitch.h b/src/common/nvswitch/kernel/inc/flcn/haldefs_flcnable_nvswitch.h index 635bab770..e2e663638 100644 --- a/src/common/nvswitch/kernel/inc/flcn/haldefs_flcnable_nvswitch.h +++ b/src/common/nvswitch/kernel/inc/flcn/haldefs_flcnable_nvswitch.h @@ -107,6 +107,6 @@ typedef struct { struct ENGINE_DESCRIPTOR_TYPE *pEngDescUc, struct ENGINE_DESCRIPTOR_TYPE *pEngDescBc); -} flcnable_hal; +} __mutable_const flcnable_hal; #endif //_HALDEFS_FLCNABLE_NVSWITCH_H_ diff --git a/src/common/nvswitch/kernel/inc/haldef_nvswitch.h b/src/common/nvswitch/kernel/inc/haldef_nvswitch.h index fdbd271b1..a1cf80d21 100644 --- a/src/common/nvswitch/kernel/inc/haldef_nvswitch.h +++ b/src/common/nvswitch/kernel/inc/haldef_nvswitch.h @@ -335,7 +335,7 @@ typedef struct nvswitch_hal_functions NVSWITCH_HAL_FUNCTION_LIST(DECLARE_HAL_FUNCTIONS, HAL) NVSWITCH_HAL_FUNCTION_LIST_LS10(DECLARE_HAL_FUNCTIONS, HAL) -} nvswitch_hal; +} __no_const nvswitch_hal; // // Fill in HAL function pointer table diff --git a/src/common/sdk/nvidia/inc/nvtypes.h b/src/common/sdk/nvidia/inc/nvtypes.h index 68fd32c20..13900d2aa 100644 --- a/src/common/sdk/nvidia/inc/nvtypes.h +++ b/src/common/sdk/nvidia/inc/nvtypes.h @@ -524,6 +524,20 @@ typedef struct #define NV_ATTRIBUTE_UNUSED #endif +// grsecurity compatibility +#ifndef __no_const +#define __no_const +#endif +#ifndef __do_const +#define __do_const +#endif +#ifndef __mutable_const +#define __mutable_const +#endif +#ifndef __nolocal +#define __nolocal +#endif + #if defined(__GNUC__) #if (__GNUC__ > 3) || \ ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) && (__GNUC_PATCHLEVEL__ >= 1)) From 684be25e76699b591cff06dbbab3b4fb12f25381 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 20:03:45 +0000 Subject: [PATCH 43/57] src/nvidia-modeset: disable certain gcc plugins for C++ code The following gcc plugins in grsecurity are incompatible with C++ code as of now: - SIZE_OVERFLOW: lacks METHOD_TYPE handling and likely many other tree types, - RESPECTRE: similar reasons as for SIZE_OVERFLOW, just too complex, - AUTOSLAB: same, but also not needed, as C++ memory allocations get proxied by DisplayPort::Object::new which calls dpMalloc() which is implemented in C and therefore does get instrumented by AUTOSLAB. Forcibly disable these plugins for C++ code. The lack of instrumenting C++ code has no impact on the reset of the kernel. Signed-off-by: Mathias Krause --- src/nvidia-modeset/nvidia-modeset.Kbuild | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/nvidia-modeset/nvidia-modeset.Kbuild b/src/nvidia-modeset/nvidia-modeset.Kbuild index 3e61d1227..35cd64e2a 100644 --- a/src/nvidia-modeset/nvidia-modeset.Kbuild +++ b/src/nvidia-modeset/nvidia-modeset.Kbuild @@ -103,6 +103,27 @@ cxx_cflags_filter += -W%designated-init cxx_cflags_filter += -W%override-init cxx_cflags_filter += -std=gnu11 +# C++ incompatible gcc plugins (as of now): +# - SIZE_OVERFLOW: lacks METHOD_TYPE handling (and probably others) +# - RESPECTRE: too complex +# - AUTOSLAB: not needed (operator new calls into the C runtime) +ifeq ($(CONFIG_PAX_SIZE_OVERFLOW),y) +cxx_cflags_filter += -DSIZE_OVERFLOW_PLUGIN +cxx_cflags_filter += -fplugin=%/size_overflow_plugin.so +cxx_cflags_filter += -fplugin-arg-size_overflow_plugin% +endif +ifeq ($(CONFIG_PAX_RESPECTRE_PLUGIN),y) +cxx_cflags_filter += -DRESPECTRE_PLUGIN% +cxx_cflags_filter += -fplugin=%/respectre_plugin.so +cxx_cflags_filter += -fplugin-arg-respectre_plugin% +endif +ifeq ($(CONFIG_PAX_AUTOSLAB_PLUGIN),y) +cxx_cflags_filter += -DAUTOSLAB_PLUGIN +cxx_cflags_filter += -DAUTOSLAB_BASENAME% +cxx_cflags_filter += -fplugin=%/autoslab_plugin.so +cxx_cflags_filter += -fplugin-arg-autoslab_plugin% +endif + CXX_FLAGS := $(nv-modeset-kernel-cxxflags) cxx_flags = $(filter-out $(cxx_cflags_filter),$(c_flags)) $(CXX_FLAGS) From 302a3534d5a92deb97f6f46825b6dfdade3b9d43 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 27 Feb 2026 09:08:52 +0000 Subject: [PATCH 44/57] src/nvidia: disable --gc-sections for kbuild Using --gc-sections for dropping unused sections also removes crucial secions like .alt_instructions or .return_sites which are needed for instrumenting code on module load accordingly to the CPU mitigations and features supported / needed by a given system. Disable --gc-sections and related linker and compiler flags for kbuild builds. Disabling --gc-sections also prevents the symbol localization trick for memset and memcpy from working, leaving these symbols defined in the final object instead of getting dropped. This prevents them from getting replaced by the kernel's implementation, causing endless loops at runtime, as memset() is implemented to call os_mem_set() which itself just calls memset(). The fix for this is to just skip gcc_helper.o from getting linked and leaving memset / memcpy undefined. The module loader will resolve them. Signed-off-by: Mathias Krause --- src/nvidia/nvidia.Kbuild | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/nvidia/nvidia.Kbuild b/src/nvidia/nvidia.Kbuild index 90787377a..f92fdbfc8 100644 --- a/src/nvidia/nvidia.Kbuild +++ b/src/nvidia/nvidia.Kbuild @@ -10,8 +10,13 @@ NV_KERNEL_O_OBJS = $(nv-kernel-objs) include $(src)/$(nvidia_src)/srcs.mk include $(src)/$(nvidia_src)/defs.mk -# The source files for nv-kernel.o are all SRCS and SRCS_CXX defined in -# srcs.mk, and the NVIDIA ID string +# The source files for nv-kernel.o are all SRCS, except gcc_helper.c, and +# SRCS_CXX defined in srcs.mk, and the NVIDIA ID string +# +# We filter gcc_helper.c to avoid creating loops, os_mem_set() calling memset() +# calling os_mem_set()... The approach of the OS-agnostic build of localizing +# symbols and having --gc-sections drop them doesn't work here, unfortunately. +SRCS := $(filter-out %/gcc_helper.c,$(SRCS)) SRCS := $(addprefix $(nvidia_src)/,$(SRCS)) SRCS_CXX := $(addprefix $(nvidia_src)/,$(SRCS_CXX)) NVIDSTRING := $(addprefix $(nvidia_src)/,g_nvid_string.c) @@ -48,20 +53,22 @@ nv-kernel-cflags += -Wno-implicit-fallthrough # lots of missing prototypes, all accross the board nv-kernel-cflags-remove := -Wmissing-declarations -Wmissing-prototypes -# Define how to perform dead code elimination: place each symbol in its own -# section at compile time, and garbage collect unreachable sections at link -# time. exports_link_command.txt tells the linker which symbols need to be -# exported from $(NV_KERNEL_O) so the linker can determine which symbols are -# unreachable. -nv-kernel-cflags += -ffunction-sections -nv-kernel-cflags += -fdata-sections - -nv-kernel-ldflags := --gc-sections -nv-kernel-ldflags += @$(src)/$(nvidia_src)/$(EXPORTS_LINK_COMMAND) -nv-kernel-ldflags += -T $(src)/$(nvidia_src)/$(LINKER_SCRIPT) - -nv-kernel-objcopyflags := --localize-symbol=memset -nv-kernel-objcopyflags += --localize-symbol=memcpy +# XXX: We cannot make use of --gc-sections, as that would also drop crucial +# XXX: sections like .alt_instructions or .return_sites. +## Define how to perform dead code elimination: place each symbol in its own +## section at compile time, and garbage collect unreachable sections at link +## time. exports_link_command.txt tells the linker which symbols need to be +## exported from $(NV_KERNEL_O) so the linker can determine which symbols are +## unreachable. +#nv-kernel-cflags += -ffunction-sections +#nv-kernel-cflags += -fdata-sections +# +#nv-kernel-ldflags := --gc-sections +#nv-kernel-ldflags += @$(src)/$(nvidia_src)/$(EXPORTS_LINK_COMMAND) +#nv-kernel-ldflags += -T $(src)/$(nvidia_src)/$(LINKER_SCRIPT) + +#nv-kernel-objcopyflags := --localize-symbol=memset +#nv-kernel-objcopyflags += --localize-symbol=memcpy #nv-kernel-objcopyflags += --remove-section=.note.gnu.property # move early -I... flags to after ours -- what a hack! From 2c344853def92ce67186b992da77e2f9ed7a1050 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 20:18:04 +0000 Subject: [PATCH 45/57] src/nvidia: make "IFACES" types compatible with grsecurity Make "IFACES" types which are embedded in larger types that often get modified 'no_const' to fix build errors for grsecurity kernels which try to enforce making instances of these types const otherwise. TODO: Implement this as a cocci script, as this is touching generated code. Signed-off-by: Mathias Krause --- src/nvidia/generated/g_gsync_nvoc.h | 2 +- src/nvidia/generated/g_rpc_hal.h | 4 ++-- src/nvidia/generated/g_rpcstructurecopy_hal.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nvidia/generated/g_gsync_nvoc.h b/src/nvidia/generated/g_gsync_nvoc.h index 7bfba72a8..1f6e2e3f9 100644 --- a/src/nvidia/generated/g_gsync_nvoc.h +++ b/src/nvidia/generated/g_gsync_nvoc.h @@ -200,7 +200,7 @@ typedef struct GSYNC_HAL_IFACES { GsyncSetVRR *gsyncSetVRR; GsyncSetRasterSyncDecodeMode *gsyncSetRasterSyncDecodeMode; -} GSYNC_HAL_IFACES; +} __no_const GSYNC_HAL_IFACES; typedef struct _def_gsync { NvU32 gsyncId; diff --git a/src/nvidia/generated/g_rpc_hal.h b/src/nvidia/generated/g_rpc_hal.h index 5a1235c49..a894aba77 100644 --- a/src/nvidia/generated/g_rpc_hal.h +++ b/src/nvidia/generated/g_rpc_hal.h @@ -29,7 +29,7 @@ typedef struct RPC_OBJ_IFACES { RpcDestroy *__rpcDestroy__ ; /* Destroy the RPC object */ RpcSendMessage *__rpcSendMessage__ ; /* Send an RPC message */ RpcRecvPoll *__rpcRecvPoll__ ; /* Receive an RPC message */ -} RPC_OBJ_IFACES; +} __no_const RPC_OBJ_IFACES; @@ -383,7 +383,7 @@ typedef struct RPC_HAL_IFACES { RpcUnmapMemoryDma *rpcUnmapMemoryDma; /* UNMAP_MEMORY_DMA */ RpcSetGuestSystemInfoExt *rpcSetGuestSystemInfoExt; /* SET_GUEST_SYSTEM_INFO_EXT */ Rpc_iGrp_ipVersions_getInfo *rpc_iGrp_ipVersions_getInfo; /* Return lookup table of hal interface ptrs based on IP_VERSION */ -} RPC_HAL_IFACES; +} __no_const RPC_HAL_IFACES; // diff --git a/src/nvidia/generated/g_rpcstructurecopy_hal.h b/src/nvidia/generated/g_rpcstructurecopy_hal.h index 7af8c2e41..2fb4d61cb 100644 --- a/src/nvidia/generated/g_rpcstructurecopy_hal.h +++ b/src/nvidia/generated/g_rpcstructurecopy_hal.h @@ -158,7 +158,7 @@ typedef struct RPCSTRUCTURECOPY_HAL_IFACES { Deserialize_NV0080_CTRL_MSENC_GET_CAPS_V2_PARAMS *deserialize_NV0080_CTRL_MSENC_GET_CAPS_V2_PARAMS; /* HAL function to deserialize NV0080_CTRL_MSENC_GET_CAPS_V2_PARAMS */ Deserialize_VGPU_GET_LATENCY_BUFFER_SIZE *deserialize_VGPU_GET_LATENCY_BUFFER_SIZE; /* HAL function to deserialize VGPU_GET_LATENCY_BUFFER_SIZE */ Rpcstructurecopy_iGrp_ipVersions_getInfo *rpcstructurecopy_iGrp_ipVersions_getInfo; /* Return lookup table of hal interface ptrs based on IP_VERSION */ -} RPCSTRUCTURECOPY_HAL_IFACES; +} __no_const RPCSTRUCTURECOPY_HAL_IFACES; // From 3be6831dc7bf22f642e1990f135d10692fe5a18c Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 22:03:29 +0000 Subject: [PATCH 46/57] src/nvidia: make nv_work_item_t compatible with grsecurity nv_work_item_t is embedding a function pointer union, grsecurity tries to constify. Mark it 'no_const' to fix the build. Signed-off-by: Mathias Krause --- src/nvidia/arch/nvalloc/unix/include/nv-priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/arch/nvalloc/unix/include/nv-priv.h b/src/nvidia/arch/nvalloc/unix/include/nv-priv.h index 0b0302203..443574f49 100644 --- a/src/nvidia/arch/nvalloc/unix/include/nv-priv.h +++ b/src/nvidia/arch/nvalloc/unix/include/nv-priv.h @@ -69,7 +69,7 @@ typedef struct nv_work_item_s { OSWorkItemFunction *pGpuFunction; OSSystemWorkItemFunction *pSystemFunction; - } func; + } __no_const func; void *pData; } nv_work_item_t; From 3337080d85106bda50b1cb6ef47897facf9a97be Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 22:07:50 +0000 Subject: [PATCH 47/57] src/nvidia: make MMU_WALK_CALLBACKS compatible with grsecurity MMU_WALK_CALLBACKS would normaly be forcibly constified. However, gvaspaceExternalRootDirCommit_IMPL() wants to modify such objects to override certain members. Make the type 'mutable_const' to allow that under grsecurity kernels. Signed-off-by: Mathias Krause --- src/nvidia/inc/libraries/mmu/mmu_walk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvidia/inc/libraries/mmu/mmu_walk.h b/src/nvidia/inc/libraries/mmu/mmu_walk.h index ce9b97676..b9fb74291 100644 --- a/src/nvidia/inc/libraries/mmu/mmu_walk.h +++ b/src/nvidia/inc/libraries/mmu/mmu_walk.h @@ -406,7 +406,7 @@ typedef struct MmuWalkCBFillEntries *FillEntries; MmuWalkCBCopyEntries *CopyEntries; MmuWalkCBWriteBuffer *WriteBuffer; -} MMU_WALK_CALLBACKS; +} __mutable_const MMU_WALK_CALLBACKS; /*! * Flags that affect walk library behavior. From 5ccc8f071ca3a471507df9fff41f1fb59deb959c Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 4 Mar 2026 10:12:00 +0000 Subject: [PATCH 48/57] src/nvidia: make callback wrapping of tmrCtrlCmdEventCreate() grsec compatible The compiler warns about mismatched function pointer types for 'pTimeProc'. Use a union for the temporary type punning. Signed-off-by: Mathias Krause --- src/nvidia/generated/g_objtmr_nvoc.h | 5 ++++- src/nvidia/src/kernel/gpu/timer/timer.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nvidia/generated/g_objtmr_nvoc.h b/src/nvidia/generated/g_objtmr_nvoc.h index 31e87ed2a..820d84802 100644 --- a/src/nvidia/generated/g_objtmr_nvoc.h +++ b/src/nvidia/generated/g_objtmr_nvoc.h @@ -120,7 +120,10 @@ struct DAYMSECTIME */ struct TMR_EVENT { - TIMEPROC pTimeProc; //pUserData; // Swap in the inner function and data - pEvent->pTimeProc = (TIMEPROC) pObj_Inner->pTimeProc; // Intentionally the wrong type! + pEvent->pTimeProcWrap = pObj_Inner->pTimeProc; pEvent->pUserData = pObj_Inner->pCallbackData; // Perform the actual callback the way the user expects it pObj_Inner->pTimeProc((void *)pEvent->pUserData); // Rewrap whatever changes the user may have made - pObj_Inner->pTimeProc = (TMR_CALLBACK_FUNCTION) pEvent->pTimeProc; + pObj_Inner->pTimeProc = pEvent->pTimeProcWrap; pObj_Inner->pCallbackData = pEvent->pUserData; // Restore the wrapper function and data From 1a5c5f1644b70485e371a4eb611b172330907c60 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 22:05:26 +0000 Subject: [PATCH 49/57] src/nvidia: nvalloc - constify pioFuncs and memFuncs Make 'pioFuncs' and 'memFuncs' static const instances and use designated initializers, avoiding build breakage under grsecurity kernels. Signed-off-by: Mathias Krause --- src/nvidia/arch/nvalloc/unix/src/vbioscall.c | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/nvidia/arch/nvalloc/unix/src/vbioscall.c b/src/nvidia/arch/nvalloc/unix/src/vbioscall.c index 8eeb85e99..6c7f028ef 100644 --- a/src/nvidia/arch/nvalloc/unix/src/vbioscall.c +++ b/src/nvidia/arch/nvalloc/unix/src/vbioscall.c @@ -270,22 +270,22 @@ RmInitX86EmuState(OBJGPU *pGpu) { int i; struct x86emu_mem_seg *pseg; X86EMU_intrFuncs *intFuncs; - X86EMU_pioFuncs pioFuncs = { - (&x_inb), - (&x_inw), - (&x_inl), - (&x_outb), - (&x_outw), - (&x_outl) + static const X86EMU_pioFuncs pioFuncs = { + .inb = x_inb, + .inw = x_inw, + .inl = x_inl, + .outb = x_outb, + .outw = x_outw, + .outl = x_outl }; - X86EMU_memFuncs memFuncs = { - (&Mem_rb), - (&Mem_rw), - (&Mem_rl), - (&Mem_wb), - (&Mem_ww), - (&Mem_wl) + static const X86EMU_memFuncs memFuncs = { + .rdb = Mem_rb, + .rdw = Mem_rw, + .rdl = Mem_rl, + .wrb = Mem_wb, + .wrw = Mem_ww, + .wrl = Mem_wl }; if (!NV_PRIMARY_VGA(NV_GET_NV_STATE(pGpu))) // not the primary GPU From ebd68abcec7b81f15eef16405790cbb6665254b5 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 17:37:04 -0400 Subject: [PATCH 50/57] src/nvidia: mark THREAD_STATE_NODE nolocal for grsecurity compatibility grsecurity's private kernel stack feature demands 'struct THREAD_STATE_NODE' objects to be moved off the stack as different threads cannot access each other's kernel stacks. Signed-off-by: Mathias Krause --- src/nvidia/inc/kernel/core/thread_state.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/nvidia/inc/kernel/core/thread_state.h b/src/nvidia/inc/kernel/core/thread_state.h index 01ac1e485..60d0406fd 100644 --- a/src/nvidia/inc/kernel/core/thread_state.h +++ b/src/nvidia/inc/kernel/core/thread_state.h @@ -58,9 +58,7 @@ typedef struct THREAD_STATE_FREE_CALLBACK MAKE_LIST(THREAD_STATE_FREE_CB_LIST, THREAD_STATE_FREE_CALLBACK); -typedef struct THREAD_STATE_NODE THREAD_STATE_NODE; - -struct THREAD_STATE_NODE +typedef struct THREAD_STATE_NODE { OS_THREAD_HANDLE threadId; /*! @@ -90,7 +88,7 @@ struct THREAD_STATE_NODE * Only supported on non-ISR CPU RM paths. */ THREAD_STATE_FREE_CB_LIST cbList; -}; +} __nolocal THREAD_STATE_NODE; MAKE_INTRUSIVE_MAP(ThreadStateNodeMap, THREAD_STATE_NODE, node); From fadae3b5882af64bd519ddcf1a4b8af05fb5ab5d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Feb 2026 16:38:49 +0000 Subject: [PATCH 51/57] src/nvidia: support mangling sources with coccinelle The sources below src/nvidia/generated/ violate type constraints enforced by grsecurity's RANDSTRUCT or PaX's RAP. Support preprocessing these via coccinelle scripts to fix these prior to compiling them. Signed-off-by: Mathias Krause --- src/nvidia/cocci.sh | 53 +++++++++++++++++++++++++++++++++++++ src/nvidia/nvidia.Kbuild | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/nvidia/cocci.sh diff --git a/src/nvidia/cocci.sh b/src/nvidia/cocci.sh new file mode 100644 index 000000000..aceb1c2e6 --- /dev/null +++ b/src/nvidia/cocci.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# Helper to invoke spatch with optional pre- and post-processing filters and +# optional additional arguments.. +# +# Not meant to be used directly but invoked via Kbuild! +# +# (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +null_filter() { + case "$1" in + pre) ;; + diff) cat; ;; + post) ;; + esac +} + +filter() { + ${1:-null}_filter "$2" +} + +check_prog() { + BIN="$1" + PKG="$2" + + if [ -z "$(command -v $BIN 2>/dev/null)" ]; then + echo >&2 "error: $BIN not found, please install $PKG!" + return 1 + fi + + return 0 +} + +if [ $# -lt 2 ]; then + echo >&2 "error: spatch file and program missing!" + exit 1 +fi + +SCRIPT=$1; shift +SPATCH=$1; shift + +if ! check_prog "$SPATCH" coccinelle; then + echo >&2 "error: missing required programs!" + exit 2 +fi + +FILTER=$(echo "$SCRIPT" | sed -n 's|.*:||p') +SCRIPT=${SCRIPT%:*} +EXTRA_ARGS=$(sed -n 's|// options: ||p' $SCRIPT) + +filter "$FILTER" pre +$SPATCH --sp-file "$SCRIPT" "$@" $EXTRA_ARGS | filter "$FILTER" diff +filter "$FILTER" post diff --git a/src/nvidia/nvidia.Kbuild b/src/nvidia/nvidia.Kbuild index f92fdbfc8..fb8e57fa9 100644 --- a/src/nvidia/nvidia.Kbuild +++ b/src/nvidia/nvidia.Kbuild @@ -20,6 +20,63 @@ SRCS := $(filter-out %/gcc_helper.c,$(SRCS)) SRCS := $(addprefix $(nvidia_src)/,$(SRCS)) SRCS_CXX := $(addprefix $(nvidia_src)/,$(SRCS_CXX)) NVIDSTRING := $(addprefix $(nvidia_src)/,g_nvid_string.c) +ALL_SRCS := $(SRCS) $(SRCS_CXX) $(NVIDSTRING) + +COCCI := $(SHELL) cocci.sh +PATCH ?= patch +SPATCH ?= spatch + +# generated/ is most insteresting to us, but some cocci scripts require +# overriding the --dir option, making the leading './' important to still have +# --ignore filter the bindata files which don't need any fixups but make spatch +# complain about exhausting its stack space. +SPATCH_OPTS := --dir ./generated/ +SPATCH_OPTS += --ignore ./generated/g_bindata +SPATCH_OPTS += -I generated/ +SPATCH_OPTS += --include-headers # headers should be processed (patched) too +SPATCH_OPTS += --patch . # for 'patch -p1 …' +SPATCH_OPTS += --smpl-spacing # don't mess with spacing too much to keep diffs small +SPATCH_OPTS += --very-quiet + +JOBS := $(patsubst -j%,%,$(filter -j%,$(MAKEFLAGS))) +ifneq ($(JOBS),) +SPATCH_OPTS += --jobs $(JOBS) +endif + +# order here is important and defines patch order too! +COCCI_SCRIPTS_ARGS := + +COCCI_SCRIPTS := $(filter %.cocci,$(subst :, ,$(COCCI_SCRIPTS_ARGS))) +COCCI_PATCHES = $(addprefix 0???-,$(COCCI_SCRIPTS:.cocci=.diff)) +COCCI_PATCH_MARKER := .cocci_patched + +PATCH_CANDIDATES := $(filter $(nvidia_src)/generated/%,$(ALL_SRCS)) +PATCH_CANDIDATES := $(PATCH_CANDIDATES:.c=.o) +PATCH_CANDIDATES := $(PATCH_CANDIDATES:.cpp=.o) +$(addprefix $(obj)/,$(PATCH_CANDIDATES)): $(obj)/$(nvidia_src)/$(COCCI_PATCH_MARKER) + +$(obj)/$(nvidia_src)/$(COCCI_PATCH_MARKER): $(addprefix $(obj)/$(nvidia_src)/,$(COCCI_SCRIPTS)) + @echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + @echo '!!! Generating cocci patches, this may take a while. !!!' + @echo '!!! DO NOT INTERRUPT, OR SOURCES WILL BE MESSED UP! !!!' + @echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' + @cd $(src)/$(nvidia_src) && i=0 && \ + for s in $(COCCI_SCRIPTS_ARGS); do \ + i=$$((i+1)); \ + c=$${s%:*}; \ + p=$$(printf "%04d-%s" $$i "$${c%.cocci}.diff"); \ + t=.tmp.$$p; \ + echo " COCCI $$c"; \ + $(COCCI) "$$s" "$(SPATCH)" $(SPATCH_OPTS) > $$t || exit 1; \ + mv $$t $$p; \ + echo " PATCH $$p"; \ + $(PATCH) -p1 <$$p; \ + done + @touch $@ + +# XXX: better reverse apply the patches on clean +#clean-files += $(addprefix $(nvidia_src)/,$(COCCI_PATCH_MARKER) $(COCCI_PATCHES)) +clean-files += $(addprefix $(nvidia_src)/,pfunc.list) nv-kernel-objs := $(SRCS:.c=.o) nv-kernel-objs += $(SRCS_CXX:.cpp=.o) From 9011d9afd78c34be43b62f0157946d7aa7cf2c23 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 27 Nov 2025 21:38:15 +0000 Subject: [PATCH 52/57] fix_nvoc_dtor.cocci: fix NVOC_DYNAMIC_DTOR CFI violations Signed-off-by: Mathias Krause --- src/nvidia/fix_nvoc_dtor.cocci | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/nvidia/fix_nvoc_dtor.cocci diff --git a/src/nvidia/fix_nvoc_dtor.cocci b/src/nvidia/fix_nvoc_dtor.cocci new file mode 100644 index 000000000..1789967ae --- /dev/null +++ b/src/nvidia/fix_nvoc_dtor.cocci @@ -0,0 +1,49 @@ +// Coccinelle script to fix 'dtor' function pointer casts to use proper +// types to prevent runtime CFI violations, e.g. under RAP. +// +// We need to create a thunk in any case as there may be calls to the strongly +// typed function from other TUs, causing CFI violations if we'd just change +// the function's signature to match the dtor function pointer prototype. +// +// typedef void (*NVOC_DYNAMIC_DTOR)(Dynamic*); +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +// replace function casts to (NVOC_DYNAMIC_DTOR) with its thunk +@dtor_cast@ +identifier fn; +fresh identifier fnthunk = fn ## "_THUNK"; +@@ +- (NVOC_DYNAMIC_DTOR) &fn ++ &fnthunk + +// add decl for the thunk, if needed, i.e. if the original func had one +@thunk_decl@ +identifier dtor_cast.fn, dtor_cast.fnthunk, arg; +typedef Dynamic; +type T, R; +@@ +// XXX: matching function decls is only poorly supported, so we need this hack +( +-R fn(T) ++R fn(T); ++static void fnthunk(Dynamic *) +; +| +-R fn(T arg) ++R fn(T arg); ++static void fnthunk(Dynamic *arg) +; +) + +// add thunk function +@thunk_def@ +identifier dtor_cast.fn, dtor_cast.fnthunk, arg; +typedef Dynamic; +type T, R; +@@ +R fn(T arg) { ... } ++ ++static void fnthunk(Dynamic *arg) { ++ fn((T)arg); ++} From 3900714b9fca8938ed783963394c29f5b7c53e78 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 27 Nov 2025 22:15:50 +0000 Subject: [PATCH 53/57] fix_nvoc_ctor.cocci: fix NVOC_DYNAMIC_OBJ_CREATE CFI violations Signed-off-by: Mathias Krause --- src/nvidia/fix_nvoc_ctor.cocci | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/nvidia/fix_nvoc_ctor.cocci diff --git a/src/nvidia/fix_nvoc_ctor.cocci b/src/nvidia/fix_nvoc_ctor.cocci new file mode 100644 index 000000000..28c8e1b3e --- /dev/null +++ b/src/nvidia/fix_nvoc_ctor.cocci @@ -0,0 +1,43 @@ +// Coccinelle script to fix 'objCreatefn' function pointer casts to use proper +// types to prevent runtime CFI violations, e.g. under RAP. +// +// As for fix_nvoc_dtor.cocci, we need to create a thunk. +// +// typedef NV_STATUS (*NVOC_DYNAMIC_OBJ_CREATE)(Dynamic**, Dynamic *pParent, NvU32 createFlags, va_list); +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +// replace function casts to (NVOC_DYNAMIC_OBJ_CREATE) with its thunk +@ctor_cast@ +identifier fn; +fresh identifier fnthunk = fn ## "_THUNK"; +@@ +- (NVOC_DYNAMIC_OBJ_CREATE) &fn ++ &fnthunk + +// add decl for the thunk +// XXX: little hacky, as the decl is in the .h file, thereby we cannot match on +// XXX: @ctor_cast@ and need to use heuristics based on the function name. +@thunk_decl@ +identifier fn =~ "^__nvoc_objCreateDynamic_"; +fresh identifier fnthunk = fn ## "_THUNK"; +typedef NV_STATUS, Dynamic, NvU32, va_list; +type T1, T2, T3, T4, R; +@@ +// XXX: matching function decls is only poorly supported, so we need this hack +-R fn(T1, T2, T3, T4) ++R fn(T1, T2, T3, T4); ++NV_STATUS fnthunk(Dynamic **, Dynamic *, NvU32, va_list) +; + +// add thunk function +@thunk_def@ +identifier ctor_cast.fn, ctor_cast.fnthunk, a1, a2, a3, a4; +typedef NV_STATUS, Dynamic, NvU32, va_list; +type T1, T2, T3, T4, R; +@@ +R fn(T1 a1, T2 a2, T3 a3, T4 a4) { ... } ++ ++NV_STATUS fnthunk(Dynamic **a1, Dynamic *a2, NvU32 a3, va_list a4) { ++ return fn((T1)a1, (T2)a2, a3, a4); ++} From f049e83c975f37657b0e040583d10a0d348bd40b Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Fri, 5 Dec 2025 21:00:58 +0000 Subject: [PATCH 54/57] fix_nvoc_pfunc*.cocci: fix bad pFunc fprt casts Drop all the casts and provide thunks that do the necessary type conversion. Signed-off-by: Mathias Krause --- src/nvidia/cocci.sh | 76 ++++++++++++++ src/nvidia/fix_nvoc_pfunc_addr.cocci | 51 ++++++++++ src/nvidia/fix_nvoc_pfunc_null.cocci | 35 +++++++ src/nvidia/fix_nvoc_pfunc_thunk.cocci | 138 ++++++++++++++++++++++++++ src/nvidia/fix_nvoc_pfunc_type.cocci | 21 ++++ src/nvidia/fix_nvoc_pfunc_use.cocci | 56 +++++++++++ 6 files changed, 377 insertions(+) create mode 100644 src/nvidia/fix_nvoc_pfunc_addr.cocci create mode 100644 src/nvidia/fix_nvoc_pfunc_null.cocci create mode 100644 src/nvidia/fix_nvoc_pfunc_thunk.cocci create mode 100644 src/nvidia/fix_nvoc_pfunc_type.cocci create mode 100644 src/nvidia/fix_nvoc_pfunc_use.cocci diff --git a/src/nvidia/cocci.sh b/src/nvidia/cocci.sh index aceb1c2e6..2c8b0e596 100644 --- a/src/nvidia/cocci.sh +++ b/src/nvidia/cocci.sh @@ -7,6 +7,82 @@ # # (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. +pfunc_filter() { + # What a hack! + # + # coccinelle doesn't evaluate both sides of a #if ... #else ... #endif + # block and even worse, it doesn't even implement enough preprocessor + # logic to actually understand the #if expression and always only + # handles the #if branch for non-trivial expressions. + # Work around that by modifying the expression to '#if 0' and use + # --noif0-passing to get the #else branch. *sigh!* + # + # Hack #2: + # On top of that we need yet another hack to get thunk definitions as + # blindly adding thunks for all ever possible functions doesn't work + # (there are multiple decls that'd lead to multiple static inline thunk + # definitions). So we record which functions we want a thunk for via + # pfunc_list_filter() and use that to actually generate thunks only for + # these. Gross! + case "$1" in + pre) sed 's|\(#if\) \(NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG\)|\1 0//\2|' -i generated/*.[ch]; ;; + diff) sed 's|\(#if\) 0//\(NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG\)|\1 \2|'; ;; + post) sed 's|\(#if\) 0//\(NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG\)|\1 \2|' -i generated/*.[ch]; ;; + esac +} + +pfunc_list_filter() { + case "$1" in + # To create thunks for all replaced pFunc replacements, we create a + # file 'pfunc.list' with all their names. That'll get used by + # fix_nvoc_pfunc_thunk.cocci to create thunks for each of these -- and + # only these. + # + # Don't look too close at how we do that -- yet another hack ;P + diff) + fifo=$(mktemp -u) + mkfifo "$fifo" + + sed -n 's|^-.*pFunc=.*&\(.*\),|\1|p' <"$fifo" >pfunc.list & + sed_pid=$! + + # copy the diff to the 'pfunc.list' creation process + pfunc_filter "$@" | tee "$fifo" + + wait $sed_pid + rm "$fifo" + ;; + + *) pfunc_filter "$@";; + esac +} + +pfunc_sli_filter() { + # Oh well, another hack. + # + # coccinelle cannot cope with the SLI_LOOP_START / SLI_LOOP_END macros, + # leading to parse errors and, in turn, missing thunk generation. + # Work around that by simplify the macros, similar to what we already + # do for NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG in pfunc_filter(). + # + # Fortunately, only this one file needs it: + SLI_FILES=" + arch/nvalloc/unix/src/unix_console.c + " + + case "$1" in + pre) sed 's|\(SLI_LOOP_START\)|do { //\1|;s|\(SLI_LOOP_END\)|} while(0);//\1|' -i $SLI_FILES + pfunc_filter "$@" + ;; + diff) sed 's|do { //\(SLI_LOOP_START\)|\1|;s|} while(0);//\(SLI_LOOP_END\)|\1|' | \ + pfunc_filter "$@" + ;; + post) sed 's|do { //\(SLI_LOOP_START\)|\1|;s|} while(0);//\(SLI_LOOP_END\)|\1|' -i $SLI_FILES + pfunc_filter "$@" + ;; + esac +} + null_filter() { case "$1" in pre) ;; diff --git a/src/nvidia/fix_nvoc_pfunc_addr.cocci b/src/nvidia/fix_nvoc_pfunc_addr.cocci new file mode 100644 index 000000000..edeb9dd61 --- /dev/null +++ b/src/nvidia/fix_nvoc_pfunc_addr.cocci @@ -0,0 +1,51 @@ +// Coccinelle script to fix 'pFunc' function pointer casts to use proper +// types to prevent runtime CFI violations, e.g. under RAP. +// +// As for fix_nvoc_dtor.cocci, we need to create a thunk. The thunk takes two +// arguments, even if the implementation takes only one. That'll get handled +// when adding a thunk definition. +// +// NV_STATUS (*pFunc)(void *, void *); +// +// As coccinelle cannot handle the preprocessor branches for the 'pFunc' +// assignment correctly, we need a workaround that simplifies the code so +// coccinelle can understand it (see cocci.sh:pfunc_filter()). +// +// This script handles the part of replacing taking the address of the real +// function. It uses heuristics based on the function name to avoid false +// positives. Post-processing in cocci.sh creates a file pfunc.list that'll +// get used by fix_nvoc_pfunc_thunk.cocci to create the thunks. +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +@initialize:python@ +@@ +import re + +# cocci's regex support is too limiting, use python for the filtering +type_match = re.compile(r"void *\( *\* *\) *\( *void *\)") # cocci adds spaces +func_match = re.compile(r"_(IMPL|DISPATCH|KERNEL|[0-9a-f]{6})$") + +// search for (function) pointer casts (filtered in @pfunc_cast_filter@) +@pfunc_cast disable drop_cast@ +identifier fn; +type T; +@@ + (T) &fn + +@script:python pfunc_cast_filter@ +t << pfunc_cast.T; +f << pfunc_cast.fn; +@@ +if not type_match.search(t) or not func_match.search(f): +# print(f">>> '({t}) {f}' didn't match") + cocci.include_match(False) + +// drop cast and replace function with a thunk +@remove_cast depends on pfunc_cast_filter@ +identifier pfunc_cast.fn; +type pfunc_cast.T; +fresh identifier fnthunk = fn ## "_THUNK"; +@@ +- (T) &fn ++ &fnthunk diff --git a/src/nvidia/fix_nvoc_pfunc_null.cocci b/src/nvidia/fix_nvoc_pfunc_null.cocci new file mode 100644 index 000000000..6c3c99fd4 --- /dev/null +++ b/src/nvidia/fix_nvoc_pfunc_null.cocci @@ -0,0 +1,35 @@ +// Coccinelle script to fix 'pFunc' function pointer casts to use proper types. +// +// Similar to fix_nvoc_pfunc_addr.cocci, just for the NULL fptr. +// +// We simply want to drop the cast as it's unneeded. As it's in the '#if 0' +// block, we need to tell cocci to look at that: +// +// options: --noif0-passing +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +@initialize:python@ +@@ +import re + +type_match = re.compile(r"void *\( *\* *\) *\( *void *\)") # cocci adds spaces + +// search for (function) pointer casts (filtered in @pfunc_cast_filter@) +@pfunc_null_cast disable drop_cast@ +type T; +@@ + (T) NULL + +@script:python pfunc_cast_filter@ +t << pfunc_null_cast.T; +@@ +if not type_match.search(t): + cocci.include_match(False) + +@remove_null_cast depends on pfunc_cast_filter@ +type pfunc_null_cast.T; +@@ +- (T) + NULL + diff --git a/src/nvidia/fix_nvoc_pfunc_thunk.cocci b/src/nvidia/fix_nvoc_pfunc_thunk.cocci new file mode 100644 index 000000000..b0ebf30d8 --- /dev/null +++ b/src/nvidia/fix_nvoc_pfunc_thunk.cocci @@ -0,0 +1,138 @@ +// Coccinelle script to fix 'pFunc' function pointer casts to use proper +// types to prevent runtime CFI violations, e.g. under RAP. +// +// fix_nvoc_pfunc_addr.cocci already replaced the function pointer with a +// thunk. What's left is to actually generate the thunk declarations and +// definitions. +// +// NV_STATUS (*pFunc)(void *, void *); +// +// This script depends on fix_nvoc_pfunc_addr.cocci to generate a file +// 'pfunc.list' with all the functions that have been replaced (see +// cocci.sh:pfunc_list_filter()). +// +// Implementations aren't limited to generated/ but live also in src/kernel/ +// or even arch/nvalloc/. Therefore scan all source files: +// +// options: --dir . --allow-inconsistent-paths +// +// The --allow-inconsistent-paths is to work around bogus(?) warnings. +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +@initialize:python@ +@@ +with open('pfunc.list', 'r') as file: + pfuncs = file.read().splitlines() + +// search for potential pFunc decls, filtered by @pfunc_decl_filter@ +@pfunc_decl@ +identifier fn; +identifier a1, a2; +type T1, T2, R; +@@ +( +R fn(T1 a1); +| +R fn(T1 a1, T2 a2); +) + +@script:python pfunc_decl_filter@ +func << pfunc_decl.fn; +@@ +if func not in pfuncs: + cocci.include_match(False) +#else: +# print(f">>> {func} included") + +// Add thunk decls right next to the original function's decl to make sure +// it'll be declared when its address is taken. +@pfunc_thunk_decl depends on pfunc_decl_filter@ +identifier pfunc_decl.fn; +type pfunc_decl.R; +parameter list P; +fresh identifier thunk = fn ## "_THUNK"; +typedef NV_STATUS; +@@ +// XXX: matching function decls is only poorly supported, so we need this hack +-R fn(P) ++R fn(P); ++NV_STATUS thunk(void *obj, void *arg) +; + +// search for potential pFunc definitions, filtered by @pfunc_def_filter@ +// +// TODO: Try to merge with pfunc_decl* +@pfunc_def@ +identifier fn; +identifier a1, a2; +type T1, T2, R; +@@ +( +R fn(T1 a1) { ... } +| +R fn(T1 a1, T2 a2) { ... } +) + +@script:python pfunc_def_filter@ +func << pfunc_def.fn; +@@ +if func not in pfuncs: + cocci.include_match(False) +#else: +# print(f">>> {func} included") + +// Add thunk definitions +// +// TODO: merge all of these +@pfunc_thunk_def_two_args_inline depends on pfunc_def_filter@ +identifier pfunc_def.fn; +identifier pfunc_def.a1, pfunc_def.a2; +type pfunc_def.T1, pfunc_def.T2, pfunc_def.R; +fresh identifier thunk = fn ## "_THUNK"; +typedef NV_STATUS; +@@ + static inline R fn(T1 a1, T2 a2) { ... } ++static inline NV_STATUS thunk(void *obj, void *arg) ++{ ++ return fn((T1)obj, (T2)arg); ++} + +@pfunc_thunk_def_two_args depends on pfunc_def_filter && !pfunc_thunk_def_two_args_inline@ +identifier pfunc_def.fn; +identifier pfunc_def.a1, pfunc_def.a2; +type pfunc_def.T1, pfunc_def.T2, pfunc_def.R; +fresh identifier thunk = fn ## "_THUNK"; +typedef NV_STATUS; +@@ + R fn(T1 a1, T2 a2) { ... } ++NV_STATUS thunk(void *obj, void *arg) ++{ ++ return fn((T1)obj, (T2)arg); ++} + +@pfunc_thunk_def_one_arg_inline depends on pfunc_def_filter@ +identifier pfunc_def.fn; +identifier pfunc_def.a1; +type pfunc_def.T1, pfunc_def.R; +fresh identifier thunk = fn ## "_THUNK"; +typedef NV_STATUS; +@@ + static inline R fn(T1 a1) { ... } ++static inline NV_STATUS thunk(void *obj, void *arg) ++{ ++ return fn((T1)obj); ++} + +@pfunc_thunk_def_one_arg depends on pfunc_def_filter && !pfunc_thunk_def_one_arg_inline@ +identifier pfunc_def.fn; +identifier pfunc_def.a1; +type pfunc_def.T1, pfunc_def.R; +fresh identifier thunk = fn ## "_THUNK"; +typedef NV_STATUS; +@@ + R fn(T1 a1) { ... } ++NV_STATUS thunk(void *obj, void *arg) ++{ ++ return fn((T1)obj); ++} diff --git a/src/nvidia/fix_nvoc_pfunc_type.cocci b/src/nvidia/fix_nvoc_pfunc_type.cocci new file mode 100644 index 000000000..b4682a639 --- /dev/null +++ b/src/nvidia/fix_nvoc_pfunc_type.cocci @@ -0,0 +1,21 @@ +// Coccinelle script to fix 'pFunc' member function pointer type to match what +// fix_nvoc_pfunc.cocci expects. +// +// The structure type is located in inc/libraries/nvoc/runtime.h, override +// the --dir ... parameter to only patch that: +// +// options: --dir inc/libraries/nvoc/ +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +@pfunc_member@ +typedef NV_STATUS; +@@ +struct NVOC_EXPORTED_METHOD_DEF +{ + ... +- void (*pFunc) (...) ++ NV_STATUS (*pFunc)(void *, void *) + ; + ... +}; diff --git a/src/nvidia/fix_nvoc_pfunc_use.cocci b/src/nvidia/fix_nvoc_pfunc_use.cocci new file mode 100644 index 000000000..a9c6c3a7f --- /dev/null +++ b/src/nvidia/fix_nvoc_pfunc_use.cocci @@ -0,0 +1,56 @@ +// Coccinelle script to fix 'pFunc' function pointer users to use the type +// expected by fix_nvoc_pfunc_type.cocci and ensure it gets passed two args. +// +// NV_STATUS (*pFunc)(void *, void *); +// +// pFunc use is in src/kernel/gpu/deferred_api.c, src/kernel/gpu/gpu.c and +// src/libraries/resserv/src/rs_resource.c, therefore override the --dir +// option: +// +// options: --dir src/ +// +// (c) 2025,2026 Open Source Security, Inc. All Rights Reserved. + +// cases with a local variable +@pfunc_use_var@ +struct NVOC_EXPORTED_METHOD_DEF *e; +typedef NV_STATUS; +expression arg; +identifier fn; +type T; +@@ + +-T fn = ((T) e->pFunc) ++NV_STATUS (*fn)(void *, void *) = e->pFunc + ; + <... + fn( + arg ++ , NULL + ) + ...> + +// cases which cast and use ->pFunc directly +@pfunc_use_cast@ +struct NVOC_EXPORTED_METHOD_DEF *e; +expression arg1, arg2; +type T; +@@ +( +-((T) e->pFunc) ++(e->pFunc) + (arg1, arg2) +| +-((T) e->pFunc) ++(e->pFunc) + (arg1 ++ , NULL + ) +) + +// get rid of the now unused typedef as well +@pfunc_typedef@ +type pfunc_use_var.T; +typedef NV_STATUS; +@@ +- typedef NV_STATUS (*T)(...); From ba610b7735f6a62bc78e5e5582cf85649b10d88f Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 12 Mar 2026 15:05:21 +0100 Subject: [PATCH 55/57] fix_*_init.cocci: fix missing desgnated inits The 'rcp_hal_init' filter needs recountdiff from patchutils! Signed-off-by: Mathias Krause --- src/nvidia/cocci.sh | 19 ++++++++++++++++++- src/nvidia/fix_hal_iface_init.cocci | 24 ++++++++++++++++++++++++ src/nvidia/fix_rpc_hal_init.cocci | 23 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/nvidia/fix_hal_iface_init.cocci create mode 100644 src/nvidia/fix_rpc_hal_init.cocci diff --git a/src/nvidia/cocci.sh b/src/nvidia/cocci.sh index 2c8b0e596..c91721b32 100644 --- a/src/nvidia/cocci.sh +++ b/src/nvidia/cocci.sh @@ -83,6 +83,21 @@ pfunc_sli_filter() { esac } +rpc_hal_init_filter() { + # What a hack, take 2! + # + # To modify structure initialization to use designated initializers, we + # post-process a cocci patch that simply removes the init to inject + # lines that add the correct initialization, based on the fact that the + # field member is mentioned in a trailing comment. To make that a valid + # diff, we fix it up using recountdiff. + case "$1" in + pre) ;; + diff) sed 's|^-\( *\)\([^ ]\+\), *// *\([^ ]\+\)$|&\n+\1.\3 = \2,|' | recountdiff; ;; + post) ;; + esac +} + null_filter() { case "$1" in pre) ;; @@ -115,7 +130,9 @@ fi SCRIPT=$1; shift SPATCH=$1; shift -if ! check_prog "$SPATCH" coccinelle; then +if ! check_prog "$SPATCH" coccinelle || \ + ! check_prog recountdiff patchutils; +then echo >&2 "error: missing required programs!" exit 2 fi diff --git a/src/nvidia/fix_hal_iface_init.cocci b/src/nvidia/fix_hal_iface_init.cocci new file mode 100644 index 000000000..5ef38614c --- /dev/null +++ b/src/nvidia/fix_hal_iface_init.cocci @@ -0,0 +1,24 @@ +// Coccinelle script to fix structure initialization to use designated +// initializer to make these compatible with Linux's RANDSTRUCT. +// +// Here we handle instances of HAL_IFACE_SETUP: +// +// typedef struct { +// void (*rpcHalIfacesSetupFn)(PRPC_HAL_IFACES pRpcHal); +// void (*rpcstructurecopyHalIfacesSetupFn)(PRPCSTRUCTURECOPY_HAL_IFACES pRpcstructurecopyHal); +// } HAL_IFACE_SETUP +// +// We simply hard-code the field names. +// +// (c) 2026 Open Source Security, Inc. All Rights Reserved. + +@@ +identifier his; +identifier f1, f2; +@@ + static HAL_IFACE_SETUP his = { +- f1, +- f2, ++ .rpcHalIfacesSetupFn = f1, ++ .rpcstructurecopyHalIfacesSetupFn = f2, + }; diff --git a/src/nvidia/fix_rpc_hal_init.cocci b/src/nvidia/fix_rpc_hal_init.cocci new file mode 100644 index 000000000..c4a9c0f69 --- /dev/null +++ b/src/nvidia/fix_rpc_hal_init.cocci @@ -0,0 +1,23 @@ +// Coccinelle script to fix structure initialization to use designated +// initializer to make these compatible with Linux's RANDSTRUCT. +// +// As coccinelle has no support for referencing a field's member name, we +// post-process the patch with a sed script to do just that (the field name is +// mentioned by a trailing comment). +// +// (c) 2026 Open Source Security, Inc. All Rights Reserved. + +@@ +typedef RPC_HAL_IFACES, RPCSTRUCTURECOPY_HAL_IFACES; +identifier id; +@@ + + static +( + RPC_HAL_IFACES +| + RPCSTRUCTURECOPY_HAL_IFACES +) + id = { +- ... + }; From 23a3af9246e55150f21229eba10c045578fc1e27 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 16 Dec 2025 13:59:48 +0000 Subject: [PATCH 56/57] src/nvidia: kbuild - hook up cocci scripts Hook up the various coccinelle scripts so they're actually used. Signed-off-by: Mathias Krause --- src/nvidia/nvidia.Kbuild | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/nvidia/nvidia.Kbuild b/src/nvidia/nvidia.Kbuild index fb8e57fa9..9938ec802 100644 --- a/src/nvidia/nvidia.Kbuild +++ b/src/nvidia/nvidia.Kbuild @@ -44,13 +44,26 @@ SPATCH_OPTS += --jobs $(JOBS) endif # order here is important and defines patch order too! -COCCI_SCRIPTS_ARGS := +COCCI_SCRIPTS_ARGS := fix_nvoc_dtor.cocci +COCCI_SCRIPTS_ARGS += fix_nvoc_ctor.cocci +COCCI_SCRIPTS_ARGS += fix_nvoc_pfunc_type.cocci +COCCI_SCRIPTS_ARGS += fix_nvoc_pfunc_null.cocci:pfunc +COCCI_SCRIPTS_ARGS += fix_nvoc_pfunc_addr.cocci:pfunc_list +COCCI_SCRIPTS_ARGS += fix_nvoc_pfunc_thunk.cocci:pfunc_sli +COCCI_SCRIPTS_ARGS += fix_nvoc_pfunc_use.cocci +COCCI_SCRIPTS_ARGS += fix_hal_iface_init.cocci +COCCI_SCRIPTS_ARGS += fix_rpc_hal_init.cocci:rpc_hal_init COCCI_SCRIPTS := $(filter %.cocci,$(subst :, ,$(COCCI_SCRIPTS_ARGS))) COCCI_PATCHES = $(addprefix 0???-,$(COCCI_SCRIPTS:.cocci=.diff)) COCCI_PATCH_MARKER := .cocci_patched -PATCH_CANDIDATES := $(filter $(nvidia_src)/generated/%,$(ALL_SRCS)) +# XXX: +# Unfortunately, some cocci scripts override the --dir option, making more +# than generated/ be affected. Even worse, some changes have to be done to +# header files, impacting potentially all sources. Be safe and prevent any +# compilation from happening until all files are patched. +PATCH_CANDIDATES := $(ALL_SRCS) PATCH_CANDIDATES := $(PATCH_CANDIDATES:.c=.o) PATCH_CANDIDATES := $(PATCH_CANDIDATES:.cpp=.o) $(addprefix $(obj)/,$(PATCH_CANDIDATES)): $(obj)/$(nvidia_src)/$(COCCI_PATCH_MARKER) From 03505ed5628c52dc7c21307b0c3a07bccf50d91d Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 18 Mar 2026 06:15:39 -0400 Subject: [PATCH 57/57] XXX: nvidia: comment about memory leak --- src/nvidia/arch/nvalloc/unix/src/osinit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nvidia/arch/nvalloc/unix/src/osinit.c b/src/nvidia/arch/nvalloc/unix/src/osinit.c index 44185ad78..2b9cfc731 100644 --- a/src/nvidia/arch/nvalloc/unix/src/osinit.c +++ b/src/nvidia/arch/nvalloc/unix/src/osinit.c @@ -1635,6 +1635,8 @@ NvBool RmInitPrivateState( // Only certain Tegra PCI iGPUs support Rail-Gating pNv->supports_tegra_igpu_rg = pNv->is_tegra_pci_igpu && pGpuArch->bGpuarchSupportsIgpuRg; + // XXX: objDelete(pGpuArch) as it's dynamically allocated, see src/nvidia/src/kernel/gpu_mgr/gpu_mgr.c:gpumgrGetGpuArch_IMPL() + kvgpumgrAttachGpu(pNv->gpu_id); os_mem_set(nvp, 0, sizeof(*nvp));