So far (xlate|unxlate)_dev_mem_ptr for read/write /dev/mem relies on a generic high_memory check in valid_phys_addr_range(), which does not allow to access any memory above high_memory whatsoever. By adding the high_memory check to (xlate|unxlate)_dev_mem_ptr, it still will be possible to use __va safely for kernel mapped memory and it will also allow read/write to access non-system RAM above high_memory once the high_memory check is removed from valid_phys_addr_range. Signed-off-by: Frantisek Hrbata <fhrbata@xxxxxxxxxx> --- arch/x86/mm/ioremap.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index baff1da..1ae7323 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -320,8 +320,11 @@ void *xlate_dev_mem_ptr(unsigned long phys) void *addr; unsigned long start = phys & PAGE_MASK; - /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */ - if (page_is_ram(start >> PAGE_SHIFT)) + /* + * If page is RAM and is mapped by kernel, we can use __va. + * Otherwise ioremap and unmap. + */ + if (page_is_ram(start >> PAGE_SHIFT) && phys <= __pa(high_memory)) return __va(phys); addr = (void __force *)ioremap_cache(start, PAGE_SIZE); @@ -333,7 +336,7 @@ void *xlate_dev_mem_ptr(unsigned long phys) void unxlate_dev_mem_ptr(unsigned long phys, void *addr) { - if (page_is_ram(phys >> PAGE_SHIFT)) + if (page_is_ram(phys >> PAGE_SHIFT) && phys <= __pa(high_memory)) return; iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK)); -- 1.9.3 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>