* [PATCH 0/2] arm: add early_ioremap support @ 2014-07-09 9:39 Leif Lindholm 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm ` (3 more replies) 0 siblings, 4 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 9:39 UTC (permalink / raw) To: linux-arm-kernel 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 -- 1.7.10.4 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/2] arm: use generic fixmap.h 2014-07-09 9:39 [PATCH 0/2] arm: add early_ioremap support Leif Lindholm @ 2014-07-09 9:39 ` Leif Lindholm 2014-07-09 20:49 ` Mark Salter 2014-07-22 16:39 ` Tomasz Figa 2014-07-09 9:39 ` [PATCH 2/2] arm: add early_ioremap support Leif Lindholm ` (2 subsequent siblings) 3 siblings, 2 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 9:39 UTC (permalink / raw) To: linux-arm-kernel From: Mark Salter <msalter@redhat.com> 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. Signed-off-by: Mark Salter <msalter@redhat.com> [Rebased to 3.16-rc4, reverse kmap fixmap traversal] Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> --- 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(-) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 74124b0..8992431 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -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 diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 45aeaac..3c59cdf 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -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 diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 659c75d..ad82c05 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -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 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 1/2] arm: use generic fixmap.h 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm @ 2014-07-09 20:49 ` Mark Salter 2014-07-18 14:33 ` Leif Lindholm 2014-07-22 16:39 ` Tomasz Figa 1 sibling, 1 reply; 36+ messages in thread From: Mark Salter @ 2014-07-09 20:49 UTC (permalink / raw) To: linux-arm-kernel On Wed, 2014-07-09 at 10:39 +0100, Leif Lindholm wrote: > From: Mark Salter <msalter@redhat.com> > > 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. > > Signed-off-by: Mark Salter <msalter@redhat.com> > [Rebased to 3.16-rc4, reverse kmap fixmap traversal] > Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> > --- > 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(-) > > diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h > index 74124b0..8992431 100644 > --- a/arch/arm/include/asm/fixmap.h > +++ b/arch/arm/include/asm/fixmap.h > @@ -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 > diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c > index 45aeaac..3c59cdf 100644 > --- a/arch/arm/mm/highmem.c > +++ b/arch/arm/mm/highmem.c > @@ -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) ? > +#define __kmap_virt_to_fix(x) (FIX_KMAP_NR_PTES - 1 - __fix_to_virt(x)) shouldn't this use __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 > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c > index 659c75d..ad82c05 100644 > --- a/arch/arm/mm/init.c > +++ b/arch/arm/mm/init.c > @@ -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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/2] arm: use generic fixmap.h 2014-07-09 20:49 ` Mark Salter @ 2014-07-18 14:33 ` Leif Lindholm 2014-07-25 19:56 ` Kees Cook 0 siblings, 1 reply; 36+ messages in thread From: Leif Lindholm @ 2014-07-18 14:33 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 04:49:02PM -0400, Mark Salter wrote: > On Wed, 2014-07-09 at 10:39 +0100, Leif Lindholm wrote: > > diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c > > index 45aeaac..3c59cdf 100644 > > --- a/arch/arm/mm/highmem.c > > +++ b/arch/arm/mm/highmem.c > > @@ -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) ? > > > +#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 >From d0a82cd19000139d32232f415bcf46f476c16561 Mon Sep 17 00:00:00 2001 From: Mark Salter <msalter@redhat.com> 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. Signed-off-by: Mark Salter <msalter@redhat.com> [Rebased to 3.16-rc4, reverse kmap fixmap traversal] Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> --- 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(-) diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 74124b0..8992431 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -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 diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 45aeaac..2e5b773 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -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 diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 659c75d..ad82c05 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -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 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 1/2] arm: use generic fixmap.h 2014-07-18 14:33 ` Leif Lindholm @ 2014-07-25 19:56 ` Kees Cook 0 siblings, 0 replies; 36+ messages in thread From: Kees Cook @ 2014-07-25 19:56 UTC (permalink / raw) To: linux-arm-kernel On Fri, Jul 18, 2014 at 7:33 AM, Leif Lindholm <leif.lindholm@linaro.org> wrote: > On Wed, Jul 09, 2014 at 04:49:02PM -0400, Mark Salter wrote: >> On Wed, 2014-07-09 at 10:39 +0100, Leif Lindholm wrote: >> > diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c >> > index 45aeaac..3c59cdf 100644 >> > --- a/arch/arm/mm/highmem.c >> > +++ b/arch/arm/mm/highmem.c >> > @@ -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) ? >> >> > +#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 > > From d0a82cd19000139d32232f415bcf46f476c16561 Mon Sep 17 00:00:00 2001 > From: Mark Salter <msalter@redhat.com> > 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. > > Signed-off-by: Mark Salter <msalter@redhat.com> > [Rebased to 3.16-rc4, reverse kmap fixmap traversal] > Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> > --- > 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(-) > > diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h > index 74124b0..8992431 100644 > --- a/arch/arm/include/asm/fixmap.h > +++ b/arch/arm/include/asm/fixmap.h > @@ -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 > diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c > index 45aeaac..2e5b773 100644 > --- a/arch/arm/mm/highmem.c > +++ b/arch/arm/mm/highmem.c > @@ -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 > diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c > index 659c75d..ad82c05 100644 > --- a/arch/arm/mm/init.c > +++ b/arch/arm/mm/init.c > @@ -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 > > > _______________________________________________ > 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 -- Kees Cook Chrome OS Security ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/2] arm: use generic fixmap.h 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm 2014-07-09 20:49 ` Mark Salter @ 2014-07-22 16:39 ` Tomasz Figa 1 sibling, 0 replies; 36+ messages in thread From: Tomasz Figa @ 2014-07-22 16:39 UTC (permalink / raw) To: linux-arm-kernel Hi Leif, On 09.07.2014 11:39, Leif Lindholm wrote: > From: Mark Salter <msalter@redhat.com> > > 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. > > Signed-off-by: Mark Salter <msalter@redhat.com> > [Rebased to 3.16-rc4, reverse kmap fixmap traversal] > Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> > --- > 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] > -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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-09 9:39 [PATCH 0/2] arm: add early_ioremap support Leif Lindholm 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm @ 2014-07-09 9:39 ` Leif Lindholm 2014-07-09 9:49 ` Russell King - ARM Linux 2014-07-22 16:48 ` Tomasz Figa 2014-07-09 9:42 ` [PATCH 0/2] " Russell King - ARM Linux 2014-07-09 9:47 ` Will Deacon 3 siblings, 2 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 9:39 UTC (permalink / raw) To: linux-arm-kernel From: Mark Salter <msalter@redhat.com> 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 <leif.lindholm@linaro.org> here: https://lkml.org/lkml/2013/10/3/279 Signed-off-by: Mark Salter <msalter@redhat.com> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> Tested-by: Leif Lindholm <leif.lindholm@linaro.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> CC: linux-arm-kernel at lists.infradead.org CC: Russell King <linux@arm.linux.org.uk> CC: Catalin Marinas <catalin.marinas@arm.com> CC: Will Deacon <will.deacon@arm.com> CC: Arnd Bergmann <arnd@arndb.de> --- 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 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 245058b..04b8f8a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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" diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index f5a3576..0bc5a02 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -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 diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3d23418..7b8a981 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -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> /* diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8a16ee5..aa2621a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -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(); diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 91da64d..1c8ce752 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -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 diff --git a/arch/arm/mm/early_ioremap.c b/arch/arm/mm/early_ioremap.c new file mode 100644 index 0000000..1013109 --- /dev/null +++ b/arch/arm/mm/early_ioremap.c @@ -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() + */ + +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/fixmap.h> +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +#include <asm/mach/map.h> + +static pte_t bm_pte[PTRS_PER_PTE] __aligned(PTE_HWTABLE_SIZE) __initdata; + +static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) +{ + unsigned int index = pgd_index(addr); + pgd_t *pgd = cpu_get_pgd() + index; + pud_t *pud = pud_offset(pgd, addr); + pmd_t *pmd = pmd_offset(pud, addr); + + return pmd; +} + +static inline pte_t * __init early_ioremap_pte(unsigned long addr) +{ + return &bm_pte[pte_index(addr)]; +} + +void __init early_ioremap_init(void) +{ + pmd_t *pmd; + + pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); + pmd_populate_kernel(NULL, pmd, bm_pte); + + if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) { + WARN_ON(1); + pr_warn("pmd %p != %p\n", + pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))); + pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", + fix_to_virt(FIX_BTMAP_BEGIN)); + pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n", + fix_to_virt(FIX_BTMAP_END)); + pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END); + pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN); + } + + early_ioremap_setup(); +} + +void __init __early_set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t flags) +{ + unsigned long addr = __fix_to_virt(idx); + pte_t *pte; + u64 desc; + + if (idx > FIX_KMAP_END) { + BUG(); + return; + } + pte = early_ioremap_pte(addr); + + if (pgprot_val(flags)) + set_pte_at(NULL, addr, pte, + pfn_pte(phys >> PAGE_SHIFT, flags)); + else + pte_clear(NULL, addr, pte); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + desc = *pte; +} + +void __init +early_ioremap_shutdown(void) +{ + pmd_t *pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); + + pmd_clear(pmd); +} diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index ab14b79..608dc36 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -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(); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-09 9:39 ` [PATCH 2/2] arm: add early_ioremap support Leif Lindholm @ 2014-07-09 9:49 ` Russell King - ARM Linux 2014-07-09 11:48 ` Leif Lindholm 2014-07-22 16:48 ` Tomasz Figa 1 sibling, 1 reply; 36+ messages in thread From: Russell King - ARM Linux @ 2014-07-09 9:49 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 10:39:52AM +0100, Leif Lindholm wrote: > +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. > diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c > index 8a16ee5..aa2621a 100644 > --- a/arch/arm/kernel/setup.c > +++ b/arch/arm/kernel/setup.c > @@ -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. > +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? > +void __init > +early_ioremap_shutdown(void) Nit: should be a single line. The rest of the patch looks fine, thanks. -- FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly improving, and getting towards what was expected from it. ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-09 9:49 ` Russell King - ARM Linux @ 2014-07-09 11:48 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 11:48 UTC (permalink / raw) To: linux-arm-kernel Hi Russell, On Wed, Jul 09, 2014 at 10:49:26AM +0100, Russell King - ARM Linux wrote: > On Wed, Jul 09, 2014 at 10:39:52AM +0100, Leif Lindholm wrote: > > +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. Fixed in attached. > > diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c > > index 8a16ee5..aa2621a 100644 > > --- a/arch/arm/kernel/setup.c > > +++ b/arch/arm/kernel/setup.c > > @@ -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. Fixed in attached. > > +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? No, merely picked the wrong interface, and it seemed to work. Fixed in attached. > > +void __init > > +early_ioremap_shutdown(void) > > Nit: should be a single line. Fixed in attached. > The rest of the patch looks fine, thanks. Thank you for your comments. / Leif >From 6937e88fc0bc62e125d891889334b6659f2efd28 Mon Sep 17 00:00:00 2001 From: Mark Salter <msalter@redhat.com> 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 <leif.lindholm@linaro.org> here: https://lkml.org/lkml/2013/10/3/279 Signed-off-by: Mark Salter <msalter@redhat.com> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org> Tested-by: Leif Lindholm <leif.lindholm@linaro.org> Acked-by: Catalin Marinas <catalin.marinas@arm.com> CC: linux-arm-kernel at lists.infradead.org CC: Russell King <linux@arm.linux.org.uk> CC: Catalin Marinas <catalin.marinas@arm.com> CC: Will Deacon <will.deacon@arm.com> CC: Arnd Bergmann <arnd@arndb.de> --- 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 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 245058b..5ddafaf 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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" diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index f5a3576..0bc5a02 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -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 diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3d23418..7b8a981 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -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> /* diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8a16ee5..b1f397c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -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(); diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 91da64d..1c8ce752 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -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 diff --git a/arch/arm/mm/early_ioremap.c b/arch/arm/mm/early_ioremap.c new file mode 100644 index 0000000..6444454 --- /dev/null +++ b/arch/arm/mm/early_ioremap.c @@ -0,0 +1,84 @@ +/* + * early_ioremap() support for ARM + * + * Based on existing support in arch/x86/mm/ioremap.c + * + * Restrictions: currently only functional before paging_init() + */ + +#include <linux/init.h> +#include <linux/io.h> + +#include <asm/fixmap.h> +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +#include <asm/mach/map.h> + +static pte_t bm_pte[PTRS_PER_PTE] __aligned(PTE_HWTABLE_SIZE) __initdata; + +static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) +{ + pgd_t *pgd = pgd_offset_k(addr); + pud_t *pud = pud_offset(pgd, addr); + pmd_t *pmd = pmd_offset(pud, addr); + + return pmd; +} + +static inline pte_t * __init early_ioremap_pte(unsigned long addr) +{ + return &bm_pte[pte_index(addr)]; +} + +void __init early_ioremap_init(void) +{ + pmd_t *pmd; + + pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); + pmd_populate_kernel(NULL, pmd, bm_pte); + + if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) { + WARN_ON(1); + pr_warn("pmd %p != %p\n", + pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))); + pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n", + fix_to_virt(FIX_BTMAP_BEGIN)); + pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n", + fix_to_virt(FIX_BTMAP_END)); + pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END); + pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN); + } + + early_ioremap_setup(); +} + +void __init __early_set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t flags) +{ + unsigned long addr = __fix_to_virt(idx); + pte_t *pte; + u64 desc; + + if (idx > FIX_KMAP_END) { + BUG(); + return; + } + pte = early_ioremap_pte(addr); + + if (pgprot_val(flags)) + set_pte_at(NULL, addr, pte, + pfn_pte(phys >> PAGE_SHIFT, flags)); + else + pte_clear(NULL, addr, pte); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE); + desc = *pte; +} + +void __init early_ioremap_shutdown(void) +{ + pmd_t *pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); + + pmd_clear(pmd); +} diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index ab14b79..608dc36 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -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(); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-09 9:39 ` [PATCH 2/2] arm: add early_ioremap support Leif Lindholm 2014-07-09 9:49 ` Russell King - ARM Linux @ 2014-07-22 16:48 ` Tomasz Figa 2014-07-22 17:11 ` Rob Herring 1 sibling, 1 reply; 36+ messages in thread From: Tomasz Figa @ 2014-07-22 16:48 UTC (permalink / raw) To: linux-arm-kernel Hi Leif, On 09.07.2014 11:39, Leif Lindholm wrote: > From: Mark Salter <msalter@redhat.com> > > 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 <leif.lindholm@linaro.org> > here: > > https://lkml.org/lkml/2013/10/3/279 [snip] > diff --git a/arch/arm/mm/early_ioremap.c b/arch/arm/mm/early_ioremap.c > new file mode 100644 > index 0000000..1013109 > --- /dev/null > +++ b/arch/arm/mm/early_ioremap.c > @@ -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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-22 16:48 ` Tomasz Figa @ 2014-07-22 17:11 ` Rob Herring 2014-07-22 17:27 ` Tomasz Figa 0 siblings, 1 reply; 36+ messages in thread From: Rob Herring @ 2014-07-22 17:11 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jul 22, 2014 at 11:48 AM, Tomasz Figa <t.figa@samsung.com> wrote: > Hi Leif, > > On 09.07.2014 11:39, Leif Lindholm wrote: >> From: Mark Salter <msalter@redhat.com> >> >> 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 <leif.lindholm@linaro.org> >> here: >> >> https://lkml.org/lkml/2013/10/3/279 > > [snip] > >> diff --git a/arch/arm/mm/early_ioremap.c b/arch/arm/mm/early_ioremap.c >> new file mode 100644 >> index 0000000..1013109 >> --- /dev/null >> +++ b/arch/arm/mm/early_ioremap.c >> @@ -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. 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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 2/2] arm: add early_ioremap support 2014-07-22 17:11 ` Rob Herring @ 2014-07-22 17:27 ` Tomasz Figa 0 siblings, 0 replies; 36+ messages in thread From: Tomasz Figa @ 2014-07-22 17:27 UTC (permalink / raw) To: linux-arm-kernel On 22.07.2014 19:11, Rob Herring wrote: > On Tue, Jul 22, 2014 at 11:48 AM, Tomasz Figa <t.figa@samsung.com> wrote: >> Hi Leif, >> >> On 09.07.2014 11:39, Leif Lindholm wrote: >>> From: Mark Salter <msalter@redhat.com> >>> >>> 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 <leif.lindholm@linaro.org> >>> here: >>> >>> https://lkml.org/lkml/2013/10/3/279 >> >> [snip] >> >>> diff --git a/arch/arm/mm/early_ioremap.c b/arch/arm/mm/early_ioremap.c >>> new file mode 100644 >>> index 0000000..1013109 >>> --- /dev/null >>> +++ b/arch/arm/mm/early_ioremap.c >>> @@ -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. > > 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. Thanks Rob. I'll give it a try. Best regards, Tomasz ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap support 2014-07-09 9:39 [PATCH 0/2] arm: add early_ioremap support Leif Lindholm 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm 2014-07-09 9:39 ` [PATCH 2/2] arm: add early_ioremap support Leif Lindholm @ 2014-07-09 9:42 ` Russell King - ARM Linux 2014-07-09 9:58 ` Leif Lindholm 2014-07-09 9:47 ` Will Deacon 3 siblings, 1 reply; 36+ messages in thread From: Russell King - ARM Linux @ 2014-07-09 9:42 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 10:39:50AM +0100, Leif Lindholm wrote: > 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. -- FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly improving, and getting towards what was expected from it. ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap support 2014-07-09 9:42 ` [PATCH 0/2] " Russell King - ARM Linux @ 2014-07-09 9:58 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 9:58 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 10:42:42AM +0100, Russell King - ARM Linux wrote: > On Wed, Jul 09, 2014 at 10:39:50AM +0100, Leif Lindholm wrote: > > 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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap support 2014-07-09 9:39 [PATCH 0/2] arm: add early_ioremap support Leif Lindholm ` (2 preceding siblings ...) 2014-07-09 9:42 ` [PATCH 0/2] " Russell King - ARM Linux @ 2014-07-09 9:47 ` Will Deacon 2014-07-09 10:02 ` Leif Lindholm 3 siblings, 1 reply; 36+ messages in thread From: Will Deacon @ 2014-07-09 9:47 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 10:39:50AM +0100, Leif Lindholm wrote: > 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 Curious: why are you sending these patches instead of Mark? Will ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap support 2014-07-09 9:47 ` Will Deacon @ 2014-07-09 10:02 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2014-07-09 10:02 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jul 09, 2014 at 10:47:30AM +0100, Will Deacon wrote: > On Wed, Jul 09, 2014 at 10:39:50AM +0100, Leif Lindholm wrote: > > 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 > > Curious: 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 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-25 17:46 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-25 17:46 UTC (permalink / raw) To: linux-arm-kernel; +Cc: linux-doc, linux-kernel, patches, nico, Leif Lindholm x86 and ia64 have the early_ioremap()/early_iounmap() functions, which are useful for supporting things like UEFI, ACPI and SMBIOS, where configuration tables need to be parsed before proper memory management is available, regardless of highmem status. This patchset implements a restricted form of early_ioremap(), available before paging_init() only. Like the x86 code on which it is based, it (p)re-uses the fixmap regions for its virtual mapping range. Up to 7 simultaneous mappings of up to 128KB can be accommodated in the available fixmap space. Leif Lindholm (2): Documentation: arm: early_ioremap arm: add early_ioremap support Documentation/arm/00-INDEX | 2 + Documentation/arm/early_ioremap.txt | 12 ++ arch/arm/Kconfig | 7 + arch/arm/include/asm/fixmap.h | 31 +++- arch/arm/include/asm/io.h | 13 ++ arch/arm/kernel/setup.c | 3 + arch/arm/mm/Makefile | 1 + arch/arm/mm/early_ioremap.c | 273 +++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 2 + 9 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 Documentation/arm/early_ioremap.txt create mode 100644 arch/arm/mm/early_ioremap.c -- 1.7.10.4 ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-25 17:46 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-25 17:46 UTC (permalink / raw) To: linux-arm-kernel x86 and ia64 have the early_ioremap()/early_iounmap() functions, which are useful for supporting things like UEFI, ACPI and SMBIOS, where configuration tables need to be parsed before proper memory management is available, regardless of highmem status. This patchset implements a restricted form of early_ioremap(), available before paging_init() only. Like the x86 code on which it is based, it (p)re-uses the fixmap regions for its virtual mapping range. Up to 7 simultaneous mappings of up to 128KB can be accommodated in the available fixmap space. Leif Lindholm (2): Documentation: arm: early_ioremap arm: add early_ioremap support Documentation/arm/00-INDEX | 2 + Documentation/arm/early_ioremap.txt | 12 ++ arch/arm/Kconfig | 7 + arch/arm/include/asm/fixmap.h | 31 +++- arch/arm/include/asm/io.h | 13 ++ arch/arm/kernel/setup.c | 3 + arch/arm/mm/Makefile | 1 + arch/arm/mm/early_ioremap.c | 273 +++++++++++++++++++++++++++++++++++ arch/arm/mm/mmu.c | 2 + 9 files changed, 342 insertions(+), 2 deletions(-) create mode 100644 Documentation/arm/early_ioremap.txt create mode 100644 arch/arm/mm/early_ioremap.c -- 1.7.10.4 ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-25 17:46 ` Leif Lindholm @ 2013-06-26 18:52 ` Arnd Bergmann -1 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 18:52 UTC (permalink / raw) To: linux-arm-kernel Cc: Leif Lindholm, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Tuesday 25 June 2013, Leif Lindholm wrote: > x86 and ia64 have the early_ioremap()/early_iounmap() functions, which are > useful for supporting things like UEFI, ACPI and SMBIOS, where configuration > tables need to be parsed before proper memory management is available, > regardless of highmem status. > > This patchset implements a restricted form of early_ioremap(), available > before paging_init() only. Like the x86 code on which it is based, it > (p)re-uses the fixmap regions for its virtual mapping range. Up to 7 > simultaneous mappings of up to 128KB can be accommodated in the available > fixmap space. +rmk I made a similar suggestion to extending the use of fixmap recently, see "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that fixmap is intentionally limited to just kmap_atomic uses at the moment and changing that would potentially have a significant impact when we run out of pages in the fixmap area. The method we use on ARM normally is the iotable_init() function, which requires hardcoding a virtual address at the moment. It might be nicer to change that code than to put early_ioremap into fixmap. Note that early_ioremap in fixmap is a bit of a kludge on x86 as well because it is very much /not/ a fixed mapping like the rest of fixmap, they just use it because it's convenient. Extending the iotable mechanism on ARM would be the convenient solution for us I think. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 18:52 ` Arnd Bergmann 0 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 18:52 UTC (permalink / raw) To: linux-arm-kernel On Tuesday 25 June 2013, Leif Lindholm wrote: > x86 and ia64 have the early_ioremap()/early_iounmap() functions, which are > useful for supporting things like UEFI, ACPI and SMBIOS, where configuration > tables need to be parsed before proper memory management is available, > regardless of highmem status. > > This patchset implements a restricted form of early_ioremap(), available > before paging_init() only. Like the x86 code on which it is based, it > (p)re-uses the fixmap regions for its virtual mapping range. Up to 7 > simultaneous mappings of up to 128KB can be accommodated in the available > fixmap space. +rmk I made a similar suggestion to extending the use of fixmap recently, see "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that fixmap is intentionally limited to just kmap_atomic uses at the moment and changing that would potentially have a significant impact when we run out of pages in the fixmap area. The method we use on ARM normally is the iotable_init() function, which requires hardcoding a virtual address at the moment. It might be nicer to change that code than to put early_ioremap into fixmap. Note that early_ioremap in fixmap is a bit of a kludge on x86 as well because it is very much /not/ a fixed mapping like the rest of fixmap, they just use it because it's convenient. Extending the iotable mechanism on ARM would be the convenient solution for us I think. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 18:52 ` Arnd Bergmann @ 2013-06-26 19:23 ` Leif Lindholm -1 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 19:23 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Wed, Jun 26, 2013 at 08:52:09PM +0200, Arnd Bergmann wrote: > I made a similar suggestion to extending the use of fixmap recently, see > "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that > fixmap is intentionally limited to just kmap_atomic uses at the moment > and changing that would potentially have a significant impact when we > run out of pages in the fixmap area. Is this an issue here, since (unlike x86) this early_ioremap only works before paging_init()? > The method we use on ARM normally is the iotable_init() function, which > requires hardcoding a virtual address at the moment. > > It might be nicer to change that code than to put early_ioremap into > fixmap. Note that early_ioremap in fixmap is a bit of a kludge on x86 > as well because it is very much /not/ a fixed mapping like the rest > of fixmap, they just use it because it's convenient. Yes, but they also only use it (at least the bits where I looked) for temporary mappings very early in the boot process. That is certainly how I use it. So at least my intention was to use it before kmap is even available. > Extending the iotable mechanism on ARM would be the convenient > solution for us I think. Could that easily be extended to give similar semantics sufficiently that we can progress with merging more of the UEFI and ACPI support together as common code with x86/ia64? / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 19:23 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 19:23 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 26, 2013 at 08:52:09PM +0200, Arnd Bergmann wrote: > I made a similar suggestion to extending the use of fixmap recently, see > "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that > fixmap is intentionally limited to just kmap_atomic uses at the moment > and changing that would potentially have a significant impact when we > run out of pages in the fixmap area. Is this an issue here, since (unlike x86) this early_ioremap only works before paging_init()? > The method we use on ARM normally is the iotable_init() function, which > requires hardcoding a virtual address at the moment. > > It might be nicer to change that code than to put early_ioremap into > fixmap. Note that early_ioremap in fixmap is a bit of a kludge on x86 > as well because it is very much /not/ a fixed mapping like the rest > of fixmap, they just use it because it's convenient. Yes, but they also only use it (at least the bits where I looked) for temporary mappings very early in the boot process. That is certainly how I use it. So at least my intention was to use it before kmap is even available. > Extending the iotable mechanism on ARM would be the convenient > solution for us I think. Could that easily be extended to give similar semantics sufficiently that we can progress with merging more of the UEFI and ACPI support together as common code with x86/ia64? / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 19:23 ` Leif Lindholm @ 2013-06-26 21:23 ` Arnd Bergmann -1 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 21:23 UTC (permalink / raw) To: Leif Lindholm Cc: linux-arm-kernel, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Wednesday 26 June 2013, Leif Lindholm wrote: > On Wed, Jun 26, 2013 at 08:52:09PM +0200, Arnd Bergmann wrote: > > I made a similar suggestion to extending the use of fixmap recently, see > > "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that > > fixmap is intentionally limited to just kmap_atomic uses at the moment > > and changing that would potentially have a significant impact when we > > run out of pages in the fixmap area. > > Is this an issue here, since (unlike x86) this early_ioremap only works > before paging_init()? The main problem is that the total fixmap size is only around 900kb, and we want to reserve at least 64kb per cpu for kmap_atomic. If you want to fit multiple 128kb mappings in there, you run out of space really fast. > > Extending the iotable mechanism on ARM would be the convenient > > solution for us I think. > > Could that easily be extended to give similar semantics sufficiently > that we can progress with merging more of the UEFI and ACPI support > together as common code with x86/ia64? I don't know what the requirements are, but the idea with iotable is that the mappings stay around at run time, while it seems you want to discard them at some point. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 21:23 ` Arnd Bergmann 0 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 21:23 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 26 June 2013, Leif Lindholm wrote: > On Wed, Jun 26, 2013 at 08:52:09PM +0200, Arnd Bergmann wrote: > > I made a similar suggestion to extending the use of fixmap recently, see > > "Re: SCU registers mapping for CA9/CA5 cores". Russell pointed out that > > fixmap is intentionally limited to just kmap_atomic uses at the moment > > and changing that would potentially have a significant impact when we > > run out of pages in the fixmap area. > > Is this an issue here, since (unlike x86) this early_ioremap only works > before paging_init()? The main problem is that the total fixmap size is only around 900kb, and we want to reserve at least 64kb per cpu for kmap_atomic. If you want to fit multiple 128kb mappings in there, you run out of space really fast. > > Extending the iotable mechanism on ARM would be the convenient > > solution for us I think. > > Could that easily be extended to give similar semantics sufficiently > that we can progress with merging more of the UEFI and ACPI support > together as common code with x86/ia64? I don't know what the requirements are, but the idea with iotable is that the mappings stay around at run time, while it seems you want to discard them at some point. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 21:23 ` Arnd Bergmann @ 2013-06-26 21:34 ` Leif Lindholm -1 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 21:34 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Wed, Jun 26, 2013 at 11:23:50PM +0200, Arnd Bergmann wrote: > > Is this an issue here, since (unlike x86) this early_ioremap only works > > before paging_init()? > > The main problem is that the total fixmap size is only around 900kb, > and we want to reserve at least 64kb per cpu for kmap_atomic. > If you want to fit multiple 128kb mappings in there, you run out of > space really fast. Sorry, I still don't get it. Are you saying that kmap_atomic is available before kmap_init() (in paging_init())? If not, all of my mappings are discarded (well, abandoned to be more correct), so I don't see how it affects kmap. > > > Extending the iotable mechanism on ARM would be the convenient > > > solution for us I think. > > > > Could that easily be extended to give similar semantics sufficiently > > that we can progress with merging more of the UEFI and ACPI support > > together as common code with x86/ia64? > > I don't know what the requirements are, but the idea with iotable > is that the mappings stay around at run time, while it seems you want > to discard them at some point. Indeed - almost immediately. x86 early_ioremap can coexist with kmap; the intent of my implementation is to use the kmap region only before kmap is available. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 21:34 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 21:34 UTC (permalink / raw) To: linux-arm-kernel On Wed, Jun 26, 2013 at 11:23:50PM +0200, Arnd Bergmann wrote: > > Is this an issue here, since (unlike x86) this early_ioremap only works > > before paging_init()? > > The main problem is that the total fixmap size is only around 900kb, > and we want to reserve at least 64kb per cpu for kmap_atomic. > If you want to fit multiple 128kb mappings in there, you run out of > space really fast. Sorry, I still don't get it. Are you saying that kmap_atomic is available before kmap_init() (in paging_init())? If not, all of my mappings are discarded (well, abandoned to be more correct), so I don't see how it affects kmap. > > > Extending the iotable mechanism on ARM would be the convenient > > > solution for us I think. > > > > Could that easily be extended to give similar semantics sufficiently > > that we can progress with merging more of the UEFI and ACPI support > > together as common code with x86/ia64? > > I don't know what the requirements are, but the idea with iotable > is that the mappings stay around at run time, while it seems you want > to discard them at some point. Indeed - almost immediately. x86 early_ioremap can coexist with kmap; the intent of my implementation is to use the kmap region only before kmap is available. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 21:34 ` Leif Lindholm @ 2013-06-26 22:13 ` Arnd Bergmann -1 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 22:13 UTC (permalink / raw) To: Leif Lindholm Cc: linux-arm-kernel, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Wednesday 26 June 2013, Leif Lindholm wrote: > On Wed, Jun 26, 2013 at 11:23:50PM +0200, Arnd Bergmann wrote: > > > Is this an issue here, since (unlike x86) this early_ioremap only works > > > before paging_init()? > > > > The main problem is that the total fixmap size is only around 900kb, > > and we want to reserve at least 64kb per cpu for kmap_atomic. > > If you want to fit multiple 128kb mappings in there, you run out of > > space really fast. > > Sorry, I still don't get it. Are you saying that kmap_atomic is > available before kmap_init() (in paging_init())? > > If not, all of my mappings are discarded (well, abandoned to be more > correct), so I don't see how it affects kmap. Sorry, I was under the assumption that the mappings are meant to stay around. > > > > Extending the iotable mechanism on ARM would be the convenient > > > > solution for us I think. > > > > > > Could that easily be extended to give similar semantics sufficiently > > > that we can progress with merging more of the UEFI and ACPI support > > > together as common code with x86/ia64? > > > > I don't know what the requirements are, but the idea with iotable > > is that the mappings stay around at run time, while it seems you want > > to discard them at some point. > > Indeed - almost immediately. > > x86 early_ioremap can coexist with kmap; the intent of my > implementation is to use the kmap region only before kmap is available. So if you never plan to use fixmap and early_ioremap at the same time, why even bother using the fixmap code? Wouldn't it be easier to just use the same memory area and ensure we never use fixmap before we're done with early_ioremap? Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 22:13 ` Arnd Bergmann 0 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-26 22:13 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 26 June 2013, Leif Lindholm wrote: > On Wed, Jun 26, 2013 at 11:23:50PM +0200, Arnd Bergmann wrote: > > > Is this an issue here, since (unlike x86) this early_ioremap only works > > > before paging_init()? > > > > The main problem is that the total fixmap size is only around 900kb, > > and we want to reserve at least 64kb per cpu for kmap_atomic. > > If you want to fit multiple 128kb mappings in there, you run out of > > space really fast. > > Sorry, I still don't get it. Are you saying that kmap_atomic is > available before kmap_init() (in paging_init())? > > If not, all of my mappings are discarded (well, abandoned to be more > correct), so I don't see how it affects kmap. Sorry, I was under the assumption that the mappings are meant to stay around. > > > > Extending the iotable mechanism on ARM would be the convenient > > > > solution for us I think. > > > > > > Could that easily be extended to give similar semantics sufficiently > > > that we can progress with merging more of the UEFI and ACPI support > > > together as common code with x86/ia64? > > > > I don't know what the requirements are, but the idea with iotable > > is that the mappings stay around at run time, while it seems you want > > to discard them at some point. > > Indeed - almost immediately. > > x86 early_ioremap can coexist with kmap; the intent of my > implementation is to use the kmap region only before kmap is available. So if you never plan to use fixmap and early_ioremap at the same time, why even bother using the fixmap code? Wouldn't it be easier to just use the same memory area and ensure we never use fixmap before we're done with early_ioremap? Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 22:13 ` Arnd Bergmann @ 2013-06-26 23:25 ` Leif Lindholm -1 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 23:25 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, nico, patches, linux-kernel, linux-doc, Russell King - ARM Linux On Thu, Jun 27, 2013 at 12:13:55AM +0200, Arnd Bergmann wrote: > > Sorry, I still don't get it. Are you saying that kmap_atomic is > > available before kmap_init() (in paging_init())? > > > > If not, all of my mappings are discarded (well, abandoned to be more > > correct), so I don't see how it affects kmap. > > Sorry, I was under the assumption that the mappings are meant to > stay around. Ok, just so I'm not completely lost :) No, the purpose is just like for x86 - do early parsing of things like the UEFI system and configuration tables, DMI and ACPI, in order to populate global structs and stuff. > > Indeed - almost immediately. > > > > x86 early_ioremap can coexist with kmap; the intent of my > > implementation is to use the kmap region only before kmap is available. > > So if you never plan to use fixmap and early_ioremap at the same time, > why even bother using the fixmap code? Wouldn't it be easier to just > use the same memory area and ensure we never use fixmap before > we're done with early_ioremap? Well, I did have a crazy idea that much/most of the early_ioremap code could be made generic and shared between x86 and arm (and any other 32-bit architecture). Using the fixmap macros would make that possible with a minimum of ifdefs. If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() (but not beyond the "booting" system state), using the same macros would help there too. I had no need for that for my EFI patches. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-26 23:25 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-26 23:25 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jun 27, 2013 at 12:13:55AM +0200, Arnd Bergmann wrote: > > Sorry, I still don't get it. Are you saying that kmap_atomic is > > available before kmap_init() (in paging_init())? > > > > If not, all of my mappings are discarded (well, abandoned to be more > > correct), so I don't see how it affects kmap. > > Sorry, I was under the assumption that the mappings are meant to > stay around. Ok, just so I'm not completely lost :) No, the purpose is just like for x86 - do early parsing of things like the UEFI system and configuration tables, DMI and ACPI, in order to populate global structs and stuff. > > Indeed - almost immediately. > > > > x86 early_ioremap can coexist with kmap; the intent of my > > implementation is to use the kmap region only before kmap is available. > > So if you never plan to use fixmap and early_ioremap at the same time, > why even bother using the fixmap code? Wouldn't it be easier to just > use the same memory area and ensure we never use fixmap before > we're done with early_ioremap? Well, I did have a crazy idea that much/most of the early_ioremap code could be made generic and shared between x86 and arm (and any other 32-bit architecture). Using the fixmap macros would make that possible with a minimum of ifdefs. If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() (but not beyond the "booting" system state), using the same macros would help there too. I had no need for that for my EFI patches. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-26 23:25 ` Leif Lindholm @ 2013-06-27 8:47 ` Arnd Bergmann -1 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-27 8:47 UTC (permalink / raw) To: linux-arm-kernel Cc: Leif Lindholm, Russell King - ARM Linux, patches, linux-doc, linux-kernel, nico On Thursday 27 June 2013 01:25:06 Leif Lindholm wrote: > On Thu, Jun 27, 2013 at 12:13:55AM +0200, Arnd Bergmann wrote: > > > Sorry, I still don't get it. Are you saying that kmap_atomic is > > > available before kmap_init() (in paging_init())? > > > > > > If not, all of my mappings are discarded (well, abandoned to be more > > > correct), so I don't see how it affects kmap. > > > > Sorry, I was under the assumption that the mappings are meant to > > stay around. > > Ok, just so I'm not completely lost > > No, the purpose is just like for x86 - do early parsing of things like > the UEFI system and configuration tables, DMI and ACPI, in order to > populate global structs and stuff. But are those tables actually in MMIO registers? I thought they are just memory, and in that case using any form of ioremap is wrong on ARM. Why do you even have to map them? Can't the boot loader pass those tables in regular addressable memory? > > > Indeed - almost immediately. > > > > > > x86 early_ioremap can coexist with kmap; the intent of my > > > implementation is to use the kmap region only before kmap is available. > > > > So if you never plan to use fixmap and early_ioremap at the same time, > > why even bother using the fixmap code? Wouldn't it be easier to just > > use the same memory area and ensure we never use fixmap before > > we're done with early_ioremap? > > Well, I did have a crazy idea that much/most of the early_ioremap code > could be made generic and shared between x86 and arm (and any other > 32-bit architecture). Using the fixmap macros would make that possible > with a minimum of ifdefs. > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > (but not beyond the "booting" system state), using the same macros would > help there too. I had no need for that for my EFI patches. I guess I need to look at the EFI patches first. It sounds to me like you shouldn't actually be using early_ioremap here or on another architecture. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-27 8:47 ` Arnd Bergmann 0 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-27 8:47 UTC (permalink / raw) To: linux-arm-kernel On Thursday 27 June 2013 01:25:06 Leif Lindholm wrote: > On Thu, Jun 27, 2013 at 12:13:55AM +0200, Arnd Bergmann wrote: > > > Sorry, I still don't get it. Are you saying that kmap_atomic is > > > available before kmap_init() (in paging_init())? > > > > > > If not, all of my mappings are discarded (well, abandoned to be more > > > correct), so I don't see how it affects kmap. > > > > Sorry, I was under the assumption that the mappings are meant to > > stay around. > > Ok, just so I'm not completely lost > > No, the purpose is just like for x86 - do early parsing of things like > the UEFI system and configuration tables, DMI and ACPI, in order to > populate global structs and stuff. But are those tables actually in MMIO registers? I thought they are just memory, and in that case using any form of ioremap is wrong on ARM. Why do you even have to map them? Can't the boot loader pass those tables in regular addressable memory? > > > Indeed - almost immediately. > > > > > > x86 early_ioremap can coexist with kmap; the intent of my > > > implementation is to use the kmap region only before kmap is available. > > > > So if you never plan to use fixmap and early_ioremap at the same time, > > why even bother using the fixmap code? Wouldn't it be easier to just > > use the same memory area and ensure we never use fixmap before > > we're done with early_ioremap? > > Well, I did have a crazy idea that much/most of the early_ioremap code > could be made generic and shared between x86 and arm (and any other > 32-bit architecture). Using the fixmap macros would make that possible > with a minimum of ifdefs. > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > (but not beyond the "booting" system state), using the same macros would > help there too. I had no need for that for my EFI patches. I guess I need to look at the EFI patches first. It sounds to me like you shouldn't actually be using early_ioremap here or on another architecture. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-27 8:47 ` Arnd Bergmann @ 2013-06-27 9:29 ` Leif Lindholm -1 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-27 9:29 UTC (permalink / raw) To: Arnd Bergmann Cc: linux-arm-kernel, Russell King - ARM Linux, patches, linux-doc, linux-kernel, nico On Thu, Jun 27, 2013 at 10:47:21AM +0200, Arnd Bergmann wrote: > > No, the purpose is just like for x86 - do early parsing of things like > > the UEFI system and configuration tables, DMI and ACPI, in order to > > populate global structs and stuff. > > But are those tables actually in MMIO registers? I thought they > are just memory, and in that case using any form of ioremap is > wrong on ARM. Why do you even have to map them? Can't the boot > loader pass those tables in regular addressable memory? Don't get too stuck on the name - x86 frequently uses *ioremap() in many places when just accessing memory, and that has carried into EFI, ACPI and DMI subsystems, which we now want to use on ARM. In fact, they have early_memremap(), but don't use it for either EFI or ACPI. The ia64 implementation actually performs a lookup in the EFI memmap to decide whether early_ioremap() returns cacheable memory or not (and falls back to noncacheable before memory map is available). That said, I had somehow managed to get into my mind that the kernel used -fno-unaligned-access, so thought MT_DEV_NONSHARED was safe. Clearly it isn't, so that will need to change, making the semantic match even worse... As for the need of mapping - some of these descriptors are needed very early in the boot process. Also, depending on platform, they may reside at any offset from start of RAM (<2^32 physical address), rendering __va()/__phys_to_virt()/... unusable. > > Well, I did have a crazy idea that much/most of the early_ioremap code > > could be made generic and shared between x86 and arm (and any other > > 32-bit architecture). Using the fixmap macros would make that possible > > with a minimum of ifdefs. > > > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > > (but not beyond the "booting" system state), using the same macros would > > help there too. I had no need for that for my EFI patches. > > I guess I need to look at the EFI patches first. It sounds to me > like you shouldn't actually be using early_ioremap here or on another > architecture. No, but I had been kind of hoping not having to rework the early memory initialisation for three subsystems on two other platforms in order to be able to merge common code between them. And it would have felt silly to invent a new mechanism just for ARM, preventing that option. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-27 9:29 ` Leif Lindholm 0 siblings, 0 replies; 36+ messages in thread From: Leif Lindholm @ 2013-06-27 9:29 UTC (permalink / raw) To: linux-arm-kernel On Thu, Jun 27, 2013 at 10:47:21AM +0200, Arnd Bergmann wrote: > > No, the purpose is just like for x86 - do early parsing of things like > > the UEFI system and configuration tables, DMI and ACPI, in order to > > populate global structs and stuff. > > But are those tables actually in MMIO registers? I thought they > are just memory, and in that case using any form of ioremap is > wrong on ARM. Why do you even have to map them? Can't the boot > loader pass those tables in regular addressable memory? Don't get too stuck on the name - x86 frequently uses *ioremap() in many places when just accessing memory, and that has carried into EFI, ACPI and DMI subsystems, which we now want to use on ARM. In fact, they have early_memremap(), but don't use it for either EFI or ACPI. The ia64 implementation actually performs a lookup in the EFI memmap to decide whether early_ioremap() returns cacheable memory or not (and falls back to noncacheable before memory map is available). That said, I had somehow managed to get into my mind that the kernel used -fno-unaligned-access, so thought MT_DEV_NONSHARED was safe. Clearly it isn't, so that will need to change, making the semantic match even worse... As for the need of mapping - some of these descriptors are needed very early in the boot process. Also, depending on platform, they may reside at any offset from start of RAM (<2^32 physical address), rendering __va()/__phys_to_virt()/... unusable. > > Well, I did have a crazy idea that much/most of the early_ioremap code > > could be made generic and shared between x86 and arm (and any other > > 32-bit architecture). Using the fixmap macros would make that possible > > with a minimum of ifdefs. > > > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > > (but not beyond the "booting" system state), using the same macros would > > help there too. I had no need for that for my EFI patches. > > I guess I need to look at the EFI patches first. It sounds to me > like you shouldn't actually be using early_ioremap here or on another > architecture. No, but I had been kind of hoping not having to rework the early memory initialisation for three subsystems on two other platforms in order to be able to merge common code between them. And it would have felt silly to invent a new mechanism just for ARM, preventing that option. / Leif ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 0/2] arm: add early_ioremap() support 2013-06-27 9:29 ` Leif Lindholm @ 2013-06-27 11:55 ` Arnd Bergmann -1 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-27 11:55 UTC (permalink / raw) To: Leif Lindholm Cc: linux-arm-kernel, Russell King - ARM Linux, patches, linux-doc, linux-kernel, nico On Thursday 27 June 2013, Leif Lindholm wrote: > On Thu, Jun 27, 2013 at 10:47:21AM +0200, Arnd Bergmann wrote: > > > No, the purpose is just like for x86 - do early parsing of things like > > > the UEFI system and configuration tables, DMI and ACPI, in order to > > > populate global structs and stuff. > > > > But are those tables actually in MMIO registers? I thought they > > are just memory, and in that case using any form of ioremap is > > wrong on ARM. Why do you even have to map them? Can't the boot > > loader pass those tables in regular addressable memory? > > Don't get too stuck on the name - x86 frequently uses *ioremap() in > many places when just accessing memory, and that has carried into EFI, > ACPI and DMI subsystems, which we now want to use on ARM. In fact, they > have early_memremap(), but don't use it for either EFI or ACPI. The difference of course is that x86 doesn't use page table flags to tell the difference between MMIO and memory. It is not harmful on x86 to access memory through ioremap, but it is on most other architectures. You get either unspecified behavior due to conflicting cache flags or you get a hard checkstop based on how the CPU treats this. If you want to make the EFI code architecture independent, I think you should change the EFI code. > The ia64 implementation actually performs a lookup in the EFI memmap > to decide whether early_ioremap() returns cacheable memory or not > (and falls back to noncacheable before memory map is available). > > That said, I had somehow managed to get into my mind that the kernel > used -fno-unaligned-access, so thought MT_DEV_NONSHARED was safe. > Clearly it isn't, so that will need to change, making the semantic > match even worse... > > As for the need of mapping - some of these descriptors are needed very > early in the boot process. Also, depending on platform, they may reside > at any offset from start of RAM (<2^32 physical address), rendering > __va()/__phys_to_virt()/... unusable. Can you explain why they are needed this early? Also, can't we define the boot protocol to require these tables within the first GB of RAM? > > > Well, I did have a crazy idea that much/most of the early_ioremap code > > > could be made generic and shared between x86 and arm (and any other > > > 32-bit architecture). Using the fixmap macros would make that possible > > > with a minimum of ifdefs. > > > > > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > > > (but not beyond the "booting" system state), using the same macros would > > > help there too. I had no need for that for my EFI patches. > > > > I guess I need to look at the EFI patches first. It sounds to me > > like you shouldn't actually be using early_ioremap here or on another > > architecture. > > No, but I had been kind of hoping not having to rework the early memory > initialisation for three subsystems on two other platforms in order to > be able to merge common code between them. And it would have felt silly > to invent a new mechanism just for ARM, preventing that option. Well, if you can get around the "early" requirement, things can become much easier, you can basically #define early_ioremap(addr, size) ioremap(addr, size) #define early_memremap(addr, size) ioremap_cached(addr, size) and just need to fix the places where the common code mistakenly calls early_ioremap instead of early_memremap. Chances are that even if you can't avoid the requirement for early maps entirely that you only really have to worry about a small number of callers, for which you can then introduce architecture specific functions that do one thing in an appropriate way. On ARM, this may end up being __va(), kmap_atomic() or iotable_init() depending on the requirements. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 0/2] arm: add early_ioremap() support @ 2013-06-27 11:55 ` Arnd Bergmann 0 siblings, 0 replies; 36+ messages in thread From: Arnd Bergmann @ 2013-06-27 11:55 UTC (permalink / raw) To: linux-arm-kernel On Thursday 27 June 2013, Leif Lindholm wrote: > On Thu, Jun 27, 2013 at 10:47:21AM +0200, Arnd Bergmann wrote: > > > No, the purpose is just like for x86 - do early parsing of things like > > > the UEFI system and configuration tables, DMI and ACPI, in order to > > > populate global structs and stuff. > > > > But are those tables actually in MMIO registers? I thought they > > are just memory, and in that case using any form of ioremap is > > wrong on ARM. Why do you even have to map them? Can't the boot > > loader pass those tables in regular addressable memory? > > Don't get too stuck on the name - x86 frequently uses *ioremap() in > many places when just accessing memory, and that has carried into EFI, > ACPI and DMI subsystems, which we now want to use on ARM. In fact, they > have early_memremap(), but don't use it for either EFI or ACPI. The difference of course is that x86 doesn't use page table flags to tell the difference between MMIO and memory. It is not harmful on x86 to access memory through ioremap, but it is on most other architectures. You get either unspecified behavior due to conflicting cache flags or you get a hard checkstop based on how the CPU treats this. If you want to make the EFI code architecture independent, I think you should change the EFI code. > The ia64 implementation actually performs a lookup in the EFI memmap > to decide whether early_ioremap() returns cacheable memory or not > (and falls back to noncacheable before memory map is available). > > That said, I had somehow managed to get into my mind that the kernel > used -fno-unaligned-access, so thought MT_DEV_NONSHARED was safe. > Clearly it isn't, so that will need to change, making the semantic > match even worse... > > As for the need of mapping - some of these descriptors are needed very > early in the boot process. Also, depending on platform, they may reside > at any offset from start of RAM (<2^32 physical address), rendering > __va()/__phys_to_virt()/... unusable. Can you explain why they are needed this early? Also, can't we define the boot protocol to require these tables within the first GB of RAM? > > > Well, I did have a crazy idea that much/most of the early_ioremap code > > > could be made generic and shared between x86 and arm (and any other > > > 32-bit architecture). Using the fixmap macros would make that possible > > > with a minimum of ifdefs. > > > > > > If we ever wanted early_ioremap() to work like on x86, beyond kmap_init() > > > (but not beyond the "booting" system state), using the same macros would > > > help there too. I had no need for that for my EFI patches. > > > > I guess I need to look at the EFI patches first. It sounds to me > > like you shouldn't actually be using early_ioremap here or on another > > architecture. > > No, but I had been kind of hoping not having to rework the early memory > initialisation for three subsystems on two other platforms in order to > be able to merge common code between them. And it would have felt silly > to invent a new mechanism just for ARM, preventing that option. Well, if you can get around the "early" requirement, things can become much easier, you can basically #define early_ioremap(addr, size) ioremap(addr, size) #define early_memremap(addr, size) ioremap_cached(addr, size) and just need to fix the places where the common code mistakenly calls early_ioremap instead of early_memremap. Chances are that even if you can't avoid the requirement for early maps entirely that you only really have to worry about a small number of callers, for which you can then introduce architecture specific functions that do one thing in an appropriate way. On ARM, this may end up being __va(), kmap_atomic() or iotable_init() depending on the requirements. Arnd ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2014-07-25 19:56 UTC | newest] Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-07-09 9:39 [PATCH 0/2] arm: add early_ioremap support Leif Lindholm 2014-07-09 9:39 ` [PATCH 1/2] arm: use generic fixmap.h Leif Lindholm 2014-07-09 20:49 ` Mark Salter 2014-07-18 14:33 ` Leif Lindholm 2014-07-25 19:56 ` Kees Cook 2014-07-22 16:39 ` Tomasz Figa 2014-07-09 9:39 ` [PATCH 2/2] arm: add early_ioremap support Leif Lindholm 2014-07-09 9:49 ` Russell King - ARM Linux 2014-07-09 11:48 ` Leif Lindholm 2014-07-22 16:48 ` Tomasz Figa 2014-07-22 17:11 ` Rob Herring 2014-07-22 17:27 ` Tomasz Figa 2014-07-09 9:42 ` [PATCH 0/2] " Russell King - ARM Linux 2014-07-09 9:58 ` Leif Lindholm 2014-07-09 9:47 ` Will Deacon 2014-07-09 10:02 ` Leif Lindholm -- strict thread matches above, loose matches on Subject: below -- 2013-06-25 17:46 [PATCH 0/2] arm: add early_ioremap() support Leif Lindholm 2013-06-25 17:46 ` Leif Lindholm 2013-06-26 18:52 ` Arnd Bergmann 2013-06-26 18:52 ` Arnd Bergmann 2013-06-26 19:23 ` Leif Lindholm 2013-06-26 19:23 ` Leif Lindholm 2013-06-26 21:23 ` Arnd Bergmann 2013-06-26 21:23 ` Arnd Bergmann 2013-06-26 21:34 ` Leif Lindholm 2013-06-26 21:34 ` Leif Lindholm 2013-06-26 22:13 ` Arnd Bergmann 2013-06-26 22:13 ` Arnd Bergmann 2013-06-26 23:25 ` Leif Lindholm 2013-06-26 23:25 ` Leif Lindholm 2013-06-27 8:47 ` Arnd Bergmann 2013-06-27 8:47 ` Arnd Bergmann 2013-06-27 9:29 ` Leif Lindholm 2013-06-27 9:29 ` Leif Lindholm 2013-06-27 11:55 ` Arnd Bergmann 2013-06-27 11:55 ` Arnd Bergmann
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.