1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 257c8a661SMike Rapoport #include <linux/memblock.h> 378c86e5eSJeremy Fitzhardinge #include <linux/mmdebug.h> 44b599fedSPaul Gortmaker #include <linux/export.h> 578c86e5eSJeremy Fitzhardinge #include <linux/mm.h> 678c86e5eSJeremy Fitzhardinge 778c86e5eSJeremy Fitzhardinge #include <asm/page.h> 8*186525bdSIngo Molnar #include <linux/vmalloc.h> 978c86e5eSJeremy Fitzhardinge 1078c86e5eSJeremy Fitzhardinge #include "physaddr.h" 1178c86e5eSJeremy Fitzhardinge 1278c86e5eSJeremy Fitzhardinge #ifdef CONFIG_X86_64 1378c86e5eSJeremy Fitzhardinge 140bdf525fSAlexander Duyck #ifdef CONFIG_DEBUG_VIRTUAL __phys_addr(unsigned long x)1578c86e5eSJeremy Fitzhardingeunsigned long __phys_addr(unsigned long x) 1678c86e5eSJeremy Fitzhardinge { 170bdf525fSAlexander Duyck unsigned long y = x - __START_KERNEL_map; 180bdf525fSAlexander Duyck 190bdf525fSAlexander Duyck /* use the carry flag to determine if x was < __START_KERNEL_map */ 200bdf525fSAlexander Duyck if (unlikely(x > y)) { 210bdf525fSAlexander Duyck x = y + phys_base; 220bdf525fSAlexander Duyck 230bdf525fSAlexander Duyck VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); 2478c86e5eSJeremy Fitzhardinge } else { 250bdf525fSAlexander Duyck x = y + (__START_KERNEL_map - PAGE_OFFSET); 260bdf525fSAlexander Duyck 270bdf525fSAlexander Duyck /* carry flag will be set if starting x was >= PAGE_OFFSET */ 280bdf525fSAlexander Duyck VIRTUAL_BUG_ON((x > y) || !phys_addr_valid(x)); 2978c86e5eSJeremy Fitzhardinge } 300bdf525fSAlexander Duyck 3178c86e5eSJeremy Fitzhardinge return x; 3278c86e5eSJeremy Fitzhardinge } 3378c86e5eSJeremy Fitzhardinge EXPORT_SYMBOL(__phys_addr); 347d74275dSAlexander Duyck __phys_addr_symbol(unsigned long x)357d74275dSAlexander Duyckunsigned long __phys_addr_symbol(unsigned long x) 367d74275dSAlexander Duyck { 377d74275dSAlexander Duyck unsigned long y = x - __START_KERNEL_map; 387d74275dSAlexander Duyck 397d74275dSAlexander Duyck /* only check upper bounds since lower bounds will trigger carry */ 407d74275dSAlexander Duyck VIRTUAL_BUG_ON(y >= KERNEL_IMAGE_SIZE); 417d74275dSAlexander Duyck 427d74275dSAlexander Duyck return y + phys_base; 437d74275dSAlexander Duyck } 447d74275dSAlexander Duyck EXPORT_SYMBOL(__phys_addr_symbol); 450bdf525fSAlexander Duyck #endif 4678c86e5eSJeremy Fitzhardinge __virt_addr_valid(unsigned long x)4778c86e5eSJeremy Fitzhardingebool __virt_addr_valid(unsigned long x) 4878c86e5eSJeremy Fitzhardinge { 490bdf525fSAlexander Duyck unsigned long y = x - __START_KERNEL_map; 500bdf525fSAlexander Duyck 510bdf525fSAlexander Duyck /* use the carry flag to determine if x was < __START_KERNEL_map */ 520bdf525fSAlexander Duyck if (unlikely(x > y)) { 530bdf525fSAlexander Duyck x = y + phys_base; 540bdf525fSAlexander Duyck 550bdf525fSAlexander Duyck if (y >= KERNEL_IMAGE_SIZE) 5678c86e5eSJeremy Fitzhardinge return false; 5778c86e5eSJeremy Fitzhardinge } else { 580bdf525fSAlexander Duyck x = y + (__START_KERNEL_map - PAGE_OFFSET); 590bdf525fSAlexander Duyck 600bdf525fSAlexander Duyck /* carry flag will be set if starting x was >= PAGE_OFFSET */ 610bdf525fSAlexander Duyck if ((x > y) || !phys_addr_valid(x)) 6278c86e5eSJeremy Fitzhardinge return false; 6378c86e5eSJeremy Fitzhardinge } 6478c86e5eSJeremy Fitzhardinge 6578c86e5eSJeremy Fitzhardinge return pfn_valid(x >> PAGE_SHIFT); 6678c86e5eSJeremy Fitzhardinge } 6778c86e5eSJeremy Fitzhardinge EXPORT_SYMBOL(__virt_addr_valid); 6878c86e5eSJeremy Fitzhardinge 6978c86e5eSJeremy Fitzhardinge #else 7078c86e5eSJeremy Fitzhardinge 7178c86e5eSJeremy Fitzhardinge #ifdef CONFIG_DEBUG_VIRTUAL __phys_addr(unsigned long x)7278c86e5eSJeremy Fitzhardingeunsigned long __phys_addr(unsigned long x) 7378c86e5eSJeremy Fitzhardinge { 74a25b9316SDave Hansen unsigned long phys_addr = x - PAGE_OFFSET; 7578c86e5eSJeremy Fitzhardinge /* VMALLOC_* aren't constants */ 7678c86e5eSJeremy Fitzhardinge VIRTUAL_BUG_ON(x < PAGE_OFFSET); 7778c86e5eSJeremy Fitzhardinge VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x)); 78a25b9316SDave Hansen /* max_low_pfn is set early, but not _that_ early */ 79a25b9316SDave Hansen if (max_low_pfn) { 80a25b9316SDave Hansen VIRTUAL_BUG_ON((phys_addr >> PAGE_SHIFT) > max_low_pfn); 81a25b9316SDave Hansen BUG_ON(slow_virt_to_phys((void *)x) != phys_addr); 82a25b9316SDave Hansen } 83a25b9316SDave Hansen return phys_addr; 8478c86e5eSJeremy Fitzhardinge } 8578c86e5eSJeremy Fitzhardinge EXPORT_SYMBOL(__phys_addr); 8678c86e5eSJeremy Fitzhardinge #endif 8778c86e5eSJeremy Fitzhardinge __virt_addr_valid(unsigned long x)8878c86e5eSJeremy Fitzhardingebool __virt_addr_valid(unsigned long x) 8978c86e5eSJeremy Fitzhardinge { 9078c86e5eSJeremy Fitzhardinge if (x < PAGE_OFFSET) 9178c86e5eSJeremy Fitzhardinge return false; 9278c86e5eSJeremy Fitzhardinge if (__vmalloc_start_set && is_vmalloc_addr((void *) x)) 9378c86e5eSJeremy Fitzhardinge return false; 9478c86e5eSJeremy Fitzhardinge if (x >= FIXADDR_START) 9578c86e5eSJeremy Fitzhardinge return false; 9678c86e5eSJeremy Fitzhardinge return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT); 9778c86e5eSJeremy Fitzhardinge } 9878c86e5eSJeremy Fitzhardinge EXPORT_SYMBOL(__virt_addr_valid); 9978c86e5eSJeremy Fitzhardinge 10078c86e5eSJeremy Fitzhardinge #endif /* CONFIG_X86_64 */ 101