x86: Make it so that __pa_symbol can only process kernel symbols on x86_64
PATCH 1/1 x86: Make it so that __pa_symbol can only process kernel symbols on x86_64
I submitted an earlier patch that make __phys_addr an inline. This obviously results in an increase in the code size. One step I can take to reduce that is to make it so that the __pa_symbol call does a direct translation for kernel addresses instead of covering all of virtual memory.
On my system this reduced the size for __pa_symbol from 5 instructions totalling 30 bytes to 3 instructions totalling 16 bytes.
Signed-off-by Alexander Duyck <[email protected]>
---
arch/x86/include/asm/page.h | 3 ++- arch/x86/include/asm/page_32.h | 1 + arch/x86/include/asm/page_64_types.h | 3 +++ arch/x86/mm/physaddr.c | 15 +++++++++++++++ 4 files changed, 21 insertions(+), 1 deletions(-)
arch/x86/include/asm/page.h +2 -1
@@ -44,7 +44,8 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,* case properly. Once all supported versions of gcc understand it, we can * remove this Voodoo magic stuff. (i.e. once gcc3.x is deprecated) */ -#define __pa_symbol (x) __pa(__phys_reloc_hide((unsigned long)(x))) +#define __pa_symbol (x) \ + __phys_addr_symbol(__phys_reloc_hide((unsigned long)(x)))#define __va (x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
arch/x86/include/asm/page_32.h +1 -0
@@ -15,6 +15,7 @@ extern unsigned long __phys_addr(unsigned long);#else #define __phys_addr (x) __phys_addr_nodebug(x)#endif +#define __phys_addr_symbol (x) __phys_addr(x)#define __phys_reloc_hide (x) RELOC_HIDE((x), 0)#ifdef CONFIG_FLATMEM
arch/x86/include/asm/page_64_types.h +3 -0
@@ -60,6 +60,7 @@ extern unsigned long phys_base;#ifdef CONFIG_DEBUG_VIRTUAL extern unsigned long __phys_addr (unsigned long ); +extern unsigned long __phys_addr_symbol (unsigned long );#else static inline unsigned long __phys_addr (unsigned long x) {
@@ -70,6 +71,8 @@ static inline unsigned long __phys_addr(unsigned long x) return x; } +#define __phys_addr_symbol (x) \ + ((unsigned long)(x) - __START_KERNEL_map + phys_base)#endif #define __phys_reloc_hide (x) (x)
arch/x86/mm/physaddr.c +15 -0
@@ -29,6 +29,21 @@ unsigned long __phys_addr(unsigned long x) return x; }EXPORT_SYMBOL (__phys_addr); + +unsigned long __phys_addr_symbol (unsigned long x) +{ +unsigned long y = x - __START_KERNEL_map; + +/* use the carry flag to determine if x was < __START_KERNEL_map */ +VIRTUAL_BUG_ON (x < y); + + x = y + phys_base; + +VIRTUAL_BUG_ON (y >=KERNEL_IMAGE_SIZE ); + +return x; +} +EXPORT_SYMBOL (__phys_addr_symbol);#endif bool __virt_addr_valid (unsigned long x)