Skip to content

Commit 93a8347

Browse files
danglin44gregkh
authored andcommitted
parisc: Fix patch code locking and flushing
[ Upstream commit a9fe7fa ] This change fixes the following: 1) The flags variable is not initialized. Always use raw_spin_lock_irqsave and raw_spin_unlock_irqrestore to serialize patching. 2) flush_kernel_vmap_range is primarily intended for DMA flushes. Since __patch_text_multiple is often called with interrupts disabled, it is better to directly call flush_kernel_dcache_range_asm and flush_kernel_icache_range_asm. This avoids an extra call. 3) The final call to flush_icache_range is unnecessary. Signed-off-by: John David Anglin <[email protected]> Signed-off-by: Helge Deller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent f77f482 commit 93a8347

File tree

1 file changed

+11
-14
lines changed

1 file changed

+11
-14
lines changed

arch/parisc/kernel/patch.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags,
4040

4141
*need_unmap = 1;
4242
set_fixmap(fixmap, page_to_phys(page));
43-
if (flags)
44-
raw_spin_lock_irqsave(&patch_lock, *flags);
45-
else
46-
__acquire(&patch_lock);
43+
raw_spin_lock_irqsave(&patch_lock, *flags);
4744

4845
return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
4946
}
@@ -52,10 +49,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
5249
{
5350
clear_fixmap(fixmap);
5451

55-
if (flags)
56-
raw_spin_unlock_irqrestore(&patch_lock, *flags);
57-
else
58-
__release(&patch_lock);
52+
raw_spin_unlock_irqrestore(&patch_lock, *flags);
5953
}
6054

6155
void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
@@ -67,8 +61,9 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
6761
int mapped;
6862

6963
/* Make sure we don't have any aliases in cache */
70-
flush_kernel_vmap_range(addr, len);
71-
flush_icache_range(start, end);
64+
flush_kernel_dcache_range_asm(start, end);
65+
flush_kernel_icache_range_asm(start, end);
66+
flush_tlb_kernel_range(start, end);
7267

7368
p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, &mapped);
7469

@@ -81,19 +76,21 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len)
8176
* We're crossing a page boundary, so
8277
* need to remap
8378
*/
84-
flush_kernel_vmap_range((void *)fixmap,
85-
(p-fixmap) * sizeof(*p));
79+
flush_kernel_dcache_range_asm((unsigned long)fixmap,
80+
(unsigned long)p);
81+
flush_tlb_kernel_range((unsigned long)fixmap,
82+
(unsigned long)p);
8683
if (mapped)
8784
patch_unmap(FIX_TEXT_POKE0, &flags);
8885
p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags,
8986
&mapped);
9087
}
9188
}
9289

93-
flush_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p));
90+
flush_kernel_dcache_range_asm((unsigned long)fixmap, (unsigned long)p);
91+
flush_tlb_kernel_range((unsigned long)fixmap, (unsigned long)p);
9492
if (mapped)
9593
patch_unmap(FIX_TEXT_POKE0, &flags);
96-
flush_icache_range(start, end);
9794
}
9895

9996
void __kprobes __patch_text(void *addr, u32 insn)

0 commit comments

Comments
 (0)