From 854a06b7310a3ba35d817e133d5e31e0873fb0b7 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 20 Nov 2025 16:40:41 +0000 Subject: [PATCH 01/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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