ARC fixes for 6.7
- build error for hugetlb, sparse and smatch fixes - Removal of VIPT aliasing cache code -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEOXpuCuR6hedrdLCJadfx3eKKwl4FAmWBJsIACgkQadfx3eKK wl5mjQ/+NnUv9+CT3uFJFue9KNfNVQg8ZxGHd3eOMa6rJJRx5SSpPHGKcsa0mdda /u+OmqFTnkx1OahrJcSo6epOQc4MW6W43cFqcDWQnQDPr7s8Za6GFXGAhayXu5ff Qnp/Bb1WUF97KHdpvYhl6zy0U5Er9pfT2qpWFzNwue0woNwg4RCIxhcPtSHnzJ5J 06CWPKmtRkFVZo3dwDKHnyL41P0nhLqE4PfNtl7fEDHVU0G5S+L4csyHpSULbVLn 5V+5oSDaQLy0dKw6fQAcntikqAKRZVP//8NWOEkqnbtAI37yO6gsrCEZxOvIqpGc ovjejC4pzS7lscQurQYWUtCd5GYreypIC0E0Luf78Iopt1KjpgqXmPjaS5sT2om1 LCVt2LEmImtxA1aBIVZGshYyA2oebKARVfVvaxRaVj5un89J3nTS6pkiwdWwK8JC E2cAyfgnDW9n3J7gGbfOiRBqLna3fFUqBpybCcN/IP8fnCd7VGv9dnMMABWy1kP8 MmzJEjAC3nKXyoQo8cf96aOGqzt6fL3odxO/nvaFjyq0AmRN4I410ZJfylqSFVYe n3bpjgZDRcaZkRltkk9eMDxl82BKMivYLr3Vya/r4WZSZr/+I7jIKzw9Tcbq9SjT r4haRp/tVqJuOX5CSMEExV6AuJ07aliztIrWD3qh38bFnXYlAOw= =82fK -----END PGP SIGNATURE----- Merge tag 'arc-6.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc Pull ARC fixes from Vineet Gupta: - build error for hugetlb, sparse and smatch fixes - removal of VIPT aliasing cache code * tag 'arc-6.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: ARC: add hugetlb definitions ARC: fix smatch warning ARC: fix spare error ARC: mm: retire support for aliasing VIPT D$ ARC: entry: move ARCompact specific bits out of entry.h ARC: entry: SAVE_ABI_CALLEE_REG: ISA/ABI specific helper
This commit is contained in:
commit
9c749e61a1
@ -49,7 +49,6 @@ config ARC
|
||||
select OF
|
||||
select OF_EARLY_FLATTREE
|
||||
select PCI_SYSCALL if PCI
|
||||
select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
|
||||
select HAVE_ARCH_JUMP_LABEL if ISA_ARCV2 && !CPU_ENDIAN_BE32
|
||||
select TRACE_IRQFLAGS_SUPPORT
|
||||
|
||||
@ -232,10 +231,6 @@ config ARC_CACHE_PAGES
|
||||
Note that Global I/D ENABLE + Per Page DISABLE works but corollary
|
||||
Global DISABLE + Per Page ENABLE won't work
|
||||
|
||||
config ARC_CACHE_VIPT_ALIASING
|
||||
bool "Support VIPT Aliasing D$"
|
||||
depends on ARC_HAS_DCACHE && ISA_ARCOMPACT
|
||||
|
||||
endif #ARC_CACHE
|
||||
|
||||
config ARC_HAS_ICCM
|
||||
|
@ -44,31 +44,10 @@ void dma_cache_wback(phys_addr_t start, unsigned long sz);
|
||||
|
||||
#define flush_cache_dup_mm(mm) /* called on fork (VIVT only) */
|
||||
|
||||
#ifndef CONFIG_ARC_CACHE_VIPT_ALIASING
|
||||
|
||||
#define flush_cache_mm(mm) /* called on munmap/exit */
|
||||
#define flush_cache_range(mm, u_vstart, u_vend)
|
||||
#define flush_cache_page(vma, u_vaddr, pfn) /* PF handling/COW-break */
|
||||
|
||||
#else /* VIPT aliasing dcache */
|
||||
|
||||
/* To clear out stale userspace mappings */
|
||||
void flush_cache_mm(struct mm_struct *mm);
|
||||
void flush_cache_range(struct vm_area_struct *vma,
|
||||
unsigned long start,unsigned long end);
|
||||
void flush_cache_page(struct vm_area_struct *vma,
|
||||
unsigned long user_addr, unsigned long page);
|
||||
|
||||
/*
|
||||
* To make sure that userspace mapping is flushed to memory before
|
||||
* get_user_pages() uses a kernel mapping to access the page
|
||||
*/
|
||||
#define ARCH_HAS_FLUSH_ANON_PAGE
|
||||
void flush_anon_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long u_vaddr);
|
||||
|
||||
#endif /* CONFIG_ARC_CACHE_VIPT_ALIASING */
|
||||
|
||||
/*
|
||||
* A new pagecache page has PG_arch_1 clear - thus dcache dirty by default
|
||||
* This works around some PIO based drivers which don't call flush_dcache_page
|
||||
@ -76,28 +55,6 @@ void flush_anon_page(struct vm_area_struct *vma,
|
||||
*/
|
||||
#define PG_dc_clean PG_arch_1
|
||||
|
||||
#define CACHE_COLORS_NUM 4
|
||||
#define CACHE_COLORS_MSK (CACHE_COLORS_NUM - 1)
|
||||
#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & CACHE_COLORS_MSK)
|
||||
|
||||
/*
|
||||
* Simple wrapper over config option
|
||||
* Bootup code ensures that hardware matches kernel configuration
|
||||
*/
|
||||
static inline int cache_is_vipt_aliasing(void)
|
||||
{
|
||||
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
|
||||
}
|
||||
|
||||
/*
|
||||
* checks if two addresses (after page aligning) index into same cache set
|
||||
*/
|
||||
#define addr_not_cache_congruent(addr1, addr2) \
|
||||
({ \
|
||||
cache_is_vipt_aliasing() ? \
|
||||
(CACHE_COLOR(addr1) != CACHE_COLOR(addr2)) : 0; \
|
||||
})
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
memcpy(dst, src, len); \
|
||||
|
@ -291,4 +291,36 @@
|
||||
/* M = 8-1 N = 8 */
|
||||
.endm
|
||||
|
||||
.macro SAVE_ABI_CALLEE_REGS
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push r23
|
||||
push r24
|
||||
push r25
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ABI_CALLEE_REGS
|
||||
pop r25
|
||||
pop r24
|
||||
pop r23
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
.endm
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,91 @@
|
||||
#include <asm/irqflags-compact.h>
|
||||
#include <asm/thread_info.h> /* For THREAD_SIZE */
|
||||
|
||||
/* Note on the LD/ST addr modes with addr reg wback
|
||||
*
|
||||
* LD.a same as LD.aw
|
||||
*
|
||||
* LD.a reg1, [reg2, x] => Pre Incr
|
||||
* Eff Addr for load = [reg2 + x]
|
||||
*
|
||||
* LD.ab reg1, [reg2, x] => Post Incr
|
||||
* Eff Addr for load = [reg2]
|
||||
*/
|
||||
|
||||
.macro PUSHAX aux
|
||||
lr r9, [\aux]
|
||||
push r9
|
||||
.endm
|
||||
|
||||
.macro POPAX aux
|
||||
pop r9
|
||||
sr r9, [\aux]
|
||||
.endm
|
||||
|
||||
.macro SAVE_R0_TO_R12
|
||||
push r0
|
||||
push r1
|
||||
push r2
|
||||
push r3
|
||||
push r4
|
||||
push r5
|
||||
push r6
|
||||
push r7
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
.endm
|
||||
|
||||
.macro RESTORE_R12_TO_R0
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop r7
|
||||
pop r6
|
||||
pop r5
|
||||
pop r4
|
||||
pop r3
|
||||
pop r2
|
||||
pop r1
|
||||
pop r0
|
||||
.endm
|
||||
|
||||
.macro SAVE_ABI_CALLEE_REGS
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push r23
|
||||
push r24
|
||||
push r25
|
||||
.endm
|
||||
|
||||
.macro RESTORE_ABI_CALLEE_REGS
|
||||
pop r25
|
||||
pop r24
|
||||
pop r23
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
.endm
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* Switch to Kernel Mode stack if SP points to User Mode stack
|
||||
*
|
||||
@ -235,7 +320,7 @@
|
||||
SWITCH_TO_KERNEL_STK
|
||||
|
||||
|
||||
PUSH 0x003\LVL\()abcd /* Dummy ECR */
|
||||
st.a 0x003\LVL\()abcd, [sp, -4] /* Dummy ECR */
|
||||
sub sp, sp, 8 /* skip orig_r0 (not needed)
|
||||
skip pt_regs->sp, already saved above */
|
||||
|
||||
|
@ -21,114 +21,12 @@
|
||||
#include <asm/entry-arcv2.h>
|
||||
#endif
|
||||
|
||||
/* Note on the LD/ST addr modes with addr reg wback
|
||||
*
|
||||
* LD.a same as LD.aw
|
||||
*
|
||||
* LD.a reg1, [reg2, x] => Pre Incr
|
||||
* Eff Addr for load = [reg2 + x]
|
||||
*
|
||||
* LD.ab reg1, [reg2, x] => Post Incr
|
||||
* Eff Addr for load = [reg2]
|
||||
*/
|
||||
|
||||
.macro PUSH reg
|
||||
st.a \reg, [sp, -4]
|
||||
.endm
|
||||
|
||||
.macro PUSHAX aux
|
||||
lr r9, [\aux]
|
||||
PUSH r9
|
||||
.endm
|
||||
|
||||
.macro POP reg
|
||||
ld.ab \reg, [sp, 4]
|
||||
.endm
|
||||
|
||||
.macro POPAX aux
|
||||
POP r9
|
||||
sr r9, [\aux]
|
||||
.endm
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* Helpers to save/restore Scratch Regs:
|
||||
* used by Interrupt/Exception Prologue/Epilogue
|
||||
*-------------------------------------------------------------*/
|
||||
.macro SAVE_R0_TO_R12
|
||||
PUSH r0
|
||||
PUSH r1
|
||||
PUSH r2
|
||||
PUSH r3
|
||||
PUSH r4
|
||||
PUSH r5
|
||||
PUSH r6
|
||||
PUSH r7
|
||||
PUSH r8
|
||||
PUSH r9
|
||||
PUSH r10
|
||||
PUSH r11
|
||||
PUSH r12
|
||||
.endm
|
||||
|
||||
.macro RESTORE_R12_TO_R0
|
||||
POP r12
|
||||
POP r11
|
||||
POP r10
|
||||
POP r9
|
||||
POP r8
|
||||
POP r7
|
||||
POP r6
|
||||
POP r5
|
||||
POP r4
|
||||
POP r3
|
||||
POP r2
|
||||
POP r1
|
||||
POP r0
|
||||
|
||||
.endm
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* Helpers to save/restore callee-saved regs:
|
||||
* used by several macros below
|
||||
*-------------------------------------------------------------*/
|
||||
.macro SAVE_R13_TO_R25
|
||||
PUSH r13
|
||||
PUSH r14
|
||||
PUSH r15
|
||||
PUSH r16
|
||||
PUSH r17
|
||||
PUSH r18
|
||||
PUSH r19
|
||||
PUSH r20
|
||||
PUSH r21
|
||||
PUSH r22
|
||||
PUSH r23
|
||||
PUSH r24
|
||||
PUSH r25
|
||||
.endm
|
||||
|
||||
.macro RESTORE_R25_TO_R13
|
||||
POP r25
|
||||
POP r24
|
||||
POP r23
|
||||
POP r22
|
||||
POP r21
|
||||
POP r20
|
||||
POP r19
|
||||
POP r18
|
||||
POP r17
|
||||
POP r16
|
||||
POP r15
|
||||
POP r14
|
||||
POP r13
|
||||
.endm
|
||||
|
||||
/*
|
||||
* save user mode callee regs as struct callee_regs
|
||||
* - needed by fork/do_signal/unaligned-access-emulation.
|
||||
*/
|
||||
.macro SAVE_CALLEE_SAVED_USER
|
||||
SAVE_R13_TO_R25
|
||||
SAVE_ABI_CALLEE_REGS
|
||||
.endm
|
||||
|
||||
/*
|
||||
@ -136,18 +34,18 @@
|
||||
* - could have been changed by ptrace tracer or unaligned-access fixup
|
||||
*/
|
||||
.macro RESTORE_CALLEE_SAVED_USER
|
||||
RESTORE_R25_TO_R13
|
||||
RESTORE_ABI_CALLEE_REGS
|
||||
.endm
|
||||
|
||||
/*
|
||||
* save/restore kernel mode callee regs at the time of context switch
|
||||
*/
|
||||
.macro SAVE_CALLEE_SAVED_KERNEL
|
||||
SAVE_R13_TO_R25
|
||||
SAVE_ABI_CALLEE_REGS
|
||||
.endm
|
||||
|
||||
.macro RESTORE_CALLEE_SAVED_KERNEL
|
||||
RESTORE_R25_TO_R13
|
||||
RESTORE_ABI_CALLEE_REGS
|
||||
.endm
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
|
@ -10,6 +10,13 @@
|
||||
#include <linux/types.h>
|
||||
#include <asm-generic/pgtable-nopmd.h>
|
||||
|
||||
/*
|
||||
* Hugetlb definitions.
|
||||
*/
|
||||
#define HPAGE_SHIFT PMD_SHIFT
|
||||
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
|
||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||
|
||||
static inline pte_t pmd_pte(pmd_t pmd)
|
||||
{
|
||||
return __pte(pmd_val(pmd));
|
||||
|
@ -54,6 +54,10 @@ struct pt_regs {
|
||||
ecr_reg ecr;
|
||||
};
|
||||
|
||||
struct callee_regs {
|
||||
unsigned long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13;
|
||||
};
|
||||
|
||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, ecr)
|
||||
|
||||
#else
|
||||
@ -92,16 +96,14 @@ struct pt_regs {
|
||||
unsigned long status32;
|
||||
};
|
||||
|
||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, status32)
|
||||
|
||||
#endif
|
||||
|
||||
/* Callee saved registers - need to be saved only when you are scheduled out */
|
||||
|
||||
struct callee_regs {
|
||||
unsigned long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13;
|
||||
};
|
||||
|
||||
#define MAX_REG_OFFSET offsetof(struct pt_regs, status32)
|
||||
|
||||
#endif
|
||||
|
||||
#define instruction_pointer(regs) ((regs)->ret)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
|
@ -153,7 +153,7 @@ static int arcv2_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len)
|
||||
{
|
||||
int n = 0;
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
const char *release, *cpu_nm, *isa_nm = "ARCv2";
|
||||
const char *release = "", *cpu_nm = "HS38", *isa_nm = "ARCv2";
|
||||
int dual_issue = 0, dual_enb = 0, mpy_opt, present;
|
||||
int bpu_full, bpu_cache, bpu_pred, bpu_ret_stk;
|
||||
char mpy_nm[16], lpb_nm[32];
|
||||
@ -172,8 +172,6 @@ static int arcv2_mumbojumbo(int c, struct cpuinfo_arc *info, char *buf, int len)
|
||||
* releases only update it.
|
||||
*/
|
||||
|
||||
cpu_nm = "HS38";
|
||||
|
||||
if (info->arcver > 0x50 && info->arcver <= 0x53) {
|
||||
release = arc_hs_rel[info->arcver - 0x51].str;
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ struct rt_sigframe {
|
||||
unsigned int sigret_magic;
|
||||
};
|
||||
|
||||
static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
|
||||
static int save_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs)
|
||||
{
|
||||
int err = 0;
|
||||
#ifndef CONFIG_ISA_ARCOMPACT
|
||||
@ -75,12 +75,12 @@ static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
|
||||
#else
|
||||
v2abi.r58 = v2abi.r59 = 0;
|
||||
#endif
|
||||
err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi));
|
||||
err = __copy_to_user(&mctx->v2abi, (void const *)&v2abi, sizeof(v2abi));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs)
|
||||
static int restore_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs)
|
||||
{
|
||||
int err = 0;
|
||||
#ifndef CONFIG_ISA_ARCOMPACT
|
||||
|
@ -145,10 +145,9 @@ dc_chk:
|
||||
p_dc->sz_k = 1 << (dbcr.sz - 1);
|
||||
|
||||
n += scnprintf(buf + n, len - n,
|
||||
"D-Cache\t\t: %uK, %dway/set, %uB Line, %s%s%s\n",
|
||||
"D-Cache\t\t: %uK, %dway/set, %uB Line, %s%s\n",
|
||||
p_dc->sz_k, assoc, p_dc->line_len,
|
||||
vipt ? "VIPT" : "PIPT",
|
||||
p_dc->colors > 1 ? " aliasing" : "",
|
||||
IS_USED_CFG(CONFIG_ARC_HAS_DCACHE));
|
||||
|
||||
slc_chk:
|
||||
@ -703,51 +702,10 @@ static inline void arc_slc_enable(void)
|
||||
* Exported APIs
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handle cache congruency of kernel and userspace mappings of page when kernel
|
||||
* writes-to/reads-from
|
||||
*
|
||||
* The idea is to defer flushing of kernel mapping after a WRITE, possible if:
|
||||
* -dcache is NOT aliasing, hence any U/K-mappings of page are congruent
|
||||
* -U-mapping doesn't exist yet for page (finalised in update_mmu_cache)
|
||||
* -In SMP, if hardware caches are coherent
|
||||
*
|
||||
* There's a corollary case, where kernel READs from a userspace mapped page.
|
||||
* If the U-mapping is not congruent to K-mapping, former needs flushing.
|
||||
*/
|
||||
void flush_dcache_folio(struct folio *folio)
|
||||
{
|
||||
struct address_space *mapping;
|
||||
|
||||
if (!cache_is_vipt_aliasing()) {
|
||||
clear_bit(PG_dc_clean, &folio->flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't handle anon pages here */
|
||||
mapping = folio_flush_mapping(folio);
|
||||
if (!mapping)
|
||||
return;
|
||||
|
||||
/*
|
||||
* pagecache page, file not yet mapped to userspace
|
||||
* Make a note that K-mapping is dirty
|
||||
*/
|
||||
if (!mapping_mapped(mapping)) {
|
||||
clear_bit(PG_dc_clean, &folio->flags);
|
||||
} else if (folio_mapped(folio)) {
|
||||
/* kernel reading from page with U-mapping */
|
||||
phys_addr_t paddr = (unsigned long)folio_address(folio);
|
||||
unsigned long vaddr = folio_pos(folio);
|
||||
|
||||
/*
|
||||
* vaddr is not actually the virtual address, but is
|
||||
* congruent to every user mapping.
|
||||
*/
|
||||
if (addr_not_cache_congruent(paddr, vaddr))
|
||||
__flush_dcache_pages(paddr, vaddr,
|
||||
folio_nr_pages(folio));
|
||||
}
|
||||
clear_bit(PG_dc_clean, &folio->flags);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(flush_dcache_folio);
|
||||
|
||||
@ -921,44 +879,6 @@ noinline void flush_cache_all(void)
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARC_CACHE_VIPT_ALIASING
|
||||
|
||||
void flush_cache_mm(struct mm_struct *mm)
|
||||
{
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr,
|
||||
unsigned long pfn)
|
||||
{
|
||||
phys_addr_t paddr = pfn << PAGE_SHIFT;
|
||||
|
||||
u_vaddr &= PAGE_MASK;
|
||||
|
||||
__flush_dcache_pages(paddr, u_vaddr, 1);
|
||||
|
||||
if (vma->vm_flags & VM_EXEC)
|
||||
__inv_icache_pages(paddr, u_vaddr, 1);
|
||||
}
|
||||
|
||||
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
flush_cache_all();
|
||||
}
|
||||
|
||||
void flush_anon_page(struct vm_area_struct *vma, struct page *page,
|
||||
unsigned long u_vaddr)
|
||||
{
|
||||
/* TBD: do we really need to clear the kernel mapping */
|
||||
__flush_dcache_pages((phys_addr_t)page_address(page), u_vaddr, 1);
|
||||
__flush_dcache_pages((phys_addr_t)page_address(page),
|
||||
(phys_addr_t)page_address(page), 1);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void copy_user_highpage(struct page *to, struct page *from,
|
||||
unsigned long u_vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
@ -966,46 +886,11 @@ void copy_user_highpage(struct page *to, struct page *from,
|
||||
struct folio *dst = page_folio(to);
|
||||
void *kfrom = kmap_atomic(from);
|
||||
void *kto = kmap_atomic(to);
|
||||
int clean_src_k_mappings = 0;
|
||||
|
||||
/*
|
||||
* If SRC page was already mapped in userspace AND it's U-mapping is
|
||||
* not congruent with K-mapping, sync former to physical page so that
|
||||
* K-mapping in memcpy below, sees the right data
|
||||
*
|
||||
* Note that while @u_vaddr refers to DST page's userspace vaddr, it is
|
||||
* equally valid for SRC page as well
|
||||
*
|
||||
* For !VIPT cache, all of this gets compiled out as
|
||||
* addr_not_cache_congruent() is 0
|
||||
*/
|
||||
if (page_mapcount(from) && addr_not_cache_congruent(kfrom, u_vaddr)) {
|
||||
__flush_dcache_pages((unsigned long)kfrom, u_vaddr, 1);
|
||||
clean_src_k_mappings = 1;
|
||||
}
|
||||
|
||||
copy_page(kto, kfrom);
|
||||
|
||||
/*
|
||||
* Mark DST page K-mapping as dirty for a later finalization by
|
||||
* update_mmu_cache(). Although the finalization could have been done
|
||||
* here as well (given that both vaddr/paddr are available).
|
||||
* But update_mmu_cache() already has code to do that for other
|
||||
* non copied user pages (e.g. read faults which wire in pagecache page
|
||||
* directly).
|
||||
*/
|
||||
clear_bit(PG_dc_clean, &dst->flags);
|
||||
|
||||
/*
|
||||
* if SRC was already usermapped and non-congruent to kernel mapping
|
||||
* sync the kernel mapping back to physical page
|
||||
*/
|
||||
if (clean_src_k_mappings) {
|
||||
__flush_dcache_pages((unsigned long)kfrom,
|
||||
(unsigned long)kfrom, 1);
|
||||
} else {
|
||||
clear_bit(PG_dc_clean, &src->flags);
|
||||
}
|
||||
clear_bit(PG_dc_clean, &src->flags);
|
||||
|
||||
kunmap_atomic(kto);
|
||||
kunmap_atomic(kfrom);
|
||||
@ -1140,17 +1025,8 @@ static noinline void __init arc_cache_init_master(void)
|
||||
dc->line_len, L1_CACHE_BYTES);
|
||||
|
||||
/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
|
||||
if (is_isa_arcompact()) {
|
||||
int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
|
||||
|
||||
if (dc->colors > 1) {
|
||||
if (!handled)
|
||||
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
|
||||
if (CACHE_COLORS_NUM != dc->colors)
|
||||
panic("CACHE_COLORS_NUM not optimized for config\n");
|
||||
} else if (handled && dc->colors == 1) {
|
||||
panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
|
||||
}
|
||||
if (is_isa_arcompact() && dc->colors > 1) {
|
||||
panic("Aliasing VIPT cache not supported\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,6 @@
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#define COLOUR_ALIGN(addr, pgoff) \
|
||||
((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \
|
||||
(((pgoff) << PAGE_SHIFT) & (SHMLBA - 1)))
|
||||
|
||||
/*
|
||||
* Ensure that shared mappings are correctly aligned to
|
||||
* avoid aliasing issues with VIPT caches.
|
||||
@ -31,21 +27,13 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
int do_align = 0;
|
||||
int aliasing = cache_is_vipt_aliasing();
|
||||
struct vm_unmapped_area_info info;
|
||||
|
||||
/*
|
||||
* We only need to do colour alignment if D cache aliases.
|
||||
*/
|
||||
if (aliasing)
|
||||
do_align = filp || (flags & MAP_SHARED);
|
||||
|
||||
/*
|
||||
* We enforce the MAP_FIXED case.
|
||||
*/
|
||||
if (flags & MAP_FIXED) {
|
||||
if (aliasing && flags & MAP_SHARED &&
|
||||
if (flags & MAP_SHARED &&
|
||||
(addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
|
||||
return -EINVAL;
|
||||
return addr;
|
||||
@ -55,10 +43,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
return -ENOMEM;
|
||||
|
||||
if (addr) {
|
||||
if (do_align)
|
||||
addr = COLOUR_ALIGN(addr, pgoff);
|
||||
else
|
||||
addr = PAGE_ALIGN(addr);
|
||||
addr = PAGE_ALIGN(addr);
|
||||
|
||||
vma = find_vma(mm, addr);
|
||||
if (TASK_SIZE - len >= addr &&
|
||||
@ -70,7 +55,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
info.length = len;
|
||||
info.low_limit = mm->mmap_base;
|
||||
info.high_limit = TASK_SIZE;
|
||||
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
|
||||
info.align_mask = 0;
|
||||
info.align_offset = pgoff << PAGE_SHIFT;
|
||||
return vm_unmapped_area(&info);
|
||||
}
|
||||
|
@ -478,21 +478,15 @@ void update_mmu_cache_range(struct vm_fault *vmf, struct vm_area_struct *vma,
|
||||
|
||||
create_tlb(vma, vaddr, ptep);
|
||||
|
||||
if (page == ZERO_PAGE(0)) {
|
||||
if (page == ZERO_PAGE(0))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exec page : Independent of aliasing/page-color considerations,
|
||||
* since icache doesn't snoop dcache on ARC, any dirty
|
||||
* K-mapping of a code page needs to be wback+inv so that
|
||||
* icache fetch by userspace sees code correctly.
|
||||
* !EXEC page: If K-mapping is NOT congruent to U-mapping, flush it
|
||||
* so userspace sees the right data.
|
||||
* (Avoids the flush for Non-exec + congruent mapping case)
|
||||
* For executable pages, since icache doesn't snoop dcache, any
|
||||
* dirty K-mapping of a code page needs to be wback+inv so that
|
||||
* icache fetch by userspace sees code correctly.
|
||||
*/
|
||||
if ((vma->vm_flags & VM_EXEC) ||
|
||||
addr_not_cache_congruent(paddr, vaddr)) {
|
||||
if (vma->vm_flags & VM_EXEC) {
|
||||
struct folio *folio = page_folio(page);
|
||||
int dirty = !test_and_set_bit(PG_dc_clean, &folio->flags);
|
||||
if (dirty) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user