* needs caching for fixmap
@ 2008-02-15 4:06 Hideo Saito
2008-02-26 6:49 ` Paul Mundt
0 siblings, 1 reply; 2+ messages in thread
From: Hideo Saito @ 2008-02-15 4:06 UTC (permalink / raw)
To: linux-sh
Hi Paul,
When I start up on linux-2.6.24 for SH7780, there are many assertion failed as follows although kernel doesn't hang up.
It seems that the failed address is fix-mapping pages and the entry on UTLB is replaced before using it at |copy_page_slow|.
[ 17.667186] Unable to handle kernel paging request at virtual address dfff1400
[ 17.718559] pc = 8804aba8
[ 17.749845] *pde = 00000000
[ 17.783201] Oops: 0000 [#1]
[ 17.816551] Modules linked in:
[ 17.853062]
[ 17.870799] Pid : 839, Comm: default.hotplug
[ 17.927145] PC is at copy_page_slow+0x10/0x4c
[ 17.979295] PC : 8804aba8 SP : 8fafde60 SR : 40008100 TEA : dfff1400 Not tainted
[ 18.074226] R0 : 887353e0 R1 : 00000000 R2 : 0000000a R3 : 0000007b
[ 18.153509] R4 : 00000028 R5 : 00000029 R6 : 0000003b R7 : 00000026
[ 18.232795] R8 : dfff2000 R9 : 0fcbc53e R10 : 88735400 R11 : dfff1400
[ 18.312076] R12 : 004b9108 R13 : 882c4140 R14 : 0fcbc55c
[ 18.375712] MACH: 00000000 MACL: 00000000 GBR : 2976f658 PR : 8804b794
[ 18.454989]
[ 18.454996] Call trace:
[ 18.502980] [<88080f9e>] do_wp_page+0x28a/0x442
[ 18.557227] [<88081fb8>] handle_mm_fault+0x538/0x5b0
[ 18.616691] [<88061468>] __rcu_process_callbacks+0x144/0x206
[ 18.684494] [<8804a7ee>] do_page_fault+0xa6/0x2c0
[ 18.740829] [<8805637c>] __do_softirq+0x3c/0x98
[ 18.795074] [<88056402>] do_softirq+0x2a/0x58
[ 18.847234] [<880460e0>] ret_from_exception+0x0/0x8
[ 18.905654] [<880460e0>] ret_from_exception+0x0/0x8
[ 18.964075] [<8804e0bc>] schedule_tail+0x0/0x58
[ 19.018319] [<8808efbc>] filp_close+0x30/0x68
[ 19.070479] [<8808efce>] filp_close+0x42/0x68
[ 19.122638] [<880460e0>] ret_from_exception+0x0/0x8
[ 19.181058] [<880460e0>] ret_from_exception+0x0/0x8
[ 19.239484]
Following changes is available for this problem.
--- ./arch/sh/mm/pg-sh4.c.org 2008-01-25 07:58:37.000000000 +0900
+++ ./arch/sh/mm/pg-sh4.c 2008-02-06 17:19:58.000000000 +0900
@@ -11,27 +11,45 @@
#include <linux/fs.h>
#include <linux/highmem.h>
#include <linux/module.h>
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
#define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
+pte_t fix_cmap_ptes[FIX_N_COLOURS];
+
+void put_fix_cmap_ptes(enum fixed_addresses idx, pte_t pte)
+{
+ fix_cmap_ptes[idx] = pte;
+}
+
+pte_t get_fix_cmap_ptes(unsigned long addr)
+{
+ int idx = __virt_to_fix(addr);
+ static pte_t null;
+
+ if (idx > 0 && idx <= FIX_N_COLOURS)
+ return fix_cmap_ptes[FIX_CMAP_END - idx];
+ return null;
+}
+
static inline void *kmap_coherent(struct page *page, unsigned long addr)
{
enum fixed_addresses idx;
unsigned long vaddr, flags;
pte_t pte;
inc_preempt_count();
idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT;
vaddr = __fix_to_virt(FIX_CMAP_END - idx);
pte = mk_pte(page, PAGE_KERNEL);
+ put_fix_cmap_ptes(idx, pte);
local_irq_save(flags);
flush_tlb_one(get_asid(), vaddr);
local_irq_restore(flags);
update_mmu_cache(NULL, vaddr, pte);
return (void *)vaddr;
--- ./arch/sh/mm/fault.c.org 2008-01-25 07:58:37.000000000 +0900
+++ ./arch/sh/mm/fault.c 2008-02-15 12:00:43.000000000 +0900
@@ -266,16 +266,25 @@ asmlinkage int __kprobes __do_page_fault
/*
* We don't take page faults for P1, P2, and parts of P4, these
* are always mapped, whether it be due to legacy behaviour in
* 29-bit mode, or due to PMB configuration in 32-bit mode.
*/
if (address >= P3SEG && address < P3_ADDR_MAX) {
pgd = pgd_offset_k(address);
+ if (*(int *) pgd = 0) {
+ pte_t get_fix_cmap_ptes(unsigned long addr);
+
+ entry = get_fix_cmap_ptes(address);
+ if (!pte_none(entry)) {
+ update_mmu_cache(NULL, address, entry);
+ return 0;
+ }
+ }
} else {
if (unlikely(address >= TASK_SIZE || !current->mm))
return 1;
pgd = pgd_offset(current->mm, address);
}
pud = pud_offset(pgd, address);
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: needs caching for fixmap 2008-02-15 4:06 needs caching for fixmap Hideo Saito @ 2008-02-26 6:49 ` Paul Mundt 0 siblings, 0 replies; 2+ messages in thread From: Paul Mundt @ 2008-02-26 6:49 UTC (permalink / raw) To: linux-sh On Fri, Feb 15, 2008 at 01:06:31PM +0900, Hideo Saito wrote: > When I start up on linux-2.6.24 for SH7780, there are many assertion > failed as follows although kernel doesn't hang up. It seems that the > failed address is fix-mapping pages and the entry on UTLB is replaced > before using it at |copy_page_slow|. > [snip] > --- ./arch/sh/mm/fault.c.org 2008-01-25 07:58:37.000000000 +0900 > +++ ./arch/sh/mm/fault.c 2008-02-15 12:00:43.000000000 +0900 > @@ -266,16 +266,25 @@ asmlinkage int __kprobes __do_page_fault > > /* > * We don't take page faults for P1, P2, and parts of P4, these > * are always mapped, whether it be due to legacy behaviour in > * 29-bit mode, or due to PMB configuration in 32-bit mode. > */ > if (address >= P3SEG && address < P3_ADDR_MAX) { > pgd = pgd_offset_k(address); > + if (*(int *) pgd = 0) { > + pte_t get_fix_cmap_ptes(unsigned long addr); > + > + entry = get_fix_cmap_ptes(address); > + if (!pte_none(entry)) { > + update_mmu_cache(NULL, address, entry); > + return 0; > + } > + } > } else { > if (unlikely(address >= TASK_SIZE || !current->mm)) > return 1; > > pgd = pgd_offset(current->mm, address); > } > > pud = pud_offset(pgd, address); We really don't want to shove this in the __do_page_fault() path. We also do not need a cache for each of the possible colours, how does something like this look? --- arch/sh/mm/init.c | 12 +++++++++--- arch/sh/mm/pg-sh4.c | 17 +++++++++++++++++ include/asm-sh/pgtable.h | 6 ++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index e2ed6dd..de54536 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -169,6 +169,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end, void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long vaddr; int nid; /* We don't need to map the kernel through the TLB, as @@ -180,10 +181,15 @@ void __init paging_init(void) * check for a null value. */ set_TTB(swapper_pg_dir); - /* Populate the relevant portions of swapper_pg_dir so that + /* + * Populate the relevant portions of swapper_pg_dir so that * we can use the fixmap entries without calling kmalloc. - * pte's will be filled in by __set_fixmap(). */ - page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir); + * pte's will be filled in by __set_fixmap(). + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + page_table_range_init(vaddr, 0, swapper_pg_dir); + + kmap_coherent_init(); memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index 8c7a9ca..3ecec1d 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -7,6 +7,7 @@ * Released under the terms of the GNU GPL v2.0. */ #include <linux/mm.h> +#include <linux/init.h> #include <linux/mutex.h> #include <linux/fs.h> #include <linux/highmem.h> @@ -16,6 +17,20 @@ #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask) +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) + +static pte_t *kmap_coherent_pte; + +void __init kmap_coherent_init(void) +{ + unsigned long vaddr; + + /* cache the first coherent kmap pte */ + vaddr = __fix_to_virt(FIX_CMAP_BEGIN); + kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); +} + static inline void *kmap_coherent(struct page *page, unsigned long addr) { enum fixed_addresses idx; @@ -34,6 +49,8 @@ static inline void *kmap_coherent(struct page *page, unsigned long addr) update_mmu_cache(NULL, vaddr, pte); + set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); + return (void *)vaddr; } diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index a4a8f8b..081c1be 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -147,6 +147,12 @@ extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd); +#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU) +extern void kmap_coherent_init(void); +#else +#define kmap_coherent_init() do { } while (0) +#endif + #include <asm-generic/pgtable.h> #endif /* __ASM_SH_PGTABLE_H */ ^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-02-26 6:49 UTC | newest] Thread overview: 2+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-02-15 4:06 needs caching for fixmap Hideo Saito 2008-02-26 6:49 ` Paul Mundt
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.