* HIGHMEM fix for r24k
@ 2009-04-23 22:23 Jon Fraser
2009-04-24 1:17 ` David VomLehn
2009-04-24 15:43 ` Ralf Baechle
0 siblings, 2 replies; 8+ messages in thread
From: Jon Fraser @ 2009-04-23 22:23 UTC (permalink / raw)
To: linux-mips@linux-mips.org
For all you guys working on HIGMEM.
I found a bug that was keeping HIGHMEM from working on mips 24k
processors starting at 2.6.26.
2008-04-28 Chris Dearman [MIPS] Allow setting of the cache attribute at
run ...
This commit introduces the variable _page_cachable_default, which
defaults to zero.
arch/mips/mm/cache.c:
unsigned long _page_cachable_default;
The variable is used to create the prototype PTE for __kmap_atomic in
arch/mips/mm/init.c:kmap_init.
The variable is initialized in arch/mips/mm/c-r4k.c:coherency_setup.
Unfortunately, the variable is used before it is initialized properly.
As a result, all kmap_atomic PTE have the cache coherency algorithm mode set to 0.
Mode 0 is "cacheable, nocoherent, write-through, no write allocate".
This is not valid on my r24k and my not be on any r24k.
The result is that writes to kmap_atomic pages get corrupted. This was confirmed
using a jtag probe, examining uncached memory, the D cache itself, and cached memory.
I've changed the variable declaration to be:
unsigned long _page_cachable_default = _CACHE_CACHABLE_NONCOHERENT;
My highmem kernel now works. This is w/o discontiguous or sparsemem set.
I do have two discontiguous banks of memory.
I'm not sure of the best fix. Simple reordering of the the init code to
set the variable before it gets used breaks other initialization.
My kernel tree is a big mess right now and I'm back at 2.6.26 where the bug was introduce.
As soon as I have 2.6.28 or 29 working, I'll post any more changes.
Jon Fraser
Broadcom
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: HIGHMEM fix for r24k
2009-04-23 22:23 HIGHMEM fix for r24k Jon Fraser
@ 2009-04-24 1:17 ` David VomLehn
2009-04-24 15:43 ` Ralf Baechle
1 sibling, 0 replies; 8+ messages in thread
From: David VomLehn @ 2009-04-24 1:17 UTC (permalink / raw)
To: Jon Fraser; +Cc: linux-mips@linux-mips.org
On Thu, Apr 23, 2009 at 06:23:44PM -0400, Jon Fraser wrote:
> For all you guys working on HIGMEM.
>
> I found a bug that was keeping HIGHMEM from working on mips 24k
> processors starting at 2.6.26.
>
>
> 2008-04-28 Chris Dearman [MIPS] Allow setting of the cache attribute at
> run ...
>
> This commit introduces the variable _page_cachable_default, which
> defaults to zero.
>
> arch/mips/mm/cache.c:
> unsigned long _page_cachable_default;
>
> The variable is used to create the prototype PTE for __kmap_atomic in
> arch/mips/mm/init.c:kmap_init.
>
> The variable is initialized in arch/mips/mm/c-r4k.c:coherency_setup.
>
> Unfortunately, the variable is used before it is initialized properly.
> As a result, all kmap_atomic PTE have the cache coherency algorithm mode set to 0.
> Mode 0 is "cacheable, nocoherent, write-through, no write allocate".
> This is not valid on my r24k and my not be on any r24k.
>
> The result is that writes to kmap_atomic pages get corrupted. This was confirmed
> using a jtag probe, examining uncached memory, the D cache itself, and cached memory.
Ouch, sounds like a nasty bit of work finding this...thanks!
> Jon Fraser
> Broadcom
David VomLehn
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: HIGHMEM fix for r24k
2009-04-23 22:23 HIGHMEM fix for r24k Jon Fraser
2009-04-24 1:17 ` David VomLehn
@ 2009-04-24 15:43 ` Ralf Baechle
2009-04-24 16:13 ` Jon Fraser
1 sibling, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2009-04-24 15:43 UTC (permalink / raw)
To: Jon Fraser; +Cc: linux-mips@linux-mips.org
On Thu, Apr 23, 2009 at 06:23:44PM -0400, Jon Fraser wrote:
> For all you guys working on HIGMEM.
>
> I found a bug that was keeping HIGHMEM from working on mips 24k
> processors starting at 2.6.26.
>
>
> 2008-04-28 Chris Dearman [MIPS] Allow setting of the cache attribute at
> run ...
>
> This commit introduces the variable _page_cachable_default, which
> defaults to zero.
>
> arch/mips/mm/cache.c:
> unsigned long _page_cachable_default;
>
> The variable is used to create the prototype PTE for __kmap_atomic in
> arch/mips/mm/init.c:kmap_init.
>
> The variable is initialized in arch/mips/mm/c-r4k.c:coherency_setup.
>
> Unfortunately, the variable is used before it is initialized properly.
> As a result, all kmap_atomic PTE have the cache coherency algorithm mode set to 0.
> Mode 0 is "cacheable, nocoherent, write-through, no write allocate".
> This is not valid on my r24k and my not be on any r24k.
>
> The result is that writes to kmap_atomic pages get corrupted. This was confirmed
> using a jtag probe, examining uncached memory, the D cache itself, and cached memory.
>
> I've changed the variable declaration to be:
> unsigned long _page_cachable_default = _CACHE_CACHABLE_NONCOHERENT;
There is no safe value of _page_cachable_default; it's all processor and
even platform dependent. What you found is essentially an ordering bug
so let's fix the ordering!
Ralf
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: HIGHMEM fix for r24k
2009-04-24 15:43 ` Ralf Baechle
@ 2009-04-24 16:13 ` Jon Fraser
2009-04-25 9:24 ` Ralf Baechle
0 siblings, 1 reply; 8+ messages in thread
From: Jon Fraser @ 2009-04-24 16:13 UTC (permalink / raw)
To: Ralf Baechle; +Cc: jfraser, linux-mips@linux-mips.org
On Fri, 2009-04-24 at 08:43 -0700, Ralf Baechle wrote:
> On Thu, Apr 23, 2009 at 06:23:44PM -0400, Jon Fraser wrote:
>
> > For all you guys working on HIGMEM.
> >
> > I found a bug that was keeping HIGHMEM from working on mips 24k
> > processors starting at 2.6.26.
> >
> >
> > 2008-04-28 Chris Dearman [MIPS] Allow setting of the cache attribute at
> > run ...
> >
> > This commit introduces the variable _page_cachable_default, which
> > defaults to zero.
> >
> > arch/mips/mm/cache.c:
> > unsigned long _page_cachable_default;
> >
> > The variable is used to create the prototype PTE for __kmap_atomic in
> > arch/mips/mm/init.c:kmap_init.
> >
> > The variable is initialized in arch/mips/mm/c-r4k.c:coherency_setup.
> >
> > Unfortunately, the variable is used before it is initialized properly.
> > As a result, all kmap_atomic PTE have the cache coherency algorithm mode set to 0.
> > Mode 0 is "cacheable, nocoherent, write-through, no write allocate".
> > This is not valid on my r24k and my not be on any r24k.
> >
> > The result is that writes to kmap_atomic pages get corrupted. This was confirmed
> > using a jtag probe, examining uncached memory, the D cache itself, and cached memory.
> >
> > I've changed the variable declaration to be:
> > unsigned long _page_cachable_default = _CACHE_CACHABLE_NONCOHERENT;
>
> There is no safe value of _page_cachable_default; it's all processor and
> even platform dependent. What you found is essentially an ordering bug
> so let's fix the ordering!
>
> Ralf
>
That's why I haven't proposed a fix yet. But there are other people
dealing with the same HIGHMEM issues and I wanted them to know about the
problem.
Jon
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: HIGHMEM fix for r24k
2009-04-24 16:13 ` Jon Fraser
@ 2009-04-25 9:24 ` Ralf Baechle
2009-05-04 14:49 ` Jon Fraser
0 siblings, 1 reply; 8+ messages in thread
From: Ralf Baechle @ 2009-04-25 9:24 UTC (permalink / raw)
To: Jon Fraser; +Cc: linux-mips@linux-mips.org
On Fri, Apr 24, 2009 at 12:13:52PM -0400, Jon Fraser wrote:
> That's why I haven't proposed a fix yet. But there are other people
> dealing with the same HIGHMEM issues and I wanted them to know about the
> problem.
Can you test below fix? Thanks,
Ralf
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/fixmap.h | 3 +++
arch/mips/include/asm/highmem.h | 6 ++++--
arch/mips/mm/highmem.c | 25 +++++++++++++++++++------
arch/mips/mm/init.c | 26 --------------------------
4 files changed, 26 insertions(+), 34 deletions(-)
diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
index 9cc8522..0f5caa1 100644
--- a/arch/mips/include/asm/fixmap.h
+++ b/arch/mips/include/asm/fixmap.h
@@ -108,6 +108,9 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
return __virt_to_fix(vaddr);
}
+#define kmap_get_fixmap_pte(vaddr) \
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
/*
* Called from pgtable_init()
*/
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
index 4374ab2..25adfb0 100644
--- a/arch/mips/include/asm/highmem.h
+++ b/arch/mips/include/asm/highmem.h
@@ -30,8 +30,6 @@
/* declarations for highmem.c */
extern unsigned long highstart_pfn, highend_pfn;
-extern pte_t *kmap_pte;
-extern pgprot_t kmap_prot;
extern pte_t *pkmap_page_table;
/*
@@ -62,6 +60,10 @@ extern struct page *__kmap_atomic_to_page(void *ptr);
#define flush_cache_kmaps() flush_cache_all()
+extern void kmap_init(void);
+
+#define kmap_prot PAGE_KERNEL
+
#endif /* __KERNEL__ */
#endif /* _ASM_HIGHMEM_H */
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 4481656..2b1309b 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -1,7 +1,12 @@
#include <linux/module.h>
#include <linux/highmem.h>
+#include <asm/fixmap.h>
#include <asm/tlbflush.h>
+static pte_t *kmap_pte;
+
+unsigned long highstart_pfn, highend_pfn;
+
void *__kmap(struct page *page)
{
void *addr;
@@ -14,6 +19,7 @@ void *__kmap(struct page *page)
return addr;
}
+EXPORT_SYMBOL(__kmap);
void __kunmap(struct page *page)
{
@@ -22,6 +28,7 @@ void __kunmap(struct page *page)
return;
kunmap_high(page);
}
+EXPORT_SYMBOL(__kunmap);
/*
* kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
@@ -48,11 +55,12 @@ void *__kmap_atomic(struct page *page, enum km_type type)
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(*(kmap_pte - idx)));
#endif
- set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+ set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
local_flush_tlb_one((unsigned long)vaddr);
return (void*) vaddr;
}
+EXPORT_SYMBOL(__kmap_atomic);
void __kunmap_atomic(void *kvaddr, enum km_type type)
{
@@ -77,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
pagefault_enable();
}
+EXPORT_SYMBOL(__kunmap_atomic);
/*
* This is the same as kmap_atomic() but can map memory that doesn't
@@ -92,7 +101,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+ set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
flush_tlb_one(vaddr);
return (void*) vaddr;
@@ -111,7 +120,11 @@ struct page *__kmap_atomic_to_page(void *ptr)
return pte_page(*pte);
}
-EXPORT_SYMBOL(__kmap);
-EXPORT_SYMBOL(__kunmap);
-EXPORT_SYMBOL(__kmap_atomic);
-EXPORT_SYMBOL(__kunmap_atomic);
+void __init kmap_init(void)
+{
+ unsigned long kmap_vstart;
+
+ /* cache the first kmap pte */
+ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+ kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index d934894..c551129 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -104,14 +104,6 @@ unsigned long setup_zero_pages(void)
return 1UL << order;
}
-/*
- * These are almost like kmap_atomic / kunmap_atmic except they take an
- * additional address argument as the hint.
- */
-
-#define kmap_get_fixmap_pte(vaddr) \
- pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
-
#ifdef CONFIG_MIPS_MT_SMTC
static pte_t *kmap_coherent_pte;
static void __init kmap_coherent_init(void)
@@ -264,24 +256,6 @@ void copy_from_user_page(struct vm_area_struct *vma,
}
}
-#ifdef CONFIG_HIGHMEM
-unsigned long highstart_pfn, highend_pfn;
-
-pte_t *kmap_pte;
-pgprot_t kmap_prot;
-
-static void __init kmap_init(void)
-{
- unsigned long kmap_vstart;
-
- /* cache the first kmap pte */
- kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
- kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
-
- kmap_prot = PAGE_KERNEL;
-}
-#endif /* CONFIG_HIGHMEM */
-
void __init fixrange_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: HIGHMEM fix for r24k
2009-04-25 9:24 ` Ralf Baechle
@ 2009-05-04 14:49 ` Jon Fraser
2009-05-04 17:23 ` David VomLehn (dvomlehn)
0 siblings, 1 reply; 8+ messages in thread
From: Jon Fraser @ 2009-05-04 14:49 UTC (permalink / raw)
To: Ralf Baechle; +Cc: jfraser, linux-mips@linux-mips.org
Hi Ralf,
Just wanted to acknowledge your email. I've been playing catch
up for the last week after spending a large amount of unscheduled time
finding the root cause of this bug. I should be able to get to applying
this patch this week. Were these against HOT or 2.6.29?
Jon
On Sat, 2009-04-25 at 02:24 -0700, Ralf Baechle wrote:
> On Fri, Apr 24, 2009 at 12:13:52PM -0400, Jon Fraser wrote:
>
> > That's why I haven't proposed a fix yet. But there are other people
> > dealing with the same HIGHMEM issues and I wanted them to know about the
> > problem.
>
> Can you test below fix? Thanks,
>
> Ralf
>
> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
>
> arch/mips/include/asm/fixmap.h | 3 +++
> arch/mips/include/asm/highmem.h | 6 ++++--
> arch/mips/mm/highmem.c | 25 +++++++++++++++++++------
> arch/mips/mm/init.c | 26 --------------------------
> 4 files changed, 26 insertions(+), 34 deletions(-)
>
> diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
> index 9cc8522..0f5caa1 100644
> --- a/arch/mips/include/asm/fixmap.h
> +++ b/arch/mips/include/asm/fixmap.h
> @@ -108,6 +108,9 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
> return __virt_to_fix(vaddr);
> }
>
> +#define kmap_get_fixmap_pte(vaddr) \
> + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
> +
> /*
> * Called from pgtable_init()
> */
> diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
> index 4374ab2..25adfb0 100644
> --- a/arch/mips/include/asm/highmem.h
> +++ b/arch/mips/include/asm/highmem.h
> @@ -30,8 +30,6 @@
> /* declarations for highmem.c */
> extern unsigned long highstart_pfn, highend_pfn;
>
> -extern pte_t *kmap_pte;
> -extern pgprot_t kmap_prot;
> extern pte_t *pkmap_page_table;
>
> /*
> @@ -62,6 +60,10 @@ extern struct page *__kmap_atomic_to_page(void *ptr);
>
> #define flush_cache_kmaps() flush_cache_all()
>
> +extern void kmap_init(void);
> +
> +#define kmap_prot PAGE_KERNEL
> +
> #endif /* __KERNEL__ */
>
> #endif /* _ASM_HIGHMEM_H */
> diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
> index 4481656..2b1309b 100644
> --- a/arch/mips/mm/highmem.c
> +++ b/arch/mips/mm/highmem.c
> @@ -1,7 +1,12 @@
> #include <linux/module.h>
> #include <linux/highmem.h>
> +#include <asm/fixmap.h>
> #include <asm/tlbflush.h>
>
> +static pte_t *kmap_pte;
> +
> +unsigned long highstart_pfn, highend_pfn;
> +
> void *__kmap(struct page *page)
> {
> void *addr;
> @@ -14,6 +19,7 @@ void *__kmap(struct page *page)
>
> return addr;
> }
> +EXPORT_SYMBOL(__kmap);
>
> void __kunmap(struct page *page)
> {
> @@ -22,6 +28,7 @@ void __kunmap(struct page *page)
> return;
> kunmap_high(page);
> }
> +EXPORT_SYMBOL(__kunmap);
>
> /*
> * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
> @@ -48,11 +55,12 @@ void *__kmap_atomic(struct page *page, enum km_type type)
> #ifdef CONFIG_DEBUG_HIGHMEM
> BUG_ON(!pte_none(*(kmap_pte - idx)));
> #endif
> - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
> + set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
> local_flush_tlb_one((unsigned long)vaddr);
>
> return (void*) vaddr;
> }
> +EXPORT_SYMBOL(__kmap_atomic);
>
> void __kunmap_atomic(void *kvaddr, enum km_type type)
> {
> @@ -77,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
>
> pagefault_enable();
> }
> +EXPORT_SYMBOL(__kunmap_atomic);
>
> /*
> * This is the same as kmap_atomic() but can map memory that doesn't
> @@ -92,7 +101,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
> debug_kmap_atomic(type);
> idx = type + KM_TYPE_NR*smp_processor_id();
> vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> - set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
> + set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
> flush_tlb_one(vaddr);
>
> return (void*) vaddr;
> @@ -111,7 +120,11 @@ struct page *__kmap_atomic_to_page(void *ptr)
> return pte_page(*pte);
> }
>
> -EXPORT_SYMBOL(__kmap);
> -EXPORT_SYMBOL(__kunmap);
> -EXPORT_SYMBOL(__kmap_atomic);
> -EXPORT_SYMBOL(__kunmap_atomic);
> +void __init kmap_init(void)
> +{
> + unsigned long kmap_vstart;
> +
> + /* cache the first kmap pte */
> + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> +}
> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> index d934894..c551129 100644
> --- a/arch/mips/mm/init.c
> +++ b/arch/mips/mm/init.c
> @@ -104,14 +104,6 @@ unsigned long setup_zero_pages(void)
> return 1UL << order;
> }
>
> -/*
> - * These are almost like kmap_atomic / kunmap_atmic except they take an
> - * additional address argument as the hint.
> - */
> -
> -#define kmap_get_fixmap_pte(vaddr) \
> - pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
> -
> #ifdef CONFIG_MIPS_MT_SMTC
> static pte_t *kmap_coherent_pte;
> static void __init kmap_coherent_init(void)
> @@ -264,24 +256,6 @@ void copy_from_user_page(struct vm_area_struct *vma,
> }
> }
>
> -#ifdef CONFIG_HIGHMEM
> -unsigned long highstart_pfn, highend_pfn;
> -
> -pte_t *kmap_pte;
> -pgprot_t kmap_prot;
> -
> -static void __init kmap_init(void)
> -{
> - unsigned long kmap_vstart;
> -
> - /* cache the first kmap pte */
> - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> -
> - kmap_prot = PAGE_KERNEL;
> -}
> -#endif /* CONFIG_HIGHMEM */
> -
> void __init fixrange_init(unsigned long start, unsigned long end,
> pgd_t *pgd_base)
> {
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: HIGHMEM fix for r24k
2009-05-04 14:49 ` Jon Fraser
@ 2009-05-04 17:23 ` David VomLehn (dvomlehn)
2009-05-04 17:23 ` David VomLehn (dvomlehn)
0 siblings, 1 reply; 8+ messages in thread
From: David VomLehn (dvomlehn) @ 2009-05-04 17:23 UTC (permalink / raw)
To: jfraser, Ralf Baechle; +Cc: linux-mips
I applied it against the head of tree, but it didn't work. I've been too
tied up with other things, though, so I haven't been able to dig into
it. It is entirely possible that there is nothing wrong with the patch.
> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org
> [mailto:linux-mips-bounce@linux-mips.org] On Behalf Of Jon Fraser
> Sent: Monday, May 04, 2009 7:50 AM
> To: Ralf Baechle
> Cc: jfraser@broadcom.com; linux-mips@linux-mips.org
> Subject: Re: HIGHMEM fix for r24k
>
> Hi Ralf,
>
> Just wanted to acknowledge your email. I've been
> playing catch
> up for the last week after spending a large amount of unscheduled time
> finding the root cause of this bug. I should be able to get
> to applying
> this patch this week. Were these against HOT or 2.6.29?
>
> Jon
>
>
> On Sat, 2009-04-25 at 02:24 -0700, Ralf Baechle wrote:
> > On Fri, Apr 24, 2009 at 12:13:52PM -0400, Jon Fraser wrote:
> >
> > > That's why I haven't proposed a fix yet. But there are
> other people
> > > dealing with the same HIGHMEM issues and I wanted them to
> know about the
> > > problem.
> >
> > Can you test below fix? Thanks,
> >
> > Ralf
> >
> > Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
> >
> > arch/mips/include/asm/fixmap.h | 3 +++
> > arch/mips/include/asm/highmem.h | 6 ++++--
> > arch/mips/mm/highmem.c | 25 +++++++++++++++++++------
> > arch/mips/mm/init.c | 26 --------------------------
> > 4 files changed, 26 insertions(+), 34 deletions(-)
> >
> > diff --git a/arch/mips/include/asm/fixmap.h
> b/arch/mips/include/asm/fixmap.h
> > index 9cc8522..0f5caa1 100644
> > --- a/arch/mips/include/asm/fixmap.h
> > +++ b/arch/mips/include/asm/fixmap.h
> > @@ -108,6 +108,9 @@ static inline unsigned long
> virt_to_fix(const unsigned long vaddr)
> > return __virt_to_fix(vaddr);
> > }
> >
> > +#define kmap_get_fixmap_pte(vaddr)
> \
> > +
> pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
> (vaddr)), (vaddr)), (vaddr))
> > +
> > /*
> > * Called from pgtable_init()
> > */
> > diff --git a/arch/mips/include/asm/highmem.h
> b/arch/mips/include/asm/highmem.h
> > index 4374ab2..25adfb0 100644
> > --- a/arch/mips/include/asm/highmem.h
> > +++ b/arch/mips/include/asm/highmem.h
> > @@ -30,8 +30,6 @@
> > /* declarations for highmem.c */
> > extern unsigned long highstart_pfn, highend_pfn;
> >
> > -extern pte_t *kmap_pte;
> > -extern pgprot_t kmap_prot;
> > extern pte_t *pkmap_page_table;
> >
> > /*
> > @@ -62,6 +60,10 @@ extern struct page
> *__kmap_atomic_to_page(void *ptr);
> >
> > #define flush_cache_kmaps() flush_cache_all()
> >
> > +extern void kmap_init(void);
> > +
> > +#define kmap_prot PAGE_KERNEL
> > +
> > #endif /* __KERNEL__ */
> >
> > #endif /* _ASM_HIGHMEM_H */
> > diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
> > index 4481656..2b1309b 100644
> > --- a/arch/mips/mm/highmem.c
> > +++ b/arch/mips/mm/highmem.c
> > @@ -1,7 +1,12 @@
> > #include <linux/module.h>
> > #include <linux/highmem.h>
> > +#include <asm/fixmap.h>
> > #include <asm/tlbflush.h>
> >
> > +static pte_t *kmap_pte;
> > +
> > +unsigned long highstart_pfn, highend_pfn;
> > +
> > void *__kmap(struct page *page)
> > {
> > void *addr;
> > @@ -14,6 +19,7 @@ void *__kmap(struct page *page)
> >
> > return addr;
> > }
> > +EXPORT_SYMBOL(__kmap);
> >
> > void __kunmap(struct page *page)
> > {
> > @@ -22,6 +28,7 @@ void __kunmap(struct page *page)
> > return;
> > kunmap_high(page);
> > }
> > +EXPORT_SYMBOL(__kunmap);
> >
> > /*
> > * kmap_atomic/kunmap_atomic is significantly faster than
> kmap/kunmap because
> > @@ -48,11 +55,12 @@ void *__kmap_atomic(struct page *page,
> enum km_type type)
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > BUG_ON(!pte_none(*(kmap_pte - idx)));
> > #endif
> > - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
> > + set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
> > local_flush_tlb_one((unsigned long)vaddr);
> >
> > return (void*) vaddr;
> > }
> > +EXPORT_SYMBOL(__kmap_atomic);
> >
> > void __kunmap_atomic(void *kvaddr, enum km_type type)
> > {
> > @@ -77,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum
> km_type type)
> >
> > pagefault_enable();
> > }
> > +EXPORT_SYMBOL(__kunmap_atomic);
> >
> > /*
> > * This is the same as kmap_atomic() but can map memory
> that doesn't
> > @@ -92,7 +101,7 @@ void *kmap_atomic_pfn(unsigned long pfn,
> enum km_type type)
> > debug_kmap_atomic(type);
> > idx = type + KM_TYPE_NR*smp_processor_id();
> > vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> > - set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
> > + set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
> > flush_tlb_one(vaddr);
> >
> > return (void*) vaddr;
> > @@ -111,7 +120,11 @@ struct page *__kmap_atomic_to_page(void *ptr)
> > return pte_page(*pte);
> > }
> >
> > -EXPORT_SYMBOL(__kmap);
> > -EXPORT_SYMBOL(__kunmap);
> > -EXPORT_SYMBOL(__kmap_atomic);
> > -EXPORT_SYMBOL(__kunmap_atomic);
> > +void __init kmap_init(void)
> > +{
> > + unsigned long kmap_vstart;
> > +
> > + /* cache the first kmap pte */
> > + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> > + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> > +}
> > diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> > index d934894..c551129 100644
> > --- a/arch/mips/mm/init.c
> > +++ b/arch/mips/mm/init.c
> > @@ -104,14 +104,6 @@ unsigned long setup_zero_pages(void)
> > return 1UL << order;
> > }
> >
> > -/*
> > - * These are almost like kmap_atomic / kunmap_atmic except
> they take an
> > - * additional address argument as the hint.
> > - */
> > -
> > -#define kmap_get_fixmap_pte(vaddr)
> \
> > -
> pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
> (vaddr)), (vaddr)), (vaddr))
> > -
> > #ifdef CONFIG_MIPS_MT_SMTC
> > static pte_t *kmap_coherent_pte;
> > static void __init kmap_coherent_init(void)
> > @@ -264,24 +256,6 @@ void copy_from_user_page(struct
> vm_area_struct *vma,
> > }
> > }
> >
> > -#ifdef CONFIG_HIGHMEM
> > -unsigned long highstart_pfn, highend_pfn;
> > -
> > -pte_t *kmap_pte;
> > -pgprot_t kmap_prot;
> > -
> > -static void __init kmap_init(void)
> > -{
> > - unsigned long kmap_vstart;
> > -
> > - /* cache the first kmap pte */
> > - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> > - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> > -
> > - kmap_prot = PAGE_KERNEL;
> > -}
> > -#endif /* CONFIG_HIGHMEM */
> > -
> > void __init fixrange_init(unsigned long start, unsigned long end,
> > pgd_t *pgd_base)
> > {
> >
>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: HIGHMEM fix for r24k
2009-05-04 17:23 ` David VomLehn (dvomlehn)
@ 2009-05-04 17:23 ` David VomLehn (dvomlehn)
0 siblings, 0 replies; 8+ messages in thread
From: David VomLehn (dvomlehn) @ 2009-05-04 17:23 UTC (permalink / raw)
To: jfraser, Ralf Baechle; +Cc: linux-mips
I applied it against the head of tree, but it didn't work. I've been too
tied up with other things, though, so I haven't been able to dig into
it. It is entirely possible that there is nothing wrong with the patch.
> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org
> [mailto:linux-mips-bounce@linux-mips.org] On Behalf Of Jon Fraser
> Sent: Monday, May 04, 2009 7:50 AM
> To: Ralf Baechle
> Cc: jfraser@broadcom.com; linux-mips@linux-mips.org
> Subject: Re: HIGHMEM fix for r24k
>
> Hi Ralf,
>
> Just wanted to acknowledge your email. I've been
> playing catch
> up for the last week after spending a large amount of unscheduled time
> finding the root cause of this bug. I should be able to get
> to applying
> this patch this week. Were these against HOT or 2.6.29?
>
> Jon
>
>
> On Sat, 2009-04-25 at 02:24 -0700, Ralf Baechle wrote:
> > On Fri, Apr 24, 2009 at 12:13:52PM -0400, Jon Fraser wrote:
> >
> > > That's why I haven't proposed a fix yet. But there are
> other people
> > > dealing with the same HIGHMEM issues and I wanted them to
> know about the
> > > problem.
> >
> > Can you test below fix? Thanks,
> >
> > Ralf
> >
> > Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
> >
> > arch/mips/include/asm/fixmap.h | 3 +++
> > arch/mips/include/asm/highmem.h | 6 ++++--
> > arch/mips/mm/highmem.c | 25 +++++++++++++++++++------
> > arch/mips/mm/init.c | 26 --------------------------
> > 4 files changed, 26 insertions(+), 34 deletions(-)
> >
> > diff --git a/arch/mips/include/asm/fixmap.h
> b/arch/mips/include/asm/fixmap.h
> > index 9cc8522..0f5caa1 100644
> > --- a/arch/mips/include/asm/fixmap.h
> > +++ b/arch/mips/include/asm/fixmap.h
> > @@ -108,6 +108,9 @@ static inline unsigned long
> virt_to_fix(const unsigned long vaddr)
> > return __virt_to_fix(vaddr);
> > }
> >
> > +#define kmap_get_fixmap_pte(vaddr)
> \
> > +
> pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
> (vaddr)), (vaddr)), (vaddr))
> > +
> > /*
> > * Called from pgtable_init()
> > */
> > diff --git a/arch/mips/include/asm/highmem.h
> b/arch/mips/include/asm/highmem.h
> > index 4374ab2..25adfb0 100644
> > --- a/arch/mips/include/asm/highmem.h
> > +++ b/arch/mips/include/asm/highmem.h
> > @@ -30,8 +30,6 @@
> > /* declarations for highmem.c */
> > extern unsigned long highstart_pfn, highend_pfn;
> >
> > -extern pte_t *kmap_pte;
> > -extern pgprot_t kmap_prot;
> > extern pte_t *pkmap_page_table;
> >
> > /*
> > @@ -62,6 +60,10 @@ extern struct page
> *__kmap_atomic_to_page(void *ptr);
> >
> > #define flush_cache_kmaps() flush_cache_all()
> >
> > +extern void kmap_init(void);
> > +
> > +#define kmap_prot PAGE_KERNEL
> > +
> > #endif /* __KERNEL__ */
> >
> > #endif /* _ASM_HIGHMEM_H */
> > diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
> > index 4481656..2b1309b 100644
> > --- a/arch/mips/mm/highmem.c
> > +++ b/arch/mips/mm/highmem.c
> > @@ -1,7 +1,12 @@
> > #include <linux/module.h>
> > #include <linux/highmem.h>
> > +#include <asm/fixmap.h>
> > #include <asm/tlbflush.h>
> >
> > +static pte_t *kmap_pte;
> > +
> > +unsigned long highstart_pfn, highend_pfn;
> > +
> > void *__kmap(struct page *page)
> > {
> > void *addr;
> > @@ -14,6 +19,7 @@ void *__kmap(struct page *page)
> >
> > return addr;
> > }
> > +EXPORT_SYMBOL(__kmap);
> >
> > void __kunmap(struct page *page)
> > {
> > @@ -22,6 +28,7 @@ void __kunmap(struct page *page)
> > return;
> > kunmap_high(page);
> > }
> > +EXPORT_SYMBOL(__kunmap);
> >
> > /*
> > * kmap_atomic/kunmap_atomic is significantly faster than
> kmap/kunmap because
> > @@ -48,11 +55,12 @@ void *__kmap_atomic(struct page *page,
> enum km_type type)
> > #ifdef CONFIG_DEBUG_HIGHMEM
> > BUG_ON(!pte_none(*(kmap_pte - idx)));
> > #endif
> > - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
> > + set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
> > local_flush_tlb_one((unsigned long)vaddr);
> >
> > return (void*) vaddr;
> > }
> > +EXPORT_SYMBOL(__kmap_atomic);
> >
> > void __kunmap_atomic(void *kvaddr, enum km_type type)
> > {
> > @@ -77,6 +85,7 @@ void __kunmap_atomic(void *kvaddr, enum
> km_type type)
> >
> > pagefault_enable();
> > }
> > +EXPORT_SYMBOL(__kunmap_atomic);
> >
> > /*
> > * This is the same as kmap_atomic() but can map memory
> that doesn't
> > @@ -92,7 +101,7 @@ void *kmap_atomic_pfn(unsigned long pfn,
> enum km_type type)
> > debug_kmap_atomic(type);
> > idx = type + KM_TYPE_NR*smp_processor_id();
> > vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
> > - set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
> > + set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
> > flush_tlb_one(vaddr);
> >
> > return (void*) vaddr;
> > @@ -111,7 +120,11 @@ struct page *__kmap_atomic_to_page(void *ptr)
> > return pte_page(*pte);
> > }
> >
> > -EXPORT_SYMBOL(__kmap);
> > -EXPORT_SYMBOL(__kunmap);
> > -EXPORT_SYMBOL(__kmap_atomic);
> > -EXPORT_SYMBOL(__kunmap_atomic);
> > +void __init kmap_init(void)
> > +{
> > + unsigned long kmap_vstart;
> > +
> > + /* cache the first kmap pte */
> > + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> > + kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> > +}
> > diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> > index d934894..c551129 100644
> > --- a/arch/mips/mm/init.c
> > +++ b/arch/mips/mm/init.c
> > @@ -104,14 +104,6 @@ unsigned long setup_zero_pages(void)
> > return 1UL << order;
> > }
> >
> > -/*
> > - * These are almost like kmap_atomic / kunmap_atmic except
> they take an
> > - * additional address argument as the hint.
> > - */
> > -
> > -#define kmap_get_fixmap_pte(vaddr)
> \
> > -
> pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
> (vaddr)), (vaddr)), (vaddr))
> > -
> > #ifdef CONFIG_MIPS_MT_SMTC
> > static pte_t *kmap_coherent_pte;
> > static void __init kmap_coherent_init(void)
> > @@ -264,24 +256,6 @@ void copy_from_user_page(struct
> vm_area_struct *vma,
> > }
> > }
> >
> > -#ifdef CONFIG_HIGHMEM
> > -unsigned long highstart_pfn, highend_pfn;
> > -
> > -pte_t *kmap_pte;
> > -pgprot_t kmap_prot;
> > -
> > -static void __init kmap_init(void)
> > -{
> > - unsigned long kmap_vstart;
> > -
> > - /* cache the first kmap pte */
> > - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
> > - kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
> > -
> > - kmap_prot = PAGE_KERNEL;
> > -}
> > -#endif /* CONFIG_HIGHMEM */
> > -
> > void __init fixrange_init(unsigned long start, unsigned long end,
> > pgd_t *pgd_base)
> > {
> >
>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-05-04 17:23 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-23 22:23 HIGHMEM fix for r24k Jon Fraser
2009-04-24 1:17 ` David VomLehn
2009-04-24 15:43 ` Ralf Baechle
2009-04-24 16:13 ` Jon Fraser
2009-04-25 9:24 ` Ralf Baechle
2009-05-04 14:49 ` Jon Fraser
2009-05-04 17:23 ` David VomLehn (dvomlehn)
2009-05-04 17:23 ` David VomLehn (dvomlehn)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).