[Kgdb-bugreport] [PATCH] Fix incorrect usage of cache flush API
Status: Beta
Brought to you by:
jwessel
From: Deepak S. <ds...@pl...> - 2004-09-10 01:08:20
|
Current KGDB code calls flash_cache_range() followed by flush_icache_range(). This has two problems: 1) It is overly redundant since the two functions are defined as doing basically the same thing. 2) flush_cache_range() is defined to work on _user_ virtual addresses as documented on Documentation/cachetlb.txt. flush_icache_range() is defined to work on _kernel_ addresses. On ARM, calling flush_cache_range() on kernel mapping, where there is no backing vma causes us to OOPs since we look at the VMA for the VM_EXEC flag to determine if we need to invalidte the icache. Following patch checks to see if the address we are flushing is a user or kernel address and calls the appropriate functon. Please apply, ~Deepak Signed-off-by: Deepak Saxena <ds...@pl...> Index: linux-2.6.8.1-kgdb/kernel/kgdb.c =================================================================== --- linux-2.6.8.1-kgdb.orig/kernel/kgdb.c 2004-09-09 17:50:23.000000000 -0700 +++ linux-2.6.8.1-kgdb/kernel/kgdb.c 2004-09-09 17:52:57.000000000 -0700 @@ -623,8 +623,10 @@ BREAK_INSTR_SIZE)) < 0) return error; } - flush_cache_range(current->mm, addr, addr + BREAK_INSTR_SIZE); - flush_icache_range(addr, addr + BREAK_INSTR_SIZE); + if (current->mm && addr < TASK_SIZE) + flush_cache_range(current->mm, addr, addr + BREAK_INSTR_SIZE); + else + flush_icache_range(addr, addr + BREAK_INSTR_SIZE); kgdb_break[breakno].state = bp_enabled; kgdb_break[breakno].type = bp_breakpoint; @@ -650,9 +652,12 @@ kgdb_break[i].saved_instr, BREAK_INSTR_SIZE)) < 0) return error; - flush_cache_range(current->mm, addr, - addr + BREAK_INSTR_SIZE); - flush_icache_range(addr, addr + BREAK_INSTR_SIZE); + if (current->mm && addr < TASK_SIZE) + flush_cache_range(current->mm, addr, + addr + BREAK_INSTR_SIZE); + else + flush_icache_range(addr, + addr + BREAK_INSTR_SIZE); kgdb_break[i].state = bp_disabled; return 0; } @@ -674,9 +679,12 @@ kgdb_break[i].saved_instr, BREAK_INSTR_SIZE)) < 0) return error; - flush_cache_range(current->mm, addr, - addr + BREAK_INSTR_SIZE); - flush_icache_range(addr, addr + BREAK_INSTR_SIZE); + if (current->mm && addr < TASK_SIZE) + flush_cache_range(current->mm, addr, + addr + BREAK_INSTR_SIZE); + else + flush_icache_range(addr, + addr + BREAK_INSTR_SIZE); } kgdb_break[i].state = bp_disabled; } -- Deepak Saxena - dsaxena at plexity dot net - http://www.plexity.net/ "Unlike me, many of you have accepted the situation of your imprisonment and will die here like rotten cabbages." - Number 6 |