From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:47
Hi all,
flush_icache_range is mostly used for kernel address, except for the following
cases:
- the nommu brk and mmap implementations,
- the read_code helper that is only used for binfmt_flat, binfmt_elf_fdpic,
and binfmt_aout including the broken ia32 compat version
- binfmt_flat itself,
none of which really are used by a typical MMU enabled kernel, as a.out can
only be build for alpha and m68k to start with.
But strangely enough commit ae92ef8a4424 ("PATCH] flush icache in correct
context") added a "set_fs(KERNEL_DS)" around the flush_icache_range call
in the module loader, because apparently m68k assumed user pointers.
This series first cleans up the cacheflush implementations, largely by
switching as much as possible to the asm-generic version after a few
preparations, then moves the misnamed current flush_icache_user_range to
a new name, to finally introduce a real flush_icache_user_range to be used
for the above use cases to flush the instruction cache for a userspace
address range. The last patch then drops the set_fs in the module code
and moves it into the m68k implementation.
A git tree is available here:
git://git.infradead.org/users/hch/misc.git flush_icache_range
Gitweb:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/flush_icache_range
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:33
The second argument is the end "pointer", not the length.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/kernel/machine_kexec.c | 1 +
1 file changed, 1 insertion(+)
@@ -177,6 +177,7 @@ void machine_kexec(struct kimage *kimage)*theofflineCPUs.Therefore,wemustusethe__*varianthere.*/__flush_icache_range((uintptr_t)reboot_code_buffer,+(uintptr_t)reboot_code_buffer+arm64_relocate_new_kernel_size);/* Flush the kimage list and its buffers. */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:40
__flush_icache_user_range is not used in modular code, so unexport it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/mm/cache.c | 1 -
1 file changed, 1 deletion(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:47
flush_icache_page is only used by mm/memory.c.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/nds32/mm/cacheflush.c | 1 -
1 file changed, 1 deletion(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:49
The arguments passed look bogus, try to fix them to something that seems
to make sense.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/kernel/fiq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:55:52
flush_cache_user_range is an ARMism not used by any generic or unicore32
specific code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/unicore32/include/asm/cacheflush.h | 8 --------
1 file changed, 8 deletions(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:08
This seems to lead to some crazy include loops when using
asm-generic/cacheflush.h on more architectures, so leave it
to the arch header for now.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/um/include/asm/tlb.h | 2 ++
arch/x86/include/asm/cacheflush.h | 2 ++
include/asm-generic/cacheflush.h | 3 ---
3 files changed, 4 insertions(+), 3 deletions(-)
@@ -2,9 +2,6 @@#ifndef _ASM_GENERIC_CACHEFLUSH_H#define _ASM_GENERIC_CACHEFLUSH_H-/* Keep includes the same across arches. */-#include<linux/mm.h>-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0/*
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:08
There is a magic ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE cpp symbol that
guards non-stub availability of flush_dcache_pagge. Use that to
check if flush_dcache_pagg is implemented.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/asm-generic/cacheflush.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:12
ARM64 needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/include/asm/cacheflush.h | 46 ++++-------------------------
1 file changed, 5 insertions(+), 41 deletions(-)
@@ -154,29 +136,11 @@ static __always_inline void __flush_icache_all(void)dsb(ish);}-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)--/*-*Wedon'tappeartoneedtodoanythinghere.Infact,ifwedid,we'd-*duplicatecacheflushingelsewhereperformedbyflush_dcache_page().-*/-#define flush_icache_page(vma,page) do { } while (0)--/*-*NotrequiredonAArch64(PIPTorVIPTnon-aliasingD-cache).-*/-staticinlinevoidflush_cache_vmap(unsignedlongstart,unsignedlongend)-{-}--staticinlinevoidflush_cache_vunmap(unsignedlongstart,unsignedlongend)-{-}-intset_memory_valid(unsignedlongaddr,intnumpages,intenable);intset_direct_map_invalid_noflush(structpage*page);intset_direct_map_default_noflush(structpage*page);-#endif+#include<asm-generic/cacheflush.h>++#endif /* __ASM_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:14
C6x needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/c6x/include/asm/cacheflush.h | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)
@@ -16,21 +16,6 @@#include<asm/page.h>#include<asm/string.h>-/*-*virtually-indexedcachemanagement(ourcacheisphysicallyindexed)-*/-#define flush_cache_all() do {} while (0)-#define flush_cache_mm(mm) do {} while (0)-#define flush_cache_dup_mm(mm) do {} while (0)-#define flush_cache_range(mm, start, end) do {} while (0)-#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)-#define flush_cache_vmap(start, end) do {} while (0)-#define flush_cache_vunmap(start, end) do {} while (0)-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0-#define flush_dcache_page(page) do {} while (0)-#define flush_dcache_mmap_lock(mapping) do {} while (0)-#define flush_dcache_mmap_unlock(mapping) do {} while (0)-/**physically-indexedcachemanagement*/
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:21
Microblaze needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/microblaze/include/asm/cacheflush.h | 29 ++----------------------
1 file changed, 2 insertions(+), 27 deletions(-)
@@ -77,27 +74,9 @@ do { \flush_dcache_range((unsigned)(addr),(unsigned)(addr)+PAGE_SIZE);\}while(0);-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)--#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) \flush_dcache_range(pfn<<PAGE_SHIFT,(pfn<<PAGE_SHIFT)+PAGE_SIZE);-/* MS: kgdb code use this macro, wrong len with FLASH */-#if 0-#define flush_cache_range(vma, start, len) { \-flush_icache_range((unsigned)(start),(unsigned)(start)+(len));\-flush_dcache_range((unsigned)(start),(unsigned)(start)+(len));\-}-#endif--#define flush_cache_range(vma, start, len) do { } while (0)-staticinlinevoidcopy_to_user_page(structvm_area_struct*vma,structpage*page,unsignedlongvaddr,void*dst,void*src,intlen)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:24
OpenRISC needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/openrisc/include/asm/cacheflush.h | 31 +++++---------------------
1 file changed, 6 insertions(+), 25 deletions(-)
@@ -62,31 +62,12 @@ static inline void flush_dcache_page(struct page *page)clear_bit(PG_dc_clean,&page->flags);}-/*-*Otherinterfacesarenotrequiredsincewedonothavevirtually-*indexedortaggedcaches.Sowecanusethedefaulthere.-*/-#define flush_cache_all() do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)-#define flush_icache_range(start, end) do { } while (0)-#define flush_icache_page(vma, pg) do { } while (0)-#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)--#define copy_to_user_page(vma, page, vaddr, dst, src, len) \-do{\-memcpy(dst,src,len);\-if(vma->vm_flags&VM_EXEC)\-sync_icache_dcache(page);\-}while(0)+#define flush_icache_user_range(vma, page, addr, len) \+do{\+if(vma->vm_flags&VM_EXEC)\+sync_icache_dcache(page);\+}while(0)-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)+#include<asm-generic/cacheflush.h>#endif /* __ASM_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:45
The Xtensa implementation of flush_icache_range seems to be able to
cope with user addresses. Just define flush_icache_user_range to
flush_icache_range.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/xtensa/include/asm/cacheflush.h | 2 ++
1 file changed, 2 insertions(+)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:56:47
The SuperH implementation of flush_icache_range seems to be able to
cope with user addresses. Just define flush_icache_user_range to
flush_icache_range.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/sh/include/asm/cacheflush.h | 1 +
1 file changed, 1 insertion(+)
@@ -854,7 +854,7 @@ static int load_flat_file(struct linux_binprm *bprm,#endif /* CONFIG_BINFMT_FLAT_OLD */}-flush_icache_range(start_code,end_code);+flush_icache_user_range(start_code,end_code);/* zero the BSS, BRK and stack areas */if(clear_user((void__user*)(datapos+data_len),bss_len+
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:07
flush_icache_range generally operates on kernel addresses, but for some
reason m68k needed a set_fs override. Move that into the m68k code
insted of keeping it in the module loader.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/mm/cache.c | 4 ++++
kernel/module.c | 8 --------
2 files changed, 4 insertions(+), 8 deletions(-)
@@ -1287,7 +1287,7 @@ unsigned long do_mmap(struct file *file,/* we flush the region from the icache only when the first executable*mappingofitismade*/if(vma->vm_flags&VM_EXEC&&!region->vm_icache_flushed){-flush_icache_range(region->vm_start,region->vm_end);+flush_icache_user_range(region->vm_start,region->vm_end);region->vm_icache_flushed=true;}
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:32
Rename the current flush_icache_range to flush_icache_user_range as
per commit ae92ef8a4424 ("PATCH] flush icache in correct context") there
seems to be an assumption that it operates on user addresses. Add a
flush_icache_range around it that for now is a no-op.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/include/asm/cacheflush_mm.h | 2 ++
arch/m68k/mm/cache.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
@@ -73,7 +73,7 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr)/* Push n pages at kernel virtual address and clear the icache *//* RZ: use cpush %bc instead of cpush %dc, cinv %ic */-voidflush_icache_range(unsignedlongaddress,unsignedlongendaddr)+voidflush_icache_user_range(unsignedlongaddress,unsignedlongendaddr){if(CPU_IS_COLDFIRE){unsignedlongstart,end;
@@ -104,6 +104,11 @@ void flush_icache_range(unsigned long address, unsigned long endaddr):"di"(FLUSH_I));}}++voidflush_icache_range(unsignedlongaddress,unsignedlongendaddr)+{+flush_icache_user_range(address,endaddr);+}EXPORT_SYMBOL(flush_icache_range);voidflush_icache_user_page(structvm_area_struct*vma,structpage*page,
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:33
Only build read_code when binary formats that use it are built into the
kernel.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fs/exec.c | 3 +++
1 file changed, 3 insertions(+)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:40
flush_icache_user_range will be the name for a generic primitive.
Move the arm name so that arm already has an implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/cacheflush.h | 4 ++--
arch/arm/kernel/traps.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
@@ -566,7 +566,7 @@ __do_cache_op(unsigned long start, unsigned long end)if(fatal_signal_pending(current))return0;-ret=flush_cache_user_range(start,start+chunk);+ret=flush_icache_user_range(start,start+chunk);if(ret)returnret;
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:41
Define flush_icache_user_range to flush_icache_range unless the
architecture provides its own implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/asm-generic/cacheflush.h | 4 ++++
1 file changed, 4 insertions(+)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:42
flush_icache_user_range is only used by <asm-generic/cacheflush.h>, so
remove it from the architectures that implement it, but don't use
<asm-generic/cacheflush.h>.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/include/asm/cacheflush.h | 3 ---
arch/sparc/include/asm/cacheflush_32.h | 2 --
arch/sparc/include/asm/cacheflush_64.h | 1 -
arch/unicore32/include/asm/cacheflush.h | 3 ---
4 files changed, 9 deletions(-)
@@ -49,7 +49,6 @@ void __flush_dcache_range(unsigned long start, unsigned long end);voidflush_dcache_page(structpage*page);#define flush_icache_page(vma, pg) do { } while(0)-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)voidflush_ptrace_access(structvm_area_struct*,structpage*,unsignedlonguaddr,void*kaddr,
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:44
RISC-V needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Also remove the pointless __KERNEL__ ifdef while we're at it.
---
arch/riscv/include/asm/cacheflush.h | 62 ++---------------------------
1 file changed, 3 insertions(+), 59 deletions(-)
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:46
Power needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Also remove the pointless __KERNEL__ ifdef while we're at it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/powerpc/include/asm/cacheflush.h | 42 +++++++--------------------
1 file changed, 10 insertions(+), 32 deletions(-)
@@ -4,23 +4,9 @@#ifndef _ASM_POWERPC_CACHEFLUSH_H#define _ASM_POWERPC_CACHEFLUSH_H-#ifdef __KERNEL__-#include<linux/mm.h>#include<asm/cputable.h>-/*-*Nocacheflushingisrequiredwhenaddressmappingsarechanged,-*becausethecachesonPowerPCsarephysicallyaddressed.-*/-#define flush_cache_all() do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)-#define flush_icache_page(vma, page) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)-#ifdef CONFIG_PPC_BOOK3S_64/**Book3shasnoptesyncaftersettingapte,sowithoutthisptesyncit's
@@ -33,20 +19,20 @@ static inline void flush_cache_vmap(unsigned long start, unsigned long end){asmvolatile("ptesync":::"memory");}-#else-staticinlinevoidflush_cache_vmap(unsignedlongstart,unsignedlongend){}-#endif+#define flush_cache_vmap flush_cache_vmap+#endif /* CONFIG_PPC_BOOK3S_64 */#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1externvoidflush_dcache_page(structpage*page);-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)voidflush_icache_range(unsignedlongstart,unsignedlongstop);-externvoidflush_icache_user_range(structvm_area_struct*vma,-structpage*page,unsignedlongaddr,-intlen);-externvoidflush_dcache_icache_page(structpage*page);+#define flush_icache_range flush_icache_range++voidflush_icache_user_range(structvm_area_struct*vma,structpage*page,+unsignedlongaddr,intlen);+#define flush_icache_user_range flush_icache_user_range++voidflush_dcache_icache_page(structpage*page);void__flush_dcache_icache(void*page);/**
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:57:52
m68knommu needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/m68k/include/asm/cacheflush_no.h | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
@@ -9,25 +9,8 @@#include<asm/mcfsim.h>#define flush_cache_all() __flush_cache_all()-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr) do { } while (0)#define flush_dcache_range(start, len) __flush_dcache_all()-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0-#define flush_dcache_page(page) do { } while (0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)#define flush_icache_range(start, len) __flush_icache_all()-#define flush_icache_page(vma,pg) do { } while (0)-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)--#define copy_to_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)voidmcf_cache_push(void);
@@ -98,4 +81,6 @@ static inline void cache_clear(unsigned long paddr, int len)__clear_cache_all();}+#include<asm-generic/cacheflush.h>+#endif /* _M68KNOMMU_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:58:00
IA64 needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/ia64/include/asm/cacheflush.h | 28 +++-------------------------
1 file changed, 3 insertions(+), 25 deletions(-)
@@ -12,44 +12,22 @@#include<asm/page.h>-/*-*Cacheflushingroutines.Thisisthekindofstuffthatcanbeveryexpensive,sotry-*toavoidthemwheneverpossible.-*/--#define flush_cache_all() do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)-#define flush_icache_page(vma,page) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1#define flush_dcache_page(page) \do{\clear_bit(PG_arch_1,&(page)->flags);\}while(0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)--externvoidflush_icache_range(unsignedlongstart,unsignedlongend);+externvoidflush_icache_range(unsignedlongstart,unsignedlongend);+#define flush_icache_range flush_icache_rangeexternvoidclflush_cache_range(void*addr,intsize);-#define flush_icache_user_range(vma, page, user_addr, len) \do{\unsignedlong_addr=(unsignedlong)page_address(page)+((user_addr)&~PAGE_MASK);\flush_icache_range(_addr,_addr+(len));\}while(0)-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \-do{memcpy(dst,src,len);\-flush_icache_user_range(vma,page,vaddr,len);\-}while(0)-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)+#include<asm-generic/cacheflush.h>#endif /* _ASM_IA64_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:58:08
Hexagon needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/hexagon/include/asm/cacheflush.h | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
@@ -25,29 +25,17 @@#define LINESIZE 32#define LINEBITS 5-#define flush_cache_all() do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0-#define flush_dcache_page(page) do { } while (0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)-#define flush_icache_page(vma, pg) do { } while (0)-#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)-/**FlushDcacherangethroughcurrentmap.*/externvoidflush_dcache_range(unsignedlongstart,unsignedlongend);+#define flush_dcache_range flush_dcache_range/**FlushIcacherangethroughcurrentmap.*/externvoidflush_icache_range(unsignedlongstart,unsignedlongend);+#define flush_icache_range flush_icache_range/**Memory-managementrelatedflushesaretheretoensureinnon-physically
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:58:22
Alpha needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/alpha/include/asm/cacheflush.h | 28 ++++++----------------------
1 file changed, 6 insertions(+), 22 deletions(-)
@@ -4,19 +4,6 @@#include<linux/mm.h>-/* Caches aren't brain-dead on the Alpha. */-#define flush_cache_all() do { } while (0)-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0-#define flush_dcache_page(page) do { } while (0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)-/* Note that the following two definitions are _highly_ dependentonthecontextsinwhichtheyareusedinthekernel.Ipersonallythinkitiscriminalhowlooselydefinedthesemacrosare.*/
@@ -59,20 +46,17 @@ flush_icache_user_range(struct vm_area_struct *vma, struct page *page,mm->context[smp_processor_id()]=0;}}-#else+#define flush_icache_user_range flush_icache_user_range+#else /* CONFIG_SMP */externvoidflush_icache_user_range(structvm_area_struct*vma,structpage*page,unsignedlongaddr,intlen);-#endif+#define flush_icache_user_range flush_icache_user_range+#endif /* CONFIG_SMP *//* This is used only in __do_fault and do_swap_page. */#define flush_icache_page(vma, page) \-flush_icache_user_range((vma),(page),0,0)+flush_icache_user_range((vma),(page),0,0)-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \-do{memcpy(dst,src,len);\-flush_icache_user_range(vma,page,vaddr,len);\-}while(0)-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)+#include<asm-generic/cacheflush.h>#endif /* _ALPHA_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:58:26
cacheflush.h uses a somewhat to generic include guard name that clashes
with various arch files. Use a more specific one.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/asm-generic/cacheflush.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
@@ -1,6 +1,6 @@/* SPDX-License-Identifier: GPL-2.0 */-#ifndef __ASM_CACHEFLUSH_H-#define __ASM_CACHEFLUSH_H+#ifndef _ASM_GENERIC_CACHEFLUSH_H+#define _ASM_GENERIC_CACHEFLUSH_H/* Keep includes the same across arches. */#include<linux/mm.h>
@@ -109,4 +109,4 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end)memcpy(dst,src,len)#endif-#endif /* __ASM_CACHEFLUSH_H */+#endif /* _ASM_GENERIC_CACHEFLUSH_H */
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-10 07:58:29
flush_icache_user_range is only used by copy_to_user_page, which is
only used by core VM code.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/powerpc/mm/mem.c | 1 -
1 file changed, 1 deletion(-)
On Sun, May 10, 2020 at 9:57 AM Christoph Hellwig [off-list ref] wrote:
The function currently known as flush_icache_user_range only operates
on a single page. Rename it to flush_icache_user_page as we'll need
the name flush_icache_user_range for something else soon.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
On Sun, May 10, 2020 at 9:57 AM Christoph Hellwig [off-list ref] wrote:
Rename the current flush_icache_range to flush_icache_user_range as
per commit ae92ef8a4424 ("PATCH] flush icache in correct context") there
seems to be an assumption that it operates on user addresses. Add a
flush_icache_range around it that for now is a no-op.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
On Sun, May 10, 2020 at 9:57 AM Christoph Hellwig [off-list ref] wrote:
flush_icache_range generally operates on kernel addresses, but for some
reason m68k needed a set_fs override. Move that into the m68k code
insted of keeping it in the module loader.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Hi Christoph,
On Sun, May 10, 2020 at 9:55 AM Christoph Hellwig [off-list ref] wrote:
none of which really are used by a typical MMU enabled kernel, as a.out can
only be build for alpha and m68k to start with.
Quoting myself:
"I think it's safe to assume no one still runs a.out binaries on m68k."
http://lore.kernel.org/r/CAMuHMdW+m0Q+j3rsQdMXnrEPm+XB5Y2AQrxW5sD1mZAKgmEqoA@mail.gmail.com
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
From: Will Deacon <will@kernel.org> Date: 2020-05-11 07:51:28
[+James and Catalin]
On Sun, May 10, 2020 at 09:54:41AM +0200, Christoph Hellwig wrote:
quoted hunk
The second argument is the end "pointer", not the length.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/kernel/machine_kexec.c | 1 +
1 file changed, 1 insertion(+)
Urgh, well spotted. It's annoyingly different from __flush_dcache_area().
But now I'm wondering what this code actually does... the loop condition
in invalidate_icache_by_line works with 64-bit arithmetic, so we could
spend a /very/ long time here afaict. It's also a bit annoying that we
do a bunch of redundant D-cache maintenance too.
Should we use invalidate_icache_range() here instead? (and why does that
thing need to toggle uaccess)? Argh, too many questions!
Will
On Mon, May 11, 2020 at 08:51:15AM +0100, Will Deacon wrote:
On Sun, May 10, 2020 at 09:54:41AM +0200, Christoph Hellwig wrote:
quoted
The second argument is the end "pointer", not the length.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/kernel/machine_kexec.c | 1 +
1 file changed, 1 insertion(+)
Urgh, well spotted. It's annoyingly different from __flush_dcache_area().
But now I'm wondering what this code actually does... the loop condition
in invalidate_icache_by_line works with 64-bit arithmetic, so we could
spend a /very/ long time here afaict.
I think it goes through the loop only once. The 'b.lo' saves us here.
OTOH, there is no I-cache maintenance done.
It's also a bit annoying that we do a bunch of redundant D-cache
maintenance too. Should we use invalidate_icache_range() here instead?
Since we have the __flush_dcache_area() above it for cleaning to PoC, we
could use invalidate_icache_range() here. We probably didn't have this
function at the time, it was added for KVM (commit 4fee94736603cd6).
(and why does that thing need to toggle uaccess)?
invalidate_icache_range() doesn't need to, it works on the kernel linear
map.
__flush_icache_range() doesn't need to either, that's a side-effect of
the fall-through implementation.
Anyway, I think Christoph's patch needs to go in with a fixes tag:
Fixes: d28f6df1305a ("arm64/kexec: Add core kexec support")
Cc: <redacted> # 4.8.x-
and we'll change these functions/helpers going forward for arm64.
Happy to pick this up via the arm64 for-next/fixes branch.
--
Catalin
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-11 15:11:31
On Mon, May 11, 2020 at 09:40:39AM +0200, Geert Uytterhoeven wrote:
On Sun, May 10, 2020 at 9:57 AM Christoph Hellwig [off-list ref] wrote:
quoted
flush_icache_range generally operates on kernel addresses, but for some
reason m68k needed a set_fs override. Move that into the m68k code
insted of keeping it in the module loader.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Btw, do you know what part of flush_icache_range relied on set_fs?
Do any of the m68k maintainers have an idea how to handle that in
a nicer way when we can split the implementations?
Do you want to drop the:
select HAVE_AOUT if MMU
for m68k then?
Note that we'll still need flush_icache_user_range for m68k with mmu,
as it also allows binfmt_flat for mmu configs.
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-11 15:15:40
On Mon, May 11, 2020 at 12:00:14PM +0100, Catalin Marinas wrote:
Anyway, I think Christoph's patch needs to go in with a fixes tag:
Fixes: d28f6df1305a ("arm64/kexec: Add core kexec support")
Cc: <redacted> # 4.8.x-
and we'll change these functions/helpers going forward for arm64.
Happy to pick this up via the arm64 for-next/fixes branch.
Please do, there are no dependencies on it in this series (I originally
planned to switch flush_icache_range to pass a kernel pointer + len
instead of the strange unsigned long start and end. That still looks
very useful, but the series already is way too large, so I'm going to
defer that change for another merge window).
Hi Christoph,
On Mon, May 11, 2020 at 5:11 PM Christoph Hellwig [off-list ref] wrote:
On Mon, May 11, 2020 at 09:40:39AM +0200, Geert Uytterhoeven wrote:
quoted
On Sun, May 10, 2020 at 9:57 AM Christoph Hellwig [off-list ref] wrote:
quoted
flush_icache_range generally operates on kernel addresses, but for some
reason m68k needed a set_fs override. Move that into the m68k code
insted of keeping it in the module loader.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Btw, do you know what part of flush_icache_range relied on set_fs?
Do any of the m68k maintainers have an idea how to handle that in
a nicer way when we can split the implementations?
arch/m68k/mm/cache.c:virt_to_phys_slow()
All instructions that look up addresses in the page tables look at the
source/destination function codes (SFC/DFC) to know if they have to use
the supervisor or user page tables.
So the actual implementation is the same: set_fs() merely configures
SFC/DFC, to select the address space to use.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
Do you want to drop the:
select HAVE_AOUT if MMU
for m68k then?
If that helps to reduce maintenance, it's fine for me.
That leaves alpha as the sole user?
Note that we'll still need flush_icache_user_range for m68k with mmu,
as it also allows binfmt_flat for mmu configs.
Understood.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
From: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Date: 2020-05-11 16:02:35
On Sun, May 10, 2020 at 09:54:42AM +0200, Christoph Hellwig wrote:
__flush_icache_user_range is not used in modular code, so unexport it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/mm/cache.c | 1 -
1 file changed, 1 deletion(-)
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-11 16:37:57
On Mon, May 11, 2020 at 05:24:30PM +0200, Geert Uytterhoeven wrote:
quoted
Btw, do you know what part of flush_icache_range relied on set_fs?
Do any of the m68k maintainers have an idea how to handle that in
a nicer way when we can split the implementations?
arch/m68k/mm/cache.c:virt_to_phys_slow()
All instructions that look up addresses in the page tables look at the
source/destination function codes (SFC/DFC) to know if they have to use
the supervisor or user page tables.
So the actual implementation is the same: set_fs() merely configures
SFC/DFC, to select the address space to use.
So instead of the magic instructions could we use the normal kernel
virt to phys helpers instead of switching the addresses space? Something
like this patch on top of the series:
Hi Christoph,
On 10/5/20 5:54 pm, Christoph Hellwig wrote:
m68knommu needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Signed-off-by: Christoph Hellwig <hch@lst.de>
@@ -9,25 +9,8 @@#include<asm/mcfsim.h>#define flush_cache_all() __flush_cache_all()-#define flush_cache_mm(mm) do { } while (0)-#define flush_cache_dup_mm(mm) do { } while (0)-#define flush_cache_range(vma, start, end) do { } while (0)-#define flush_cache_page(vma, vmaddr) do { } while (0)#define flush_dcache_range(start, len) __flush_dcache_all()-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0-#define flush_dcache_page(page) do { } while (0)-#define flush_dcache_mmap_lock(mapping) do { } while (0)-#define flush_dcache_mmap_unlock(mapping) do { } while (0)#define flush_icache_range(start, len) __flush_icache_all()-#define flush_icache_page(vma,pg) do { } while (0)-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)-#define flush_cache_vmap(start, end) do { } while (0)-#define flush_cache_vunmap(start, end) do { } while (0)--#define copy_to_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \-memcpy(dst,src,len)voidmcf_cache_push(void);
@@ -98,4 +81,6 @@ static inline void cache_clear(unsigned long paddr, int len)__clear_cache_all();}+#include<asm-generic/cacheflush.h>+#endif /* _M68KNOMMU_CACHEFLUSH_H */
@@ -854,7 +854,7 @@ static int load_flat_file(struct linux_binprm *bprm,#endif /* CONFIG_BINFMT_FLAT_OLD */}-flush_icache_range(start_code,end_code);+flush_icache_user_range(start_code,end_code);/* zero the BSS, BRK and stack areas */if(clear_user((void__user*)(datapos+data_len),bss_len+
On Sun, 10 May 2020 00:54:58 PDT (-0700), Christoph Hellwig wrote:
quoted hunk
RISC-V needs almost no cache flushing routines of its own. Rely on
asm-generic/cacheflush.h for the defaults.
Also remove the pointless __KERNEL__ ifdef while we're at it.
---
arch/riscv/include/asm/cacheflush.h | 62 ++---------------------------
1 file changed, 3 insertions(+), 59 deletions(-)
Thanks!
Reviewed-by: Palmer Dabbelt <redacted>
Acked-by: Palmer Dabbelt <redacted>
Were you trying to get these all in at once, or do you want me to take it into
my tree?
From: Christoph Hellwig <hch@lst.de> Date: 2020-05-13 06:23:28
On Tue, May 12, 2020 at 04:00:26PM -0700, Palmer Dabbelt wrote:
Reviewed-by: Palmer Dabbelt <redacted>
Acked-by: Palmer Dabbelt <redacted>
Were you trying to get these all in at once, or do you want me to take it into
my tree?
Except for the small fixups at the beginning of the series this needs
to go in together. I'll have to do at least another resend, and after
that I hope Andrew is going to pick it up.