diff --git a/commitFile.txt b/commitFile.txt index 11785a8..e352ab2 100644 --- a/commitFile.txt +++ b/commitFile.txt @@ -21,7 +21,7 @@ d580300f41118dacc5569fffa9f47e78c5883141 - kernel-open/common/inc/nv-modeset-int 5bc7a748c7d3dfa6559ca4f9fe6199e17098ec8f - kernel-open/common/inc/nv-lock.h b249abc0a7d0c9889008e98cb2f8515a9d310b85 - kernel-open/common/inc/nvgputypes.h e4a4f57abb8769d204468b2f5000c81f5ea7c92f - kernel-open/common/inc/nv-procfs.h -8b19b93e958aca626899f035334a4c96f8776eb6 - kernel-open/common/inc/nv.h +04565a9da52f9e5275a89ecbe6e103b25008414a - kernel-open/common/inc/nv.h ede1f77acb43e28391bceac058e00a7a8d799b0d - kernel-open/common/inc/nvmisc.h ae374d3e438f8d3b60df8c4602618c58564b73f9 - kernel-open/common/inc/rm-gpu-ops.h 3f7b20e27e6576ee1f2f0557d269697a0b8af7ec - kernel-open/common/inc/nv-firmware-registry.h @@ -35,7 +35,7 @@ a3d1e51c0f4217f1dc4cb0c48aa0eafd054d4e5e - kernel-open/common/inc/nv-procfs-util 81592e5c17bebad04cd11d73672c859baa070329 - kernel-open/common/inc/nv-chardev-numbers.h 61cf8f3fd32142dc402f6802b5d4c9af6c875c35 - kernel-open/common/inc/nv-firmware.h d5253e7e4abd3ad8d72375260aa80037adcd8973 - kernel-open/common/inc/nv_dpy_id.h -61a9589e4a8ec122e5a6c2258658d493ee747897 - kernel-open/common/inc/nv-platform.h +f4f6ef99266975becbd50ee25030e61dedbeba6d - kernel-open/common/inc/nv-platform.h b986bc6591ba17a74ad81ec4c93347564c6d5165 - kernel-open/common/inc/nvkms-format.h 4f487eccd762f3ca645a685d5c333ff569e7987c - kernel-open/common/inc/nv-kthread-q-os.h 4015c4557ea0790a2bdf5695832c89e31d75aee9 - kernel-open/common/inc/nvlimits.h @@ -92,7 +92,7 @@ ef8fd76c55625aeaa71c9b789c4cf519ef6116b2 - kernel-open/nvidia/libspdm_hkdf.c f16e6a33b5004566333fb8b99504a0fb95d51226 - kernel-open/nvidia/nv-gpio.c 8ed2c3b93eeaa52342d944e794180fd5d386688a - kernel-open/nvidia/libspdm_rsa_ext.c 2e5d18118835c19c5ca7edee9bceeae613b9d7f9 - kernel-open/nvidia/nv-procfs.c -23009178fd74b867836e8c23055544a900aeea7a - kernel-open/nvidia/nv.c +17502601d63ff2f353e2a65a016ee9310fa65f23 - kernel-open/nvidia/nv.c 65fe797fb5d4af2db67544ddb79d49ab1b7ca859 - kernel-open/nvidia/nv-dsi-parse-panel-props.c e3efae4ed920545062a2d06064df8be1a2a42135 - kernel-open/nvidia/nv-caps-imex.h 8c64e75aaaa9ac6f17aae7ed62db23eb2e5b9953 - kernel-open/nvidia/nv_uvm_interface.c @@ -108,7 +108,7 @@ c762aa186dc72ed0b9183492f9bd187c301d33d3 - kernel-open/nvidia/nv-kthread-q.c 70bece14e12b9ffc92816ee8159a4ce596579d78 - kernel-open/nvidia/os-pci.c a677049bb56fa5ebe22fe43b0c4a12acd58a6677 - kernel-open/nvidia/nv-p2p.c e4d12f027cb5f74124da71bbbc23bcb33651834a - kernel-open/nvidia/nv-pci-table.c -5aec112c8a7eca49686f36efefe6d6e3e9548e32 - kernel-open/nvidia/nv-pci.c +1bc3343eecfa3194929d2e1d5620a652f109434d - kernel-open/nvidia/nv-pci.c 6dfc57ac42bed97c6ff81d82e493f05b369e0b84 - kernel-open/nvidia/nvspdm_cryptlib_extensions.h bba706cfbc04b3a880b5e661066f92e765fad663 - kernel-open/nvidia/nv-caps-imex.c ed3c83f62e4ccc4b53d886eedd4b47518a361393 - kernel-open/nvidia/nv-dmabuf.c @@ -123,7 +123,7 @@ c50865d3070a0c3476ce24ff1ab4cc4e3f9ea4be - kernel-open/nvidia/detect-self-hosted 3b27e4eaa97bd6fa71f1a075b50af69b1ec16454 - kernel-open/nvidia/libspdm_ec.c dd9e367cba9e0672c998ec6d570be38084a365ab - kernel-open/nvidia/libspdm_rand.c d8b8077adb7fd70eb9528d421bdef98c4378b57a - kernel-open/nvidia/nv-msi.c -23ae2957e6d58ab1b41398b6fdeecb7c475300b9 - kernel-open/nvidia/nv-platform.c +c528e4f865384d2a2eb1cc4b90344273caf89f15 - kernel-open/nvidia/nv-platform.c dd819a875c584bc469082fcf519779ea00b1d952 - kernel-open/nvidia/libspdm_aead_aes_gcm.c 74958745f83b14c04aaa60248bf5c86ceef6b5cb - kernel-open/nvidia/nv-acpi.c 4d19a1756af848d25fd2fd8cc691dcbcf0afb776 - kernel-open/nvidia/os-registry.c @@ -849,7 +849,7 @@ c5f16fdf43ca3d2845d120c219d1da11257072b0 - src/nvidia/nv-kernel.ld dcf4427b83cce7737f2b784d410291bf7a9612dc - src/nvidia/arch/nvalloc/unix/include/nv-reg.h 4750735d6f3b334499c81d499a06a654a052713d - src/nvidia/arch/nvalloc/unix/include/nv-caps.h 3c61881e9730a8a1686e422358cdfff59616b670 - src/nvidia/arch/nvalloc/unix/include/nv_escape.h -7fc52a43b242a8a921c2707589fa07c8c44da11c - src/nvidia/arch/nvalloc/unix/include/nv.h +8e5c39b8efa859fb811094af26ba26c6858c50ee - src/nvidia/arch/nvalloc/unix/include/nv.h 81592e5c17bebad04cd11d73672c859baa070329 - src/nvidia/arch/nvalloc/unix/include/nv-chardev-numbers.h e69045379ed58dc0110d16d17eb39a6f600f0d1d - src/nvidia/arch/nvalloc/unix/include/nv-ioctl-lockless-diag.h d1b1a1bc1fa30c1a966e95447f7831a06340d2d0 - src/nvidia/arch/nvalloc/unix/include/nv-priv.h @@ -864,14 +864,14 @@ b3ecb82f142a50bdc37eafaeb86d67f10fbcf73f - src/nvidia/arch/nvalloc/unix/include/ af45762b6eeae912cc2602acf7dc31d30775ade7 - src/nvidia/arch/nvalloc/unix/include/nv-kernel-rmapi-ops.h 107d1ecb8a128044260915ea259b1e64de3defea - src/nvidia/arch/nvalloc/unix/include/nv-ioctl-numbers.h 3a26838c4edd3525daa68ac6fc7b06842dc6fc07 - src/nvidia/arch/nvalloc/unix/include/nv-gpu-info.h -98a5a3bd7b94e69f4e7d2c3a1769583c17ef5b57 - src/nvidia/arch/nvalloc/unix/src/os.c +1af9eaf7470cfe611c6c2757ab592a42d0df58ad - src/nvidia/arch/nvalloc/unix/src/os.c a659a503a6fcffdcacd2b76ae6b1f156b4b9216c - src/nvidia/arch/nvalloc/unix/src/osmemdesc.c b5ae9b8d551a3e5489605c13686fb6cce4579598 - src/nvidia/arch/nvalloc/unix/src/power-management-tegra.c a17aae37486b325442e447489b64add3694ab8b0 - src/nvidia/arch/nvalloc/unix/src/osunix.c b5b409625fde1b640e4e93276e35248f0fccfa4c - src/nvidia/arch/nvalloc/unix/src/gcc_helper.c 07f9c0995f1fbbba9eb819321996b57c1d2b86cd - src/nvidia/arch/nvalloc/unix/src/exports-stubs.c -d8815125dbf79831b8fe55367bba60e7115243cc - src/nvidia/arch/nvalloc/unix/src/osinit.c -b1e9f004152562aebd967505fcc1f52b774aef15 - src/nvidia/arch/nvalloc/unix/src/osapi.c +00e1da5b996760d70515c7d400462ebbc9dc4cba - src/nvidia/arch/nvalloc/unix/src/osinit.c +dc5a592d8de2a6c173c6dd3cf6d079ced05a1ecd - src/nvidia/arch/nvalloc/unix/src/osapi.c a7383deea9dcab093323d8dde1ede73f85f93343 - src/nvidia/arch/nvalloc/unix/src/rmobjexportimport.c b1a6d0a1ca4307b8e8d9cf136c94ef7c9efbae4c - src/nvidia/arch/nvalloc/unix/src/registry.c 915ee6dbffff92a86d68ac38549b25aa1e146872 - src/nvidia/arch/nvalloc/unix/src/os-hypervisor-stubs.c @@ -892,7 +892,7 @@ b9903d23010ea9d63117c27d5fe0cfba09849fa4 - src/nvidia/generated/g_context_dma_nv c5cad88aa7de5a04a3b6f9836f355347448d6a7b - src/nvidia/generated/g_rmconfig_util.h db1d1e047d00780efbe4c1c1ae6e4fecd3ab49e8 - src/nvidia/generated/g_os_desc_mem_nvoc.h 1ec59322d0874153252a387dcb50bf6d7328d56e - src/nvidia/generated/g_system_mem_nvoc.c -21e57b9c63e847eeb5a29c218db2c5c37db83298 - src/nvidia/generated/g_gpu_nvoc.c +b141335ea49d7ef1b4ca267ed6db2803add4021d - src/nvidia/generated/g_gpu_nvoc.c 4613f3d42dbc899b278fca71c3aaae79159d7dbe - src/nvidia/generated/g_gpu_user_shared_data_nvoc.c b55573cb02ff8129aa4f5aa050ac53d1f4fcfdb2 - src/nvidia/generated/g_rs_resource_nvoc.h 16c8d551a3a908ec194d39c88c5603cea436c9b7 - src/nvidia/generated/g_binary_api_nvoc.c @@ -910,7 +910,7 @@ abc769851bd523ee08cf829bf3864cf5475066ec - src/nvidia/generated/g_subdevice_nvoc 255c404719b18c2a3aec2a47948c0fbcf4affd4b - src/nvidia/generated/rmconfig.h c7fda8cbe109ad2736694ce9ec0e2ab93d0e3f2c - src/nvidia/generated/g_mem_list_nvoc.h f9bdef39159a8475626a0edcbc3a53505a0ff80a - src/nvidia/generated/g_os_hal.h -dc7bbba203ee5ff91b6f14eb3abfad8c15854e1d - src/nvidia/generated/g_mem_desc_nvoc.h +e3a0a139faf20b6d7c1242efa1bcd081596bbce3 - src/nvidia/generated/g_mem_desc_nvoc.h 1702c9d021149c0f5c73ebeda7bea29e246af31d - src/nvidia/generated/g_nv_name_released.h 2e0c45e4186d44774286a71daf797c980c2ddf7a - src/nvidia/generated/g_objtmr_nvoc.c 9b78bc02a8fe0ec297167bb4bdb7f8255b94198b - src/nvidia/generated/g_disp_capabilities_nvoc.h @@ -936,7 +936,7 @@ d09bde39b1f12490ea0a696d6915d521c9f13953 - src/nvidia/generated/g_rpc-message-he f8b984c6bc09554753cfe6692dde2eb3171abc57 - src/nvidia/generated/g_disp_channel_nvoc.h 4931b316fc042705a5f094c8c23b0038f980b404 - src/nvidia/generated/g_generic_engine_nvoc.h 2a28557874bd51f567ef42c75fd4e3b09d8ad44d - src/nvidia/generated/g_gpu_arch_nvoc.c -a17058fe665949f1e3861fe092e29b229cefbe62 - src/nvidia/generated/g_mem_mgr_nvoc.h +1f2a1faecdfa5bf3b23f3549b55a7b674ce06b63 - src/nvidia/generated/g_mem_mgr_nvoc.h 7aa02b964507a8269d35dc56170955025b98bd1a - src/nvidia/generated/g_gpu_arch_nvoc.h 0b9296f7797325b80ff0900f19a3763b564eb26b - src/nvidia/generated/g_context_dma_nvoc.h 4210ff36876e84e0adf1e9d4afb6654c7e6e5060 - src/nvidia/generated/g_resserv_nvoc.h @@ -1136,7 +1136,7 @@ bffae4da6a1f9b7dc7c879587fd674b49b46dac1 - src/nvidia/inc/kernel/core/core.h 37f267155ddfc3db38f110dbb0397f0463d055ff - src/nvidia/inc/kernel/core/strict.h b00302aec7e4f4e3b89a2f699f8b1f18fc17b1ba - src/nvidia/inc/kernel/core/hal_mgr.h 2d741243a6ae800052ddd478cc6aa7ad0b18f112 - src/nvidia/inc/kernel/core/prelude.h -ebc7c06d9e94218af4cf6b0c03e83650e391e5bc - src/nvidia/inc/kernel/core/thread_state.h +7e8435a73f777a70e0824aa3c5eca8799943fe78 - src/nvidia/inc/kernel/core/thread_state.h b5859c7862fb3eeb266f7213845885789801194a - src/nvidia/inc/kernel/core/system.h 07f45cd5fab5814e21b9e84425564b43776118fd - src/nvidia/inc/kernel/gpu/gpu_resource_desc.h 7010ff346c27b6453c091f5577672b8b1821808d - src/nvidia/inc/kernel/gpu/gpu_access.h @@ -1288,7 +1288,7 @@ a16bffcad38862470b4424fa9a1b0d4013304600 - src/nvidia/src/kernel/core/hal_mgr.c 4d3f32dbc4cbe3d4d1301079eaf21005f74dea90 - src/nvidia/src/kernel/core/locks_common.c e7195ca43692b6fbf6a3533437650c596cee88db - src/nvidia/src/kernel/core/locks_minimal.c ee0bf4f81d33e9a7b6bbb2be27bb3973c8cb5b18 - src/nvidia/src/kernel/core/system.c -905a0f08067503374c757ed34d1ea87379ab4a71 - src/nvidia/src/kernel/core/thread_state.c +3edd97e49797ae6e3152a8b800c9444ee8d42330 - src/nvidia/src/kernel/core/thread_state.c afa03f17393b28b9fc791bf09c4d35833447808d - src/nvidia/src/kernel/core/hal/hal.c d3922085d63a7edf02b582fe0b6e3acba6124c25 - src/nvidia/src/kernel/core/hal/hals_all.c 8eac3ea49f9a53063f7106211e5236372d87bdaf - src/nvidia/src/kernel/core/hal/info_block.c diff --git a/kernel-open/common/inc/nv-platform.h b/kernel-open/common/inc/nv-platform.h index c6da33e..4bb286a 100644 --- a/kernel-open/common/inc/nv-platform.h +++ b/kernel-open/common/inc/nv-platform.h @@ -45,4 +45,16 @@ void nv_soc_free_irqs(nv_state_t *nv); #define NV_SUPPORTS_PLATFORM_DISPLAY_DEVICE (NV_SUPPORTS_PLATFORM_DEVICE && NV_SUPPORTS_DCE_CLIENT_IPC) +#if defined(CONFIG_OF) +NV_STATUS nv_platform_get_screen_info_dt( + NvU64 *pPhysicalAddress, + NvU32 *pFbWidth, + NvU32 *pFbHeight, + NvU32 *pFbDepth, + NvU32 *pFbPitch, + NvU64 *pFbSize +); + +#endif // CONFIG_OF + #endif diff --git a/kernel-open/common/inc/nv.h b/kernel-open/common/inc/nv.h index 433bba3..f38cc48 100644 --- a/kernel-open/common/inc/nv.h +++ b/kernel-open/common/inc/nv.h @@ -664,23 +664,24 @@ typedef NV_STATUS (*nvPmaEvictRangeCallback)(void *, NvU64, NvU64, nvgpuGpuMemor * flags */ -#define NV_FLAG_OPEN 0x0001 -#define NV_FLAG_EXCLUDE 0x0002 -#define NV_FLAG_CONTROL 0x0004 -#define NV_FLAG_PCI_P2P_UNSUPPORTED_CHIPSET 0x0008 -#define NV_FLAG_SOC_DISPLAY 0x0010 -#define NV_FLAG_USES_MSI 0x0020 -#define NV_FLAG_USES_MSIX 0x0040 -#define NV_FLAG_PASSTHRU 0x0080 -#define NV_FLAG_SUSPENDED 0x0100 +#define NV_FLAG_OPEN 0x0001 +#define NV_FLAG_EXCLUDE 0x0002 +#define NV_FLAG_CONTROL 0x0004 +#define NV_FLAG_PCI_P2P_UNSUPPORTED_CHIPSET 0x0008 +#define NV_FLAG_SOC_DISPLAY 0x0010 +#define NV_FLAG_USES_MSI 0x0020 +#define NV_FLAG_USES_MSIX 0x0040 +#define NV_FLAG_PASSTHRU 0x0080 +#define NV_FLAG_SUSPENDED 0x0100 +#define NV_FLAG_HAS_CONSOLE_IN_SYSMEM_CARVEOUT 0x0200 /* To be set when an FLR needs to be triggered after device shut down. */ -#define NV_FLAG_TRIGGER_FLR 0x0400 -#define NV_FLAG_PERSISTENT_SW_STATE 0x0800 -#define NV_FLAG_IN_RECOVERY 0x1000 -#define NV_FLAG_PCI_REMOVE_IN_PROGRESS 0x2000 -#define NV_FLAG_UNBIND_LOCK 0x4000 +#define NV_FLAG_TRIGGER_FLR 0x0400 +#define NV_FLAG_PERSISTENT_SW_STATE 0x0800 +#define NV_FLAG_IN_RECOVERY 0x1000 +#define NV_FLAG_PCI_REMOVE_IN_PROGRESS 0x2000 +#define NV_FLAG_UNBIND_LOCK 0x4000 /* To be set when GPU is not present on the bus, to help device teardown */ -#define NV_FLAG_IN_SURPRISE_REMOVAL 0x8000 +#define NV_FLAG_IN_SURPRISE_REMOVAL 0x8000 typedef enum { @@ -737,6 +738,9 @@ typedef enum #define NV_IS_DEVICE_IN_SURPRISE_REMOVAL(nv) \ (((nv)->flags & NV_FLAG_IN_SURPRISE_REMOVAL) != 0) +#define NV_HAS_CONSOLE_IN_SYSMEM_CARVEOUT(nv) \ + (((nv)->flags & NV_FLAG_HAS_CONSOLE_IN_SYSMEM_CARVEOUT) != 0) + /* * For console setup by EFI GOP, the base address is BAR1. * For console setup by VBIOS, the base address is BAR2 + 16MB. diff --git a/kernel-open/nvidia/nv-pci.c b/kernel-open/nvidia/nv-pci.c index c9f6548..d7c2212 100644 --- a/kernel-open/nvidia/nv-pci.c +++ b/kernel-open/nvidia/nv-pci.c @@ -2162,8 +2162,7 @@ failed: return -1; } -static void -nv_pci_remove(struct pci_dev *pci_dev) +static void nv_pci_remove_helper(struct pci_dev *pci_dev, bool block_if_gpu_in_use) { nv_linux_state_t *nvl = NULL; nv_state_t *nv; @@ -2171,9 +2170,6 @@ nv_pci_remove(struct pci_dev *pci_dev) NvU8 regs_bar_index = nv_bar_index_to_os_bar_index(pci_dev, NV_GPU_BAR_INDEX_REGS); - nv_printf(NV_DBG_SETUP, "NVRM: removing GPU %04x:%02x:%02x.%x\n", - NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev), - NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn)); #ifdef NV_PCI_SRIOV_SUPPORT if (pci_dev->is_virtfn) @@ -2186,15 +2182,9 @@ nv_pci_remove(struct pci_dev *pci_dev) } #endif /* NV_PCI_SRIOV_SUPPORT */ - if (nv_kmem_cache_alloc_stack(&sp) != 0) - { - return; - } - nvl = pci_get_drvdata(pci_dev); if (!nvl || (nvl->pci_dev != pci_dev)) { - nv_kmem_cache_free_stack(sp); return; } @@ -2229,6 +2219,21 @@ nv_pci_remove(struct pci_dev *pci_dev) LOCK_NV_LINUX_DEVICES(); down(&nvl->ldata_lock); + + if (!block_if_gpu_in_use && (NV_ATOMIC_READ(nvl->usage_count) != 0)) + { + up(&nvl->ldata_lock); + UNLOCK_NV_LINUX_DEVICES(); + return; + } + + if (nv_kmem_cache_alloc_stack(&sp) != 0) + { + up(&nvl->ldata_lock); + UNLOCK_NV_LINUX_DEVICES(); + return; + } + nv->flags |= NV_FLAG_PCI_REMOVE_IN_PROGRESS; rm_notify_gpu_removal(sp, nv); @@ -2251,7 +2256,6 @@ nv_pci_remove(struct pci_dev *pci_dev) */ while (NV_ATOMIC_READ(nvl->usage_count) != 0) { - /* * While waiting, release the locks so that other threads can make * forward progress. @@ -2270,7 +2274,7 @@ nv_pci_remove(struct pci_dev *pci_dev) nv_printf(NV_DBG_ERRORS, "NVRM: Failed removal of device %04x:%02x:%02x.%x!\n", NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev), - NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn)); + NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn)); WARN_ON(1); goto done; } @@ -2361,30 +2365,44 @@ done: nv_kmem_cache_free_stack(sp); } +static void +nv_pci_remove(struct pci_dev *pci_dev) +{ + + nv_printf(NV_DBG_SETUP, "NVRM: removing GPU %04x:%02x:%02x.%x\n", + NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev), + NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn)); + + nv_pci_remove_helper(pci_dev, true); +} + static void nv_pci_shutdown(struct pci_dev *pci_dev) { nv_linux_state_t *nvl = pci_get_drvdata(pci_dev); - - if (nvl != NULL) + + if (!nvl || (nvl->pci_dev != pci_dev)) { - nv_state_t *nv = NV_STATE_PTR(nvl); + return; + } - if (nvl->is_forced_shutdown) - { - nvl->is_forced_shutdown = NV_FALSE; - return; - } - - nvidia_modeset_remove(nv->gpu_id); - - nvl->nv_state.is_shutdown = NV_TRUE; + if (nvl->is_forced_shutdown) + { + nvl->is_forced_shutdown = NV_FALSE; + return; } #if defined(CONFIG_PM_DEVFREQ) nv_pci_tegra_unregister_devfreq(pci_dev); #endif + nv_pci_remove_helper(pci_dev, false); + + if (pci_get_drvdata(pci_dev) != NULL) + { + nvl->nv_state.is_shutdown = NV_TRUE; + } + /* pci_clear_master is not defined for !CONFIG_PCI */ #ifdef CONFIG_PCI pci_clear_master(pci_dev); diff --git a/kernel-open/nvidia/nv-platform.c b/kernel-open/nvidia/nv-platform.c index 4d8088b..7117431 100644 --- a/kernel-open/nvidia/nv-platform.c +++ b/kernel-open/nvidia/nv-platform.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "nv-platform.h" #include "nv-linux.h" @@ -1711,3 +1712,175 @@ NvBool nv_get_hdcp_enabled(nv_state_t *nv) return NV_FALSE; } + +#if defined(CONFIG_OF) + +// Global framebuffer cache structure +typedef struct { + NvBool dt_parsed; + NvBool dt_success; + NvU64 physical_address; + NvU32 fb_width; + NvU32 fb_height; + NvU32 fb_depth; + NvU32 fb_pitch; + NvU64 fb_size; +} screen_info_cache_t; + +// Global framebuffer cache instance +static screen_info_cache_t g_screen_info_cache = { + .dt_parsed = NV_FALSE, + .dt_success = NV_FALSE, + .physical_address = 0, + .fb_width = 0, + .fb_height = 0, + .fb_depth = 0, + .fb_pitch = 0, + .fb_size = 0 +}; + +NV_STATUS nv_platform_get_screen_info_dt( + NvU64 *pPhysicalAddress, + NvU32 *pFbWidth, + NvU32 *pFbHeight, + NvU32 *pFbDepth, + NvU32 *pFbPitch, + NvU64 *pFbSize +) +{ + // + // Try to get the framebuffer information from device tree simple-framebuffer node. + // This is particularly useful for Tegra platforms where the bootloader + // sets up a simple framebuffer via device tree. + // + + struct device_node *fb_node; + struct device_node *mem_node; + struct resource res; + u32 width, height, stride; + const char *format; + int ret; + + if (g_screen_info_cache.dt_parsed) + { + if (g_screen_info_cache.dt_success) + { + *pPhysicalAddress = g_screen_info_cache.physical_address; + *pFbWidth = g_screen_info_cache.fb_width; + *pFbHeight = g_screen_info_cache.fb_height; + *pFbDepth = g_screen_info_cache.fb_depth; + *pFbPitch = g_screen_info_cache.fb_pitch; + *pFbSize = g_screen_info_cache.fb_size; + return NV_OK; + } + else + { + return NV_ERR_NOT_SUPPORTED; + } + } + + g_screen_info_cache.dt_parsed = NV_TRUE; + + // Look for simple-framebuffer node in chosen + fb_node = of_find_node_by_path("/chosen/framebuffer"); + if (fb_node == NULL) + { + // Alternative path for some platforms + for_each_compatible_node(fb_node, NULL, "simple-framebuffer") + { + nv_printf(NV_DBG_INFO, "NVRM: Found simple-framebuffer compatible node: %s\n", + fb_node->full_name ? fb_node->full_name : "unknown"); + if (of_property_read_bool(fb_node, "status") && + !strcmp(of_get_property(fb_node, "status", NULL), "disabled")) + { + nv_printf(NV_DBG_INFO, "NVRM: Skipping disabled framebuffer node\n"); + of_node_put(fb_node); + continue; + } + break; + } + } + else + { + nv_printf(NV_DBG_INFO, "NVRM: Found framebuffer node in /chosen/framebuffer\n"); + } + + if (fb_node != NULL) + { + nv_printf(NV_DBG_INFO, "NVRM: Processing framebuffer node: %s\n", + fb_node->full_name ? fb_node->full_name : "unknown"); + // Get memory region + mem_node = of_parse_phandle(fb_node, "memory-region", 0); + if (mem_node != NULL) + { + nv_printf(NV_DBG_INFO, "NVRM: Found memory-region: %s\n", + mem_node->full_name ? mem_node->full_name : "unknown"); + ret = of_address_to_resource(mem_node, 0, &res); + of_node_put(mem_node); + if (ret == 0) + { + nv_printf(NV_DBG_INFO, "NVRM: Memory region: start=0x%llx, size=0x%llx\n", + (NvU64)res.start, (NvU64)resource_size(&res)); + // Get display parameters + if (!of_property_read_u32(fb_node, "width", &width) && + !of_property_read_u32(fb_node, "height", &height) && + !of_property_read_u32(fb_node, "stride", &stride) && + !of_property_read_string(fb_node, "format", &format)) + { + // Calculate depth from format + u32 depth = 32; // default + if (!strcmp(format, "r5g6b5") || !strcmp(format, "r5g5b5a1") || + !strcmp(format, "x1r5g5b5") || !strcmp(format, "a1r5g5b5")) + { + depth = 16; + } + else if (!strcmp(format, "r8g8b8")) + { + depth = 24; + } + nv_printf(NV_DBG_INFO, "NVRM: Found simple-framebuffer in DT: %dx%d@%d, addr=0x%llx, size=0x%llx, stride=%d, format=%s\n", + width, height, depth, (NvU64)res.start, (NvU64)resource_size(&res), stride, format); + + g_screen_info_cache.dt_success = NV_TRUE; + + g_screen_info_cache.physical_address = res.start; + g_screen_info_cache.fb_width = width; + g_screen_info_cache.fb_height = height; + g_screen_info_cache.fb_depth = depth; + g_screen_info_cache.fb_pitch = stride; + g_screen_info_cache.fb_size = resource_size(&res); + + *pPhysicalAddress = g_screen_info_cache.physical_address; + *pFbWidth = g_screen_info_cache.fb_width; + *pFbHeight = g_screen_info_cache.fb_height; + *pFbDepth = g_screen_info_cache.fb_depth; + *pFbPitch = g_screen_info_cache.fb_pitch; + *pFbSize = g_screen_info_cache.fb_size; + + of_node_put(fb_node); + return NV_OK; + } + else + { + nv_printf(NV_DBG_ERRORS, "NVRM: Failed to read display parameters from DT\n"); + } + } + else + { + nv_printf(NV_DBG_ERRORS, "NVRM: Failed to convert memory region to resource: %d\n", ret); + } + } + else + { + nv_printf(NV_DBG_ERRORS, "NVRM: No memory-region property found\n"); + } + of_node_put(fb_node); + } + else + { + nv_printf(NV_DBG_ERRORS, "NVRM: No simple-framebuffer node found - fb_node is NULL\n"); + } + + return NV_ERR_NOT_SUPPORTED; +} +#endif // CONFIG_OF diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c index 523fbe1..cdb1a6c 100644 --- a/kernel-open/nvidia/nv.c +++ b/kernel-open/nvidia/nv.c @@ -6103,6 +6103,21 @@ void NV_API_CALL nv_get_screen_info( *pPhysicalAddress = 0; *pFbWidth = *pFbHeight = *pFbDepth = *pFbPitch = *pFbSize = 0; +#if defined(CONFIG_OF) + // + // Try to get the framebuffer information from device tree simple-framebuffer node. + // This is particularly useful for Tegra platforms where the bootloader + // sets up a simple framebuffer via device tree. + // + if (pci_dev == NULL) + { + if (nv_platform_get_screen_info_dt(pPhysicalAddress, pFbWidth, pFbHeight, pFbDepth, pFbPitch, pFbSize) == NV_OK) + { + return; + } + } +#endif // CONFIG_OF + #if defined(CONFIG_FB) && defined(NV_NUM_REGISTERED_FB_PRESENT) if (num_registered_fb > 0) { @@ -6111,8 +6126,13 @@ void NV_API_CALL nv_get_screen_info( if (!registered_fb[i]) continue; - /* Make sure base address is mapped to GPU BAR */ - if (NV_IS_CONSOLE_MAPPED(nv, registered_fb[i]->fix.smem_start)) + /* + * Ensure that either this is a zero-FB SOC GPU with a console in + * the system carveout, or it’s a dGPU device with console mapped + * onto its BAR. + */ + if (NV_HAS_CONSOLE_IN_SYSMEM_CARVEOUT(nv) || + NV_IS_CONSOLE_MAPPED(nv, registered_fb[i]->fix.smem_start)) { *pPhysicalAddress = registered_fb[i]->fix.smem_start; *pFbWidth = registered_fb[i]->var.xres; @@ -6160,9 +6180,13 @@ void NV_API_CALL nv_get_screen_info( physAddr |= (NvU64)screen_info.ext_lfb_base << 32; } #endif - - /* Make sure base address is mapped to GPU BAR */ - if (NV_IS_CONSOLE_MAPPED(nv, physAddr)) + /* + * Ensure that either this is a zero-FB SOC GPU with a console in the + * system carveout, or it’s a dGPU device with console mapped onto its + * BAR. + */ + if (NV_HAS_CONSOLE_IN_SYSMEM_CARVEOUT(nv) || + NV_IS_CONSOLE_MAPPED(nv, physAddr)) { *pPhysicalAddress = physAddr; *pFbWidth = screen_info.lfb_width; @@ -6179,7 +6203,7 @@ void NV_API_CALL nv_get_screen_info( * If screen info can't be fetched with previous methods, then try * to get the base address and size from the memory resource tree. */ - if (pci_dev != NULL) + if ((pci_dev != NULL) && !NV_HAS_CONSOLE_IN_SYSMEM_CARVEOUT(nv)) { BUILD_BUG_ON(NV_GPU_BAR_INDEX_IMEM != NV_GPU_BAR_INDEX_FB + 1); for (i = NV_GPU_BAR_INDEX_FB; i <= NV_GPU_BAR_INDEX_IMEM; i++) diff --git a/push_info.txt b/push_info.txt index e7e2fae..7ccac1f 100644 --- a/push_info.txt +++ b/push_info.txt @@ -1 +1 @@ -rel-38_eng_2025-10-06 +rel-38_test_nv-tegra-migration diff --git a/src/nvidia/arch/nvalloc/unix/include/nv.h b/src/nvidia/arch/nvalloc/unix/include/nv.h index 654d033..1b5b6f4 100644 --- a/src/nvidia/arch/nvalloc/unix/include/nv.h +++ b/src/nvidia/arch/nvalloc/unix/include/nv.h @@ -664,23 +664,24 @@ typedef NV_STATUS (*nvPmaEvictRangeCallback)(void *, NvU64, NvU64, nvgpuGpuMemor * flags */ -#define NV_FLAG_OPEN 0x0001 -#define NV_FLAG_EXCLUDE 0x0002 -#define NV_FLAG_CONTROL 0x0004 -#define NV_FLAG_PCI_P2P_UNSUPPORTED_CHIPSET 0x0008 -#define NV_FLAG_SOC_DISPLAY 0x0010 -#define NV_FLAG_USES_MSI 0x0020 -#define NV_FLAG_USES_MSIX 0x0040 -#define NV_FLAG_PASSTHRU 0x0080 -#define NV_FLAG_SUSPENDED 0x0100 +#define NV_FLAG_OPEN 0x0001 +#define NV_FLAG_EXCLUDE 0x0002 +#define NV_FLAG_CONTROL 0x0004 +#define NV_FLAG_PCI_P2P_UNSUPPORTED_CHIPSET 0x0008 +#define NV_FLAG_SOC_DISPLAY 0x0010 +#define NV_FLAG_USES_MSI 0x0020 +#define NV_FLAG_USES_MSIX 0x0040 +#define NV_FLAG_PASSTHRU 0x0080 +#define NV_FLAG_SUSPENDED 0x0100 +#define NV_FLAG_HAS_CONSOLE_IN_SYSMEM_CARVEOUT 0x0200 /* To be set when an FLR needs to be triggered after device shut down. */ -#define NV_FLAG_TRIGGER_FLR 0x0400 -#define NV_FLAG_PERSISTENT_SW_STATE 0x0800 -#define NV_FLAG_IN_RECOVERY 0x1000 -#define NV_FLAG_PCI_REMOVE_IN_PROGRESS 0x2000 -#define NV_FLAG_UNBIND_LOCK 0x4000 +#define NV_FLAG_TRIGGER_FLR 0x0400 +#define NV_FLAG_PERSISTENT_SW_STATE 0x0800 +#define NV_FLAG_IN_RECOVERY 0x1000 +#define NV_FLAG_PCI_REMOVE_IN_PROGRESS 0x2000 +#define NV_FLAG_UNBIND_LOCK 0x4000 /* To be set when GPU is not present on the bus, to help device teardown */ -#define NV_FLAG_IN_SURPRISE_REMOVAL 0x8000 +#define NV_FLAG_IN_SURPRISE_REMOVAL 0x8000 typedef enum { @@ -737,6 +738,9 @@ typedef enum #define NV_IS_DEVICE_IN_SURPRISE_REMOVAL(nv) \ (((nv)->flags & NV_FLAG_IN_SURPRISE_REMOVAL) != 0) +#define NV_HAS_CONSOLE_IN_SYSMEM_CARVEOUT(nv) \ + (((nv)->flags & NV_FLAG_HAS_CONSOLE_IN_SYSMEM_CARVEOUT) != 0) + /* * For console setup by EFI GOP, the base address is BAR1. * For console setup by VBIOS, the base address is BAR2 + 16MB. diff --git a/src/nvidia/arch/nvalloc/unix/src/os.c b/src/nvidia/arch/nvalloc/unix/src/os.c index 4884cfe..d830982 100644 --- a/src/nvidia/arch/nvalloc/unix/src/os.c +++ b/src/nvidia/arch/nvalloc/unix/src/os.c @@ -818,11 +818,11 @@ NV_STATUS osAllocPagesInternal( // For carveout, the memory is already reserved so we don't have // to allocate memory. // - if (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT) || + if (memdescIsCarveoutMemory(pMemDesc) || memdescGetFlag(pMemDesc, MEMDESC_FLAGS_GUEST_ALLOCATED)) { - // We only support scanout carveout with contiguous memory. - if (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT) && + // We only support carveout with contiguous memory. + if (memdescIsCarveoutMemory(pMemDesc) && !memdescGetContiguity(pMemDesc, AT_CPU)) { status = NV_ERR_NOT_SUPPORTED; @@ -848,7 +848,7 @@ NV_STATUS osAllocPagesInternal( cpuCacheAttrib, memdescGetGuestId(pMemDesc), memdescGetPteArray(pMemDesc, AT_CPU), - memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT), + memdescIsCarveoutMemory(pMemDesc), &pMemData); } else @@ -3047,7 +3047,7 @@ osIovaMap // address is same as the DMA address. // // - if (memdescGetFlag(pIovaMapping->pPhysMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT) || + if (memdescIsCarveoutMemory(pIovaMapping->pPhysMemDesc) || memdescGetFlag(pIovaMapping->pPhysMemDesc, MEMDESC_FLAGS_GUEST_ALLOCATED)) { return NV_OK; @@ -3202,7 +3202,7 @@ osIovaUnmap // For guest-allocated or carveout memory, we never actually remapped the // memory, so we shouldn't try to unmap it here. // - if (memdescGetFlag(pIovaMapping->pPhysMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT) || + if (memdescIsCarveoutMemory(pIovaMapping->pPhysMemDesc) || memdescGetFlag(pIovaMapping->pPhysMemDesc, MEMDESC_FLAGS_GUEST_ALLOCATED)) { return; diff --git a/src/nvidia/arch/nvalloc/unix/src/osapi.c b/src/nvidia/arch/nvalloc/unix/src/osapi.c index 465ed48..404b57d 100644 --- a/src/nvidia/arch/nvalloc/unix/src/osapi.c +++ b/src/nvidia/arch/nvalloc/unix/src/osapi.c @@ -1910,7 +1910,7 @@ static NV_STATUS RmGetAllocPrivate( bPeerIoMem = memdescGetFlag(pMemDesc, MEMDESC_FLAGS_PEER_IO_MEM); if (!(pMemDesc->Allocated || bPeerIoMem || - (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT)) || + memdescIsCarveoutMemory(pMemDesc) || (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOW_EXT_SYSMEM_USER_CPU_MAPPING)))) { NV_PRINTF(LEVEL_ERROR, "Mmap is not allowed\n"); diff --git a/src/nvidia/arch/nvalloc/unix/src/osinit.c b/src/nvidia/arch/nvalloc/unix/src/osinit.c index 65faa8c..ac4fe8f 100644 --- a/src/nvidia/arch/nvalloc/unix/src/osinit.c +++ b/src/nvidia/arch/nvalloc/unix/src/osinit.c @@ -636,6 +636,11 @@ osInitNvMapping( { nv->flags |= NV_FLAG_TRIGGER_FLR; } + + if (pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_SOC_SDM)) + { + nv->flags |= NV_FLAG_HAS_CONSOLE_IN_SYSMEM_CARVEOUT; + } } static NV_STATUS diff --git a/src/nvidia/generated/g_gpu_nvoc.c b/src/nvidia/generated/g_gpu_nvoc.c index 38c6a35..e0bad0e 100644 --- a/src/nvidia/generated/g_gpu_nvoc.c +++ b/src/nvidia/generated/g_gpu_nvoc.c @@ -332,7 +332,12 @@ void __nvoc_init_dataField_OBJGPU(OBJGPU *pThis) { pThis->setProperty(pThis, PDB_PROP_GPU_RUSD_DISABLE_CLK_PUBLIC_DOMAIN_INFO, NV_FALSE); } pThis->setProperty(pThis, PDB_PROP_GPU_RECOVERY_REBOOT_REQUIRED, NV_FALSE); - pThis->setProperty(pThis, PDB_PROP_GPU_ALLOC_ISO_SYS_MEM_FROM_CARVEOUT, NV_FALSE); + + // NVOC Property Hal field -- PDB_PROP_GPU_ALLOC_ISO_SYS_MEM_FROM_CARVEOUT + // default + { + pThis->setProperty(pThis, PDB_PROP_GPU_ALLOC_ISO_SYS_MEM_FROM_CARVEOUT, NV_FALSE); + } pThis->deviceInstance = 32; diff --git a/src/nvidia/generated/g_mem_desc_nvoc.h b/src/nvidia/generated/g_mem_desc_nvoc.h index e8c037d..d2b16f9 100644 --- a/src/nvidia/generated/g_mem_desc_nvoc.h +++ b/src/nvidia/generated/g_mem_desc_nvoc.h @@ -421,6 +421,7 @@ typedef struct ADDRESS_TRANSLATION_ *ADDRESS_TRANSLATION; // #define MEMDESC_FLAGS_ALLOC_AS_LOCALIZED NVBIT64(50) +// Indicate whether memdesc tracks the memory allocated from the scanout-carevout heap. #define MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT NVBIT64(51) // Force-compress pte kind when mapping with virtual pte kind @@ -436,6 +437,9 @@ typedef struct ADDRESS_TRANSLATION_ *ADDRESS_TRANSLATION; // Indicate if memdesc is allocated for non IO-coherent memory. #define MEMDESC_FLAGS_NON_IO_COHERENT NVBIT64(54) +// Indicate if memdesc is tracking the uefi carveout memory. +#define MEMDESC_FLAGS_ALLOC_FROM_UEFI_CARVEOUT NVBIT64(55) + // // RM internal allocations owner tags // Total 200 tags are introduced, out of which some are already @@ -1211,6 +1215,13 @@ NV_STATUS memdescFillMemdescForPhysAttr(MEMORY_DESCRIPTOR *pMemDesc, ADDRESS_TRA NvBool memdescIsEgm(MEMORY_DESCRIPTOR *pMemDesc); NvU64 memdescGetAdjustedPageSize(MEMORY_DESCRIPTOR *pMemDesc); +static inline NvBool +memdescIsCarveoutMemory(MEMORY_DESCRIPTOR *pMemDesc) +{ + return !!(pMemDesc->_flags & (MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT | + MEMDESC_FLAGS_ALLOC_FROM_UEFI_CARVEOUT)); +} + /*! * @brief Get PTE kind * diff --git a/src/nvidia/generated/g_mem_mgr_nvoc.h b/src/nvidia/generated/g_mem_mgr_nvoc.h index 00b8c07..653f2ef 100644 --- a/src/nvidia/generated/g_mem_mgr_nvoc.h +++ b/src/nvidia/generated/g_mem_mgr_nvoc.h @@ -2324,6 +2324,8 @@ static inline NV_STATUS memmgrCalculateHeapOffsetWithGSP(OBJGPU *pGpu, struct Me #define memmgrCalculateHeapOffsetWithGSP_HAL(pGpu, pMemoryManager, offset) memmgrCalculateHeapOffsetWithGSP(pGpu, pMemoryManager, offset) +NV_STATUS memmgrGetCarveoutRegionInfo_KERNEL(POBJGPU pGpu, struct MemoryManager *pMemoryManager, NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS *pParams); + static inline NV_STATUS memmgrGetCarveoutRegionInfo_56cd7a(POBJGPU pGpu, struct MemoryManager *pMemoryManager, NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS *pParams) { return NV_OK; } @@ -2335,7 +2337,7 @@ static inline NV_STATUS memmgrGetCarveoutRegionInfo(POBJGPU pGpu, struct MemoryM return NV_ERR_NOT_SUPPORTED; } #else //__nvoc_mem_mgr_h_disabled -#define memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, pParams) memmgrGetCarveoutRegionInfo_56cd7a(pGpu, pMemoryManager, pParams) +#define memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, pParams) memmgrGetCarveoutRegionInfo_KERNEL(pGpu, pMemoryManager, pParams) #endif //__nvoc_mem_mgr_h_disabled #define memmgrGetCarveoutRegionInfo_HAL(pGpu, pMemoryManager, pParams) memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, pParams) diff --git a/src/nvidia/inc/kernel/core/thread_state.h b/src/nvidia/inc/kernel/core/thread_state.h index a619a6c..1f721c8 100644 --- a/src/nvidia/inc/kernel/core/thread_state.h +++ b/src/nvidia/inc/kernel/core/thread_state.h @@ -76,6 +76,7 @@ struct THREAD_STATE_NODE */ NvU32 threadSeqId; NvBool bValid; + NvBool bUsingHeap; THREAD_TIMEOUT_STATE timeout; NvU32 cpuNum; NvU32 flags; @@ -208,6 +209,7 @@ void threadStateOnlyProcessWorkISRAndDeferredIntHandler(THREAD_STATE_NODE void threadStateOnlyFreeISRAndDeferredIntHandler(THREAD_STATE_NODE *, OBJGPU*, NvU32); void threadStateFreeISRAndDeferredIntHandler(THREAD_STATE_NODE *, OBJGPU*, NvU32); void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags); +THREAD_STATE_NODE* threadStateAlloc(NvU32 flags); void threadStateFree(THREAD_STATE_NODE *pThreadNode, NvU32 flags); NV_STATUS threadStateGetCurrent(THREAD_STATE_NODE **ppThreadNode, OBJGPU *pGpu); diff --git a/src/nvidia/src/kernel/core/thread_state.c b/src/nvidia/src/kernel/core/thread_state.c index ffa8d8a..4d83bf5 100644 --- a/src/nvidia/src/kernel/core/thread_state.c +++ b/src/nvidia/src/kernel/core/thread_state.c @@ -505,27 +505,21 @@ static void _threadStateLogInitCaller(THREAD_STATE_NODE *pThreadNode, NvU64 func } /** - * @brief Initialize a threadState for regular threads (non-interrupt context) + * @brief Common initialization logic for both stack and heap thread state nodes * - * @param[in/out] pThreadNode - * @param[in] flags + * @param[in/out] pThreadNode The node to initialize + * @param[in] flags Thread state flags + * @param[in] bUsingHeap NV_TRUE if heap-allocated, NV_FALSE if stack-allocated * + * @return NV_OK on success, error code on failure */ -void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags) +static NV_STATUS _threadStateInitCommon(THREAD_STATE_NODE *pThreadNode, NvU32 flags, NvBool bUsingHeap) { NV_STATUS rmStatus; NvU64 funcAddr; - // Isrs should be using threadStateIsrInit(). - NV_ASSERT((flags & (THREAD_STATE_FLAGS_IS_ISR_LOCKLESS | - THREAD_STATE_FLAGS_IS_ISR | - THREAD_STATE_FLAGS_DEFERRED_INT_HANDLER_RUNNING)) == 0); - - // Check to see if ThreadState is enabled - if (!(threadStateDatabase.setupFlags & THREAD_STATE_SETUP_FLAGS_ENABLED)) - return; - portMemSet(pThreadNode, 0, sizeof(*pThreadNode)); + pThreadNode->bUsingHeap = bUsingHeap; pThreadNode->threadSeqId = portAtomicIncrementU32(&threadStateDatabase.threadSeqCntr); pThreadNode->cpuNum = osGetCurrentProcessorNumber(); pThreadNode->flags = flags; @@ -543,9 +537,10 @@ void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags) rmStatus = osGetCurrentThread(&pThreadNode->threadId); if (rmStatus != NV_OK) - return; + return rmStatus; - NV_ASSERT_OR_RETURN_VOID(pThreadNode->cpuNum < threadStateDatabase.maxCPUs); + NV_ASSERT_OR_RETURN(pThreadNode->cpuNum < threadStateDatabase.maxCPUs, + NV_ERR_INVALID_STATE); funcAddr = (NvU64) (NV_RETURN_ADDRESS()); @@ -555,27 +550,23 @@ void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags) // Reset the threadId as insertion failed. bValid is already NV_FALSE pThreadNode->threadId = 0; portSyncSpinlockRelease(threadStateDatabase.spinlock); - return; - } - else - { - pThreadNode->bValid = NV_TRUE; - rmStatus = NV_OK; + return NV_ERR_GENERIC; } + pThreadNode->bValid = NV_TRUE; _threadStateLogInitCaller(pThreadNode, funcAddr); portSyncSpinlockRelease(threadStateDatabase.spinlock); _threadStatePrintInfo(pThreadNode); - NV_ASSERT(rmStatus == NV_OK); threadPriorityStateAlloc(); if (TLS_MIRROR_THREADSTATE) { THREAD_STATE_NODE **pTls = (THREAD_STATE_NODE **)tlsEntryAcquire(TLS_ENTRY_ID_THREADSTATE); - NV_ASSERT_OR_RETURN_VOID(pTls != NULL); + NV_ASSERT_OR_RETURN(pTls != NULL, NV_ERR_INVALID_STATE); + if (*pTls != NULL) { NV_PRINTF(LEVEL_WARNING, @@ -584,6 +575,66 @@ void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags) } *pTls = pThreadNode; } + return NV_OK; +} + +/** + * @brief Initialize a threadState for regular threads (non-interrupt context) + * Use the new UAF-safe API for new code, threadStateAlloc(). + * @param[in/out] pThreadNode + * @param[in] flags + * + */ +void threadStateInit(THREAD_STATE_NODE *pThreadNode, NvU32 flags) +{ + // Isrs should be using threadStateIsrInit(). + NV_ASSERT_OR_RETURN_VOID((flags & (THREAD_STATE_FLAGS_IS_ISR_LOCKLESS | + THREAD_STATE_FLAGS_IS_ISR | + THREAD_STATE_FLAGS_DEFERRED_INT_HANDLER_RUNNING)) == 0); + + // Check to see if ThreadState is enabled + if (!(threadStateDatabase.setupFlags & THREAD_STATE_SETUP_FLAGS_ENABLED)) + return; + + // Use common initialization logic (stack-allocated) + // Note: Legacy void API ignores errors for backward compatibility + _threadStateInitCommon(pThreadNode, flags, NV_FALSE); +} + +/** + * @brief Allocate a heap-based threadState + * @param[in] flags Thread state flags + * + * @return Heap-allocated THREAD_STATE_NODE* on success, NULL on failure + */ +THREAD_STATE_NODE* threadStateAlloc(NvU32 flags) +{ + THREAD_STATE_NODE *pHeapNode; + NV_STATUS rmStatus; + + // Isrs should be using threadStateIsrInit(). + NV_ASSERT_OR_RETURN((flags & (THREAD_STATE_FLAGS_IS_ISR_LOCKLESS | + THREAD_STATE_FLAGS_IS_ISR | + THREAD_STATE_FLAGS_DEFERRED_INT_HANDLER_RUNNING)) == 0, NULL); + + // Check to see if ThreadState is enabled + if (!(threadStateDatabase.setupFlags & THREAD_STATE_SETUP_FLAGS_ENABLED)) + return NULL; + + // Allocate heap node directly + pHeapNode = portMemAllocNonPaged(sizeof(THREAD_STATE_NODE)); + if (pHeapNode == NULL) + return NULL; + + rmStatus = _threadStateInitCommon(pHeapNode, flags, NV_TRUE); + if (rmStatus != NV_OK) + goto cleanup_heap; + + return pHeapNode; + +cleanup_heap: + portMemFree(pHeapNode); + return NULL; } /** @@ -874,6 +925,12 @@ void threadStateFree(THREAD_STATE_NODE *pThreadNode, NvU32 flags) r); } } + + // Free heap memory if this node was heap-allocated + if (pThreadNode->bUsingHeap) + { + portMemFree(pThreadNode); + } } /**