1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Based on arch/arm/mm/mmap.c
4  *
5  * Copyright (C) 2012 ARM Ltd.
6  */
7 
8 #include <linux/io.h>
9 #include <linux/memblock.h>
10 #include <linux/types.h>
11 
12 #include <asm/page.h>
13 
14 /*
15  * You really shouldn't be using read() or write() on /dev/mem.  This might go
16  * away in the future.
17  */
valid_phys_addr_range(phys_addr_t addr,size_t size)18 int valid_phys_addr_range(phys_addr_t addr, size_t size)
19 {
20 	/*
21 	 * Check whether addr is covered by a memory region without the
22 	 * MEMBLOCK_NOMAP attribute, and whether that region covers the
23 	 * entire range. In theory, this could lead to false negatives
24 	 * if the range is covered by distinct but adjacent memory regions
25 	 * that only differ in other attributes. However, few of such
26 	 * attributes have been defined, and it is debatable whether it
27 	 * follows that /dev/mem read() calls should be able traverse
28 	 * such boundaries.
29 	 */
30 	return memblock_is_region_memory(addr, size) &&
31 	       memblock_is_map_memory(addr);
32 }
33 
34 /*
35  * Do not allow /dev/mem mappings beyond the supported physical range.
36  */
valid_mmap_phys_addr_range(unsigned long pfn,size_t size)37 int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
38 {
39 	return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
40 }
41