From 1e83ec96df8ff9bf3b8a9cf49253a242a8d87bc0 Mon Sep 17 00:00:00 2001 From: Ketan Patil Date: Fri, 28 Feb 2025 04:54:26 +0000 Subject: [PATCH] video: tegra: nvmap: Fix build failure Linux v6.10 and v6.11 are failing as follow_pfn was removed since kernel v6.10 Use conftest to detect if follow_pfn, follow_pfnmap_start functions are present or not and based upon this result, call the appropriate functions in nvmap code. Bug 5007238 Change-Id: Ie7e0c9bde652fd89158a5778aa8254fc86bf4696 Signed-off-by: Ketan Patil Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3311535 Reviewed-by: Jon Hunter Reviewed-by: mobile promotions GVS: buildbot_gerritrpt Tested-by: mobile promotions Reviewed-by: svcacv --- drivers/video/tegra/nvmap/nvmap_alloc.c | 31 ++++++++++++++++++++-- scripts/conftest/Makefile | 2 ++ scripts/conftest/conftest.sh | 34 +++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/drivers/video/tegra/nvmap/nvmap_alloc.c b/drivers/video/tegra/nvmap/nvmap_alloc.c index 9b8c54a2..543e2664 100644 --- a/drivers/video/tegra/nvmap/nvmap_alloc.c +++ b/drivers/video/tegra/nvmap/nvmap_alloc.c @@ -353,7 +353,7 @@ static const unsigned int heap_policy_excl[] = { static int nvmap_page_from_vma(struct vm_area_struct *vma, ulong vaddr, struct page **page) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +#if defined(NV_FOLLOW_PFNMAP_START_PRESENT) unsigned long pfn; struct follow_pfnmap_args args = { .vma = vma, @@ -379,7 +379,7 @@ static int nvmap_page_from_vma(struct vm_area_struct *vma, ulong vaddr, struct p fail: return -EINVAL; -#else +#elif defined(NV_FOLLOW_PFN_PRESENT) unsigned long pfn; if (follow_pfn(vma, vaddr, &pfn)) { @@ -398,6 +398,33 @@ fail: fail: return -EINVAL; +#else + unsigned long pfn; + spinlock_t *ptl; + pte_t *ptep; + + mmap_read_lock(current->mm); + if (follow_pte(vma, vaddr, &ptep, &ptl)) { + pr_err("follow_pte failed\n"); + goto fail; + } + + pfn = pte_pfn(ptep_get(ptep)); + if (!pfn_is_map_memory(pfn)) { + pr_err("no-map memory not allowed\n"); + pte_unmap_unlock(ptep, ptl); + goto fail; + } + + *page = pfn_to_page(pfn); + get_page(*page); + pte_unmap_unlock(ptep, ptl); + mmap_read_unlock(current->mm); + return 0; + +fail: + mmap_read_unlock(current->mm); + return -EINVAL; #endif } diff --git a/scripts/conftest/Makefile b/scripts/conftest/Makefile index 34bc81f9..ddbc85fd 100644 --- a/scripts/conftest/Makefile +++ b/scripts/conftest/Makefile @@ -138,6 +138,8 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += fd_empty NV_CONFTEST_FUNCTION_COMPILE_TESTS += fd_file NV_CONFTEST_FUNCTION_COMPILE_TESTS += file_struct_has_f_ref NV_CONFTEST_FUNCTION_COMPILE_TESTS += folio_entire_mapcount +NV_CONFTEST_FUNCTION_COMPILE_TESTS += follow_pfn +NV_CONFTEST_FUNCTION_COMPILE_TESTS += follow_pfnmap_start NV_CONFTEST_FUNCTION_COMPILE_TESTS += fop_unsigned_offset NV_CONFTEST_FUNCTION_COMPILE_TESTS += genpd_xlate_t_has_const_of_phandle_args NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_file_rcu_has_double_ptr_file_arg diff --git a/scripts/conftest/conftest.sh b/scripts/conftest/conftest.sh index 02e8b835..c360b228 100755 --- a/scripts/conftest/conftest.sh +++ b/scripts/conftest/conftest.sh @@ -7480,6 +7480,40 @@ compile_test() { compile_check_conftest "$CODE" "NV_FOLIO_ENTIRE_MAPCOUNT_PRESENT" "" "functions" ;; + follow_pfn) + # + # Determine if function follow_pfn() is present. + # + # Commit cb10c28ac82c9 ("mm: remove follow_pfn") + # remove follow_pfn() in Linux v6.10. + # + CODE=" + #include + int conftest(void) + { + return follow_pfn(); + }" + + compile_check_conftest "$CODE" "NV_FOLLOW_PFN_PRESENT" "" "functions" + ;; + + follow_pfnmap_start) + # + # Determine if function follow_pfnmap_start() is present. + # + # Commit 6da8e9634bb7e3 ("mm: new follow_pfnmap API") + # add follow_pfnmap_start() in Linux v6.12. + # + CODE=" + #include + int conftest(void) + { + return follow_pfnmap_start(); + }" + + compile_check_conftest "$CODE" "NV_FOLLOW_PFNMAP_START_PRESENT" "" "functions" + ;; + fop_unsigned_offset) # # Determine if definition FOP_UNSIGNED_OFFSET is present.