arm: add early_ioremap support
cover arm: add early_ioremap support
early_ioremap()/early_memremap() create temporary virtual mappings in the fixmap region during boot time. Part of the support now exists in core code, but depends on the generic fixmap support.
This set converts arm to use the generic fixmap support, and adds the architecture-specific part of early_ioremap support.
The fixmap/kmap changes in 3.15 complicated things slightly compared to previous iterations of these patches - this version works around that by introducing local macros in arm/mm/highmem.c.
Tested on TC2 and software models, with/without LPAE.
Mark Salter (2):
arm: use generic fixmap.h
arm: add early_ioremap support
arch/arm/Kconfig | 11 ++++++ arch/arm/include/asm/Kbuild | 1 + arch/arm/include/asm/fixmap.h | 45 +++++++++++++-------- arch/arm/include/asm/io.h | 1 + arch/arm/kernel/setup.c | 3 ++ arch/arm/mm/Makefile | 1 + arch/arm/mm/early_ioremap.c | 86 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/highmem.c | 13 ++++--- arch/arm/mm/init.c | 2 +- arch/arm/mm/mmu.c | 2 + 10 files changed, 143 insertions(+), 22 deletions(-) create mode 100644 arch/arm/mm/early_ioremap.c
Signature · 1 line
1.7.10.4
PATCH 1/2 arm: use generic fixmap.h
From: Mark Salter <[email protected]>
ARM is different from other architectures in that fixmap pages are indexed with a positive offset from FIXADDR_START. Other architectures index with a negative offset from FIXADDR_TOP. In order to use the generic fixmap.h definitions, this patch redefines FIXADDR_TOP to be inclusive of the useable range. That is, FIXADDR_TOP is the virtual address of the topmost fixed page. The newly defined FIXADDR_END is the first virtual address past the fixed mappings.
The patch also introduces local helper macros in highmem.c to reverse the iteration order of fixmap pages.
--- arch/arm/include/asm/fixmap.h | 45 ++++++++++++++++++++++++++--------------- arch/arm/mm/highmem.c | 13 +++++++----- arch/arm/mm/init.c | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-)
arch/arm/include/asm/fixmap.h +29 -16
@@ -1,28 +1,41 @@#ifndef _ASM_FIXMAP_H#define _ASM_FIXMAP_H +#include <asm/pgtable.h> +#define FIXADDR_START 0xffc00000UL -#define FIXADDR_TOP 0xffe00000UL -#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) +#define FIXADDR_END 0xffe00000UL +#define FIXADDR_SIZE (FIXADDR_END - FIXADDR_START) +#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) -#define __fix_to_virt (x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix (x) (((x) - FIXADDR_START) >> PAGE_SHIFT) +enum fixed_addresses { +FIX_KMAP_BEGIN , +FIX_KMAP_END =FIX_KMAP_NR_PTES -1 , + __end_of_fixed_addresses +}; + +/* +* Temporary boot-time mappings, used by early_ioremap(), +* before ioremap() is functional. +* +* (P)re-using the last pmd of the FIXADDR region, which is used for +* highmem later on, and statically aligned to 1MB. +* Growing down from FIXADDR_TOP +*/ +#define NR_FIX_BTMAPS 32 +#define FIX_BTMAPS_SLOTS (PTRS_PER_PTE / NR_FIX_BTMAPS) +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) +#define FIX_BTMAP_END FIX_KMAP_BEGIN +#define FIX_BTMAP_BEGIN (FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1) -extern void __this_fixmap_does_not_exist (void ); +#define FIXMAP_PAGE_NORMAL (L_PTE_MT_WRITEBACK | L_PTE_YOUNG | L_PTE_PRESENT) +#define FIXMAP_PAGE_IO (L_PTE_MT_DEV_NONSHARED | L_PTE_YOUNG | L_PTE_PRESENT) -static inline unsigned long fix_to_virt (const unsigned int idx) -{ -if (idx >=FIX_KMAP_NR_PTES ) -__this_fixmap_does_not_exist (); -return __fix_to_virt (idx); -} +extern void __early_set_fixmap (enum fixed_addresses idx, +phys_addr_t phys,pgprot_t flags); -static inline unsigned int virt_to_fix (const unsigned long vaddr) -{ -BUG_ON (vaddr >=FIXADDR_TOP || vaddr <FIXADDR_START ); -return __virt_to_fix (vaddr); -} +#include <asm-generic/fixmap.h> #endif
arch/arm/mm/highmem.c +8 -5
@@ -20,16 +20,19 @@pte_t *fixmap_page_table; +#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x))) +#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __fix_to_virt(x)) +static inline void set_fixmap_pte (int idx,pte_t pte) { -unsigned long vaddr =__fix_to_virt (idx); +unsigned long vaddr =__kmap_fix_to_virt (idx);set_pte_ext (fixmap_page_table + idx, pte,0 );local_flush_tlb_kernel_page (vaddr); }static inline pte_t get_fixmap_pte (unsigned long vaddr) { -unsigned long idx =__virt_to_fix (vaddr); +unsigned long idx =__kmap_virt_to_fix (vaddr);return *(fixmap_page_table + idx); }
@@ -78,7 +81,7 @@ void *kmap_atomic(struct page *page) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM /* * With debugging enabled, kunmap_atomic forces that entry to 0.
@@ -109,7 +112,7 @@ void __kunmap_atomic(void *kvaddr)if (cache_is_vivt ())__cpuc_flush_dcache_area ((void *)vaddr,PAGE_SIZE );#ifdef CONFIG_DEBUG_HIGHMEM -BUG_ON (vaddr !=__fix_to_virt (idx)); +BUG_ON (vaddr !=__kmap_fix_to_virt (idx));set_fixmap_pte (idx,__pte (0 ));#else (void ) idx;/* to kill a warning */
@@ -132,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM BUG_ON (!pte_none (*(fixmap_page_table + idx)));#endif
arch/arm/mm/init.c +1 -1
@@ -570,7 +570,7 @@ void __init mem_init(void)MLK (DTCM_OFFSET , (unsigned long ) dtcm_end),MLK (ITCM_OFFSET , (unsigned long ) itcm_end), #endif -MLK (FIXADDR_START ,FIXADDR_TOP ), +MLK (FIXADDR_START ,FIXADDR_END ),MLM (VMALLOC_START ,VMALLOC_END ),MLM (PAGE_OFFSET , (unsigned long )high_memory), #ifdef CONFIG_HIGHMEM
Signature · 1 line
1.7.10.4
PATCH 1/2 arm: use generic fixmap.h
Quoted 89 lines · Leif Lindholm
From: Mark Salter <[email protected]>
ARM is different from other architectures in that fixmap pages are indexed with a positive offset from
FIXADDR_START. Other architectures index with a negative offset fromFIXADDR_TOP. In order to use the genericfixmap.hdefinitions, this patch redefinesFIXADDR_TOPto be inclusive of the useable range. That is,FIXADDR_TOPis the virtual address of the topmost fixed page. The newly definedFIXADDR_ENDis the first virtual address past the fixed mappings.The patch also introduces local helper macros in
highmem.cto reverse the iteration order of fixmap pages.Signed-off-by Mark Salter <[email protected]>[Rebased to 3.16-rc4, reverse kmap fixmap traversal]Signed-off-by Leif Lindholm <[email protected]>--- arch/arm/include/asm/fixmap.h | 45 ++++++++++++++++++++++++++--------------- arch/arm/mm/highmem.c | 13 +++++++----- arch/arm/mm/init.c | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-)arch/arm/include/asm/fixmap.h +29
-16@@ -1,28 +1,41 @@#ifndef _ASM_FIXMAP_H#define _ASM_FIXMAP_H +#include <asm/pgtable.h> +#define FIXADDR_START 0xffc00000UL -#define FIXADDR_TOP 0xffe00000UL -#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) +#define FIXADDR_END 0xffe00000UL +#define FIXADDR_SIZE (FIXADDR_END - FIXADDR_START) +#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) -#define __fix_to_virt (x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix (x) (((x) - FIXADDR_START) >> PAGE_SHIFT) +enum fixed_addresses { +FIX_KMAP_BEGIN , +FIX_KMAP_END =FIX_KMAP_NR_PTES -1 , + __end_of_fixed_addresses +}; + +/* +* Temporary boot-time mappings, used by early_ioremap(), +* before ioremap() is functional. +* +* (P)re-using the last pmd of the FIXADDR region, which is used for +* highmem later on, and statically aligned to 1MB. +* Growing down from FIXADDR_TOP +*/ +#define NR_FIX_BTMAPS 32 +#define FIX_BTMAPS_SLOTS (PTRS_PER_PTE / NR_FIX_BTMAPS) +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) +#define FIX_BTMAP_END FIX_KMAP_BEGIN +#define FIX_BTMAP_BEGIN (FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1) -extern void __this_fixmap_does_not_exist (void ); +#define FIXMAP_PAGE_NORMAL (L_PTE_MT_WRITEBACK | L_PTE_YOUNG | L_PTE_PRESENT) +#define FIXMAP_PAGE_IO (L_PTE_MT_DEV_NONSHARED | L_PTE_YOUNG | L_PTE_PRESENT) -static inline unsigned long fix_to_virt (const unsigned int idx) -{ -if (idx >=FIX_KMAP_NR_PTES ) -__this_fixmap_does_not_exist (); -return __fix_to_virt (idx); -} +extern void __early_set_fixmap (enum fixed_addresses idx, +phys_addr_t phys,pgprot_t flags); -static inline unsigned int virt_to_fix (const unsigned long vaddr) -{ -BUG_ON (vaddr >=FIXADDR_TOP || vaddr <FIXADDR_START ); -return __virt_to_fix (vaddr); -} +#include <asm-generic/fixmap.h> #endif arch/arm/mm/highmem.c +0
-0
arch/arm/mm/highmem.c line 23
Quoted 4 lines
arch/arm/mm/highmem.c +1
-0@@ -20,16 +20,19 @@pte_t *fixmap_page_table; +#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x)))
FIX_KMAP_END - (x) ?
arch/arm/mm/highmem.c line 24
Quoted 1 line
arch/arm/mm/highmem.c +1
-0+#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __fix_to_virt(x))
shouldn't this use __virt_to_fix(x)?
Quoted 56 lines
arch/arm/mm/highmem.c +6
-5+static inline void set_fixmap_pte (int idx,pte_t pte) { -unsigned long vaddr =__fix_to_virt (idx); +unsigned long vaddr =__kmap_fix_to_virt (idx);set_pte_ext (fixmap_page_table + idx, pte,0 );local_flush_tlb_kernel_page (vaddr); }static inline pte_t get_fixmap_pte (unsigned long vaddr) { -unsigned long idx =__virt_to_fix (vaddr); +unsigned long idx =__kmap_virt_to_fix (vaddr);return *(fixmap_page_table + idx); }@@ -78,7 +81,7 @@ void *kmap_atomic(struct page *page) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM /* * With debugging enabled, kunmap_atomic forces that entry to 0. @@ -109,7 +112,7 @@ void __kunmap_atomic(void *kvaddr)if (cache_is_vivt ())__cpuc_flush_dcache_area ((void *)vaddr,PAGE_SIZE );#ifdef CONFIG_DEBUG_HIGHMEM -BUG_ON (vaddr !=__fix_to_virt (idx)); +BUG_ON (vaddr !=__kmap_fix_to_virt (idx));set_fixmap_pte (idx,__pte (0 ));#else (void ) idx;/* to kill a warning */ @@ -132,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM BUG_ON (!pte_none (*(fixmap_page_table + idx)));#endif arch/arm/mm/init.c +1
-1@@ -570,7 +570,7 @@ void __init mem_init(void)MLK (DTCM_OFFSET , (unsigned long ) dtcm_end),MLK (ITCM_OFFSET , (unsigned long ) itcm_end), #endif -MLK (FIXADDR_START ,FIXADDR_TOP ), +MLK (FIXADDR_START ,FIXADDR_END ),MLM (VMALLOC_START ,VMALLOC_END ),MLM (PAGE_OFFSET , (unsigned long )high_memory), #ifdef CONFIG_HIGHMEM
PATCH 1/2 arm: use generic fixmap.h
Quoted 9 lines · Mark Salter
Quoted 8 lines · Leif Lindholm
arch/arm/mm/highmem.c +0
-0@@ -20,16 +20,19 @@pte_t *fixmap_page_table;
Quoted 7 lines
arch/arm/mm/highmem.c line 23
Quoted 1 line
arch/arm/mm/highmem.c +1
-0+#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x)))
FIX_KMAP_END- (x) ?arch/arm/mm/highmem.c line 24
Quoted 1 line
arch/arm/mm/highmem.c +1
-0+#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __fix_to_virt(x))shouldn't this use
__virt_to_fix(x)?
Err, clearly.
Good thing I managed to mess up the end of the interface that actually isn't used anywhere in the kernel(!).
Fixed in the below.
/
Leif
Quoted 1 line
From
d0a82cd19000139d32232f415bcf46f476c16561Mon Sep 17 00:00:00 2001
From: Mark Salter <[email protected]>
Date: Thu, 14 Nov 2013 11:37:32 -0500
Subject: [PATCH 1/2] arm: use generic fixmap.h
ARM is different from other architectures in that fixmap pages are indexed with a positive offset from FIXADDR_START. Other architectures index with a negative offset from FIXADDR_TOP. In order to use the generic fixmap.h definitions, this patch redefines FIXADDR_TOP to be inclusive of the useable range. That is, FIXADDR_TOP is the virtual address of the topmost fixed page. The newly defined FIXADDR_END is the first virtual address past the fixed mappings.
The patch also introduces local helper macros in highmem.c to reverse the iteration order of fixmap pages.
--- arch/arm/include/asm/fixmap.h | 45 ++++++++++++++++++++++++++--------------- arch/arm/mm/highmem.c | 13 +++++++----- arch/arm/mm/init.c | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-)
arch/arm/include/asm/fixmap.h +29 -16
@@ -1,28 +1,41 @@#ifndef _ASM_FIXMAP_H#define _ASM_FIXMAP_H +#include <asm/pgtable.h> +#define FIXADDR_START 0xffc00000UL -#define FIXADDR_TOP 0xffe00000UL -#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) +#define FIXADDR_END 0xffe00000UL +#define FIXADDR_SIZE (FIXADDR_END - FIXADDR_START) +#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) -#define __fix_to_virt (x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix (x) (((x) - FIXADDR_START) >> PAGE_SHIFT) +enum fixed_addresses { +FIX_KMAP_BEGIN , +FIX_KMAP_END =FIX_KMAP_NR_PTES -1 , + __end_of_fixed_addresses +}; + +/* +* Temporary boot-time mappings, used by early_ioremap(), +* before ioremap() is functional. +* +* (P)re-using the last pmd of the FIXADDR region, which is used for +* highmem later on, and statically aligned to 1MB. +* Growing down from FIXADDR_TOP +*/ +#define NR_FIX_BTMAPS 32 +#define FIX_BTMAPS_SLOTS (PTRS_PER_PTE / NR_FIX_BTMAPS) +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) +#define FIX_BTMAP_END FIX_KMAP_BEGIN +#define FIX_BTMAP_BEGIN (FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1) -extern void __this_fixmap_does_not_exist (void ); +#define FIXMAP_PAGE_NORMAL (L_PTE_MT_WRITEBACK | L_PTE_YOUNG | L_PTE_PRESENT) +#define FIXMAP_PAGE_IO (L_PTE_MT_DEV_NONSHARED | L_PTE_YOUNG | L_PTE_PRESENT) -static inline unsigned long fix_to_virt (const unsigned int idx) -{ -if (idx >=FIX_KMAP_NR_PTES ) -__this_fixmap_does_not_exist (); -return __fix_to_virt (idx); -} +extern void __early_set_fixmap (enum fixed_addresses idx, +phys_addr_t phys,pgprot_t flags); -static inline unsigned int virt_to_fix (const unsigned long vaddr) -{ -BUG_ON (vaddr >=FIXADDR_TOP || vaddr <FIXADDR_START ); -return __virt_to_fix (vaddr); -} +#include <asm-generic/fixmap.h> #endif
arch/arm/mm/highmem.c +8 -5
@@ -20,16 +20,19 @@pte_t *fixmap_page_table; +#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x))) +#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __virt_to_fix(x)) +static inline void set_fixmap_pte (int idx,pte_t pte) { -unsigned long vaddr =__fix_to_virt (idx); +unsigned long vaddr =__kmap_fix_to_virt (idx);set_pte_ext (fixmap_page_table + idx, pte,0 );local_flush_tlb_kernel_page (vaddr); }static inline pte_t get_fixmap_pte (unsigned long vaddr) { -unsigned long idx =__virt_to_fix (vaddr); +unsigned long idx =__kmap_virt_to_fix (vaddr);return *(fixmap_page_table + idx); }
@@ -78,7 +81,7 @@ void *kmap_atomic(struct page *page) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM /* * With debugging enabled, kunmap_atomic forces that entry to 0.
@@ -109,7 +112,7 @@ void __kunmap_atomic(void *kvaddr)if (cache_is_vivt ())__cpuc_flush_dcache_area ((void *)vaddr,PAGE_SIZE );#ifdef CONFIG_DEBUG_HIGHMEM -BUG_ON (vaddr !=__fix_to_virt (idx)); +BUG_ON (vaddr !=__kmap_fix_to_virt (idx));set_fixmap_pte (idx,__pte (0 ));#else (void ) idx;/* to kill a warning */
@@ -132,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM BUG_ON (!pte_none (*(fixmap_page_table + idx)));#endif
arch/arm/mm/init.c +1 -1
@@ -570,7 +570,7 @@ void __init mem_init(void)MLK (DTCM_OFFSET , (unsigned long ) dtcm_end),MLK (ITCM_OFFSET , (unsigned long ) itcm_end), #endif -MLK (FIXADDR_START ,FIXADDR_TOP ), +MLK (FIXADDR_START ,FIXADDR_END ),MLM (VMALLOC_START ,VMALLOC_END ),MLM (PAGE_OFFSET , (unsigned long )high_memory), #ifdef CONFIG_HIGHMEM
Signature · 1 line
1.7.10.4
PATCH 1/2 arm: use generic fixmap.h
Quoted 184 lines · Leif Lindholm
Quoted 9 lines · Mark Salter
Quoted 8 lines · Leif Lindholm
arch/arm/mm/highmem.c +0
-0@@ -20,16 +20,19 @@pte_t *fixmap_page_table;Quoted 7 lines
arch/arm/mm/highmem.c line 23
Quoted 1 line
arch/arm/mm/highmem.c +1
-0+#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x)))
FIX_KMAP_END- (x) ?arch/arm/mm/highmem.c line 24
Quoted 1 line
arch/arm/mm/highmem.c +1
-0+#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __fix_to_virt(x))shouldn't this use
__virt_to_fix(x)?Err, clearly.
Good thing I managed to mess up the end of the interface that actually isn't used anywhere in the kernel(!).Fixed in the below.
/
LeifFrom
d0a82cd19000139d32232f415bcf46f476c16561Mon Sep 17 00:00:00 2001
From: Mark Salter <[email protected]>
Date: Thu, 14 Nov 2013 11:37:32 -0500
Subject: [PATCH 1/2] arm: use genericfixmap.hARM is different from other architectures in that fixmap pages are indexed with a positive offset from
FIXADDR_START. Other architectures index with a negative offset fromFIXADDR_TOP. In order to use the genericfixmap.hdefinitions, this patch redefinesFIXADDR_TOPto be inclusive of the useable range. That is,FIXADDR_TOPis the virtual address of the topmost fixed page. The newly definedFIXADDR_ENDis the first virtual address past the fixed mappings.The patch also introduces local helper macros in
highmem.cto reverse the iteration order of fixmap pages.Signed-off-by Mark Salter <[email protected]>[Rebased to 3.16-rc4, reverse kmap fixmap traversal]Signed-off-by Leif Lindholm <[email protected]>--- arch/arm/include/asm/fixmap.h | 45 ++++++++++++++++++++++++++--------------- arch/arm/mm/highmem.c | 13 +++++++----- arch/arm/mm/init.c | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-)arch/arm/include/asm/fixmap.h +29
-16@@ -1,28 +1,41 @@#ifndef _ASM_FIXMAP_H#define _ASM_FIXMAP_H +#include <asm/pgtable.h> +#define FIXADDR_START 0xffc00000UL -#define FIXADDR_TOP 0xffe00000UL -#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) +#define FIXADDR_END 0xffe00000UL +#define FIXADDR_SIZE (FIXADDR_END - FIXADDR_START) +#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) -#define __fix_to_virt (x) (FIXADDR_START + ((x) << PAGE_SHIFT)) -#define __virt_to_fix (x) (((x) - FIXADDR_START) >> PAGE_SHIFT) +enum fixed_addresses { +FIX_KMAP_BEGIN , +FIX_KMAP_END =FIX_KMAP_NR_PTES -1 , + __end_of_fixed_addresses +}; + +/* +* Temporary boot-time mappings, used by early_ioremap(), +* before ioremap() is functional. +* +* (P)re-using the last pmd of the FIXADDR region, which is used for +* highmem later on, and statically aligned to 1MB. +* Growing down from FIXADDR_TOP +*/ +#define NR_FIX_BTMAPS 32 +#define FIX_BTMAPS_SLOTS (PTRS_PER_PTE / NR_FIX_BTMAPS) +#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) +#define FIX_BTMAP_END FIX_KMAP_BEGIN +#define FIX_BTMAP_BEGIN (FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1) -extern void __this_fixmap_does_not_exist (void ); +#define FIXMAP_PAGE_NORMAL (L_PTE_MT_WRITEBACK | L_PTE_YOUNG | L_PTE_PRESENT) +#define FIXMAP_PAGE_IO (L_PTE_MT_DEV_NONSHARED | L_PTE_YOUNG | L_PTE_PRESENT) -static inline unsigned long fix_to_virt (const unsigned int idx) -{ -if (idx >=FIX_KMAP_NR_PTES ) -__this_fixmap_does_not_exist (); -return __fix_to_virt (idx); -} +extern void __early_set_fixmap (enum fixed_addresses idx, +phys_addr_t phys,pgprot_t flags); -static inline unsigned int virt_to_fix (const unsigned long vaddr) -{ -BUG_ON (vaddr >=FIXADDR_TOP || vaddr <FIXADDR_START ); -return __virt_to_fix (vaddr); -} +#include <asm-generic/fixmap.h> #endif arch/arm/mm/highmem.c +8
-5@@ -20,16 +20,19 @@pte_t *fixmap_page_table; +#define __kmap_fix_to_virt (x) (__fix_to_virt(FIX_KMAP_NR_PTES - 1 - (x))) +#define __kmap_virt_to_fix (x) (FIX_KMAP_NR_PTES - 1 - __virt_to_fix(x)) +static inline void set_fixmap_pte (int idx,pte_t pte) { -unsigned long vaddr =__fix_to_virt (idx); +unsigned long vaddr =__kmap_fix_to_virt (idx);set_pte_ext (fixmap_page_table + idx, pte,0 );local_flush_tlb_kernel_page (vaddr); }static inline pte_t get_fixmap_pte (unsigned long vaddr) { -unsigned long idx =__virt_to_fix (vaddr); +unsigned long idx =__kmap_virt_to_fix (vaddr);return *(fixmap_page_table + idx); }@@ -78,7 +81,7 @@ void *kmap_atomic(struct page *page) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM /* * With debugging enabled, kunmap_atomic forces that entry to 0. @@ -109,7 +112,7 @@ void __kunmap_atomic(void *kvaddr)if (cache_is_vivt ())__cpuc_flush_dcache_area ((void *)vaddr,PAGE_SIZE );#ifdef CONFIG_DEBUG_HIGHMEM -BUG_ON (vaddr !=__fix_to_virt (idx)); +BUG_ON (vaddr !=__kmap_fix_to_virt (idx));set_fixmap_pte (idx,__pte (0 ));#else (void ) idx;/* to kill a warning */ @@ -132,7 +135,7 @@ void *kmap_atomic_pfn(unsigned long pfn) type =kmap_atomic_idx_push (); idx = type +KM_TYPE_NR *smp_processor_id (); - vaddr =__fix_to_virt (idx); + vaddr =__kmap_fix_to_virt (idx);#ifdef CONFIG_DEBUG_HIGHMEM BUG_ON (!pte_none (*(fixmap_page_table + idx)));#endif arch/arm/mm/init.c +1
-2@@ -570,7 +570,7 @@ void __init mem_init(void)MLK (DTCM_OFFSET , (unsigned long ) dtcm_end),MLK (ITCM_OFFSET , (unsigned long ) itcm_end), #endif -MLK (FIXADDR_START ,FIXADDR_TOP ), +MLK (FIXADDR_START ,FIXADDR_END ),MLM (VMALLOC_START ,VMALLOC_END ),MLM (PAGE_OFFSET , (unsigned long )high_memory), #ifdef CONFIG_HIGHMEM --1.7.10.4
Quoted 4 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
I'd like to use this for kernel RO text handling too (kprobes and kgdb). Is this patch alone in good enough shape for landing in -next? I would want this added as well:
https://patchwork.kernel.org/patch/3941001/
Thoughts?
-Kees
Signature · 2 lines
Kees Cook Chrome OS Security
PATCH 1/2 arm: use generic fixmap.h
In reply to Leif LindholmHi Leif,
Quoted 13 lines · Leif Lindholm
From: Mark Salter <[email protected]>
ARM is different from other architectures in that fixmap pages are indexed with a positive offset from
FIXADDR_START. Other architectures index with a negative offset fromFIXADDR_TOP. In order to use the genericfixmap.hdefinitions, this patch redefinesFIXADDR_TOPto be inclusive of the useable range. That is,FIXADDR_TOPis the virtual address of the topmost fixed page. The newly definedFIXADDR_ENDis the first virtual address past the fixed mappings.The patch also introduces local helper macros in
highmem.cto reverse the iteration order of fixmap pages.
Quoted 9 lines
Signed-off-by Mark Salter <[email protected]>[Rebased to 3.16-rc4, reverse kmap fixmap traversal]Signed-off-by Leif Lindholm <[email protected]>--- arch/arm/include/asm/fixmap.h | 45 ++++++++++++++++++++++++++--------------- arch/arm/mm/highmem.c | 13 +++++++----- arch/arm/mm/init.c | 2 +- 3 files changed, 38 insertions(+), 22 deletions(-)
I've tried to use this series to enable earlycon without hardcoded static mappings, but apparently something is not right yet. Please see below.
[snip]
arch/arm/include/asm/fixmap.h line 34
Quoted 3 lines
arch/arm/include/asm/fixmap.h +2
-1-extern void __this_fixmap_does_not_exist (void ); +#define FIXMAP_PAGE_NORMAL (L_PTE_MT_WRITEBACK | L_PTE_YOUNG | L_PTE_PRESENT) +#define FIXMAP_PAGE_IO (L_PTE_MT_DEV_NONSHARED | L_PTE_YOUNG | L_PTE_PRESENT)
This set of flags gives a read-only mapping on the machine I'm testing on (Exynos4412, Cortex A9MPcore). If I use the same set of flags as used in arch/arm/mm/mmu.c for MT_DEVICE_NONSHARED then the mapping works fine.
Best regards,
Tomasz
PATCH 2/2 arm: add early_ioremap support
In reply to Leif LindholmFrom: Mark Salter <[email protected]>
This patch uses the generic early_ioremap code to implement early_ioremap for ARM. The ARM-specific bits come mostly from an earlier patch from Leif Lindholm <[email protected]> here:
https://lkml.org/lkml/2013/10/3/279
--- arch/arm/Kconfig | 11 ++++++ arch/arm/include/asm/Kbuild | 1 + arch/arm/include/asm/io.h | 1 + arch/arm/kernel/setup.c | 3 ++ arch/arm/mm/Makefile | 1 + arch/arm/mm/early_ioremap.c | 86 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 2 + 7 files changed, 105 insertions(+) create mode 100644 arch/arm/mm/early_ioremap.c
arch/arm/Kconfig +11 -0
@@ -1800,6 +1800,17 @@ config UACCESS_WITH_MEMCPY However, if the CPU data cache is using a write-allocate mode, this option is unlikely to provide any performance gain. +config EARLY_IOREMAP + depends on MMU + bool "Provide early_ioremap() support for kernel initialization." + select GENERIC_EARLY_IOREMAP + help + Provide a mechanism for kernel initialisation code to temporarily + map, in a highmem-agnostic way, memory pages in before ioremap() + and friends are available (before paging_init() has run). It uses + the same virtual memory range as kmap so all early mappings must + be unmapped before paging_init() is called. + config SECCOMP bool prompt "Enable seccomp to safely compute untrusted bytecode"
arch/arm/include/asm/Kbuild +1 -0
@@ -4,6 +4,7 @@ generic-y += auxvec.h generic-y += bitsperlong.h generic-y += cputime.h generic-y += current.h +generic-y += early_ioremap.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h
arch/arm/include/asm/io.h +1 -0
@@ -28,6 +28,7 @@#include <asm/byteorder.h> #include <asm/memory.h> #include <asm-generic/pci_iomap.h> +#include <asm/early_ioremap.h> #include <xen/xen.h> /*
arch/arm/kernel/setup.c +3 -0
@@ -36,6 +36,7 @@#include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> +#include <asm/io.h> #include <asm/procinfo.h> #include <asm/psci.h> #include <asm/sections.h>
@@ -894,6 +895,8 @@ void __init setup_arch(char **cmdline_p)parse_early_param (); +early_ioremap_init (); +early_paging_init (mdesc,lookup_processor_type (read_cpuid_id ()));setup_dma_zone (mdesc);sanity_check_meminfo ();
arch/arm/mm/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARM_PTDUMP) += dump.o obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o +obj-$(CONFIG_EARLY_IOREMAP) += early_ioremap.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
arch/arm/mm/early_ioremap.c new file +86 -0
86 lines not on this page · raw message
arch/arm/mm/mmu.c +2 -0
@@ -36,6 +36,7 @@#include <asm/mach/map.h> #include <asm/mach/pci.h> #include <asm/fixmap.h> +#include <asm/early_ioremap.h> #include "mm.h" #include "tcm.h"
@@ -1474,6 +1475,7 @@ void __init paging_init(const struct machine_desc *mdesc) {void *zero_page; +early_ioremap_reset ();build_mem_type_table ();prepare_page_table ();map_lowmem ();
Signature · 1 line
1.7.10.4
PATCH 2/2 arm: add early_ioremap support
arch/arm/Kconfig config UACCESS_WITH_MEMCPY · line 1806
Quoted 4 lines · Leif Lindholm
arch/arm/Kconfig +4
-0+config EARLY_IOREMAP + depends on MMU + bool "Provide early_ioremap() support for kernel initialization." + select GENERIC_EARLY_IOREMAP
Nit: please order as bool, then depends, then select.
arch/arm/kernel/setup.c line 39
Quoted 9 lines
arch/arm/kernel/setup.c +1
-0@@ -36,6 +36,7 @@#include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> +#include <asm/io.h>
Please always use linux/io.h in preference to asm/io.h.
arch/arm/kernel/setup.c
Quoted 4 lines
arch/arm/kernel/setup.c +4
-0+static inline pmd_t *__init early_ioremap_pmd (unsigned long addr) +{ +unsigned int index =pgd_index (addr); +pgd_t *pgd =cpu_get_pgd () + index;
What is the reasoning for using cpu_get_pgd() ? Is there some specific reason you want to read from the hardware register rather than using the pgd_offset_k() macro here?
arch/arm/kernel/setup.c
Quoted 2 lines
arch/arm/kernel/setup.c +2
-0+void __init +early_ioremap_shutdown (void )
Nit: should be a single line.
The rest of the patch looks fine, thanks.
Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly improving, and getting towards what was expected from it.
PATCH 2/2 arm: add early_ioremap support
Hi Russell,
Quoted 7 lines · Russell King - ARM Linux
Review
Quoted 4 lines · Leif Lindholm
(quoted diff) +4
-0+config EARLY_IOREMAP + depends on MMU + bool "Provide early_ioremap() support for kernel initialization." + select GENERIC_EARLY_IOREMAPNit: please order as bool, then depends, then select.
Fixed in attached.
Quoted 11 lines
arch/arm/kernel/setup.c line 39
Quoted 9 lines
arch/arm/kernel/setup.c +1
-0@@ -36,6 +36,7 @@#include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> +#include <asm/io.h> Please always use
linux/io.hin preference toasm/io.h.
Fixed in attached.
Quoted 8 lines
arch/arm/kernel/setup.c
Quoted 4 lines
arch/arm/kernel/setup.c +4
-0+static inline pmd_t *__init early_ioremap_pmd (unsigned long addr) +{ +unsigned int index =pgd_index (addr); +pgd_t *pgd =cpu_get_pgd () + index;What is the reasoning for using
cpu_get_pgd()? Is there some specific reason you want to read from the hardware register rather than using thepgd_offset_k()macro here?
No, merely picked the wrong interface, and it seemed to work. Fixed in attached.
Quoted 4 lines
arch/arm/kernel/setup.c
Quoted 2 lines
arch/arm/kernel/setup.c +2
-0+void __init +early_ioremap_shutdown (void )Nit: should be a single line.
Fixed in attached.
Quoted 1 line
The rest of the patch looks fine, thanks.
Thank you for your comments.
/
Leif
Quoted 1 line
From
6937e88fc0bc62e125d891889334b6659f2efd28Mon Sep 17 00:00:00 2001
From: Mark Salter <[email protected]>
Date: Wed, 27 Nov 2013 10:21:11 -0500
Subject: [PATCH 2/2] arm: add early_ioremap support
This patch uses the generic early_ioremap code to implement early_ioremap for ARM. The ARM-specific bits come mostly from an earlier patch from Leif Lindholm <[email protected]> here:
https://lkml.org/lkml/2013/10/3/279
--- arch/arm/Kconfig | 11 ++++++ arch/arm/include/asm/Kbuild | 1 + arch/arm/include/asm/io.h | 1 + arch/arm/kernel/setup.c | 3 ++ arch/arm/mm/Makefile | 1 + arch/arm/mm/early_ioremap.c | 84 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 2 ++ 7 files changed, 103 insertions(+) create mode 100644 arch/arm/mm/early_ioremap.c
arch/arm/Kconfig +11 -0
@@ -1800,6 +1800,17 @@ config UACCESS_WITH_MEMCPY However, if the CPU data cache is using a write-allocate mode, this option is unlikely to provide any performance gain. +config EARLY_IOREMAP + bool "Provide early_ioremap() support for kernel initialization." + depends on MMU + select GENERIC_EARLY_IOREMAP + help + Provide a mechanism for kernel initialisation code to temporarily + map, in a highmem-agnostic way, memory pages in before ioremap() + and friends are available (before paging_init() has run). It uses + the same virtual memory range as kmap so all early mappings must + be unmapped before paging_init() is called. + config SECCOMP bool prompt "Enable seccomp to safely compute untrusted bytecode"
arch/arm/include/asm/Kbuild +1 -0
@@ -4,6 +4,7 @@ generic-y += auxvec.h generic-y += bitsperlong.h generic-y += cputime.h generic-y += current.h +generic-y += early_ioremap.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h
arch/arm/include/asm/io.h +1 -0
@@ -28,6 +28,7 @@#include <asm/byteorder.h> #include <asm/memory.h> #include <asm-generic/pci_iomap.h> +#include <asm/early_ioremap.h> #include <xen/xen.h> /*
arch/arm/kernel/setup.c +3 -0
@@ -30,6 +30,7 @@#include <linux/bug.h> #include <linux/compiler.h> #include <linux/sort.h> +#include <linux/io.h> #include <asm/unified.h> #include <asm/cp15.h>
@@ -894,6 +895,8 @@ void __init setup_arch(char **cmdline_p)parse_early_param (); +early_ioremap_init (); +early_paging_init (mdesc,lookup_processor_type (read_cpuid_id ()));setup_dma_zone (mdesc);sanity_check_meminfo ();
arch/arm/mm/Makefile +1 -0
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARM_PTDUMP) += dump.o obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o +obj-$(CONFIG_EARLY_IOREMAP) += early_ioremap.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
arch/arm/mm/early_ioremap.c new file +84 -0
84 lines not on this page · raw message
arch/arm/mm/mmu.c +2 -0
@@ -36,6 +36,7 @@#include <asm/mach/map.h> #include <asm/mach/pci.h> #include <asm/fixmap.h> +#include <asm/early_ioremap.h> #include "mm.h" #include "tcm.h"
@@ -1474,6 +1475,7 @@ void __init paging_init(const struct machine_desc *mdesc) {void *zero_page; +early_ioremap_reset ();build_mem_type_table ();prepare_page_table ();map_lowmem ();
Signature · 1 line
1.7.10.4
PATCH 2/2 arm: add early_ioremap support
In reply to Leif LindholmHi Leif,
Quoted 8 lines · Leif Lindholm
From: Mark Salter <[email protected]>
This patch uses the generic
early_ioremapcode to implementearly_ioremapfor ARM. The ARM-specific bits come mostly from an earlier patch from Leif Lindholm <[email protected]> here:
[snip]
arch/arm/mm/early_ioremap.c line 6
Quoted 12 lines
arch/arm/mm/early_ioremap.c new file +6
-0@@ -0,0 +1,86 @@ +/* +* early_ioremap() support for ARM +* +* Based on existing support in arch/x86/mm/ioremap.c +* +* Restrictions: currently only functional before paging_init()
Uhm, that's bad... This would explain why my earlycon code generates a fault as soon as something prints after paging_init(). I'd say this feature would be much more useful if mappings were carried over paging_init(), so that mapped devices are available later as well.
I'll see if I can code this on top of your patch, but unfortunately it might end up with -ENOTIME.
Best regards,
Tomasz
PATCH 2/2 arm: add early_ioremap support
Quoted 32 lines · Tomasz Figa
Hi Leif,
Quoted 8 lines · Leif Lindholm
From: Mark Salter <[email protected]>
This patch uses the generic
early_ioremapcode to implementearly_ioremapfor ARM. The ARM-specific bits come mostly from an earlier patch from Leif Lindholm <[email protected]> here:[snip]
arch/arm/mm/early_ioremap.c line 6
Quoted 12 lines
arch/arm/mm/early_ioremap.c new file +6
-0@@ -0,0 +1,86 @@ +/* +* early_ioremap() support for ARM +* +* Based on existing support in arch/x86/mm/ioremap.c +* +* Restrictions: currently only functional before paging_init() Uhm, that's bad... This would explain why my earlycon code generates a fault as soon as something prints after
paging_init(). I'd say this feature would be much more useful if mappings were carried overpaging_init(), so that mapped devices are available later as well.
Quoted 2 lines
I'll see if I can code this on top of your patch, but unfortunately it might end up with
-ENOTIME.
I have fixmap support that's needed for earlycon. Here is the branch:
git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git fixmap
It is based on an earlier version of patchset and not on the latest version from Leif. Unfortunately, I don't have more time to spend on it ATM.
Rob
PATCH 2/2 arm: add early_ioremap support
Quoted 36 lines · Rob Herring
Quoted 32 lines · Tomasz Figa
Hi Leif,
Quoted 8 lines · Leif Lindholm
From: Mark Salter <[email protected]>
This patch uses the generic
early_ioremapcode to implementearly_ioremapfor ARM. The ARM-specific bits come mostly from an earlier patch from Leif Lindholm <[email protected]> here:[snip]
arch/arm/mm/early_ioremap.c line 6
Quoted 12 lines
arch/arm/mm/early_ioremap.c new file +6
-0@@ -0,0 +1,86 @@ +/* +* early_ioremap() support for ARM +* +* Based on existing support in arch/x86/mm/ioremap.c +* +* Restrictions: currently only functional before paging_init() Uhm, that's bad... This would explain why my earlycon code generates a fault as soon as something prints after
paging_init(). I'd say this feature would be much more useful if mappings were carried overpaging_init(), so that mapped devices are available later as well.Quoted 2 lines
I'll see if I can code this on top of your patch, but unfortunately it might end up with
-ENOTIME.
Quoted 7 lines
I have fixmap support that's needed for earlycon. Here is the branch:
git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.gitfixmapIt is based on an earlier version of patchset and not on the latest version from Leif. Unfortunately, I don't have more time to spend on it ATM.
Thanks Rob. I'll give it a try.
Best regards,
Tomasz
cover arm: add early_ioremap support
In reply to Leif LindholmQuoted 3 lines · Leif Lindholm
early_ioremap()/early_memremap() create temporary virtual mappings in the fixmap region during boot time. Part of the support now exists in core code, but depends on the generic fixmap support.
Does this mean that the changes upon which this patch depends are already merged in mainline, or are they queued in some other tree?
Thanks.
Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly improving, and getting towards what was expected from it.
cover arm: add early_ioremap support
Quoted 7 lines · Russell King - ARM Linux
Quoted 3 lines · Leif Lindholm
early_ioremap()/early_memremap() create temporary virtual mappings in the fixmap region during boot time. Part of the support now exists in core code, but depends on the generic fixmap support.
Does this mean that the changes upon which this patch depends are already merged in mainline, or are they queued in some other tree?
Yes, they went into 3.15.
/
Leif
cover arm: add early_ioremap support
In reply to Leif LindholmQuoted 11 lines · Leif Lindholm
early_ioremap()/early_memremap() create temporary virtual mappings in the fixmap region during boot time. Part of the support now exists in core code, but depends on the generic fixmap support.
This set converts arm to use the generic fixmap support, and adds the architecture-specific part of
early_ioremapsupport.The fixmap/kmap changes in 3.15 complicated things slightly compared to previous iterations of these patches - this version works around that by introducing local macros in
arm/mm/highmem.c.
Quoted 5 lines
Tested on TC2 and software models, with/without LPAE.
Mark Salter (2):
arm: use genericfixmap.h
arm: addearly_ioremapsupport
Curious: why are you sending these patches instead of Mark?
Will
cover arm: add early_ioremap support
Quoted 12 lines · Will Deacon
Quoted 11 lines · Leif Lindholm
early_ioremap()/early_memremap() create temporary virtual mappings in the fixmap region during boot time. Part of the support now exists in core code, but depends on the generic fixmap support.
This set converts arm to use the generic fixmap support, and adds the architecture-specific part of
early_ioremapsupport.The fixmap/kmap changes in 3.15 complicated things slightly compared to previous iterations of these patches - this version works around that by introducing local macros in
arm/mm/highmem.c.
Quoted 7 lines
Quoted 5 lines
Tested on TC2 and software models, with/without LPAE.
Mark Salter (2):
arm: use genericfixmap.h
arm: addearly_ioremapsupportCurious: why are you sending these patches instead of Mark?
Well, it used to form part of the larger UEFI patchset, which I'm still marshalling the 32-bit parts of (and which will follow later, but I will treat them separately from here on).
Also, I did the hacky rework to Mark's original patches for the kmap changes.
/
Leif