diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/Makefile | 15 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev6.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/abort-ev7.S | 1 | ||||
-rw-r--r-- | arch/arm/mm/cache-v6.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/cache-v7.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/cache-v7m.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/copypage-feroceon.c | 1 | ||||
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 17 | ||||
-rw-r--r-- | arch/arm/mm/fault.c | 23 | ||||
-rw-r--r-- | arch/arm/mm/fault.h | 9 | ||||
-rw-r--r-- | arch/arm/mm/nommu.c | 19 | ||||
-rw-r--r-- | arch/arm/mm/proc-v6.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7-2level.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/tlb-v6.S | 2 | ||||
-rw-r--r-- | arch/arm/mm/tlb-v7.S | 2 |
16 files changed, 63 insertions, 39 deletions
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 3510503bc5e6..71b858c9b10c 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -33,9 +33,6 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o -AFLAGS_abort-ev6.o :=-Wa,-march=armv6k -AFLAGS_abort-ev7.o :=-Wa,-march=armv7-a - obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o @@ -49,10 +46,6 @@ obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o obj-$(CONFIG_CPU_CACHE_NOP) += cache-nop.o obj-$(CONFIG_CPU_CACHE_V7M) += cache-v7m.o -AFLAGS_cache-v6.o :=-Wa,-march=armv6 -AFLAGS_cache-v7.o :=-Wa,-march=armv7-a -AFLAGS_cache-v7m.o :=-Wa,-march=armv7-m - obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o obj-$(CONFIG_CPU_COPY_FEROCEON) += copypage-feroceon.o @@ -62,8 +55,6 @@ obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o -CFLAGS_copypage-feroceon.o := -march=armv5te - obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o @@ -72,9 +63,6 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o -AFLAGS_tlb-v6.o :=-Wa,-march=armv6 -AFLAGS_tlb-v7.o :=-Wa,-march=armv7-a - obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o @@ -101,9 +89,6 @@ obj-$(CONFIG_CPU_V6K) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o proc-v7-bugs.o obj-$(CONFIG_CPU_V7M) += proc-v7m.o -AFLAGS_proc-v6.o :=-Wa,-march=armv6 -AFLAGS_proc-v7.o :=-Wa,-march=armv7-a - obj-$(CONFIG_OUTER_CACHE) += l2c-common.o obj-$(CONFIG_CACHE_B15_RAC) += cache-b15-rac.o obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index c58bf8b43fea..836dc1299243 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -16,6 +16,7 @@ * abort here if the I-TLB and D-TLB aren't seeing the same * picture. Unfortunately, this does happen. We live with it. */ + .arch armv6k .align 5 ENTRY(v6_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index f81bceacc660..53fb41c24774 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S @@ -12,6 +12,7 @@ * * Purpose : obtain information about current aborted instruction. */ + .arch armv7-a .align 5 ENTRY(v7_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index f0f65eb073e4..250c83bf7158 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -19,6 +19,8 @@ #define D_CACHE_LINE_SIZE 32 #define BTB_FLUSH_SIZE 8 +.arch armv6 + /* * v6_flush_icache_all() * diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 7c9499b728c4..127afe2096ba 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -16,6 +16,8 @@ #include "proc-macros.S" +.arch armv7-a + #ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND .globl icache_size .data diff --git a/arch/arm/mm/cache-v7m.S b/arch/arm/mm/cache-v7m.S index 1bc3a0a50753..eb60b5e5e2ad 100644 --- a/arch/arm/mm/cache-v7m.S +++ b/arch/arm/mm/cache-v7m.S @@ -18,6 +18,8 @@ #include "proc-macros.S" +.arch armv7-m + /* Generic V7M read/write macros for memory mapped cache operations */ .macro v7m_cache_read, rt, reg movw \rt, #:lower16:BASEADDR_V7M_SCB + \reg diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c index 064b19e63571..5fc8ef1e665f 100644 --- a/arch/arm/mm/copypage-feroceon.c +++ b/arch/arm/mm/copypage-feroceon.c @@ -15,6 +15,7 @@ static void feroceon_copy_user_page(void *kto, const void *kfrom) int tmp; asm volatile ("\ +.arch armv5te \n\ 1: ldmia %1!, {r2 - r7, ip, lr} \n\ pld [%1, #0] \n\ pld [%1, #32] \n\ diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index d7909091cf97..c135f6e37a00 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -564,14 +564,6 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, if (mask < 0xffffffffULL) gfp |= GFP_DMA; - /* - * Following is a work-around (a.k.a. hack) to prevent pages - * with __GFP_COMP being passed to split_page() which cannot - * handle them. The real problem is that this flag probably - * should be 0 on ARM as it is not supported on this - * platform; see CONFIG_HUGETLBFS. - */ - gfp &= ~(__GFP_COMP); args.gfp = gfp; *handle = DMA_MAPPING_ERROR; @@ -1093,15 +1085,6 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size, return __iommu_alloc_simple(dev, size, gfp, handle, coherent_flag, attrs); - /* - * Following is a work-around (a.k.a. hack) to prevent pages - * with __GFP_COMP being passed to split_page() which cannot - * handle them. The real problem is that this flag probably - * should be 0 on ARM as it is not supported on this - * platform; see CONFIG_HUGETLBFS. - */ - gfp &= ~(__GFP_COMP); - pages = __iommu_alloc_buffer(dev, size, gfp, attrs, coherent_flag); if (!pages) return NULL; diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 46cccd6bf705..2418f1efabd8 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -105,14 +105,28 @@ static inline bool is_write_fault(unsigned int fsr) return (fsr & FSR_WRITE) && !(fsr & FSR_CM); } +static inline bool is_translation_fault(unsigned int fsr) +{ + int fs = fsr_fs(fsr); +#ifdef CONFIG_ARM_LPAE + if ((fs & FS_MMU_NOLL_MASK) == FS_TRANS_NOLL) + return true; +#else + if (fs == FS_L1_TRANS || fs == FS_L2_TRANS) + return true; +#endif + return false; +} + static void die_kernel_fault(const char *msg, struct mm_struct *mm, unsigned long addr, unsigned int fsr, struct pt_regs *regs) { bust_spinlocks(1); pr_alert("8<--- cut here ---\n"); - pr_alert("Unable to handle kernel %s at virtual address %08lx\n", - msg, addr); + pr_alert("Unable to handle kernel %s at virtual address %08lx when %s\n", + msg, addr, fsr & FSR_LNX_PF ? "execute" : + fsr & FSR_WRITE ? "write" : "read"); show_pte(KERN_ALERT, mm, addr); die("Oops", regs, fsr); @@ -140,7 +154,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, if (addr < PAGE_SIZE) { msg = "NULL pointer dereference"; } else { - if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs)) + if (is_translation_fault(fsr) && + kfence_handle_page_fault(addr, is_write_fault(fsr), regs)) return; msg = "paging request"; @@ -208,7 +223,7 @@ static inline bool is_permission_fault(unsigned int fsr) { int fs = fsr_fs(fsr); #ifdef CONFIG_ARM_LPAE - if ((fs & FS_PERM_NOLL_MASK) == FS_PERM_NOLL) + if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL) return true; #else if (fs == FS_L1_PERM || fs == FS_L2_PERM) diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h index 83b5ab32d7a4..54927ba1fa6e 100644 --- a/arch/arm/mm/fault.h +++ b/arch/arm/mm/fault.h @@ -14,8 +14,9 @@ #ifdef CONFIG_ARM_LPAE #define FSR_FS_AEA 17 +#define FS_TRANS_NOLL 0x4 #define FS_PERM_NOLL 0xC -#define FS_PERM_NOLL_MASK 0x3C +#define FS_MMU_NOLL_MASK 0x3C static inline int fsr_fs(unsigned int fsr) { @@ -23,8 +24,10 @@ static inline int fsr_fs(unsigned int fsr) } #else #define FSR_FS_AEA 22 -#define FS_L1_PERM 0xD -#define FS_L2_PERM 0xF +#define FS_L1_TRANS 0x5 +#define FS_L2_TRANS 0x7 +#define FS_L1_PERM 0xD +#define FS_L2_PERM 0xF static inline int fsr_fs(unsigned int fsr) { diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index c42debaded95..c1494a4dee25 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -26,6 +26,13 @@ unsigned long vectors_base; +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; +EXPORT_SYMBOL(empty_zero_page); + #ifdef CONFIG_ARM_MPU struct mpu_rgn_info mpu_rgn_info; #endif @@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void) */ void __init paging_init(const struct machine_desc *mdesc) { + void *zero_page; + early_trap_init((void *)vectors_base); mpu_setup(); + + /* allocate the zero page. */ + zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!zero_page) + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", + __func__, PAGE_SIZE, PAGE_SIZE); + bootmem_init(); + + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); } /* diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index a0618f3e6836..203dff89ab1a 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -32,6 +32,8 @@ #define TTB_FLAGS_SMP TTB_RGN_WBWA|TTB_S #define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S +.arch armv6 + ENTRY(cpu_v6_proc_init) ret lr diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S index 5db029c8f987..0a3083ad19c2 100644 --- a/arch/arm/mm/proc-v7-2level.S +++ b/arch/arm/mm/proc-v7-2level.S @@ -24,6 +24,8 @@ #define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA #define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S +.arch armv7-a + /* * cpu_v7_switch_mm(pgd_phys, tsk) * diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 26d726a08a34..6b4ef9539b68 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -24,6 +24,8 @@ #include "proc-v7-2level.S" #endif +.arch armv7-a + ENTRY(cpu_v7_proc_init) ret lr ENDPROC(cpu_v7_proc_init) diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index 74f4b383afe3..1d91e49b2c2d 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S @@ -17,6 +17,8 @@ #define HARVARD_TLB +.arch armv6 + /* * v6wbi_flush_user_tlb_range(start, end, vma) * diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index 87bf4ab17721..35fd6d4f0d03 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S @@ -16,6 +16,8 @@ #include <asm/tlbflush.h> #include "proc-macros.S" +.arch armv7-a + /* * v7wbi_flush_user_tlb_range(start, end, vma) * |