From ef65a1309711a38041ece7ac3467d30a6e256d85 Mon Sep 17 00:00:00 2001 From: Bernhard Stoeckner Date: Tue, 13 Jan 2026 18:04:57 +0100 Subject: [PATCH] 535.288.01 --- README.md | 8 ++--- kernel-open/Kbuild | 2 +- kernel-open/common/inc/nv-linux.h | 13 +++---- kernel-open/common/inc/nv-lock.h | 12 ------- kernel-open/nvidia/nv-mmap.c | 6 ++-- kernel-open/nvidia/nv-pci.c | 10 +++--- kernel-open/nvidia/nv-procfs.c | 2 +- kernel-open/nvidia/nv-rsync.c | 4 +-- kernel-open/nvidia/nv.c | 36 +++++++++---------- src/common/inc/nvBldVer.h | 20 +++++------ src/common/inc/nvUnixVersion.h | 2 +- .../arch/kepler/kern_gsync_p2060.c | 5 ++- .../src/kernel/gpu/gr/kernel_graphics.c | 1 + src/nvidia/src/kernel/os/os_init.c | 6 ++-- version.mk | 2 +- 15 files changed, 60 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 2df7e707f..e00fd1ca5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NVIDIA Linux Open GPU Kernel Module Source This is the source release of the NVIDIA Linux open GPU kernel modules, -version 535.274.02. +version 535.288.01. ## How to Build @@ -17,7 +17,7 @@ as root: Note that the kernel modules built here must be used with GSP firmware and user-space NVIDIA GPU driver components from a corresponding -535.274.02 driver release. This can be achieved by installing +535.288.01 driver release. This can be achieved by installing the NVIDIA GPU driver from the .run file using the `--no-kernel-modules` option. E.g., @@ -180,7 +180,7 @@ software applications. ## Compatible GPUs The open-gpu-kernel-modules can be used on any Turing or later GPU -(see the table below). However, in the 535.274.02 release, +(see the table below). However, in the 535.288.01 release, GeForce and Workstation support is still considered alpha-quality. To enable use of the open kernel modules on GeForce and Workstation GPUs, @@ -188,7 +188,7 @@ set the "NVreg_OpenRmEnableUnsupportedGpus" nvidia.ko kernel module parameter to 1. For more details, see the NVIDIA GPU driver end user README here: -https://us.download.nvidia.com/XFree86/Linux-x86_64/535.274.02/README/kernel_open.html +https://us.download.nvidia.com/XFree86/Linux-x86_64/535.288.01/README/kernel_open.html In the below table, if three IDs are listed, the first is the PCI Device ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index 70ef87192..213091ca2 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -79,7 +79,7 @@ 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=\"535.274.02\" +ccflags-y += -DNV_VERSION_STRING=\"535.288.01\" ifneq ($(SYSSRCHOST1X),) ccflags-y += -I$(SYSSRCHOST1X) diff --git a/kernel-open/common/inc/nv-linux.h b/kernel-open/common/inc/nv-linux.h index e9d06c592..6a632b347 100644 --- a/kernel-open/common/inc/nv-linux.h +++ b/kernel-open/common/inc/nv-linux.h @@ -870,9 +870,9 @@ static inline dma_addr_t nv_phys_to_dma(struct device *dev, NvU64 pa) #define NV_PRINT_AT(nv_debug_level,at) \ { \ nv_printf(nv_debug_level, \ - "NVRM: VM: %s:%d: 0x%p, %d page(s), count = %d, flags = 0x%08x, " \ + "NVRM: VM: %s:%d: 0x%p, %d page(s), count = %lld, flags = 0x%08x, " \ "page_table = 0x%p\n", __FUNCTION__, __LINE__, at, \ - at->num_pages, NV_ATOMIC_READ(at->usage_count), \ + at->num_pages, (long long)atomic64_read(&at->usage_count), \ at->flags, at->page_table); \ } @@ -1196,7 +1196,7 @@ typedef struct nvidia_pte_s { typedef struct nv_alloc_s { struct nv_alloc_s *next; struct device *dev; - atomic_t usage_count; + atomic64_t usage_count; struct { NvBool contig : 1; NvBool guest : 1; @@ -1493,7 +1493,8 @@ typedef struct typedef struct nv_linux_state_s { nv_state_t nv_state; - atomic_t usage_count; + atomic64_t usage_count; + NvU32 suspend_count; struct device *dev; @@ -1832,9 +1833,9 @@ static inline NvBool nv_alloc_release(nv_linux_file_private_t *nvlfp, nv_alloc_t { NV_PRINT_AT(NV_DBG_MEMINFO, at); - if (NV_ATOMIC_DEC_AND_TEST(at->usage_count)) + if (atomic64_dec_and_test(&at->usage_count)) { - NV_ATOMIC_INC(at->usage_count); + atomic64_inc(&at->usage_count); at->next = nvlfp->free_list; nvlfp->free_list = at; diff --git a/kernel-open/common/inc/nv-lock.h b/kernel-open/common/inc/nv-lock.h index 030422948..936b35b2c 100644 --- a/kernel-open/common/inc/nv-lock.h +++ b/kernel-open/common/inc/nv-lock.h @@ -35,17 +35,6 @@ #include /* signal_pending for kernels >= 4.11 */ #endif -#if defined(CONFIG_PREEMPT_RT) || defined(CONFIG_PREEMPT_RT_FULL) -typedef raw_spinlock_t nv_spinlock_t; -#define NV_SPIN_LOCK_INIT(lock) raw_spin_lock_init(lock) -#define NV_SPIN_LOCK_IRQ(lock) raw_spin_lock_irq(lock) -#define NV_SPIN_UNLOCK_IRQ(lock) raw_spin_unlock_irq(lock) -#define NV_SPIN_LOCK_IRQSAVE(lock,flags) raw_spin_lock_irqsave(lock,flags) -#define NV_SPIN_UNLOCK_IRQRESTORE(lock,flags) raw_spin_unlock_irqrestore(lock,flags) -#define NV_SPIN_LOCK(lock) raw_spin_lock(lock) -#define NV_SPIN_UNLOCK(lock) raw_spin_unlock(lock) -#define NV_SPIN_UNLOCK_WAIT(lock) raw_spin_unlock_wait(lock) -#else typedef spinlock_t nv_spinlock_t; #define NV_SPIN_LOCK_INIT(lock) spin_lock_init(lock) #define NV_SPIN_LOCK_IRQ(lock) spin_lock_irq(lock) @@ -55,7 +44,6 @@ typedef spinlock_t nv_spinlock_t; #define NV_SPIN_LOCK(lock) spin_lock(lock) #define NV_SPIN_UNLOCK(lock) spin_unlock(lock) #define NV_SPIN_UNLOCK_WAIT(lock) spin_unlock_wait(lock) -#endif #define NV_INIT_MUTEX(mutex) sema_init(mutex, 1) diff --git a/kernel-open/nvidia/nv-mmap.c b/kernel-open/nvidia/nv-mmap.c index d4cd68bb0..f463b1c20 100644 --- a/kernel-open/nvidia/nv-mmap.c +++ b/kernel-open/nvidia/nv-mmap.c @@ -72,7 +72,7 @@ nvidia_vma_open(struct vm_area_struct *vma) if (at != NULL) { - NV_ATOMIC_INC(at->usage_count); + atomic64_inc(&at->usage_count); NV_PRINT_AT(NV_DBG_MEMINFO, at); } @@ -404,7 +404,7 @@ static int nvidia_mmap_sysmem( int ret = 0; unsigned long start = 0; - NV_ATOMIC_INC(at->usage_count); + atomic64_inc(&at->usage_count); start = vma->vm_start; for (j = page_index; j < (page_index + pages); j++) @@ -436,7 +436,7 @@ static int nvidia_mmap_sysmem( if (ret) { - NV_ATOMIC_DEC(at->usage_count); + atomic64_dec(&at->usage_count); return -EAGAIN; } start += PAGE_SIZE; diff --git a/kernel-open/nvidia/nv-pci.c b/kernel-open/nvidia/nv-pci.c index 9502c3840..4989efd19 100644 --- a/kernel-open/nvidia/nv-pci.c +++ b/kernel-open/nvidia/nv-pci.c @@ -798,7 +798,7 @@ nv_pci_remove(struct pci_dev *pci_dev) * For eGPU, fall off the bus along with clients active is a valid scenario. * Hence skipping the sanity check for eGPU. */ - if ((NV_ATOMIC_READ(nvl->usage_count) != 0) && !(nv->is_external_gpu)) + if ((atomic64_read(&nvl->usage_count) != 0) && !(nv->is_external_gpu)) { nv_printf(NV_DBG_ERRORS, "NVRM: Attempting to remove device %04x:%02x:%02x.%x with non-zero usage count!\n", @@ -809,7 +809,7 @@ nv_pci_remove(struct pci_dev *pci_dev) * We can't return from this function without corrupting state, so we wait for * the usage count to go to zero. */ - while (NV_ATOMIC_READ(nvl->usage_count) != 0) + while (atomic64_read(&nvl->usage_count) != 0) { /* @@ -865,7 +865,7 @@ nv_pci_remove(struct pci_dev *pci_dev) #endif /* Update the frontend data structures */ - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) { nvidia_frontend_remove_device((void *)&nv_fops, nvl); } @@ -890,7 +890,7 @@ nv_pci_remove(struct pci_dev *pci_dev) nv_unregister_ibmnpu_devices(nv); nv_destroy_ibmnpu_info(nv); - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) { nv_lock_destroy_locks(sp, nv); } @@ -906,7 +906,7 @@ nv_pci_remove(struct pci_dev *pci_dev) num_nv_devices--; - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) { NV_PCI_DISABLE_DEVICE(pci_dev); NV_KFREE(nvl, sizeof(nv_linux_state_t)); diff --git a/kernel-open/nvidia/nv-procfs.c b/kernel-open/nvidia/nv-procfs.c index 3fee3eddb..9fae2ff74 100644 --- a/kernel-open/nvidia/nv-procfs.c +++ b/kernel-open/nvidia/nv-procfs.c @@ -889,7 +889,7 @@ nv_procfs_close_unbind_lock( down(&nvl->ldata_lock); if ((value == 1) && !(nv->flags & NV_FLAG_UNBIND_LOCK)) { - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) rm_unbind_lock(sp, nv); if (nv->flags & NV_FLAG_UNBIND_LOCK) diff --git a/kernel-open/nvidia/nv-rsync.c b/kernel-open/nvidia/nv-rsync.c index 57860baa1..f16e70149 100644 --- a/kernel-open/nvidia/nv-rsync.c +++ b/kernel-open/nvidia/nv-rsync.c @@ -167,7 +167,7 @@ NvBool nv_get_rsync_relaxed_ordering_mode( nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv); /* shouldn't be called without opening a device */ - WARN_ON(NV_ATOMIC_READ(nvl->usage_count) == 0); + WARN_ON(atomic64_read(&nvl->usage_count) == 0); /* * g_rsync_info.relaxed_ordering_mode can be safely accessed outside of @@ -185,7 +185,7 @@ void nv_wait_for_rsync( nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv); /* shouldn't be called without opening a device */ - WARN_ON(NV_ATOMIC_READ(nvl->usage_count) == 0); + WARN_ON(atomic64_read(&nvl->usage_count) == 0); /* * g_rsync_info.relaxed_ordering_mode can be safely accessed outside of diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c index a0b0bb2ae..8721ce59d 100644 --- a/kernel-open/nvidia/nv.c +++ b/kernel-open/nvidia/nv.c @@ -311,7 +311,7 @@ nv_alloc_t *nvos_create_alloc( } memset(at->page_table, 0, pt_size); - NV_ATOMIC_SET(at->usage_count, 0); + atomic64_set(&at->usage_count, 0); for (i = 0; i < at->num_pages; i++) { @@ -341,7 +341,7 @@ int nvos_free_alloc( if (at == NULL) return -1; - if (NV_ATOMIC_READ(at->usage_count)) + if (atomic64_read(&at->usage_count)) return 1; for (i = 0; i < at->num_pages; i++) @@ -1455,13 +1455,10 @@ static int nv_open_device(nv_state_t *nv, nvidia_stack_t *sp) return -ENODEV; } - if (unlikely(NV_ATOMIC_READ(nvl->usage_count) >= NV_S32_MAX)) - return -EMFILE; - if ( ! (nv->flags & NV_FLAG_OPEN)) { /* Sanity check: !NV_FLAG_OPEN requires usage_count == 0 */ - if (NV_ATOMIC_READ(nvl->usage_count) != 0) + if (atomic64_read(&nvl->usage_count) != 0) { NV_DEV_PRINTF(NV_DBG_ERRORS, nv, "Minor device %u is referenced without being open!\n", @@ -1481,7 +1478,8 @@ static int nv_open_device(nv_state_t *nv, nvidia_stack_t *sp) return -EBUSY; } - NV_ATOMIC_INC(nvl->usage_count); + atomic64_inc(&nvl->usage_count); + return 0; } @@ -1780,7 +1778,7 @@ static void nv_close_device(nv_state_t *nv, nvidia_stack_t *sp) { nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv); - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) { nv_printf(NV_DBG_ERRORS, "NVRM: Attempting to close unopened minor device %u!\n", @@ -1789,7 +1787,7 @@ static void nv_close_device(nv_state_t *nv, nvidia_stack_t *sp) return; } - if (NV_ATOMIC_DEC_AND_TEST(nvl->usage_count)) + if (atomic64_dec_and_test(&nvl->usage_count)) nv_stop_device(nv, sp); } @@ -1820,7 +1818,7 @@ nvidia_close_callback( nv_close_device(nv, sp); bRemove = (!NV_IS_DEVICE_IN_SURPRISE_REMOVAL(nv)) && - (NV_ATOMIC_READ(nvl->usage_count) == 0) && + (atomic64_read(&nvl->usage_count) == 0) && rm_get_device_remove_flag(sp, nv->gpu_id); for (i = 0; i < NV_FOPS_STACK_INDEX_COUNT; ++i) @@ -1844,7 +1842,7 @@ nvidia_close_callback( * any cleanup related to linux layer locks and nv linux state struct. * nvidia_pci_remove when scheduled will do necessary cleanup. */ - if ((NV_ATOMIC_READ(nvl->usage_count) == 0) && nv->removed) + if ((atomic64_read(&nvl->usage_count) == 0) && nv->removed) { nvidia_frontend_remove_device((void *)&nv_fops, nvl); nv_lock_destroy_locks(sp, nv); @@ -2309,7 +2307,7 @@ nvidia_ioctl( * Only the current client should have an open file * descriptor for the device, to allow safe offlining. */ - if (NV_ATOMIC_READ(nvl->usage_count) > 1) + if (atomic64_read(&nvl->usage_count) > 1) { status = -EBUSY; goto unlock; @@ -2687,12 +2685,12 @@ nvidia_ctl_open( /* save the nv away in file->private_data */ nvlfp->nvptr = nvl; - if (NV_ATOMIC_READ(nvl->usage_count) == 0) + if (atomic64_read(&nvl->usage_count) == 0) { nv->flags |= (NV_FLAG_OPEN | NV_FLAG_CONTROL); } - NV_ATOMIC_INC(nvl->usage_count); + atomic64_inc(&nvl->usage_count); up(&nvl->ldata_lock); return 0; @@ -2718,7 +2716,7 @@ nvidia_ctl_close( nv_printf(NV_DBG_INFO, "NVRM: nvidia_ctl_close\n"); down(&nvl->ldata_lock); - if (NV_ATOMIC_DEC_AND_TEST(nvl->usage_count)) + if (atomic64_dec_and_test(&nvl->usage_count)) { nv->flags &= ~NV_FLAG_OPEN; } @@ -2887,7 +2885,7 @@ nv_alias_pages( at->guest_id = guest_id; *priv_data = at; - NV_ATOMIC_INC(at->usage_count); + atomic64_inc(&at->usage_count); NV_PRINT_AT(NV_DBG_MEMINFO, at); @@ -3462,7 +3460,7 @@ NV_STATUS NV_API_CALL nv_alloc_pages( } *priv_data = at; - NV_ATOMIC_INC(at->usage_count); + atomic64_inc(&at->usage_count); NV_PRINT_AT(NV_DBG_MEMINFO, at); @@ -3498,7 +3496,7 @@ NV_STATUS NV_API_CALL nv_free_pages( * This is described in greater detail in the comments above the * nvidia_vma_(open|release)() callbacks in nv-mmap.c. */ - if (!NV_ATOMIC_DEC_AND_TEST(at->usage_count)) + if (!atomic64_dec_and_test(&at->usage_count)) return NV_OK; if (!at->flags.guest) @@ -3526,7 +3524,7 @@ NvBool nv_lock_init_locks NV_INIT_MUTEX(&nvl->ldata_lock); NV_INIT_MUTEX(&nvl->mmap_lock); - NV_ATOMIC_SET(nvl->usage_count, 0); + atomic64_set(&nvl->usage_count, 0); if (!rm_init_event_locks(sp, nv)) return NV_FALSE; diff --git a/src/common/inc/nvBldVer.h b/src/common/inc/nvBldVer.h index dee30270f..be5e13a8f 100644 --- a/src/common/inc/nvBldVer.h +++ b/src/common/inc/nvBldVer.h @@ -36,25 +36,25 @@ // and then checked back in. You cannot make changes to these sections without // corresponding changes to the buildmeister script #ifndef NV_BUILD_BRANCH - #define NV_BUILD_BRANCH r539_56 + #define NV_BUILD_BRANCH r539_62 #endif #ifndef NV_PUBLIC_BRANCH - #define NV_PUBLIC_BRANCH r539_56 + #define NV_PUBLIC_BRANCH r539_62 #endif #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) -#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r535/r539_56-994" -#define NV_BUILD_CHANGELIST_NUM (36497304) +#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r535/r539_62-1069" +#define NV_BUILD_CHANGELIST_NUM (36903621) #define NV_BUILD_TYPE "Official" -#define NV_BUILD_NAME "rel/gpu_drv/r535/r539_56-994" -#define NV_LAST_OFFICIAL_CHANGELIST_NUM (36497304) +#define NV_BUILD_NAME "rel/gpu_drv/r535/r539_62-1069" +#define NV_LAST_OFFICIAL_CHANGELIST_NUM (36903621) #else /* Windows builds */ -#define NV_BUILD_BRANCH_VERSION "r539_56-1" -#define NV_BUILD_CHANGELIST_NUM (36476729) +#define NV_BUILD_BRANCH_VERSION "r539_62-1" +#define NV_BUILD_CHANGELIST_NUM (36902724) #define NV_BUILD_TYPE "Official" -#define NV_BUILD_NAME "539.57" -#define NV_LAST_OFFICIAL_CHANGELIST_NUM (36476729) +#define NV_BUILD_NAME "539.63" +#define NV_LAST_OFFICIAL_CHANGELIST_NUM (36902724) #define NV_BUILD_BRANCH_BASE_VERSION R535 #endif // End buildmeister python edited section diff --git a/src/common/inc/nvUnixVersion.h b/src/common/inc/nvUnixVersion.h index befac152c..88eb244ca 100644 --- a/src/common/inc/nvUnixVersion.h +++ b/src/common/inc/nvUnixVersion.h @@ -4,7 +4,7 @@ #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \ (defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1) -#define NV_VERSION_STRING "535.274.02" +#define NV_VERSION_STRING "535.288.01" #else diff --git a/src/nvidia/src/kernel/gpu/external_device/arch/kepler/kern_gsync_p2060.c b/src/nvidia/src/kernel/gpu/external_device/arch/kepler/kern_gsync_p2060.c index b25363ac5..1bc2e6b93 100644 --- a/src/nvidia/src/kernel/gpu/external_device/arch/kepler/kern_gsync_p2060.c +++ b/src/nvidia/src/kernel/gpu/external_device/arch/kepler/kern_gsync_p2060.c @@ -1163,6 +1163,8 @@ gsyncReadUniversalFrameCount_P2060 OBJTMR *pTmpTmr = NULL; OBJTMR *pTmr = GPU_GET_TIMER(pGpu); + NV_CHECK_OR_RETURN(LEVEL_INFO, gsyncIsFrameLocked_P2060(pThis), NV_ERR_INVALID_STATE); + if (!(pThis->FrameCountData.iface == NV_P2060_MAX_IFACES_PER_GSYNC)) { // @@ -1207,7 +1209,8 @@ gsyncReadUniversalFrameCount_P2060 // P2060 refreshrate is in 0.00001 Hz, so divide by 10000 to get Hz. // divide 1000000 by refreshRate to get the frame time in us. // - pThis->FrameCountData.frameTime = 1000000 / (pThis->RefreshRate/10000); //in us + NV_CHECK_OR_RETURN(LEVEL_INFO, pThis->RefreshRate >= 10, NV_ERR_INVALID_STATE); + pThis->FrameCountData.frameTime = 1000*1000*1000 / (pThis->RefreshRate/10); //in us // // Enable FrameCountTimerService to verify FrameCountData.initialDifference. diff --git a/src/nvidia/src/kernel/gpu/gr/kernel_graphics.c b/src/nvidia/src/kernel/gpu/gr/kernel_graphics.c index 016346ba6..4efc9ecca 100644 --- a/src/nvidia/src/kernel/gpu/gr/kernel_graphics.c +++ b/src/nvidia/src/kernel/gpu/gr/kernel_graphics.c @@ -358,6 +358,7 @@ kgraphicsStateLoad_IMPL NvU32 flags ) { + if (pGpu->fecsCtxswLogConsumerCount > 0) { fecsBufferMap(pGpu, pKernelGraphics); diff --git a/src/nvidia/src/kernel/os/os_init.c b/src/nvidia/src/kernel/os/os_init.c index 88c1fd9ec..81ef341ce 100644 --- a/src/nvidia/src/kernel/os/os_init.c +++ b/src/nvidia/src/kernel/os/os_init.c @@ -382,9 +382,9 @@ NvU32 vgpuDevReadReg032( OBJSYS *pSys = SYS_GET_INSTANCE(); OBJHYPERVISOR *pHypervisor = SYS_GET_HYPERVISOR(pSys); - if(!pGpu || - !pHypervisor || !pHypervisor->bDetected || !pHypervisor->bIsHVMGuest || - !GPU_GET_KERNEL_BIF(pGpu)) + + if (!pGpu || !GPU_GET_KERNEL_BIF(pGpu) || + (!IS_VIRTUAL(pGpu) && !(pHypervisor && pHypervisor->bDetected && pHypervisor->bIsHVMGuest))) { *vgpuHandled = NV_FALSE; return 0; diff --git a/version.mk b/version.mk index ad62e8636..367704cac 100644 --- a/version.mk +++ b/version.mk @@ -1,4 +1,4 @@ -NVIDIA_VERSION = 535.274.02 +NVIDIA_VERSION = 535.288.01 # This file. VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))