Commit 981b6714 authored by Russell King's avatar Russell King

ARM: provide improved virt_to_idmap() functionality

For kexec, we need more functionality from the IDMAP system.  We need to
be able to convert physical addresses to their identity mappped versions
as well as virtual addresses.

Convert the existing arch_virt_to_idmap() to deal with physical
addresses instead.
Acked-by: default avatarSantosh Shilimkar <ssantosh@kernel.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 61603016
...@@ -288,19 +288,38 @@ static inline void *phys_to_virt(phys_addr_t x) ...@@ -288,19 +288,38 @@ static inline void *phys_to_virt(phys_addr_t x)
#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
#define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT)
extern unsigned long (*arch_virt_to_idmap)(unsigned long x); extern long long arch_phys_to_idmap_offset;
/* /*
* These are for systems that have a hardware interconnect supported alias of * These are for systems that have a hardware interconnect supported alias
* physical memory for idmap purposes. Most cases should leave these * of physical memory for idmap purposes. Most cases should leave these
* untouched. Note: this can only return addresses less than 4GiB. * untouched. Note: this can only return addresses less than 4GiB.
*/ */
#define IDMAP_INVALID_ADDR ((u32)~0)
static inline unsigned long phys_to_idmap(phys_addr_t addr)
{
if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) {
addr += arch_phys_to_idmap_offset;
if (addr > (u32)~0)
addr = IDMAP_INVALID_ADDR;
}
return addr;
}
static inline phys_addr_t idmap_to_phys(unsigned long idmap)
{
phys_addr_t addr = idmap;
if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset)
addr -= arch_phys_to_idmap_offset;
return addr;
}
static inline unsigned long __virt_to_idmap(unsigned long x) static inline unsigned long __virt_to_idmap(unsigned long x)
{ {
if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) return phys_to_idmap(__virt_to_phys(x));
return arch_virt_to_idmap(x);
else
return __virt_to_phys(x);
} }
#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x)) #define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x))
......
...@@ -63,11 +63,6 @@ static void __init keystone_init(void) ...@@ -63,11 +63,6 @@ static void __init keystone_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
static unsigned long keystone_virt_to_idmap(unsigned long x)
{
return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START;
}
static long long __init keystone_pv_fixup(void) static long long __init keystone_pv_fixup(void)
{ {
long long offset; long long offset;
...@@ -91,7 +86,7 @@ static long long __init keystone_pv_fixup(void) ...@@ -91,7 +86,7 @@ static long long __init keystone_pv_fixup(void)
offset = KEYSTONE_HIGH_PHYS_START - KEYSTONE_LOW_PHYS_START; offset = KEYSTONE_HIGH_PHYS_START - KEYSTONE_LOW_PHYS_START;
/* Populate the arch idmap hook */ /* Populate the arch idmap hook */
arch_virt_to_idmap = keystone_virt_to_idmap; arch_phys_to_idmap_offset = -offset;
return offset; return offset;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* page tables. * page tables.
*/ */
pgd_t *idmap_pgd; pgd_t *idmap_pgd;
unsigned long (*arch_virt_to_idmap)(unsigned long x); long long arch_phys_to_idmap_offset;
#ifdef CONFIG_ARM_LPAE #ifdef CONFIG_ARM_LPAE
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment