162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/bug.h> 362306a36Sopenharmony_ci#include <linux/export.h> 462306a36Sopenharmony_ci#include <linux/types.h> 562306a36Sopenharmony_ci#include <linux/mmdebug.h> 662306a36Sopenharmony_ci#include <linux/mm.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/addrspace.h> 962306a36Sopenharmony_ci#include <asm/sections.h> 1062306a36Sopenharmony_ci#include <asm/io.h> 1162306a36Sopenharmony_ci#include <asm/page.h> 1262306a36Sopenharmony_ci#include <asm/dma.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistatic inline bool __debug_virt_addr_valid(unsigned long x) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci /* 1762306a36Sopenharmony_ci * MAX_DMA_ADDRESS is a virtual address that may not correspond to an 1862306a36Sopenharmony_ci * actual physical address. Enough code relies on 1962306a36Sopenharmony_ci * virt_to_phys(MAX_DMA_ADDRESS) that we just need to work around it 2062306a36Sopenharmony_ci * and always return true. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_ci if (x == MAX_DMA_ADDRESS) 2362306a36Sopenharmony_ci return true; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci return x >= PAGE_OFFSET && (KSEGX(x) < KSEG2 || 2662306a36Sopenharmony_ci IS_ENABLED(CONFIG_EVA) || 2762306a36Sopenharmony_ci !IS_ENABLED(CONFIG_HIGHMEM)); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ciphys_addr_t __virt_to_phys(volatile const void *x) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci WARN(!__debug_virt_addr_valid((unsigned long)x), 3362306a36Sopenharmony_ci "virt_to_phys used for non-linear address: %pK (%pS)\n", 3462306a36Sopenharmony_ci x, x); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return __virt_to_phys_nodebug(x); 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ciEXPORT_SYMBOL(__virt_to_phys); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciphys_addr_t __phys_addr_symbol(unsigned long x) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci /* This is bounds checking against the kernel image only. 4362306a36Sopenharmony_ci * __pa_symbol should only be used on kernel symbol addresses. 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci VIRTUAL_BUG_ON(x < (unsigned long)_text || 4662306a36Sopenharmony_ci x > (unsigned long)_end); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci return __pa_symbol_nodebug(x); 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ciEXPORT_SYMBOL(__phys_addr_symbol); 51