From c68c36804f88d75df35d2071c63f430704b467b8 Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Tue, 30 Jun 2026 22:57:25 -0300 Subject: [PATCH 1/3] fix: use `strscpy` instead of `strncpy` in kernel drive code This commit replaces all usages of "strncpy" to use "strscpy". Since Linux 7.2-rc.1, "strncpy" has been fully removed from the source, and cannot be used by drivers anymore (see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1a3746ccbb0a97bed3c06ccde6b880013b1dddc1). We also replace one of the "strncpy" for "memcpy", since "strscpy" is not suitable either here, due to always NUL terminate. --- kernel-open/nvidia-modeset/nvidia-modeset-linux.c | 4 ++-- .../nvidia-modeset/nvidia-modeset-os-interface.h | 4 ++-- kernel-open/nvidia-uvm/uvm_pmm_gpu.c | 2 +- kernel-open/nvidia/export_nvswitch.h | 6 +++--- kernel-open/nvidia/linux_nvswitch.c | 10 +++++----- kernel-open/nvidia/os-interface.c | 3 +-- src/common/nvswitch/interface/export_nvswitch.h | 12 +++++++++--- src/common/nvswitch/kernel/ls10/smbpbi_ls10.c | 3 +-- src/common/nvswitch/kernel/nvswitch.c | 4 +--- src/nvidia-modeset/kapi/src/nvkms-kapi.c | 2 +- .../include/nvidia-modeset-os-interface.h | 6 ++++-- src/nvidia-modeset/src/dp/nvdp-device.cpp | 2 +- src/nvidia-modeset/src/nvkms-dpy.c | 4 +--- src/nvidia-modeset/src/nvkms-modepool.c | 3 +-- 14 files changed, 33 insertions(+), 32 deletions(-) diff --git a/kernel-open/nvidia-modeset/nvidia-modeset-linux.c b/kernel-open/nvidia-modeset/nvidia-modeset-linux.c index 8c2cf3740b..7d46c50b96 100644 --- a/kernel-open/nvidia-modeset/nvidia-modeset-linux.c +++ b/kernel-open/nvidia-modeset/nvidia-modeset-linux.c @@ -664,9 +664,9 @@ int nvkms_strcmp(const char *s1, const char *s2) return strcmp(s1, s2); } -char* nvkms_strncpy(char *dest, const char *src, size_t n) +ssize_t nvkms_strscpy(char *dest, const char *src, size_t count) { - return strncpy(dest, src, n); + return strscpy(dest, src, count); } void nvkms_usleep(NvU64 usec) diff --git a/kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h b/kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h index a634ec2bcc..bcac52e874 100644 --- a/kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h +++ b/kernel-open/nvidia-modeset/nvidia-modeset-os-interface.h @@ -149,9 +149,9 @@ int nvkms_memcmp (const void *s1, size_t nvkms_strlen (const char *s); int nvkms_strcmp (const char *s1, const char *s2); -char* nvkms_strncpy (char *dest, +ssize_t nvkms_strscpy (char *dest, const char *src, - size_t n); + size_t count); void nvkms_usleep (NvU64 usec); NvU64 nvkms_get_usec (void); int nvkms_copyin (void *kptr, diff --git a/kernel-open/nvidia-uvm/uvm_pmm_gpu.c b/kernel-open/nvidia-uvm/uvm_pmm_gpu.c index 34e56f2272..af78b65337 100644 --- a/kernel-open/nvidia-uvm/uvm_pmm_gpu.c +++ b/kernel-open/nvidia-uvm/uvm_pmm_gpu.c @@ -2804,7 +2804,7 @@ static NV_STATUS init_chunk_split_cache_level(uvm_pmm_gpu_t *pmm, size_t level) size_t size; size_t align; if (level == 0) { - strncpy(chunk_split_cache[level].name, "uvm_gpu_chunk_t", sizeof(chunk_split_cache[level].name) - 1); + strscpy(chunk_split_cache[level].name, "uvm_gpu_chunk_t", sizeof(chunk_split_cache[level].name)); size = sizeof(uvm_gpu_chunk_t); align = __alignof__(uvm_gpu_chunk_t); } else { diff --git a/kernel-open/nvidia/export_nvswitch.h b/kernel-open/nvidia/export_nvswitch.h index c3ef36c793..d02222cb77 100644 --- a/kernel-open/nvidia/export_nvswitch.h +++ b/kernel-open/nvidia/export_nvswitch.h @@ -807,12 +807,12 @@ nvswitch_os_strlen const char *str ); -char* -nvswitch_os_strncpy +ssize_t +nvswitch_os_strscpy ( char *pDest, const char *pSrc, - NvLength length + NvLength count ); int diff --git a/kernel-open/nvidia/linux_nvswitch.c b/kernel-open/nvidia/linux_nvswitch.c index 015de1ca66..1f5ab4a7ae 100644 --- a/kernel-open/nvidia/linux_nvswitch.c +++ b/kernel-open/nvidia/linux_nvswitch.c @@ -2059,7 +2059,7 @@ nvswitch_os_read_registry_dword return -NVL_ERR_GENERIC; } - strncpy(regkey_val, regkey_val_start, regkey_val_len); + memcpy(regkey_val, regkey_val_start, regkey_val_len); regkey_val[regkey_val_len] = '\0'; if (nvswitch_os_strtouint(regkey_val, data) != 0) @@ -2406,15 +2406,15 @@ nvswitch_os_strlen return strlen(str); } -char* -nvswitch_os_strncpy +ssize_t +nvswitch_os_strscpy ( char *dest, const char *src, - NvLength length + NvLength count ) { - return strncpy(dest, src, length); + return strscpy(dest, src, count); } int diff --git a/kernel-open/nvidia/os-interface.c b/kernel-open/nvidia/os-interface.c index ebbd236ad9..7df5e59a51 100644 --- a/kernel-open/nvidia/os-interface.c +++ b/kernel-open/nvidia/os-interface.c @@ -770,8 +770,7 @@ NvU32 NV_API_CALL os_get_current_process(void) void NV_API_CALL os_get_current_process_name(char *buf, NvU32 len) { task_lock(current); - strncpy(buf, current->comm, len - 1); - buf[len - 1] = '\0'; + strscpy(buf, current->comm, len); task_unlock(current); } diff --git a/src/common/nvswitch/interface/export_nvswitch.h b/src/common/nvswitch/interface/export_nvswitch.h index bc39fa61dc..79de6651be 100644 --- a/src/common/nvswitch/interface/export_nvswitch.h +++ b/src/common/nvswitch/interface/export_nvswitch.h @@ -28,6 +28,12 @@ extern "C" { #endif +#if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) +#include /* ssize_t */ +#else +#include /* ssize_t */ +#endif + #include "nv_stdarg.h" #include "nvlink_common.h" #include "ioctl_common_nvswitch.h" @@ -803,12 +809,12 @@ nvswitch_os_strlen const char *str ); -char* -nvswitch_os_strncpy +ssize_t +nvswitch_os_strscpy ( char *pDest, const char *pSrc, - NvLength length + NvLength count ); int diff --git a/src/common/nvswitch/kernel/ls10/smbpbi_ls10.c b/src/common/nvswitch/kernel/ls10/smbpbi_ls10.c index 958f8a18f1..0f5063fb69 100644 --- a/src/common/nvswitch/kernel/ls10/smbpbi_ls10.c +++ b/src/common/nvswitch/kernel/ls10/smbpbi_ls10.c @@ -178,10 +178,9 @@ nvswitch_smbpbi_send_init_data_ls10 cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, INIT_DATA); cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_INIT_DATA; - nvswitch_os_strncpy((char *)pInitDataCmd->driverVersionString, + nvswitch_os_strscpy((char *)pInitDataCmd->driverVersionString, NV_VERSION_STRING, sizeof(pInitDataCmd->driverVersionString)); - pInitDataCmd->driverVersionString[sizeof(pInitDataCmd->driverVersionString) - 1] = 0; nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout); status = flcnQueueCmdPostBlocking(device, pFlcn, diff --git a/src/common/nvswitch/kernel/nvswitch.c b/src/common/nvswitch/kernel/nvswitch.c index 384396391c..b00a8bf41c 100644 --- a/src/common/nvswitch/kernel/nvswitch.c +++ b/src/common/nvswitch/kernel/nvswitch.c @@ -729,9 +729,7 @@ nvswitch_lib_check_api_version } nvswitch_os_memset(kernel_version, 0x0, length); - nvswitch_os_strncpy(kernel_version, NV_VERSION_STRING, VERSION_LENGTH); - - kernel_version[length - 1] = '\0'; + nvswitch_os_strscpy(kernel_version, NV_VERSION_STRING, VERSION_LENGTH); if (nvswitch_os_strncmp(user_version, kernel_version, VERSION_LENGTH)) { diff --git a/src/nvidia-modeset/kapi/src/nvkms-kapi.c b/src/nvidia-modeset/kapi/src/nvkms-kapi.c index 51178eeec1..6cd0dbe3b8 100644 --- a/src/nvidia-modeset/kapi/src/nvkms-kapi.c +++ b/src/nvidia-modeset/kapi/src/nvkms-kapi.c @@ -475,7 +475,7 @@ static NvBool KmsAllocateDevice(struct NvKmsKapiDevice *device) /* Allocate NVKMS device */ - nvkms_strncpy( + nvkms_strscpy( paramsAlloc->request.versionString, NV_VERSION_STRING, sizeof(paramsAlloc->request.versionString)); 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 a634ec2bcc..4db6acbf5b 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 @@ -31,8 +31,10 @@ #if defined(NV_KERNEL_INTERFACE_LAYER) && defined(NV_LINUX) #include /* size_t */ +#include /* ssize_t */ #else #include /* size_t */ +#include /* ssize_t */ #endif #include "nvtypes.h" /* NvU8 */ @@ -149,9 +151,9 @@ int nvkms_memcmp (const void *s1, size_t nvkms_strlen (const char *s); int nvkms_strcmp (const char *s1, const char *s2); -char* nvkms_strncpy (char *dest, +ssize_t nvkms_strscpy (char *dest, const char *src, - size_t n); + size_t count); void nvkms_usleep (NvU64 usec); NvU64 nvkms_get_usec (void); int nvkms_copyin (void *kptr, diff --git a/src/nvidia-modeset/src/dp/nvdp-device.cpp b/src/nvidia-modeset/src/dp/nvdp-device.cpp index f9015042d3..5741a224f7 100644 --- a/src/nvidia-modeset/src/dp/nvdp-device.cpp +++ b/src/nvidia-modeset/src/dp/nvdp-device.cpp @@ -124,7 +124,7 @@ void nvDPGetDpyGUID(NVDpyEvoPtr pDpyEvo) str = nvkmsDisplayPort::nvDPGetDeviceGUIDStr(pDpLibDevice->device); if (str != NULL) { - nvkms_strncpy(pDpyEvo->dp.guid.str, str, sizeof(pDpyEvo->dp.guid.str)); + nvkms_strscpy(pDpyEvo->dp.guid.str, str, sizeof(pDpyEvo->dp.guid.str)); } else { pDpyEvo->dp.guid.valid = FALSE; } diff --git a/src/nvidia-modeset/src/nvkms-dpy.c b/src/nvidia-modeset/src/nvkms-dpy.c index 7fc92fcfd7..682dff2533 100644 --- a/src/nvidia-modeset/src/nvkms-dpy.c +++ b/src/nvidia-modeset/src/nvkms-dpy.c @@ -2311,12 +2311,10 @@ static void PatchAndParseEdid( for (i = 0; i < NVT_EDID_MAX_LONG_DISPLAY_DESCRIPTOR; i++) { if (pParsedEdid->info.ldd[i].tag == NVT_EDID_DISPLAY_DESCRIPTOR_DPSN) { - nvkms_strncpy( + nvkms_strscpy( pParsedEdid->serialNumberString, (const char *)pParsedEdid->info.ldd[i].u.serial_number.str, sizeof(pParsedEdid->serialNumberString)); - pParsedEdid->serialNumberString[ - sizeof(pParsedEdid->serialNumberString) - 1] = '\0'; break; } } diff --git a/src/nvidia-modeset/src/nvkms-modepool.c b/src/nvidia-modeset/src/nvkms-modepool.c index 7b6ca75441..460e69948c 100644 --- a/src/nvidia-modeset/src/nvkms-modepool.c +++ b/src/nvidia-modeset/src/nvkms-modepool.c @@ -522,9 +522,8 @@ ValidateModeIndexEdid(NVDpyEvoPtr pDpyEvo, if (description != NULL) { nvAssert(nvkms_strlen(description) < sizeof(pReply->description)); - nvkms_strncpy(pReply->description, description, + nvkms_strscpy(pReply->description, description, sizeof(pReply->description)); - pReply->description[sizeof(pReply->description) - 1] = '\0'; } nvBuildModeName(kmsMode.timings.hVisible, kmsMode.timings.vVisible, From adfae267afa54919b2b197864a6751259ce21359 Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Wed, 1 Jul 2026 21:07:08 -0300 Subject: [PATCH 2/3] fix: handle `drm_atomic_state` rename to `drm_atomic_commit` This commit addresses the rename (see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5164f7e7ff8e) by adding a new conftest to see if it was renamed, and if so, use it. --- kernel-open/conftest.sh | 27 ++++++++++++++++++++ kernel-open/nvidia-drm/nvidia-drm-conftest.h | 13 ++++++++++ kernel-open/nvidia-drm/nvidia-drm-crtc.c | 12 +++++++-- kernel-open/nvidia-drm/nvidia-drm-sources.mk | 1 + 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 386b3242aa..5c604c6afe 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -3254,6 +3254,33 @@ compile_test() { compile_check_conftest "$CODE" "NV_PTEP_GET_PRESENT" "" "functions" ;; + drm_atomic_commit_present) + # + # Determine if the kernel has renamed struct drm_atomic_state + # to struct drm_atomic_commit. + # + # Linux kernel commit 5164f7e7ff8e ("drm: Rename struct drm_atomic_state + # to drm_atomic_commit") renames the + # struct and all associated functions. + # + echo "$CONFTEST_PREAMBLE + #include + + void conftest(void) { + struct drm_atomic_commit *state = NULL; + }" > conftest$$.c + + $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 + rm -f conftest$$.c + + if [ -f conftest$$.o ]; then + rm -f conftest$$.o + echo "#define NV_DRM_ATOMIC_COMMIT_PRESENT" | append_conftest "types" + else + echo "#undef NV_DRM_ATOMIC_COMMIT_PRESENT" | append_conftest "types" + fi + ;; + drm_plane_atomic_check_has_atomic_state_arg) # # Determine if drm_plane_helper_funcs::atomic_check takes 'state' diff --git a/kernel-open/nvidia-drm/nvidia-drm-conftest.h b/kernel-open/nvidia-drm/nvidia-drm-conftest.h index 57e70a81bf..abab9433e2 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-conftest.h +++ b/kernel-open/nvidia-drm/nvidia-drm-conftest.h @@ -217,4 +217,17 @@ vmf_insert_pfn(struct vm_area_struct *vma, unsigned long addr, #endif /* defined(NV_BSD) */ +/* + * Kernel commit 5164f7e7ff8e ("drm: Rename struct drm_atomic_state + * to drm_atomic_commit") renamed the struct and all associated functions. + */ +#if defined(NV_DRM_ATOMIC_COMMIT_PRESENT) +#define drm_atomic_state drm_atomic_commit +#define drm_atomic_state_alloc drm_atomic_commit_alloc +#define drm_atomic_state_put drm_atomic_commit_put +#define drm_atomic_state_init drm_atomic_commit_init +#define drm_atomic_state_default_clear drm_atomic_commit_default_clear +#define drm_atomic_state_default_release drm_atomic_commit_default_release +#endif + #endif /* defined(__NVIDIA_DRM_CONFTEST_H__) */ diff --git a/kernel-open/nvidia-drm/nvidia-drm-crtc.c b/kernel-open/nvidia-drm/nvidia-drm-crtc.c index 17958f8abe..4e2913843e 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-crtc.c +++ b/kernel-open/nvidia-drm/nvidia-drm-crtc.c @@ -1607,13 +1607,17 @@ static int __nv_drm_cursor_atomic_check(struct drm_plane *plane, #if defined(NV_DRM_PLANE_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) static int nv_drm_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) +#elif defined(NV_DRM_ATOMIC_COMMIT_PRESENT) +static int nv_drm_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_commit *state) #else static int nv_drm_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *plane_state) #endif { struct nv_drm_plane *nv_plane = to_nv_plane(plane); -#if defined(NV_DRM_PLANE_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) +#if defined(NV_DRM_PLANE_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) || \ + defined(NV_DRM_ATOMIC_COMMIT_PRESENT) struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); #endif @@ -2611,12 +2615,16 @@ static int color_mgmt_config_set_luts(struct nv_drm_crtc_state *nv_crtc_state, #if defined(NV_DRM_CRTC_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) static int nv_drm_crtc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state) +#elif defined(NV_DRM_ATOMIC_COMMIT_PRESENT) +static int nv_drm_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_commit *state) #else static int nv_drm_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) #endif { -#if defined(NV_DRM_CRTC_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) +#if defined(NV_DRM_CRTC_ATOMIC_CHECK_HAS_ATOMIC_STATE_ARG) || \ + defined(NV_DRM_ATOMIC_COMMIT_PRESENT) struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); #endif diff --git a/kernel-open/nvidia-drm/nvidia-drm-sources.mk b/kernel-open/nvidia-drm/nvidia-drm-sources.mk index e656f04242..ae6431611d 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-sources.mk +++ b/kernel-open/nvidia-drm/nvidia-drm-sources.mk @@ -86,6 +86,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_driver_has_gem_prime_callbacks NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_atomic_check_has_atomic_state_arg NV_CONFTEST_TYPE_COMPILE_TESTS += drm_gem_object_vmap_has_map_arg NV_CONFTEST_TYPE_COMPILE_TESTS += drm_plane_atomic_check_has_atomic_state_arg +NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_commit_present NV_CONFTEST_TYPE_COMPILE_TESTS += drm_device_has_pdev NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_state_has_no_vblank NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_config_has_allow_fb_modifiers From ab825f3cc9a527a004da9fd622c57062c4069e10 Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Sun, 12 Jul 2026 21:58:00 +0200 Subject: [PATCH 3/3] fix: use correct buffer size for `strscpy` in `nvswitch_lib_check_api_version` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes a bug introduced by the previous strncpy→strscpy conversion in nvswitch.c. The `strscpy` call was incorrectly passed `VERSION_LENGTH` (which is `strlen(NV_VERSION_STRING)` without the NUL terminator) as the destination buffer size. `strscpy` expects the full buffer size including space for the NUL terminator, so the version string was silently truncated by one character, causing the version compatibility check to always fail. Fix it by passing `length` (the caller-provided buffer size) instead. --- src/common/nvswitch/kernel/nvswitch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/nvswitch/kernel/nvswitch.c b/src/common/nvswitch/kernel/nvswitch.c index b00a8bf41c..b870ad1e6a 100644 --- a/src/common/nvswitch/kernel/nvswitch.c +++ b/src/common/nvswitch/kernel/nvswitch.c @@ -729,7 +729,7 @@ nvswitch_lib_check_api_version } nvswitch_os_memset(kernel_version, 0x0, length); - nvswitch_os_strscpy(kernel_version, NV_VERSION_STRING, VERSION_LENGTH); + nvswitch_os_strscpy(kernel_version, NV_VERSION_STRING, length); if (nvswitch_os_strncmp(user_version, kernel_version, VERSION_LENGTH)) {