|
@@ -18,6 +18,7 @@
|
|
|
|
|
|
#include <linux/elf.h>
|
|
|
#include <linux/fs.h>
|
|
|
+#include <linux/memblock.h>
|
|
|
#include <linux/mm.h>
|
|
|
#include <linux/mman.h>
|
|
|
#include <linux/export.h>
|
|
@@ -103,12 +104,18 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
|
|
|
*/
|
|
|
int valid_phys_addr_range(phys_addr_t addr, size_t size)
|
|
|
{
|
|
|
- if (addr < PHYS_OFFSET)
|
|
|
- return 0;
|
|
|
- if (addr + size > __pa(high_memory - 1) + 1)
|
|
|
- return 0;
|
|
|
-
|
|
|
- return 1;
|
|
|
+ /*
|
|
|
+ * Check whether addr is covered by a memory region without the
|
|
|
+ * MEMBLOCK_NOMAP attribute, and whether that region covers the
|
|
|
+ * entire range. In theory, this could lead to false negatives
|
|
|
+ * if the range is covered by distinct but adjacent memory regions
|
|
|
+ * that only differ in other attributes. However, few of such
|
|
|
+ * attributes have been defined, and it is debatable whether it
|
|
|
+ * follows that /dev/mem read() calls should be able traverse
|
|
|
+ * such boundaries.
|
|
|
+ */
|
|
|
+ return memblock_is_region_memory(addr, size) &&
|
|
|
+ memblock_is_map_memory(addr);
|
|
|
}
|
|
|
|
|
|
/*
|