mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-02-02 22:47:25 +00:00
570.169
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -582,6 +582,9 @@ err:
|
||||
void NV_API_CALL nv_cap_close_fd(int fd)
|
||||
{
|
||||
#if NV_FILESYSTEM_ACCESS_AVAILABLE
|
||||
struct file *file;
|
||||
NvBool is_nv_cap_fd;
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
return;
|
||||
@@ -600,6 +603,30 @@ void NV_API_CALL nv_cap_close_fd(int fd)
|
||||
return;
|
||||
}
|
||||
|
||||
file = fget(fd);
|
||||
if (file == NULL)
|
||||
{
|
||||
task_unlock(current);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure the fd belongs to the nv-cap-drv */
|
||||
is_nv_cap_fd = (file->f_op == &g_nv_cap_drv_fops);
|
||||
|
||||
fput(file);
|
||||
|
||||
/*
|
||||
* In some cases, we may be in shutdown path and execute
|
||||
* in context of unrelated process. In that case we should
|
||||
* not access any 'current' state, but instead let kernel
|
||||
* clean up capability files on its own.
|
||||
*/
|
||||
if (!is_nv_cap_fd)
|
||||
{
|
||||
task_unlock(current);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* From v4.17-rc1 (to v5.10.8) kernels have stopped exporting sys_close(fd)
|
||||
* and started exporting __close_fd, as of this commit:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-FileCopyrightText: Copyright (c) 1999-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -867,3 +867,75 @@ void NV_API_CALL nv_set_safe_to_mmap_locked(
|
||||
|
||||
nvl->safe_to_mmap = safe_to_mmap;
|
||||
}
|
||||
|
||||
#if !NV_CAN_CALL_VMA_START_WRITE
|
||||
static NvBool nv_vma_enter_locked(struct vm_area_struct *vma, NvBool detaching)
|
||||
{
|
||||
NvU32 tgt_refcnt = VMA_LOCK_OFFSET;
|
||||
NvBool interrupted = NV_FALSE;
|
||||
if (!detaching)
|
||||
{
|
||||
tgt_refcnt++;
|
||||
}
|
||||
if (!refcount_add_not_zero(VMA_LOCK_OFFSET, &vma->vm_refcnt))
|
||||
{
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
rwsem_acquire(&vma->vmlock_dep_map, 0, 0, _RET_IP_);
|
||||
prepare_to_rcuwait(&vma->vm_mm->vma_writer_wait);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
if (refcount_read(&vma->vm_refcnt) == tgt_refcnt)
|
||||
break;
|
||||
|
||||
if (signal_pending_state(TASK_UNINTERRUPTIBLE, current))
|
||||
{
|
||||
interrupted = NV_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
// This is an open-coded version of finish_rcuwait().
|
||||
rcu_assign_pointer(vma->vm_mm->vma_writer_wait.task, NULL);
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
if (interrupted)
|
||||
{
|
||||
// Clean up on error: release refcount and dep_map
|
||||
refcount_sub_and_test(VMA_LOCK_OFFSET, &vma->vm_refcnt);
|
||||
rwsem_release(&vma->vmlock_dep_map, _RET_IP_);
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
lock_acquired(&vma->vmlock_dep_map, _RET_IP_);
|
||||
return NV_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to handle VMA locking and refcount management.
|
||||
*/
|
||||
void nv_vma_start_write(struct vm_area_struct *vma)
|
||||
{
|
||||
NvU32 mm_lock_seq;
|
||||
NvBool locked;
|
||||
if (__is_vma_write_locked(vma, &mm_lock_seq))
|
||||
return;
|
||||
|
||||
locked = nv_vma_enter_locked(vma, NV_FALSE);
|
||||
|
||||
WRITE_ONCE(vma->vm_lock_seq, mm_lock_seq);
|
||||
if (locked)
|
||||
{
|
||||
NvBool detached;
|
||||
detached = refcount_sub_and_test(VMA_LOCK_OFFSET, &vma->vm_refcnt);
|
||||
rwsem_release(&vma->vmlock_dep_map, _RET_IP_);
|
||||
WARN_ON_ONCE(detached);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(nv_vma_start_write);
|
||||
#endif // !NV_CAN_CALL_VMA_START_WRITE
|
||||
|
||||
@@ -236,6 +236,9 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_pci_ats_supported
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += ecc_digits_from_bytes
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_timer_delete_sync
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_hrtimer_setup
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl___vma_start_write
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_iommu_dev_enable_feature
|
||||
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_iommu_dev_disable_feature
|
||||
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += swiotlb_dma_ops
|
||||
@@ -257,7 +260,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += add_memory_driver_managed_has_mhp_flags_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += num_registered_fb
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += pci_driver_has_driver_managed_dma
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += vm_area_struct_has_const_vm_flags
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += memory_failure_has_trapno_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += memory_failure_queue_has_trapno_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += foll_longterm_present
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += bus_type_has_iommu_ops
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += class_create_has_no_owner_arg
|
||||
|
||||
@@ -2596,7 +2596,6 @@ NV_STATUS NV_API_CALL os_offline_page_at_address
|
||||
{
|
||||
#if defined(CONFIG_MEMORY_FAILURE)
|
||||
int flags = 0;
|
||||
int ret;
|
||||
NvU64 pfn;
|
||||
struct page *page = NV_GET_PAGE_STRUCT(address);
|
||||
|
||||
@@ -2621,22 +2620,18 @@ NV_STATUS NV_API_CALL os_offline_page_at_address
|
||||
flags |= MF_SW_SIMULATED;
|
||||
#endif
|
||||
|
||||
#ifdef NV_MEMORY_FAILURE_HAS_TRAPNO_ARG
|
||||
ret = memory_failure(pfn, 0, flags);
|
||||
#else
|
||||
ret = memory_failure(pfn, flags);
|
||||
#endif
|
||||
nv_printf(NV_DBG_INFO, "NVRM: offlining page at address: 0x%llx pfn: 0x%llx\n",
|
||||
address, pfn);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
nv_printf(NV_DBG_ERRORS, "NVRM: page offlining failed. address: 0x%llx pfn: 0x%llx ret: %d\n",
|
||||
address, pfn, ret);
|
||||
return NV_ERR_OPERATING_SYSTEM;
|
||||
}
|
||||
#ifdef NV_MEMORY_FAILURE_QUEUE_HAS_TRAPNO_ARG
|
||||
memory_failure_queue(pfn, 0, flags);
|
||||
#else
|
||||
memory_failure_queue(pfn, flags);
|
||||
#endif
|
||||
|
||||
return NV_OK;
|
||||
#else // !defined(CONFIG_MEMORY_FAILURE)
|
||||
nv_printf(NV_DBG_ERRORS, "NVRM: memory_failure() not supported by kernel. page offlining failed. address: 0x%llx\n",
|
||||
nv_printf(NV_DBG_ERRORS, "NVRM: memory_failure_queue() not supported by kernel. page offlining failed. address: 0x%llx\n",
|
||||
address);
|
||||
return NV_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user