aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@snapgear.com>2009-05-20 02:12:32 -0400
committerRalf Baechle <ralf@linux-mips.org>2009-05-20 13:53:14 -0400
commita5e696e5d0f1377ff6beb10d2f40edb6a3d1de18 (patch)
tree2f7b194c53e9a7e2ab6c8b58335c299a897231fe /arch/mips
parent195d1a96ae5fdfbedb8dc4b97afee578921fa99e (diff)
MIPS: 64-bit: Fix system lockup.
The address range size calculation inside local_flush_tlb_kernel_range() is being truncated by a too small size variable holder on 64-bit systems. The truncated size can result in an erroneous tlbsize check that means we sit spinning inside a loop trying to flush a hige number of TLB entries. This is for all intents and purposes a system hang. Fix by using an appropriately sized valiable to hold the size. [Ralf: Greg's original patch submission identified the issue and fixed one instance in tlb-r4k.c but there there were several more. For consistency I also modified tlb-r3k.c even though that file is only used on 32-bit.] Signed-off-by: Greg Ungerer <gerg@snapgear.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/mm/tlb-r3k.c6
-rw-r--r--arch/mips/mm/tlb-r4k.c6
-rw-r--r--arch/mips/mm/tlb-r8k.c3
3 files changed, 5 insertions, 10 deletions
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
index f0cf46adb978..1c0048a6f5cf 100644
--- a/arch/mips/mm/tlb-r3k.c
+++ b/arch/mips/mm/tlb-r3k.c
@@ -82,8 +82,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
82 int cpu = smp_processor_id(); 82 int cpu = smp_processor_id();
83 83
84 if (cpu_context(cpu, mm) != 0) { 84 if (cpu_context(cpu, mm) != 0) {
85 unsigned long flags; 85 unsigned long size, flags;
86 int size;
87 86
88#ifdef DEBUG_TLB 87#ifdef DEBUG_TLB
89 printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", 88 printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
@@ -121,8 +120,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
121 120
122void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) 121void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
123{ 122{
124 unsigned long flags; 123 unsigned long size, flags;
125 int size;
126 124
127#ifdef DEBUG_TLB 125#ifdef DEBUG_TLB
128 printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end); 126 printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end);
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 9619f66e531e..892be426787c 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -117,8 +117,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
117 int cpu = smp_processor_id(); 117 int cpu = smp_processor_id();
118 118
119 if (cpu_context(cpu, mm) != 0) { 119 if (cpu_context(cpu, mm) != 0) {
120 unsigned long flags; 120 unsigned long size, flags;
121 int size;
122 121
123 ENTER_CRITICAL(flags); 122 ENTER_CRITICAL(flags);
124 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 123 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
@@ -160,8 +159,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
160 159
161void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) 160void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
162{ 161{
163 unsigned long flags; 162 unsigned long size, flags;
164 int size;
165 163
166 ENTER_CRITICAL(flags); 164 ENTER_CRITICAL(flags);
167 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 165 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c
index 4f01a3be215c..4ec95cc2df2f 100644
--- a/arch/mips/mm/tlb-r8k.c
+++ b/arch/mips/mm/tlb-r8k.c
@@ -111,8 +111,7 @@ out_restore:
111/* Usable for KV1 addresses only! */ 111/* Usable for KV1 addresses only! */
112void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) 112void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
113{ 113{
114 unsigned long flags; 114 unsigned long size, flags;
115 int size;
116 115
117 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 116 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
118 size = (size + 1) >> 1; 117 size = (size + 1) >> 1;