From f8d552946ed2d990521f6c044b89fee8ed97907b Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:40:05 +0200 Subject: [PATCH 1/8] Make modeset and fbdev default enabled This is generally required for Wayland on NVIDIA support. NVIDIA is also planing to enable this as default in the future. Signed-off-by: Peter Jung --- kernel-open/nvidia-drm/nvidia-drm-linux.c | 4 ++-- kernel-open/nvidia-drm/nvidia-drm-os-interface.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel-open/nvidia-drm/nvidia-drm-linux.c b/kernel-open/nvidia-drm/nvidia-drm-linux.c index 8c59b7cb2e..c7f4a2395e 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-linux.c +++ b/kernel-open/nvidia-drm/nvidia-drm-linux.c @@ -31,13 +31,13 @@ MODULE_PARM_DESC( modeset, - "Enable atomic kernel modesetting (1 = enable, 0 = disable (default))"); + "Enable atomic kernel modesetting (1 = enable (default), 0 = disable)"); module_param_named(modeset, nv_drm_modeset_module_param, bool, 0400); #if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) MODULE_PARM_DESC( fbdev, - "Create a framebuffer device (1 = enable, 0 = disable (default)) (EXPERIMENTAL)"); + "Create a framebuffer device (1 = enable (default), 0 = disable) (EXPERIMENTAL)"); module_param_named(fbdev, nv_drm_fbdev_module_param, bool, 0400); #endif diff --git a/kernel-open/nvidia-drm/nvidia-drm-os-interface.c b/kernel-open/nvidia-drm/nvidia-drm-os-interface.c index 473004b57a..75fb34b63b 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-os-interface.c +++ b/kernel-open/nvidia-drm/nvidia-drm-os-interface.c @@ -41,8 +41,8 @@ #include #endif -bool nv_drm_modeset_module_param = false; -bool nv_drm_fbdev_module_param = false; +bool nv_drm_modeset_module_param = true; +bool nv_drm_fbdev_module_param = true; void *nv_drm_calloc(size_t nmemb, size_t size) { From 9fc14d807859f3f1c772850113f9a80fc410cf7c Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:40:38 +0200 Subject: [PATCH 2/8] Do not error on unkown CPU Type and add Zen5 support Currently the Zen 5 CPU is an unknown CPU and prints an error in dmesg. Fix this with adding Zen5 support as well as change the print to a warning. Signed-off-by: Peter Jung --- src/nvidia/src/kernel/platform/cpu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/nvidia/src/kernel/platform/cpu.c b/src/nvidia/src/kernel/platform/cpu.c index bb76a9c26d..6832e77c0a 100644 --- a/src/nvidia/src/kernel/platform/cpu.c +++ b/src/nvidia/src/kernel/platform/cpu.c @@ -1401,12 +1401,14 @@ static void cpuidInfoAMD(OBJSYS *pSys, PCPUIDINFO pCpuidInfo) // Zen, Zen+, Zen 2 case 0x0A0: // Zen 3, Zen 4 + case 0x0B0: + // Zen 5 pSys->cpuInfo.type = NV0000_CTRL_SYSTEM_CPU_TYPE_RYZEN; break; default: - NV_PRINTF(LEVEL_ERROR, - "Unrecognized AMD processor in cpuidInfoAMD\n"); - pSys->cpuInfo.type = NV0000_CTRL_SYSTEM_CPU_TYPE_K8; + NV_PRINTF(LEVEL_NOTICE, + "Unrecognized AMD processor 0x%x in cpuidInfoAMD. Assuming new Ryzen\n", pCpuidInfo->Family); + pSys->cpuInfo.type = NV0000_CTRL_SYSTEM_CPU_TYPE_RYZEN; break; } } From 87337d6f6c1e2e4b23211e9c68a3b7045b170c6b Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:40:58 +0200 Subject: [PATCH 3/8] Add IBT support Signed-off-by: Peter Jung --- src/nvidia-modeset/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nvidia-modeset/Makefile b/src/nvidia-modeset/Makefile index 2b96f3faba..ed934014e4 100644 --- a/src/nvidia-modeset/Makefile +++ b/src/nvidia-modeset/Makefile @@ -151,6 +151,7 @@ ifeq ($(TARGET_ARCH),x86_64) CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -fno-jump-tables) CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch=thunk-extern) CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mindirect-branch-register) + CONDITIONAL_CFLAGS += $(call TEST_CC_ARG, -mharden-sls=all) endif CFLAGS += $(CONDITIONAL_CFLAGS) From fc366111d4270b4befe81ed3fe72f87ae374ef22 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:41:22 +0200 Subject: [PATCH 4/8] Add fix for fbdev This change has been extracted out of the 550.120 driver Signed-off-by: Peter Jung --- kernel-open/conftest.sh | 23 ++++++++++++++++++- kernel-open/header-presence-tests.mk | 1 + kernel-open/nvidia-drm/nvidia-drm-drv.c | 22 +++++++++++------- kernel-open/nvidia-drm/nvidia-drm-linux.c | 2 +- .../nvidia-drm/nvidia-drm-os-interface.h | 8 ++++++- kernel-open/nvidia-drm/nvidia-drm-sources.mk | 1 + 6 files changed, 46 insertions(+), 11 deletions(-) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index 1226cea2bb..4a239e6317 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -6596,7 +6596,9 @@ compile_test() { # Determine whether drm_fbdev_generic_setup is present. # # Added by commit 9060d7f49376 ("drm/fb-helper: Finish the - # generic fbdev emulation") in v4.19. + # generic fbdev emulation") in v4.19. Removed by commit + # aae4682e5d66 ("drm/fbdev-generic: Convert to fbdev-ttm") + # in v6.11. # CODE=" #include @@ -6610,6 +6612,25 @@ compile_test() { compile_check_conftest "$CODE" "NV_DRM_FBDEV_GENERIC_SETUP_PRESENT" "" "functions" ;; + drm_fbdev_ttm_setup) + # + # Determine whether drm_fbdev_ttm_setup is present. + # + # Added by commit aae4682e5d66 ("drm/fbdev-generic: + # Convert to fbdev-ttm") in v6.11. + # + CODE=" + #include + #if defined(NV_DRM_DRM_FBDEV_TTM_H_PRESENT) + #include + #endif + void conftest_drm_fbdev_ttm_setup(void) { + drm_fbdev_ttm_setup(); + }" + + compile_check_conftest "$CODE" "NV_DRM_FBDEV_TTM_SETUP_PRESENT" "" "functions" + ;; + drm_aperture_remove_conflicting_pci_framebuffers) # # Determine whether drm_aperture_remove_conflicting_pci_framebuffers is present. diff --git a/kernel-open/header-presence-tests.mk b/kernel-open/header-presence-tests.mk index e8d2e02b37..40204ae488 100644 --- a/kernel-open/header-presence-tests.mk +++ b/kernel-open/header-presence-tests.mk @@ -15,6 +15,7 @@ NV_HEADER_PRESENCE_TESTS = \ drm/drm_atomic_uapi.h \ drm/drm_drv.h \ drm/drm_fbdev_generic.h \ + drm/drm_fbdev_ttm.h \ drm/drm_framebuffer.h \ drm/drm_connector.h \ drm/drm_probe_helper.h \ diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c index 359ff0c470..50028c26fc 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.c +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c @@ -64,12 +64,14 @@ #include #endif -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) #include #include #endif -#if defined(NV_DRM_DRM_FBDEV_GENERIC_H_PRESENT) +#if defined(NV_DRM_DRM_FBDEV_TTM_H_PRESENT) +#include +#elif defined(NV_DRM_DRM_FBDEV_GENERIC_H_PRESENT) #include #endif @@ -476,7 +478,7 @@ static int nv_drm_load(struct drm_device *dev, unsigned long flags) return -ENODEV; } -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) /* * If fbdev is enabled, take modeset ownership now before other DRM clients * can take master (and thus NVKMS ownership). @@ -610,7 +612,7 @@ static void __nv_drm_unload(struct drm_device *dev) /* Release modeset ownership if fbdev is enabled */ -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) if (nv_dev->hasFramebufferConsole) { drm_atomic_helper_shutdown(dev); nvKms->releaseOwnership(nv_dev->pDevice); @@ -1838,7 +1840,7 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info) goto failed_drm_register; } -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) if (nv_drm_fbdev_module_param && drm_core_check_feature(dev, DRIVER_MODESET)) { @@ -1851,9 +1853,13 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info) drm_aperture_remove_conflicting_pci_framebuffers(pdev, nv_drm_driver.name); #endif } + #if defined(NV_DRM_FBDEV_TTM_AVAILABLE) + drm_fbdev_ttm_setup(dev, 32); + #elif defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) drm_fbdev_generic_setup(dev, 32); + #endif } -#endif /* defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) */ +#endif /* defined(NV_DRM_FBDEV_AVAILABLE) */ /* Add NVIDIA-DRM device into list */ @@ -1995,12 +2001,12 @@ void nv_drm_suspend_resume(NvBool suspend) if (suspend) { drm_kms_helper_poll_disable(dev); -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); #endif drm_mode_config_reset(dev); } else { -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); #endif drm_kms_helper_poll_enable(dev); diff --git a/kernel-open/nvidia-drm/nvidia-drm-linux.c b/kernel-open/nvidia-drm/nvidia-drm-linux.c index c7f4a2395e..83d40983df 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-linux.c +++ b/kernel-open/nvidia-drm/nvidia-drm-linux.c @@ -34,7 +34,7 @@ MODULE_PARM_DESC( "Enable atomic kernel modesetting (1 = enable (default), 0 = disable)"); module_param_named(modeset, nv_drm_modeset_module_param, bool, 0400); -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) MODULE_PARM_DESC( fbdev, "Create a framebuffer device (1 = enable (default), 0 = disable) (EXPERIMENTAL)"); diff --git a/kernel-open/nvidia-drm/nvidia-drm-os-interface.h b/kernel-open/nvidia-drm/nvidia-drm-os-interface.h index 6f8cfea917..a6b0f947e0 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-os-interface.h +++ b/kernel-open/nvidia-drm/nvidia-drm-os-interface.h @@ -59,14 +59,20 @@ typedef struct nv_timer nv_drm_timer; #endif #if defined(NV_DRM_FBDEV_GENERIC_SETUP_PRESENT) && defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_PRESENT) +#define NV_DRM_FBDEV_AVAILABLE #define NV_DRM_FBDEV_GENERIC_AVAILABLE #endif +#if defined(NV_DRM_FBDEV_TTM_SETUP_PRESENT) && defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_PRESENT) +#define NV_DRM_FBDEV_AVAILABLE +#define NV_DRM_FBDEV_TTM_AVAILABLE +#endif + struct page; /* Set to true when the atomic modeset feature is enabled. */ extern bool nv_drm_modeset_module_param; -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) +#if defined(NV_DRM_FBDEV_AVAILABLE) /* Set to true when the nvidia-drm driver should install a framebuffer device */ extern bool nv_drm_fbdev_module_param; #endif diff --git a/kernel-open/nvidia-drm/nvidia-drm-sources.mk b/kernel-open/nvidia-drm/nvidia-drm-sources.mk index 7ef0c5b8fd..247096b701 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-sources.mk +++ b/kernel-open/nvidia-drm/nvidia-drm-sources.mk @@ -67,6 +67,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += fence_set_error NV_CONFTEST_FUNCTION_COMPILE_TESTS += sync_file_get_fence NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_aperture_remove_conflicting_pci_framebuffers NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_fbdev_generic_setup +NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_fbdev_ttm_setup NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_attach_hdr_output_metadata_property NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_helper_crtc_enable_color_mgmt NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_crtc_enable_color_mgmt From 9120164b559f2b3d491e7cea850b7c2d8c453f08 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:42:42 +0200 Subject: [PATCH 5/8] Fix for 6.12.0-rc1 drm_mode_config_funcs.output_poll_changed removal Tentative fix for NVIDIA 560.35.03 driver for Linux 6.12-rc1. Based on https://gist.github.com/joanbm/a6d3f7f873a60dec0aa4a734c0f1d64e Signed-off-by: Peter Jung --- kernel-open/nvidia-drm/nvidia-drm-drv.c | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c index 50028c26fc..d28b33a982 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.c +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c @@ -100,6 +100,11 @@ #include #endif +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +#include +#endif + static int nv_drm_revoke_modeset_permission(struct drm_device *dev, struct drm_file *filep, NvU32 dpyId); @@ -206,7 +211,13 @@ static const struct drm_mode_config_funcs nv_mode_config_funcs = { .atomic_check = nv_drm_atomic_check, .atomic_commit = nv_drm_atomic_commit, +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0) + // Rel. commit. "drm: Remove struct + // drm_mode_config_funcs.output_poll_changed" (Thomas Zimmermann, 12 Aug + // 2024) Replace this callback with a DRM client's hotplug callback. + // This is required for e.g. /sys/class/drm/card*/modes to work. .output_poll_changed = nv_drm_output_poll_changed, +#endif }; static void nv_drm_event_callback(const struct NvKmsKapiEvent *event) @@ -1569,6 +1580,10 @@ static const struct file_operations nv_drm_fops = { .read = drm_read, .llseek = noop_llseek, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + // Rel. commit. "fs: move FMODE_UNSIGNED_OFFSET to fop_flags" (Christian Brauner, 9 Aug 2024) + .fop_flags = FOP_UNSIGNED_OFFSET, +#endif }; static const struct drm_ioctl_desc nv_drm_ioctls[] = { @@ -1777,6 +1792,20 @@ void nv_drm_update_drm_driver_features(void) } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +static int hotplug_helper_client_hotplug(struct drm_client_dev *client) +{ + nv_drm_output_poll_changed(client->dev); + return 0; +} + +static const struct drm_client_funcs nv_hotplug_helper_client_funcs = { + .owner = THIS_MODULE, + .hotplug = hotplug_helper_client_hotplug, +}; +#endif + + /* * Helper function for allocate/register DRM device for given NVIDIA GPU ID. @@ -1866,8 +1895,27 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info) nv_dev->next = dev_list; dev_list = nv_dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + /* Register a DRM client for receiving hotplug events */ + struct drm_client_dev *client = kzalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL || drm_client_init(dev, client, + "nv-hotplug-helper", &nv_hotplug_helper_client_funcs)) { + printk(KERN_WARNING "Failed to initialize the nv-hotplug-helper DRM client."); + goto failed_drm_client_init; + } + + drm_client_register(client); + pr_info("Registered the nv-hotplug-helper DRM client."); +#endif + return; /* Success */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +failed_drm_client_init: + + kfree(client); +#endif + failed_drm_register: nv_drm_dev_free(dev); From ef617771d39f421794b9cc240094b66086d52580 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:43:34 +0200 Subject: [PATCH 6/8] Replace PageSwapCache for >= 6.12 kernel Signed-off-by: Eric Naim Signed-off-by: Peter Jung --- kernel-open/nvidia-uvm/uvm_hmm.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel-open/nvidia-uvm/uvm_hmm.c b/kernel-open/nvidia-uvm/uvm_hmm.c index 93e6442405..88043bab50 100644 --- a/kernel-open/nvidia-uvm/uvm_hmm.c +++ b/kernel-open/nvidia-uvm/uvm_hmm.c @@ -23,6 +23,8 @@ #include "uvm_hmm.h" +#include + // Support for HMM ( https://docs.kernel.org/mm/hmm.html ): #ifdef NVCPU_X86_64 @@ -2694,12 +2696,19 @@ static NV_STATUS dmamap_src_sysmem_pages(uvm_va_block_t *va_block, continue; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0) if (PageSwapCache(src_page)) { // TODO: Bug 4050579: Remove this when swap cached pages can be // migrated. status = NV_WARN_MISMATCHED_TARGET; break; } +#else + if (folio_test_swapcache(page_folio(src_page))) { + status = NV_WARN_MISMATCHED_TARGET; + break; + } +#endif // If the page is already allocated, it is most likely a mirrored // page. Check to be sure it matches what we have recorded. The From 20a5b21aea8a2d2b62759a2db8fb4bf625f0c69c Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:44:33 +0200 Subject: [PATCH 7/8] silence-event-assert-until-570 Currently, when playing CS2 it reports a massive spam in the dmesg log. This will be fixed in the 570 driver. Silence it for now. Signed-off-by: Peter Jung --- src/nvidia/src/kernel/rmapi/event_notification.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvidia/src/kernel/rmapi/event_notification.c b/src/nvidia/src/kernel/rmapi/event_notification.c index cf78eadd4d..d6937cac02 100644 --- a/src/nvidia/src/kernel/rmapi/event_notification.c +++ b/src/nvidia/src/kernel/rmapi/event_notification.c @@ -286,11 +286,11 @@ static NV_STATUS _gpuEngineEventNotificationListNotify portSyncSpinlockAcquire(pEventNotificationList->pSpinlock); { // We don't expect this to be called multiple times in parallel - NV_ASSERT_OR_ELSE(pEventNotificationList->pendingEventNotifyCount == 0, + if (pEventNotificationList->pendingEventNotifyCount != 0) { portSyncSpinlockRelease(pEventNotificationList->pSpinlock); return NV_ERR_INVALID_STATE; - }); + } EngineEventNotificationListIter it = listIterAll(&pEventNotificationList->eventNotificationList); From b4816d9b2feae9250d97b8a5d59f762f6e8d2eaa Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 18 Oct 2024 22:44:59 +0200 Subject: [PATCH 8/8] nvkms: Sanitize & trim ELD product name strings Signed-off-by: Peter Jung --- src/nvidia-modeset/src/nvkms-hdmi.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/nvidia-modeset/src/nvkms-hdmi.c b/src/nvidia-modeset/src/nvkms-hdmi.c index 1dbc6c482b..963c47f6f2 100644 --- a/src/nvidia-modeset/src/nvkms-hdmi.c +++ b/src/nvidia-modeset/src/nvkms-hdmi.c @@ -1030,27 +1030,13 @@ static NvBool FillELDBuffer(const NVDpyEvoRec *pDpyEvo, if (status == NVT_STATUS_SUCCESS) { /* - * NvTiming_GetProductName() returns a nul-terminated string, but the - * string in the EDID is terminated with 0x0A and padded with 0x20. - * Put back these special characters. + * NvTiming_GetProductName returns a nul-terminated string. Figure out + * how long it is and copy the bytes up to, but not including, the nul + * terminator. */ - NvBool pastTerminator = FALSE; - NvU32 i; - - for (i = 0; i < NVT_EDID_LDD_PAYLOAD_SIZE; i++) { - if (pastTerminator) { - name[i] = 0x20; - } - if (name[i] == '\0') { - name[i] = 0x0A; - pastTerminator = TRUE; - } - } - - monitorNameLen = NVT_EDID_LDD_PAYLOAD_SIZE; - pEld->buffer[4] |= NVT_EDID_LDD_PAYLOAD_SIZE; - nvkms_memcpy(&pEld->buffer[20], name, - NVT_EDID_LDD_PAYLOAD_SIZE); + monitorNameLen = nvkms_strlen((char *)name); + pEld->buffer[4] |= monitorNameLen; + nvkms_memcpy(&pEld->buffer[20], name, monitorNameLen); } /* offset 20 + MNL ~ 20 + MNL + (3 * SAD_Count) - 1 : CEA_SADs */