public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] microblaze: fix instruction cache invalidation
@ 2016-05-23 13:46 Romeo Cane
  0 siblings, 0 replies; only message in thread
From: Romeo Cane @ 2016-05-23 13:46 UTC (permalink / raw)
  To: linux-kernel; +Cc: Michal Simek


Microblaze invalidates the instruction cache via WIC opcode which,
unlike WDC for data cache, requires the virtual address of the target
location when MMU is used. The current code always uses the physical
address, preventing the instruction cache to be properly invalidated
and exposing the risk of user space applications to crash with
signal 4 (illegal instruction) when executing the trampoline code in return
from a signal handler.
Same issue when the code is modified via copy_to_user_page.
This patch fixes the calls to instruction cache invalidation using
the correct addresses.

Signed-off-by: Romeo Cane <romeo.cane@ericsson.com>
---
 arch/microblaze/include/asm/cacheflush.h | 6 +++---
 arch/microblaze/kernel/signal.c          | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
index ffea82a..c978e64 100644
--- a/arch/microblaze/include/asm/cacheflush.h
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -106,11 +106,11 @@ static inline void copy_to_user_page(struct vm_area_struct *vma,
 				     struct page *page, unsigned long vaddr,
 				     void *dst, void *src, int len)
 {
-	u32 addr = virt_to_phys(dst);
+	u32 paddr = virt_to_phys(dst);
 	memcpy(dst, src, len);
 	if (vma->vm_flags & VM_EXEC) {
-		invalidate_icache_range(addr, addr + PAGE_SIZE);
-		flush_dcache_range(addr, addr + PAGE_SIZE);
+		invalidate_icache_range(vaddr, vaddr + PAGE_SIZE);
+		flush_dcache_range(paddr, paddr + PAGE_SIZE);
 	}
 }

diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 9700152..757dd40 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -200,6 +200,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 					address), address);

 	preempt_disable();
+	invalidate_icache_range(address, address + 8);
 	ptep = pte_offset_map(pmdp, address);
 	if (pte_present(*ptep)) {
 		address = (unsigned long) page_address(pte_page(*ptep));
@@ -207,7 +208,6 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 		address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
 		/* MS address is virtual */
 		address = __virt_to_phys(address);
-		invalidate_icache_range(address, address + 8);
 		flush_dcache_range(address, address + 8);
 	}
 	pte_unmap(ptep);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-05-23 13:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-23 13:46 [PATCH] microblaze: fix instruction cache invalidation Romeo Cane

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox