Hi Nicolas or Russell,
This patch series change fixmap mapping region to suppport 32 CPUs.
Because the "top_pmd" covers 0xfffe0000 - 0xffffffff(2M). And part
is used by vector table. So I move this region down to 0xffc00000
- 0xffdffff.
I have tested the patches on arma9(2 CPUs) and arma15(16 CPUs) platforms
BTW, As we know we can configure NR_CPUS up to 32. So we need 2048K
at most. But for ARM systems with less cpus, there is a waste
of virtual address. So should we change its size according to
NR_CPUS, as what MIPS linux does ?
Changes from v1:
---------------
- changed documentation for ARM linux memory layout.
- moved fixmap mapping region, not just extended.
Liu Hua (2):
ARM : DMA : remove useless information about DMA
ARM : extend fixmap mapping region to support 32 CPUs
Documentation/arm/memory.txt | 8 ++------
arch/arm/include/asm/fixmap.h | 4 ++--
arch/arm/include/asm/highmem.h | 1 +
arch/arm/include/asm/memory.h | 2 --
arch/arm/mm/highmem.c | 10 +++++-----
arch/arm/mm/mm.h | 7 +++++++
arch/arm/mm/mmu.c | 4 ++++
mm/highmem.c | 1 +
8 files changed, 22 insertions(+), 15 deletions(-)
--
1.9.0
In 32-bit ARM systems, the fixmap mapping region can support
no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
configure NR_CPUS up to 32. So there is a mismatch.
This patch moves fixmapping region downwards to region
0xffc00000-0xffe00000 . Then the fixmap mapping region can
support up to 32 CPUs.
Signed-off-by: Liu Hua <[email protected]>
---
Documentation/arm/memory.txt | 2 +-
arch/arm/include/asm/fixmap.h | 4 ++--
arch/arm/include/asm/highmem.h | 1 +
arch/arm/mm/highmem.c | 10 +++++-----
arch/arm/mm/mm.h | 7 +++++++
arch/arm/mm/mmu.c | 4 ++++
mm/highmem.c | 1 +
7 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 8a361c0..4bca737 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
fffe0000 fffe7fff ITCM mapping area for platforms with
ITCM mounted inside the CPU.
-fff00000 fffdffff Fixmap mapping region. Addresses provided
+ffc00000 ffdfffff Fixmap mapping region. Addresses provided
by fix_to_virt() will be located here.
ff000000 ffbfffff Reserved for future expansion of DMA
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..014a70d 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -13,8 +13,8 @@
* 0xfffe0000 and 0xfffeffff.
*/
-#define FIXADDR_START 0xfff00000UL
-#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_START 0xffc00000UL
+#define FIXADDR_TOP 0xffe00000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
#define FIX_KMAP_BEGIN 0
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 91b99ab..5355795 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -18,6 +18,7 @@
} while (0)
extern pte_t *pkmap_page_table;
+extern pte_t *fixmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 21b9e1b..9bc8988 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -69,14 +69,14 @@ void *kmap_atomic(struct page *page)
* With debugging enabled, kunmap_atomic forces that entry to 0.
* Make sure it was indeed properly unmapped.
*/
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
/*
* When debugging is off, kunmap_atomic leaves the previous mapping
* in place, so the contained TLB flush ensures the TLB is updated
* with the new mapping.
*/
- set_top_pte(vaddr, mk_pte(page, kmap_prot));
+ set_fixmap_pte(idx, mk_pte(page, kmap_prot));
return (void *)vaddr;
}
@@ -95,7 +95,7 @@ void __kunmap_atomic(void *kvaddr)
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
- set_top_pte(vaddr, __pte(0));
+ set_fixmap_pte(idx, __pte(0));
#else
(void) idx; /* to kill a warning */
#endif
@@ -119,9 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
- set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
+ set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
return (void *)vaddr;
}
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 7ea641b..3460d73 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -1,6 +1,7 @@
#ifdef CONFIG_MMU
#include <linux/list.h>
#include <linux/vmalloc.h>
+#include <asm/fixmap.h>
/* the upper-most page table pointer */
extern pmd_t *top_pmd;
@@ -25,6 +26,12 @@ static inline void set_top_pte(unsigned long va, pte_t pte)
local_flush_tlb_kernel_page(va);
}
+static inline void set_fixmap_pte(int idx, pte_t pte)
+{
+ unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte_ext(fixmap_page_table + idx, pte, 0);
+ local_flush_tlb_kernel_page(vaddr);
+}
static inline pte_t get_top_pte(unsigned long va)
{
pte_t *ptep = pte_offset_kernel(top_pmd, va);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b68c6b2..09c0a16 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -35,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
+#include <asm/fixmap.h>
#include "mm.h"
#include "tcm.h"
@@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
#ifdef CONFIG_HIGHMEM
pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
PKMAP_BASE, _PAGE_KERNEL_TABLE);
+
+ fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
+ FIXADDR_START, _PAGE_KERNEL_TABLE);
#endif
}
diff --git a/mm/highmem.c b/mm/highmem.c
index b32b70c..d0094ba 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -72,6 +72,7 @@ static unsigned int last_pkmap_nr;
static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
pte_t * pkmap_page_table;
+pte_t *fixmap_page_table;
static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
--
1.9.0
Because commit e9da6e9905e6 has remove custom consistent dma
region. So the related variable and document should be removed
Signed-off-by: Liu Hua <[email protected]>
---
Documentation/arm/memory.txt | 4 ----
arch/arm/include/asm/memory.h | 2 --
2 files changed, 6 deletions(-)
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 4bfb9ff..8a361c0 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -44,10 +44,6 @@ fffe0000 fffe7fff ITCM mapping area for platforms with
fff00000 fffdffff Fixmap mapping region. Addresses provided
by fix_to_virt() will be located here.
-ffc00000 ffefffff DMA memory mapping region. Memory returned
- by the dma_alloc_xxx functions will be
- dynamically mapped here.
-
ff000000 ffbfffff Reserved for future expansion of DMA
mapping region.
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 02fa255..2b75146 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -83,8 +83,6 @@
*/
#define IOREMAP_MAX_ORDER 24
-#define CONSISTENT_END (0xffe00000UL)
-
#else /* CONFIG_MMU */
/*
--
1.9.0
Hello,
On 2014-04-11 10:00, Liu Hua wrote:
> Because commit e9da6e9905e6 has remove custom consistent dma
> region. So the related variable and document should be removed
>
> Signed-off-by: Liu Hua <[email protected]>
Acked-by: Marek Szyprowski <[email protected]>
> ---
> Documentation/arm/memory.txt | 4 ----
> arch/arm/include/asm/memory.h | 2 --
> 2 files changed, 6 deletions(-)
>
> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
> index 4bfb9ff..8a361c0 100644
> --- a/Documentation/arm/memory.txt
> +++ b/Documentation/arm/memory.txt
> @@ -44,10 +44,6 @@ fffe0000 fffe7fff ITCM mapping area for platforms with
> fff00000 fffdffff Fixmap mapping region. Addresses provided
> by fix_to_virt() will be located here.
>
> -ffc00000 ffefffff DMA memory mapping region. Memory returned
> - by the dma_alloc_xxx functions will be
> - dynamically mapped here.
> -
> ff000000 ffbfffff Reserved for future expansion of DMA
> mapping region.
>
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index 02fa255..2b75146 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -83,8 +83,6 @@
> */
> #define IOREMAP_MAX_ORDER 24
>
> -#define CONSISTENT_END (0xffe00000UL)
> -
> #else /* CONFIG_MMU */
>
> /*
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
On Fri, 11 Apr 2014, Liu Hua wrote:
> Because commit e9da6e9905e6 has remove custom consistent dma
> region. So the related variable and document should be removed
>
> Signed-off-by: Liu Hua <[email protected]>
Acked-by: Nicolas Pitre <[email protected]>
Incidentally I sent an identical patch to RMK's patch system:
http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=8023/1
Either version is fine with me.
Nicolas
On Fri, 11 Apr 2014, Liu Hua wrote:
> In 32-bit ARM systems, the fixmap mapping region can support
> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
> configure NR_CPUS up to 32. So there is a mismatch.
>
> This patch moves fixmapping region downwards to region
> 0xffc00000-0xffe00000 . Then the fixmap mapping region can
> support up to 32 CPUs.
>
> Signed-off-by: Liu Hua <[email protected]>
Comments below.
> ---
> Documentation/arm/memory.txt | 2 +-
> arch/arm/include/asm/fixmap.h | 4 ++--
> arch/arm/include/asm/highmem.h | 1 +
> arch/arm/mm/highmem.c | 10 +++++-----
> arch/arm/mm/mm.h | 7 +++++++
> arch/arm/mm/mmu.c | 4 ++++
> mm/highmem.c | 1 +
> 7 files changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
> index 8a361c0..4bca737 100644
> --- a/Documentation/arm/memory.txt
> +++ b/Documentation/arm/memory.txt
> @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
> fffe0000 fffe7fff ITCM mapping area for platforms with
> ITCM mounted inside the CPU.
>
> -fff00000 fffdffff Fixmap mapping region. Addresses provided
> +ffc00000 ffdfffff Fixmap mapping region. Addresses provided
> by fix_to_virt() will be located here.
>
> ff000000 ffbfffff Reserved for future expansion of DMA
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index bbae919..014a70d 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -13,8 +13,8 @@
> * 0xfffe0000 and 0xfffeffff.
> */
>
> -#define FIXADDR_START 0xfff00000UL
> -#define FIXADDR_TOP 0xfffe0000UL
> +#define FIXADDR_START 0xffc00000UL
> +#define FIXADDR_TOP 0xffe00000UL
> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>
> #define FIX_KMAP_BEGIN 0
> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
> index 91b99ab..5355795 100644
> --- a/arch/arm/include/asm/highmem.h
> +++ b/arch/arm/include/asm/highmem.h
> @@ -18,6 +18,7 @@
> } while (0)
>
> extern pte_t *pkmap_page_table;
> +extern pte_t *fixmap_page_table;
>
> extern void *kmap_high(struct page *page);
> extern void kunmap_high(struct page *page);
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index 21b9e1b..9bc8988 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -69,14 +69,14 @@ void *kmap_atomic(struct page *page)
> * With debugging enabled, kunmap_atomic forces that entry to 0.
> * Make sure it was indeed properly unmapped.
> */
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> /*
> * When debugging is off, kunmap_atomic leaves the previous mapping
> * in place, so the contained TLB flush ensures the TLB is updated
> * with the new mapping.
> */
> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -95,7 +95,7 @@ void __kunmap_atomic(void *kvaddr)
> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
> - set_top_pte(vaddr, __pte(0));
> + set_fixmap_pte(idx, __pte(0));
> #else
> (void) idx; /* to kill a warning */
> #endif
> @@ -119,9 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
> idx = type + KM_TYPE_NR * smp_processor_id();
> vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> - set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
> + set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
>
> return (void *)vaddr;
> }
> diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
> index 7ea641b..3460d73 100644
> --- a/arch/arm/mm/mm.h
> +++ b/arch/arm/mm/mm.h
> @@ -1,6 +1,7 @@
> #ifdef CONFIG_MMU
> #include <linux/list.h>
> #include <linux/vmalloc.h>
> +#include <asm/fixmap.h>
>
> /* the upper-most page table pointer */
> extern pmd_t *top_pmd;
> @@ -25,6 +26,12 @@ static inline void set_top_pte(unsigned long va, pte_t pte)
> local_flush_tlb_kernel_page(va);
> }
>
> +static inline void set_fixmap_pte(int idx, pte_t pte)
> +{
> + unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> + set_pte_ext(fixmap_page_table + idx, pte, 0);
> + local_flush_tlb_kernel_page(vaddr);
> +}
This has no other users than the code in highmem.c so it probably should
live there.
Other than that...
Acked-by: Nicolas Pitre <[email protected]>
> static inline pte_t get_top_pte(unsigned long va)
> {
> pte_t *ptep = pte_offset_kernel(top_pmd, va);
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index b68c6b2..09c0a16 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -35,6 +35,7 @@
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> #include <asm/mach/pci.h>
> +#include <asm/fixmap.h>
>
> #include "mm.h"
> #include "tcm.h"
> @@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
> #ifdef CONFIG_HIGHMEM
> pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
> PKMAP_BASE, _PAGE_KERNEL_TABLE);
> +
> + fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
> + FIXADDR_START, _PAGE_KERNEL_TABLE);
> #endif
> }
>
> diff --git a/mm/highmem.c b/mm/highmem.c
> index b32b70c..d0094ba 100644
> --- a/mm/highmem.c
> +++ b/mm/highmem.c
> @@ -72,6 +72,7 @@ static unsigned int last_pkmap_nr;
> static __cacheline_aligned_in_smp DEFINE_SPINLOCK(kmap_lock);
>
> pte_t * pkmap_page_table;
> +pte_t *fixmap_page_table;
>
> static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait);
>
> --
> 1.9.0
>
On Fri, 11 Apr 2014, Liu Hua wrote:
> Hi Nicolas or Russell,
>
> This patch series change fixmap mapping region to suppport 32 CPUs.
> Because the "top_pmd" covers 0xfffe0000 - 0xffffffff(2M). And part
> is used by vector table. So I move this region down to 0xffc00000
> - 0xffdffff.
>
>
> I have tested the patches on arma9(2 CPUs) and arma15(16 CPUs) platforms
>
> BTW, As we know we can configure NR_CPUS up to 32. So we need 2048K
> at most. But for ARM systems with less cpus, there is a waste
> of virtual address. So should we change its size according to
> NR_CPUS, as what MIPS linux does ?
It is probably not worth the bother. We lived with this area reserved
for static DMA mapping while there was no longer any DMA mapped there
for quite a while.
>
> Changes from v1:
> ---------------
> - changed documentation for ARM linux memory layout.
> - moved fixmap mapping region, not just extended.
>
> Liu Hua (2):
> ARM : DMA : remove useless information about DMA
> ARM : extend fixmap mapping region to support 32 CPUs
>
> Documentation/arm/memory.txt | 8 ++------
> arch/arm/include/asm/fixmap.h | 4 ++--
> arch/arm/include/asm/highmem.h | 1 +
> arch/arm/include/asm/memory.h | 2 --
> arch/arm/mm/highmem.c | 10 +++++-----
> arch/arm/mm/mm.h | 7 +++++++
> arch/arm/mm/mmu.c | 4 ++++
> mm/highmem.c | 1 +
> 8 files changed, 22 insertions(+), 15 deletions(-)
>
> --
> 1.9.0
>
On Fri, 11 Apr 2014, Nicolas Pitre wrote:
> On Fri, 11 Apr 2014, Liu Hua wrote:
>
> > Because commit e9da6e9905e6 has remove custom consistent dma
> > region. So the related variable and document should be removed
> >
> > Signed-off-by: Liu Hua <[email protected]>
>
> Acked-by: Nicolas Pitre <[email protected]>
>
> Incidentally I sent an identical patch to RMK's patch system:
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=8023/1
>
> Either version is fine with me.
Actually mine is slightly better as I also removed the entry covering
0xff000000 to 0xffbfffff which is no longer used either.
Nicolas
Hi Nicolas,
Your version is better. you tell me this in the former letters.
So I am very sorry to forget to check that.
May be I should remake this second patch to fit your change. What do
you think about that patch?
Liu Hua
On 2014/4/12 11:12, Nicolas Pitre wrote:
> On Fri, 11 Apr 2014, Liu Hua wrote:
>
>> Because commit e9da6e9905e6 has remove custom consistent dma
>> region. So the related variable and document should be removed
>>
>> Signed-off-by: Liu Hua <[email protected]>
>
> Acked-by: Nicolas Pitre <[email protected]>
>
> Incidentally I sent an identical patch to RMK's patch system:
>
> http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=8023/1
>
> Either version is fine with me.
>
>
> Nicolas
>
>
On Sat, 12 Apr 2014, Liu hua wrote:
> Hi Nicolas,
>
> Your version is better. you tell me this in the former letters.
> So I am very sorry to forget to check that.
>
> May be I should remake this second patch to fit your change. What do
> you think about that patch?
You may simply drop your first patch and only keep the other two.
Nicolas
On 2014/4/12 22:32, Nicolas Pitre write:
> On Sat, 12 Apr 2014, Liu hua wrote:
>
>> Hi Nicolas,
>>
>> Your version is better. you tell me this in the former letters.
>> So I am very sorry to forget to check that.
>>
>> May be I should remake this second patch to fit your change. What do
>> you think about that patch?
>
> You may simply drop your first patch and only keep the other two.
>
Sure. But your patch and my second one both change Document/arm/memory.txt.
I am afraid there will be conflicts when someone tests my patch before
yours getting into the mainline.
Maybe I can spilt the document-changing part to a new patch. And send it
after yours are in the mainline.
Liu Hua
>
> Nicolas
>
>
On 2014/4/12 11:26, Nicolas Pitre wrote:
> On Fri, 11 Apr 2014, Liu Hua wrote:
>
>> In 32-bit ARM systems, the fixmap mapping region can support
>> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
>> configure NR_CPUS up to 32. So there is a mismatch.
>>
>> This patch moves fixmapping region downwards to region
>> 0xffc00000-0xffe00000 . Then the fixmap mapping region can
>> support up to 32 CPUs.
>>
>> Signed-off-by: Liu Hua <[email protected]>
>
> Comments below.
>
>> ---
>> Documentation/arm/memory.txt | 2 +-
>> arch/arm/include/asm/fixmap.h | 4 ++--
>> arch/arm/include/asm/highmem.h | 1 +
>> arch/arm/mm/highmem.c | 10 +++++-----
>> arch/arm/mm/mm.h | 7 +++++++
>> arch/arm/mm/mmu.c | 4 ++++
>> mm/highmem.c | 1 +
>> 7 files changed, 21 insertions(+), 8 deletions(-)
>>
>> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
>> index 8a361c0..4bca737 100644
>> --- a/Documentation/arm/memory.txt
>> +++ b/Documentation/arm/memory.txt
>> @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
>> fffe0000 fffe7fff ITCM mapping area for platforms with
>> ITCM mounted inside the CPU.
>>
>> -fff00000 fffdffff Fixmap mapping region. Addresses provided
>> +ffc00000 ffdfffff Fixmap mapping region. Addresses provided
>> by fix_to_virt() will be located here.
>>
>> ff000000 ffbfffff Reserved for future expansion of DMA
>> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
>> index bbae919..014a70d 100644
>> --- a/arch/arm/include/asm/fixmap.h
>> +++ b/arch/arm/include/asm/fixmap.h
>> @@ -13,8 +13,8 @@
>> * 0xfffe0000 and 0xfffeffff.
>> */
>>
>> -#define FIXADDR_START 0xfff00000UL
>> -#define FIXADDR_TOP 0xfffe0000UL
>> +#define FIXADDR_START 0xffc00000UL
>> +#define FIXADDR_TOP 0xffe00000UL
>> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>>
>> #define FIX_KMAP_BEGIN 0
>> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
>> index 91b99ab..5355795 100644
>> --- a/arch/arm/include/asm/highmem.h
>> +++ b/arch/arm/include/asm/highmem.h
>> @@ -18,6 +18,7 @@
>> } while (0)
>>
>> extern pte_t *pkmap_page_table;
>> +extern pte_t *fixmap_page_table;
>>
>> extern void *kmap_high(struct page *page);
>> extern void kunmap_high(struct page *page);
>> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
>> index 21b9e1b..9bc8988 100644
>> --- a/arch/arm/mm/highmem.c
>> +++ b/arch/arm/mm/highmem.c
>> @@ -69,14 +69,14 @@ void *kmap_atomic(struct page *page)
>> * With debugging enabled, kunmap_atomic forces that entry to 0.
>> * Make sure it was indeed properly unmapped.
>> */
>> - BUG_ON(!pte_none(get_top_pte(vaddr)));
>> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
>> #endif
>> /*
>> * When debugging is off, kunmap_atomic leaves the previous mapping
>> * in place, so the contained TLB flush ensures the TLB is updated
>> * with the new mapping.
>> */
>> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
>> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>>
>> return (void *)vaddr;
>> }
>> @@ -95,7 +95,7 @@ void __kunmap_atomic(void *kvaddr)
>> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
>> - set_top_pte(vaddr, __pte(0));
>> + set_fixmap_pte(idx, __pte(0));
>> #else
>> (void) idx; /* to kill a warning */
>> #endif
>> @@ -119,9 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
>> idx = type + KM_TYPE_NR * smp_processor_id();
>> vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> - BUG_ON(!pte_none(get_top_pte(vaddr)));
>> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
>> #endif
>> - set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
>> + set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
>>
>> return (void *)vaddr;
>> }
>> diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
>> index 7ea641b..3460d73 100644
>> --- a/arch/arm/mm/mm.h
>> +++ b/arch/arm/mm/mm.h
>> @@ -1,6 +1,7 @@
>> #ifdef CONFIG_MMU
>> #include <linux/list.h>
>> #include <linux/vmalloc.h>
>> +#include <asm/fixmap.h>
>>
>> /* the upper-most page table pointer */
>> extern pmd_t *top_pmd;
>> @@ -25,6 +26,12 @@ static inline void set_top_pte(unsigned long va, pte_t pte)
>> local_flush_tlb_kernel_page(va);
>> }
>>
>> +static inline void set_fixmap_pte(int idx, pte_t pte)
>> +{
>> + unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
>> + set_pte_ext(fixmap_page_table + idx, pte, 0);
>> + local_flush_tlb_kernel_page(vaddr);
>> +}
>
> This has no other users than the code in highmem.c so it probably should
> live there.
>
> Other than that...
>
> Acked-by: Nicolas Pitre <[email protected]>
>
> .
>
Hi Nicolas.
Sure, your suggestion made my patch looks better. How about that :
Thanks,
Liu Hua
-------------------------------------------------
Changes from v2:
moved new codes to highmem.c as more as possible.
unchanged Document/arm/memory.txt.
In 32-bit ARM systems, the fixmap mapping region can support
no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
configure NR_CPUS up to 32. So there is a mismatch.
This patch moves fixmapping region downwards to region
0xffc00000-0xffe00000 . Then the fixmap mapping region can
support up to 32 CPUs
Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Liu Hua <[email protected]>
---
arch/arm/include/asm/fixmap.h | 4 ++--
arch/arm/include/asm/highmem.h | 1 +
arch/arm/mm/highmem.c | 28 ++++++++++++++++++++++------
arch/arm/mm/mmu.c | 4 ++++
4 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..014a70d 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -13,8 +13,8 @@
* 0xfffe0000 and 0xfffeffff.
*/
-#define FIXADDR_START 0xfff00000UL
-#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_START 0xffc00000UL
+#define FIXADDR_TOP 0xffe00000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
#define FIX_KMAP_BEGIN 0
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 91b99ab..5355795 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -18,6 +18,7 @@
} while (0)
extern pte_t *pkmap_page_table;
+extern pte_t *fixmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 21b9e1b..fa97896 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -18,6 +18,22 @@
#include <asm/tlbflush.h>
#include "mm.h"
+pte_t *fixmap_page_table;
+
+static inline void set_fixmap_pte(int idx, pte_t pte)
+{
+ unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + 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);
+ idx -= FIX_KMAP_BEGIN;
+ return *(fixmap_page_table + idx);
+}
+
void *kmap(struct page *page)
{
might_sleep();
@@ -69,14 +85,14 @@ void *kmap_atomic(struct page *page)
* With debugging enabled, kunmap_atomic forces that entry to 0.
* Make sure it was indeed properly unmapped.
*/
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
/*
* When debugging is off, kunmap_atomic leaves the previous mapping
* in place, so the contained TLB flush ensures the TLB is updated
* with the new mapping.
*/
- set_top_pte(vaddr, mk_pte(page, kmap_prot));
+ set_fixmap_pte(idx, mk_pte(page, kmap_prot));
return (void *)vaddr;
}
@@ -95,7 +111,7 @@ void __kunmap_atomic(void *kvaddr)
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
- set_top_pte(vaddr, __pte(0));
+ set_fixmap_pte(idx, __pte(0));
#else
(void) idx; /* to kill a warning */
#endif
@@ -119,9 +135,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
- set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
+ set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
return (void *)vaddr;
}
@@ -133,5 +149,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
if (vaddr < FIXADDR_START)
return virt_to_page(ptr);
- return pte_page(get_top_pte(vaddr));
+ return pte_page(get_fixmap_pte(vaddr));
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b68c6b2..09c0a16 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -35,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
+#include <asm/fixmap.h>
#include "mm.h"
#include "tcm.h"
@@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
#ifdef CONFIG_HIGHMEM
pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
PKMAP_BASE, _PAGE_KERNEL_TABLE);
+
+ fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
+ FIXADDR_START, _PAGE_KERNEL_TABLE);
#endif
}
--
1.9.0
On Sun, 13 Apr 2014, Liu hua wrote:
> On 2014/4/12 22:32, Nicolas Pitre write:
> > On Sat, 12 Apr 2014, Liu hua wrote:
> >
> >> Hi Nicolas,
> >>
> >> Your version is better. you tell me this in the former letters.
> >> So I am very sorry to forget to check that.
> >>
> >> May be I should remake this second patch to fit your change. What do
> >> you think about that patch?
> >
> > You may simply drop your first patch and only keep the other two.
> >
> Sure. But your patch and my second one both change Document/arm/memory.txt.
> I am afraid there will be conflicts when someone tests my patch before
> yours getting into the mainline.
That's still an easy conflict to fix. And it is likely that git will
fix it automatically.
Nicolas
On Sun, 13 Apr 2014, Liu hua wrote:
> Hi Nicolas.
>
> Sure, your suggestion made my patch looks better. How about that :
>
> Thanks,
> Liu Hua
There is something else that bothers me.
> -------------------------------------------------
>
> Changes from v2:
> moved new codes to highmem.c as more as possible.
> unchanged Document/arm/memory.txt.
>
>
> In 32-bit ARM systems, the fixmap mapping region can support
> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
> configure NR_CPUS up to 32. So there is a mismatch.
>
> This patch moves fixmapping region downwards to region
> 0xffc00000-0xffe00000 . Then the fixmap mapping region can
> support up to 32 CPUs
>
> Acked-by: Nicolas Pitre <[email protected]>
> Signed-off-by: Liu Hua <[email protected]>
> ---
> arch/arm/include/asm/fixmap.h | 4 ++--
> arch/arm/include/asm/highmem.h | 1 +
> arch/arm/mm/highmem.c | 28 ++++++++++++++++++++++------
> arch/arm/mm/mmu.c | 4 ++++
> 4 files changed, 29 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index bbae919..014a70d 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -13,8 +13,8 @@
> * 0xfffe0000 and 0xfffeffff.
> */
>
> -#define FIXADDR_START 0xfff00000UL
> -#define FIXADDR_TOP 0xfffe0000UL
> +#define FIXADDR_START 0xffc00000UL
> +#define FIXADDR_TOP 0xffe00000UL
> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>
> #define FIX_KMAP_BEGIN 0
> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
> index 91b99ab..5355795 100644
> --- a/arch/arm/include/asm/highmem.h
> +++ b/arch/arm/include/asm/highmem.h
> @@ -18,6 +18,7 @@
> } while (0)
>
> extern pte_t *pkmap_page_table;
> +extern pte_t *fixmap_page_table;
>
> extern void *kmap_high(struct page *page);
> extern void kunmap_high(struct page *page);
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index 21b9e1b..fa97896 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -18,6 +18,22 @@
> #include <asm/tlbflush.h>
> #include "mm.h"
>
> +pte_t *fixmap_page_table;
> +
> +static inline void set_fixmap_pte(int idx, pte_t pte)
> +{
> + unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + 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);
> + idx -= FIX_KMAP_BEGIN;
> + return *(fixmap_page_table + idx);
FIX_KMAP_BEGIN represents the starting point for mapping fixmap indices
to page table entries. So here you should _add_ the
FIX_KMAP_BEGIN offset to the page table index not substract it.
Currently FIX_KMAP_BEGIN is defined to 0 but still.
> +}
> +
> void *kmap(struct page *page)
> {
> might_sleep();
> @@ -69,14 +85,14 @@ void *kmap_atomic(struct page *page)
> * With debugging enabled, kunmap_atomic forces that entry to 0.
> * Make sure it was indeed properly unmapped.
> */
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
This is therefore also wrong. It should be
fixmap_page_table + idx + FIX_KMAP_BEGIN.
> #endif
> /*
> * When debugging is off, kunmap_atomic leaves the previous mapping
> * in place, so the contained TLB flush ensures the TLB is updated
> * with the new mapping.
> */
> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -95,7 +111,7 @@ void __kunmap_atomic(void *kvaddr)
> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
> - set_top_pte(vaddr, __pte(0));
> + set_fixmap_pte(idx, __pte(0));
> #else
> (void) idx; /* to kill a warning */
> #endif
> @@ -119,9 +135,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
> idx = type + KM_TYPE_NR * smp_processor_id();
> vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
Ditto here.
In fact, this FIX_KMAP_BEGIN is only creating more confusing code for
nothing as we define it to 0 anyway, and it is not used by non
architecture specific code. So I'd suggest you create a patch to be
applied before this one that simply gets rid of FIX_KMAP_BEGIN and
FIX_KMAP_END altogether. We could reintroduce them back if ever they're
needed.
Nicolas
于 2014/4/14 1:34, Nicolas Pitre 写道:
> On Sun, 13 Apr 2014, Liu hua wrote:
>
>> Hi Nicolas.
>>
>> Sure, your suggestion made my patch looks better. How about that :
>>
>> Thanks,
>> Liu Hua
>
> There is something else that bothers me.
>
>> + unsigned long idx = __virt_to_fix(vaddr);
>> + idx -= FIX_KMAP_BEGIN;
>> + return *(fixmap_page_table + idx);
>
> FIX_KMAP_BEGIN represents the starting point for mapping fixmap indices
> to page table entries. So here you should _add_ the
> FIX_KMAP_BEGIN offset to the page table index not substract it.
> Currently FIX_KMAP_BEGIN is defined to 0 but still.
>
>> +}
>> +
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> - BUG_ON(!pte_none(get_top_pte(vaddr)));
>> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
>
> Ditto here.
>
> In fact, this FIX_KMAP_BEGIN is only creating more confusing code for
> nothing as we define it to 0 anyway, and it is not used by non
> architecture specific code. So I'd suggest you create a patch to be
> applied before this one that simply gets rid of FIX_KMAP_BEGIN and
> FIX_KMAP_END altogether. We could reintroduce them back if ever they're
> needed.
>
>
> Nicolas
>
Hi Nicolas,
Yes, it seems that FIX_KMAP_BEGIN and FIX_KMAP_END are not as important for
ARM than that for other architectures (MIPS PowerPC x86), whose FIX_KMAP_BEGIN
is not 0. I will reminder this in my patch. Anyone who need them can get
imformantion there.
Now the new patchs are following. Maybe I sould resend the patch series
with a new tag. If It is time to do that. Can I add this information
"Reviewed-by: Nicolas Pitre <[email protected]>" ?
Thanks,
Liu Hua.
-----------------patch 1-------------------------
Subject: [PATCH 1/2] ARM : fixmap : remove FIX_KMAP_BEGIN and FIX_KMAP_END
It seems that these two variables are not used by non
architecture specific code. And on ARM FIX_KMAP_BEGIN
equals zero; FIX_KMAP_END is totally not used by the
kernel.
This patch removes these two variables. The code will
become clear when I introduce a bugfix on fixmap mapping
region.
Signed-off-by: Liu Hua <[email protected]>
---
arch/arm/include/asm/fixmap.h | 12 ++++++++----
arch/arm/mm/highmem.c | 6 +++---
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index bbae919..8675bb9 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -17,9 +17,13 @@
#define FIXADDR_TOP 0xfffe0000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
-#define FIX_KMAP_BEGIN 0
-#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
-
+/* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
+ *
+ * Instead, using FIX_KMAP_NR_PTES to tell the pte number
+ * belonged to fixmap mapping region.
+ *
+ */
+#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)
@@ -27,7 +31,7 @@ extern void __this_fixmap_does_not_exist(void);
static inline unsigned long fix_to_virt(const unsigned int idx)
{
- if (idx >= FIX_KMAP_END)
+ if (idx >= FIX_KMAP_NR_PTES)
__this_fixmap_does_not_exist();
return __fix_to_virt(idx);
}
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 21b9e1b..e05e8ad 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -63,7 +63,7 @@ void *kmap_atomic(struct page *page)
type = kmap_atomic_idx_push();
idx = type + KM_TYPE_NR * smp_processor_id();
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
/*
* With debugging enabled, kunmap_atomic forces that entry to 0.
@@ -94,7 +94,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(FIX_KMAP_BEGIN + idx));
+ BUG_ON(vaddr != __fix_to_virt(idx));
set_top_pte(vaddr, __pte(0));
#else
(void) idx; /* to kill a warning */
@@ -117,7 +117,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(FIX_KMAP_BEGIN + idx);
+ vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(get_top_pte(vaddr)));
#endif
--
1.9.0
-----------------patch 2-------------------------
Subject: [PATCH 2/2] ARM : change fixmap mapping region to support 32 CPUs
In 32-bit ARM systems, the fixmap mapping region can support
no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
configure NR_CPUS up to 32. So there is a mismatch.
This patch moves fixmapping region downwards to region
0xffc00000-0xffe00000 . Then the fixmap mapping region can
support up to 32 CPUs
Signed-off-by: Liu Hua <[email protected]>
---
Documentation/arm/memory.txt | 2 +-
arch/arm/include/asm/fixmap.h | 16 ++--------------
arch/arm/include/asm/highmem.h | 1 +
arch/arm/mm/highmem.c | 27 +++++++++++++++++++++------
arch/arm/mm/mmu.c | 4 ++++
5 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index d74e8a5..256c5e0 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
fffe0000 fffe7fff ITCM mapping area for platforms with
ITCM mounted inside the CPU.
-fff00000 fffdffff Fixmap mapping region. Addresses provided
+fffc0000 ffdfffff Fixmap mapping region. Addresses provided
by fix_to_virt() will be located here.
fee00000 feffffff Mapping of PCI I/O space. This is a static
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 8675bb9..fb8a5a7 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -1,20 +1,8 @@
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H
-/*
- * Nothing too fancy for now.
- *
- * On ARM we already have well known fixed virtual addresses imposed by
- * the architecture such as the vector page which is located at 0xffff0000,
- * therefore a second level page table is already allocated covering
- * 0xfff00000 upwards.
- *
- * The cache flushing code in proc-xscale.S uses the virtual area between
- * 0xfffe0000 and 0xfffeffff.
- */
-
-#define FIXADDR_START 0xfff00000UL
-#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_START 0xffc00000UL
+#define FIXADDR_TOP 0xffe00000UL
#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
/* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 91b99ab..5355795 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -18,6 +18,7 @@
} while (0)
extern pte_t *pkmap_page_table;
+extern pte_t *fixmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index e05e8ad..45aeaac 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -18,6 +18,21 @@
#include <asm/tlbflush.h>
#include "mm.h"
+pte_t *fixmap_page_table;
+
+static inline void set_fixmap_pte(int idx, pte_t pte)
+{
+ unsigned long vaddr = __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);
+ return *(fixmap_page_table + idx);
+}
+
void *kmap(struct page *page)
{
might_sleep();
@@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
* With debugging enabled, kunmap_atomic forces that entry to 0.
* Make sure it was indeed properly unmapped.
*/
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
/*
* When debugging is off, kunmap_atomic leaves the previous mapping
* in place, so the contained TLB flush ensures the TLB is updated
* with the new mapping.
*/
- set_top_pte(vaddr, mk_pte(page, kmap_prot));
+ set_fixmap_pte(idx, mk_pte(page, kmap_prot));
return (void *)vaddr;
}
@@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(vaddr != __fix_to_virt(idx));
- set_top_pte(vaddr, __pte(0));
+ set_fixmap_pte(idx, __pte(0));
#else
(void) idx; /* to kill a warning */
#endif
@@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
idx = type + KM_TYPE_NR * smp_processor_id();
vaddr = __fix_to_virt(idx);
#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(!pte_none(get_top_pte(vaddr)));
+ BUG_ON(!pte_none(*(fixmap_page_table + idx)));
#endif
- set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
+ set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
return (void *)vaddr;
}
@@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
if (vaddr < FIXADDR_START)
return virt_to_page(ptr);
- return pte_page(get_top_pte(vaddr));
+ return pte_page(get_fixmap_pte(vaddr));
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b68c6b2..09c0a16 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -35,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/pci.h>
+#include <asm/fixmap.h>
#include "mm.h"
#include "tcm.h"
@@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
#ifdef CONFIG_HIGHMEM
pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
PKMAP_BASE, _PAGE_KERNEL_TABLE);
+
+ fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
+ FIXADDR_START, _PAGE_KERNEL_TABLE);
#endif
}
--
1.9.0
On Mon, 14 Apr 2014, Liu hua wrote:
> Yes, it seems that FIX_KMAP_BEGIN and FIX_KMAP_END are not as important for
> ARM than that for other architectures (MIPS PowerPC x86), whose FIX_KMAP_BEGIN
> is not 0. I will reminder this in my patch. Anyone who need them can get
> imformantion there.
>
>
> Now the new patchs are following. Maybe I sould resend the patch series
> with a new tag. If It is time to do that. Can I add this information
> "Reviewed-by: Nicolas Pitre <[email protected]>" ?
>
> Thanks,
> Liu Hua.
>
> -----------------patch 1-------------------------
>
> Subject: [PATCH 1/2] ARM : fixmap : remove FIX_KMAP_BEGIN and FIX_KMAP_END
>
> It seems that these two variables are not used by non
> architecture specific code. And on ARM FIX_KMAP_BEGIN
> equals zero; FIX_KMAP_END is totally not used by the
> kernel.
>
> This patch removes these two variables. The code will
> become clear when I introduce a bugfix on fixmap mapping
s/clear/clearer/
> region.
>
> Signed-off-by: Liu Hua <[email protected]>
> ---
> arch/arm/include/asm/fixmap.h | 12 ++++++++----
> arch/arm/mm/highmem.c | 6 +++---
> 2 files changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index bbae919..8675bb9 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -17,9 +17,13 @@
> #define FIXADDR_TOP 0xfffe0000UL
> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>
> -#define FIX_KMAP_BEGIN 0
> -#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
> -
> +/* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
> + *
> + * Instead, using FIX_KMAP_NR_PTES to tell the pte number
> + * belonged to fixmap mapping region.
> + *
> + */
Please move this comment to the commit log instead. This is not
important enough to occupy that much space in the code.
> +#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)
>
> @@ -27,7 +31,7 @@ extern void __this_fixmap_does_not_exist(void);
>
> static inline unsigned long fix_to_virt(const unsigned int idx)
> {
> - if (idx >= FIX_KMAP_END)
> + if (idx >= FIX_KMAP_NR_PTES)
> __this_fixmap_does_not_exist();
> return __fix_to_virt(idx);
> }
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index 21b9e1b..e05e8ad 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -63,7 +63,7 @@ void *kmap_atomic(struct page *page)
> type = kmap_atomic_idx_push();
>
> idx = type + KM_TYPE_NR * smp_processor_id();
> - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> + vaddr = __fix_to_virt(idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> /*
> * With debugging enabled, kunmap_atomic forces that entry to 0.
> @@ -94,7 +94,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(FIX_KMAP_BEGIN + idx));
> + BUG_ON(vaddr != __fix_to_virt(idx));
> set_top_pte(vaddr, __pte(0));
> #else
> (void) idx; /* to kill a warning */
> @@ -117,7 +117,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(FIX_KMAP_BEGIN + idx);
> + vaddr = __fix_to_virt(idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(!pte_none(get_top_pte(vaddr)));
> #endif
> --
> 1.9.0
With the above details fixed you may add:
Reviewed-by: Nicolas Pitre <[email protected]>
> -----------------patch 2-------------------------
>
>
>
> Subject: [PATCH 2/2] ARM : change fixmap mapping region to support 32 CPUs
>
> In 32-bit ARM systems, the fixmap mapping region can support
> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
> configure NR_CPUS up to 32. So there is a mismatch.
>
> This patch moves fixmapping region downwards to region
> 0xffc00000-0xffe00000 . Then the fixmap mapping region can
> support up to 32 CPUs
>
> Signed-off-by: Liu Hua <[email protected]>
> ---
> Documentation/arm/memory.txt | 2 +-
> arch/arm/include/asm/fixmap.h | 16 ++--------------
> arch/arm/include/asm/highmem.h | 1 +
> arch/arm/mm/highmem.c | 27 +++++++++++++++++++++------
> arch/arm/mm/mmu.c | 4 ++++
> 5 files changed, 29 insertions(+), 21 deletions(-)
>
> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
> index d74e8a5..256c5e0 100644
> --- a/Documentation/arm/memory.txt
> +++ b/Documentation/arm/memory.txt
> @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
> fffe0000 fffe7fff ITCM mapping area for platforms with
> ITCM mounted inside the CPU.
>
> -fff00000 fffdffff Fixmap mapping region. Addresses provided
> +fffc0000 ffdfffff Fixmap mapping region. Addresses provided
> by fix_to_virt() will be located here.
>
> fee00000 feffffff Mapping of PCI I/O space. This is a static
> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
> index 8675bb9..fb8a5a7 100644
> --- a/arch/arm/include/asm/fixmap.h
> +++ b/arch/arm/include/asm/fixmap.h
> @@ -1,20 +1,8 @@
> #ifndef _ASM_FIXMAP_H
> #define _ASM_FIXMAP_H
>
> -/*
> - * Nothing too fancy for now.
> - *
> - * On ARM we already have well known fixed virtual addresses imposed by
> - * the architecture such as the vector page which is located at 0xffff0000,
> - * therefore a second level page table is already allocated covering
> - * 0xfff00000 upwards.
> - *
> - * The cache flushing code in proc-xscale.S uses the virtual area between
> - * 0xfffe0000 and 0xfffeffff.
> - */
> -
> -#define FIXADDR_START 0xfff00000UL
> -#define FIXADDR_TOP 0xfffe0000UL
> +#define FIXADDR_START 0xffc00000UL
> +#define FIXADDR_TOP 0xffe00000UL
> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>
> /* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
> index 91b99ab..5355795 100644
> --- a/arch/arm/include/asm/highmem.h
> +++ b/arch/arm/include/asm/highmem.h
> @@ -18,6 +18,7 @@
> } while (0)
>
> extern pte_t *pkmap_page_table;
> +extern pte_t *fixmap_page_table;
>
> extern void *kmap_high(struct page *page);
> extern void kunmap_high(struct page *page);
> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
> index e05e8ad..45aeaac 100644
> --- a/arch/arm/mm/highmem.c
> +++ b/arch/arm/mm/highmem.c
> @@ -18,6 +18,21 @@
> #include <asm/tlbflush.h>
> #include "mm.h"
>
> +pte_t *fixmap_page_table;
> +
> +static inline void set_fixmap_pte(int idx, pte_t pte)
> +{
> + unsigned long vaddr = __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);
> + return *(fixmap_page_table + idx);
> +}
> +
> void *kmap(struct page *page)
> {
> might_sleep();
> @@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
> * With debugging enabled, kunmap_atomic forces that entry to 0.
> * Make sure it was indeed properly unmapped.
> */
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> /*
> * When debugging is off, kunmap_atomic leaves the previous mapping
> * in place, so the contained TLB flush ensures the TLB is updated
> * with the new mapping.
> */
> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(vaddr != __fix_to_virt(idx));
> - set_top_pte(vaddr, __pte(0));
> + set_fixmap_pte(idx, __pte(0));
> #else
> (void) idx; /* to kill a warning */
> #endif
> @@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
> idx = type + KM_TYPE_NR * smp_processor_id();
> vaddr = __fix_to_virt(idx);
> #ifdef CONFIG_DEBUG_HIGHMEM
> - BUG_ON(!pte_none(get_top_pte(vaddr)));
> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
> #endif
> - set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
> + set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
>
> return (void *)vaddr;
> }
> @@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
> if (vaddr < FIXADDR_START)
> return virt_to_page(ptr);
>
> - return pte_page(get_top_pte(vaddr));
> + return pte_page(get_fixmap_pte(vaddr));
> }
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index b68c6b2..09c0a16 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -35,6 +35,7 @@
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> #include <asm/mach/pci.h>
> +#include <asm/fixmap.h>
>
> #include "mm.h"
> #include "tcm.h"
> @@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
> #ifdef CONFIG_HIGHMEM
> pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
> PKMAP_BASE, _PAGE_KERNEL_TABLE);
> +
> + fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
> + FIXADDR_START, _PAGE_KERNEL_TABLE);
> #endif
> }
>
> --
> 1.9.0
Reviewed-by: Nicolas Pitre <[email protected]>
>
>
于 2014/4/14 21:50, Nicolas Pitre 写道:
> On Mon, 14 Apr 2014, Liu hua wrote:
>
>> Yes, it seems that FIX_KMAP_BEGIN and FIX_KMAP_END are not as important for
>> ARM than that for other architectures (MIPS PowerPC x86), whose FIX_KMAP_BEGIN
>> is not 0. I will reminder this in my patch. Anyone who need them can get
>> imformantion there.
>>
>>
>> Now the new patchs are following. Maybe I sould resend the patch series
>> with a new tag. If It is time to do that. Can I add this information
>> "Reviewed-by: Nicolas Pitre <[email protected]>" ?
>>
>> Thanks,
>> Liu Hua.
>>
>> -----------------patch 1-------------------------
>>
>> Subject: [PATCH 1/2] ARM : fixmap : remove FIX_KMAP_BEGIN and FIX_KMAP_END
>>
>> It seems that these two variables are not used by non
>> architecture specific code. And on ARM FIX_KMAP_BEGIN
>> equals zero; FIX_KMAP_END is totally not used by the
>> kernel.
>>
>> This patch removes these two variables. The code will
>> become clear when I introduce a bugfix on fixmap mapping
>
> s/clear/clearer/
>
>> region.
>>
>> Signed-off-by: Liu Hua <[email protected]>
>> ---
>> arch/arm/include/asm/fixmap.h | 12 ++++++++----
>> arch/arm/mm/highmem.c | 6 +++---
>> 2 files changed, 11 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
>> index bbae919..8675bb9 100644
>> --- a/arch/arm/include/asm/fixmap.h
>> +++ b/arch/arm/include/asm/fixmap.h
>> @@ -17,9 +17,13 @@
>> #define FIXADDR_TOP 0xfffe0000UL
>> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>>
>> -#define FIX_KMAP_BEGIN 0
>> -#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
>> -
>> +/* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
>> + *
>> + * Instead, using FIX_KMAP_NR_PTES to tell the pte number
>> + * belonged to fixmap mapping region.
>> + *
>> + */
>
> Please move this comment to the commit log instead. This is not
> important enough to occupy that much space in the code.
>
>> +#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)
>>
>> @@ -27,7 +31,7 @@ extern void __this_fixmap_does_not_exist(void);
>>
>> static inline unsigned long fix_to_virt(const unsigned int idx)
>> {
>> - if (idx >= FIX_KMAP_END)
>> + if (idx >= FIX_KMAP_NR_PTES)
>> __this_fixmap_does_not_exist();
>> return __fix_to_virt(idx);
>> }
>> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
>> index 21b9e1b..e05e8ad 100644
>> --- a/arch/arm/mm/highmem.c
>> +++ b/arch/arm/mm/highmem.c
>> @@ -63,7 +63,7 @@ void *kmap_atomic(struct page *page)
>> type = kmap_atomic_idx_push();
>>
>> idx = type + KM_TYPE_NR * smp_processor_id();
>> - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
>> + vaddr = __fix_to_virt(idx);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> /*
>> * With debugging enabled, kunmap_atomic forces that entry to 0.
>> @@ -94,7 +94,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(FIX_KMAP_BEGIN + idx));
>> + BUG_ON(vaddr != __fix_to_virt(idx));
>> set_top_pte(vaddr, __pte(0));
>> #else
>> (void) idx; /* to kill a warning */
>> @@ -117,7 +117,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(FIX_KMAP_BEGIN + idx);
>> + vaddr = __fix_to_virt(idx);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> BUG_ON(!pte_none(get_top_pte(vaddr)));
>> #endif
>> --
>> 1.9.0
>
> With the above details fixed you may add:
>
> Reviewed-by: Nicolas Pitre <[email protected]>
>
>> -----------------patch 2-------------------------
>>
>>
>>
>> Subject: [PATCH 2/2] ARM : change fixmap mapping region to support 32 CPUs
>>
>> In 32-bit ARM systems, the fixmap mapping region can support
>> no more than 14 CPUs(total: 896k; one CPU: 64K). And we can
>> configure NR_CPUS up to 32. So there is a mismatch.
>>
>> This patch moves fixmapping region downwards to region
>> 0xffc00000-0xffe00000 . Then the fixmap mapping region can
>> support up to 32 CPUs
>>
>> Signed-off-by: Liu Hua <[email protected]>
>> ---
>> Documentation/arm/memory.txt | 2 +-
>> arch/arm/include/asm/fixmap.h | 16 ++--------------
>> arch/arm/include/asm/highmem.h | 1 +
>> arch/arm/mm/highmem.c | 27 +++++++++++++++++++++------
>> arch/arm/mm/mmu.c | 4 ++++
>> 5 files changed, 29 insertions(+), 21 deletions(-)
>>
>> diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
>> index d74e8a5..256c5e0 100644
>> --- a/Documentation/arm/memory.txt
>> +++ b/Documentation/arm/memory.txt
>> @@ -41,7 +41,7 @@ fffe8000 fffeffff DTCM mapping area for platforms with
>> fffe0000 fffe7fff ITCM mapping area for platforms with
>> ITCM mounted inside the CPU.
>>
>> -fff00000 fffdffff Fixmap mapping region. Addresses provided
>> +fffc0000 ffdfffff Fixmap mapping region. Addresses provided
>> by fix_to_virt() will be located here.
>>
>> fee00000 feffffff Mapping of PCI I/O space. This is a static
>> diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
>> index 8675bb9..fb8a5a7 100644
>> --- a/arch/arm/include/asm/fixmap.h
>> +++ b/arch/arm/include/asm/fixmap.h
>> @@ -1,20 +1,8 @@
>> #ifndef _ASM_FIXMAP_H
>> #define _ASM_FIXMAP_H
>>
>> -/*
>> - * Nothing too fancy for now.
>> - *
>> - * On ARM we already have well known fixed virtual addresses imposed by
>> - * the architecture such as the vector page which is located at 0xffff0000,
>> - * therefore a second level page table is already allocated covering
>> - * 0xfff00000 upwards.
>> - *
>> - * The cache flushing code in proc-xscale.S uses the virtual area between
>> - * 0xfffe0000 and 0xfffeffff.
>> - */
>> -
>> -#define FIXADDR_START 0xfff00000UL
>> -#define FIXADDR_TOP 0xfffe0000UL
>> +#define FIXADDR_START 0xffc00000UL
>> +#define FIXADDR_TOP 0xffe00000UL
>> #define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
>>
>> /* Notice : FIX_KMAP_END and FIX_KMAP_BEGIN are removed.
>> diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
>> index 91b99ab..5355795 100644
>> --- a/arch/arm/include/asm/highmem.h
>> +++ b/arch/arm/include/asm/highmem.h
>> @@ -18,6 +18,7 @@
>> } while (0)
>>
>> extern pte_t *pkmap_page_table;
>> +extern pte_t *fixmap_page_table;
>>
>> extern void *kmap_high(struct page *page);
>> extern void kunmap_high(struct page *page);
>> diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
>> index e05e8ad..45aeaac 100644
>> --- a/arch/arm/mm/highmem.c
>> +++ b/arch/arm/mm/highmem.c
>> @@ -18,6 +18,21 @@
>> #include <asm/tlbflush.h>
>> #include "mm.h"
>>
>> +pte_t *fixmap_page_table;
>> +
>> +static inline void set_fixmap_pte(int idx, pte_t pte)
>> +{
>> + unsigned long vaddr = __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);
>> + return *(fixmap_page_table + idx);
>> +}
>> +
>> void *kmap(struct page *page)
>> {
>> might_sleep();
>> @@ -69,14 +84,14 @@ void *kmap_atomic(struct page *page)
>> * With debugging enabled, kunmap_atomic forces that entry to 0.
>> * Make sure it was indeed properly unmapped.
>> */
>> - BUG_ON(!pte_none(get_top_pte(vaddr)));
>> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
>> #endif
>> /*
>> * When debugging is off, kunmap_atomic leaves the previous mapping
>> * in place, so the contained TLB flush ensures the TLB is updated
>> * with the new mapping.
>> */
>> - set_top_pte(vaddr, mk_pte(page, kmap_prot));
>> + set_fixmap_pte(idx, mk_pte(page, kmap_prot));
>>
>> return (void *)vaddr;
>> }
>> @@ -95,7 +110,7 @@ void __kunmap_atomic(void *kvaddr)
>> __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> BUG_ON(vaddr != __fix_to_virt(idx));
>> - set_top_pte(vaddr, __pte(0));
>> + set_fixmap_pte(idx, __pte(0));
>> #else
>> (void) idx; /* to kill a warning */
>> #endif
>> @@ -119,9 +134,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
>> idx = type + KM_TYPE_NR * smp_processor_id();
>> vaddr = __fix_to_virt(idx);
>> #ifdef CONFIG_DEBUG_HIGHMEM
>> - BUG_ON(!pte_none(get_top_pte(vaddr)));
>> + BUG_ON(!pte_none(*(fixmap_page_table + idx)));
>> #endif
>> - set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
>> + set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
>>
>> return (void *)vaddr;
>> }
>> @@ -133,5 +148,5 @@ struct page *kmap_atomic_to_page(const void *ptr)
>> if (vaddr < FIXADDR_START)
>> return virt_to_page(ptr);
>>
>> - return pte_page(get_top_pte(vaddr));
>> + return pte_page(get_fixmap_pte(vaddr));
>> }
>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>> index b68c6b2..09c0a16 100644
>> --- a/arch/arm/mm/mmu.c
>> +++ b/arch/arm/mm/mmu.c
>> @@ -35,6 +35,7 @@
>> #include <asm/mach/arch.h>
>> #include <asm/mach/map.h>
>> #include <asm/mach/pci.h>
>> +#include <asm/fixmap.h>
>>
>> #include "mm.h"
>> #include "tcm.h"
>> @@ -1359,6 +1360,9 @@ static void __init kmap_init(void)
>> #ifdef CONFIG_HIGHMEM
>> pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
>> PKMAP_BASE, _PAGE_KERNEL_TABLE);
>> +
>> + fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
>> + FIXADDR_START, _PAGE_KERNEL_TABLE);
>> #endif
>> }
>>
>> --
>> 1.9.0
>
> Reviewed-by: Nicolas Pitre <[email protected]>
>
>>
>>
Ok, I will send the patch series with tag "v3". If there is no
bothersome details. you can add "Reviewed-by:" at than time!
Thanks,
Liu Hua