summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/Makefile7
-rw-r--r--arch/arm/boot/compressed/debug.S4
-rw-r--r--arch/arm/boot/compressed/head.S2
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.S20
-rw-r--r--arch/arm/include/asm/Kbuild1
-rw-r--r--arch/arm/include/asm/dma-mapping.h7
-rw-r--r--arch/arm/include/asm/highmem.h1
-rw-r--r--arch/arm/include/asm/unaligned.h27
-rw-r--r--arch/arm/kernel/atags_parse.c7
-rw-r--r--arch/arm/kernel/debug.S47
-rw-r--r--arch/arm/kernel/early_printk.c16
-rw-r--r--arch/arm/kernel/entry-common.S9
-rw-r--r--arch/arm/kernel/setup.c10
-rw-r--r--arch/arm/kernel/traps.c28
-rw-r--r--arch/arm/mm/dma-mapping.c21
-rw-r--r--arch/arm/mm/init.c10
-rw-r--r--arch/arm/mm/nommu.c5
19 files changed, 143 insertions, 84 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bf91aa38051d..631e61bc7ac4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
bool
default y
select ARCH_CLOCKSOURCE_DATA
+ select ARCH_DISCARD_MEMBLOCK if !HAVE_ARCH_PFN_VALID
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 47d3a1ab08d2..36ae4454554c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -44,10 +44,12 @@ endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
KBUILD_CPPFLAGS += -mbig-endian
+CHECKFLAGS += -D__ARMEB__
AS += -EB
LD += -EB
else
KBUILD_CPPFLAGS += -mlittle-endian
+CHECKFLAGS += -D__ARMEL__
AS += -EL
LD += -EL
endif
@@ -131,7 +133,7 @@ endif
KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
-CHECKFLAGS += -D__arm__
+CHECKFLAGS += -D__arm__ -m32
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index d50430c40045..9519ce3d2e1c 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -116,8 +116,11 @@ ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
asflags-y := -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol.
-KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
- awk 'END{print $$3}')
+KBSS_SZ = $(shell $(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \
+ perl -e 'while (<>) { \
+ $$bss_start=hex($$1) if /^([[:xdigit:]]+) B __bss_start$$/; \
+ $$bss_end=hex($$1) if /^([[:xdigit:]]+) B __bss_stop$$/; \
+ }; printf "%d\n", $$bss_end - $$bss_start;')
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
diff --git a/arch/arm/boot/compressed/debug.S b/arch/arm/boot/compressed/debug.S
index 5392ee63338f..8f6e37177de1 100644
--- a/arch/arm/boot/compressed/debug.S
+++ b/arch/arm/boot/compressed/debug.S
@@ -23,7 +23,11 @@ ENTRY(putc)
strb r0, [r1]
mov r0, #0x03 @ SYS_WRITEC
ARM( svc #0x123456 )
+#ifdef CONFIG_CPU_V7M
+ THUMB( bkpt #0xab )
+#else
THUMB( svc #0xab )
+#endif
mov pc, lr
.align 2
1: .word _GLOBAL_OFFSET_TABLE_ - .
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 8a756870c238..45c8823c3750 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -143,6 +143,8 @@ start:
.word _magic_start @ absolute load/run zImage address
.word _magic_end @ zImage end address
.word 0x04030201 @ endianness flag
+ .word 0x45454545 @ another magic number to indicate
+ .word _magic_table @ additional data table
__EFI_HEADER
1:
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index 7a4c59154361..e6bf6774c4bb 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -44,12 +44,22 @@ SECTIONS
*(.glue_7t)
*(.glue_7)
}
+ .table : ALIGN(4) {
+ _table_start = .;
+ LONG(ZIMAGE_MAGIC(2))
+ LONG(ZIMAGE_MAGIC(0x5a534c4b))
+ LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start))
+ LONG(ZIMAGE_MAGIC(_kernel_bss_size))
+ LONG(0)
+ _table_end = .;
+ }
.rodata : {
*(.rodata)
*(.rodata.*)
}
.piggydata : {
*(.piggydata)
+ __piggy_size_addr = . - 4;
}
. = ALIGN(4);
@@ -85,9 +95,19 @@ SECTIONS
_edata = .;
+ /*
+ * The image_end section appears after any additional loadable sections
+ * that the linker may decide to insert in the binary image. Having
+ * this symbol allows further debug in the near future.
+ */
+ .image_end (NOLOAD) : {
+ _edata_real = .;
+ }
+
_magic_sig = ZIMAGE_MAGIC(0x016f2818);
_magic_start = ZIMAGE_MAGIC(_start);
_magic_end = ZIMAGE_MAGIC(_edata);
+ _magic_table = ZIMAGE_MAGIC(_table_start - _start);
. = BSS_START;
__bss_start = .;
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 721ab5ecfb9b..0f2c8a2a8131 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -20,7 +20,6 @@ generic-y += simd.h
generic-y += sizes.h
generic-y += timex.h
generic-y += trace_clock.h
-generic-y += unaligned.h
generated-y += mach-types.h
generated-y += unistd-nr.h
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 4e0285a66ef8..462803f3a6a0 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -190,13 +190,6 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
unsigned long attrs);
/*
- * This can be called during early boot to increase the size of the atomic
- * coherent DMA pool above the default value of 256KiB. It must be called
- * before postcore_initcall.
- */
-extern void __init init_dma_coherent_pool_size(unsigned long size);
-
-/*
* For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
* and utilize bounce buffers as needed to work around limited DMA windows.
*
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 0a0e2d1784c0..61736fdccc79 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -18,7 +18,6 @@
} while (0)
extern pte_t *pkmap_page_table;
-extern pte_t *fixmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h
new file mode 100644
index 000000000000..ab905ffcf193
--- /dev/null
+++ b/arch/arm/include/asm/unaligned.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_ARM_UNALIGNED_H
+#define __ASM_ARM_UNALIGNED_H
+
+/*
+ * We generally want to set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS on ARMv6+,
+ * but we don't want to use linux/unaligned/access_ok.h since that can lead
+ * to traps on unaligned stm/ldm or strd/ldrd.
+ */
+#include <asm/byteorder.h>
+
+#if defined(__LITTLE_ENDIAN)
+# include <linux/unaligned/le_struct.h>
+# include <linux/unaligned/be_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+#elif defined(__BIG_ENDIAN)
+# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/le_byteshift.h>
+# include <linux/unaligned/generic.h>
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+#else
+# error need to define endianess
+#endif
+
+#endif /* __ASM_ARM_UNALIGNED_H */
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
index 98fbfd235ac8..c10a3e8ee998 100644
--- a/arch/arm/kernel/atags_parse.c
+++ b/arch/arm/kernel/atags_parse.c
@@ -196,11 +196,8 @@ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
break;
}
- if (!mdesc) {
- early_print("\nError: unrecognized/unsupported machine ID"
- " (r1 = 0x%08x).\n\n", machine_nr);
- dump_machine_table(); /* does not return */
- }
+ if (!mdesc)
+ return NULL;
if (__atags_pointer)
tags = phys_to_virt(__atags_pointer);
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index ea9646cc2a0e..b795dc2408c0 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -55,7 +55,9 @@ ENDPROC(printhex4)
ENTRY(printhex2)
mov r1, #2
-printhex: adr r2, hexbuf
+printhex: adr r2, hexbuf_rel
+ ldr r3, [r2]
+ add r2, r2, r3
add r3, r2, r1
mov r1, #0
strb r1, [r3]
@@ -71,7 +73,11 @@ printhex: adr r2, hexbuf
b printascii
ENDPROC(printhex2)
-hexbuf: .space 16
+ .pushsection .bss
+hexbuf_addr: .space 16
+ .popsection
+ .align
+hexbuf_rel: .long hexbuf_addr - .
.ltorg
@@ -79,25 +85,28 @@ hexbuf: .space 16
ENTRY(printascii)
addruart_current r3, r1, r2
- b 2f
-1: waituart r2, r3
- senduart r1, r3
- busyuart r2, r3
- teq r1, #'\n'
- moveq r1, #'\r'
- beq 1b
-2: teq r0, #0
+1: teq r0, #0
ldrneb r1, [r0], #1
teqne r1, #0
- bne 1b
- ret lr
+ reteq lr
+2: teq r1, #'\n'
+ bne 3f
+ mov r1, #'\r'
+ waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ mov r1, #'\n'
+3: waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ b 1b
ENDPROC(printascii)
ENTRY(printch)
addruart_current r3, r1, r2
mov r1, r0
mov r0, #0
- b 1b
+ b 2b
ENDPROC(printch)
#ifdef CONFIG_MMU
@@ -115,16 +124,26 @@ ENTRY(printascii)
mov r1, r0
mov r0, #0x04 @ SYS_WRITE0
ARM( svc #0x123456 )
+#ifdef CONFIG_CPU_V7M
+ THUMB( bkpt #0xab )
+#else
THUMB( svc #0xab )
+#endif
ret lr
ENDPROC(printascii)
ENTRY(printch)
- adr r1, hexbuf
+ adr r1, hexbuf_rel
+ ldr r2, [r1]
+ add r1, r1, r2
strb r0, [r1]
mov r0, #0x03 @ SYS_WRITEC
ARM( svc #0x123456 )
+#ifdef CONFIG_CPU_V7M
+ THUMB( bkpt #0xab )
+#else
THUMB( svc #0xab )
+#endif
ret lr
ENDPROC(printch)
diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c
index 43076536965c..9257736ec9fa 100644
--- a/arch/arm/kernel/early_printk.c
+++ b/arch/arm/kernel/early_printk.c
@@ -11,16 +11,20 @@
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/string.h>
-extern void printch(int);
+extern void printascii(const char *);
static void early_write(const char *s, unsigned n)
{
- while (n-- > 0) {
- if (*s == '\n')
- printch('\r');
- printch(*s);
- s++;
+ char buf[128];
+ while (n) {
+ unsigned l = min(n, sizeof(buf)-1);
+ memcpy(buf, s, l);
+ buf[l] = 0;
+ s += l;
+ n -= l;
+ printascii(buf);
}
}
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index ca3614dc6938..cc70bc5650a5 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -394,17 +394,8 @@ ENDPROC(sys_fstatfs64_wrapper)
* offset, we return EINVAL.
*/
sys_mmap2:
-#if PAGE_SHIFT > 12
- tst r5, #PGOFF_MASK
- moveq r5, r5, lsr #PAGE_SHIFT - 12
- streq r5, [sp, #4]
- beq sys_mmap_pgoff
- mov r0, #-EINVAL
- ret lr
-#else
str r5, [sp, #4]
b sys_mmap_pgoff
-#endif
ENDPROC(sys_mmap2)
#ifdef CONFIG_OABI_COMPAT
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8e9a3e40d949..fc40a2b40595 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1069,6 +1069,16 @@ void __init setup_arch(char **cmdline_p)
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
+ if (!mdesc) {
+ early_print("\nError: invalid dtb and unrecognized/unsupported machine ID\n");
+ early_print(" r1=0x%08x, r2=0x%08x\n", __machine_arch_type,
+ __atags_pointer);
+ if (__atags_pointer)
+ early_print(" r2[]=%*ph\n", 16,
+ phys_to_virt(__atags_pointer));
+ dump_machine_table();
+ }
+
machine_desc = mdesc;
machine_name = mdesc->name;
dump_stack_set_arch_desc("%s", mdesc->name);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 43c0560f7b2d..5cf04888c581 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
set_fs(fs);
}
-static void dump_instr(const char *lvl, struct pt_regs *regs)
+static void __dump_instr(const char *lvl, struct pt_regs *regs)
{
unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8;
- mm_segment_t fs;
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i;
/*
- * We need to switch to kernel mode so that we can use __get_user
- * to safely read from kernel space. Note that we now dump the
- * code first, just in case the backtrace kills us.
+ * Note that we now dump the code first, just in case the backtrace
+ * kills us.
*/
- fs = get_fs();
- set_fs(KERNEL_DS);
for (i = -4; i < 1 + !!thumb; i++) {
unsigned int val, bad;
if (thumb)
- bad = __get_user(val, &((u16 *)addr)[i]);
+ bad = get_user(val, &((u16 *)addr)[i]);
else
- bad = __get_user(val, &((u32 *)addr)[i]);
+ bad = get_user(val, &((u32 *)addr)[i]);
if (!bad)
p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
@@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
}
}
printk("%sCode: %s\n", lvl, str);
+}
- set_fs(fs);
+static void dump_instr(const char *lvl, struct pt_regs *regs)
+{
+ mm_segment_t fs;
+
+ if (!user_mode(regs)) {
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ __dump_instr(lvl, regs);
+ set_fs(fs);
+ } else {
+ __dump_instr(lvl, regs);
+ }
}
#ifdef CONFIG_ARM_UNWIND
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index fcf1473d6fed..ada8eb206a90 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -382,9 +382,9 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
}
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
-static struct gen_pool *atomic_pool;
+static struct gen_pool *atomic_pool __ro_after_init;
-static size_t atomic_pool_size = DEFAULT_DMA_COHERENT_POOL_SIZE;
+static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE;
static int __init early_coherent_pool(char *p)
{
@@ -393,21 +393,6 @@ static int __init early_coherent_pool(char *p)
}
early_param("coherent_pool", early_coherent_pool);
-void __init init_dma_coherent_pool_size(unsigned long size)
-{
- /*
- * Catch any attempt to set the pool size too late.
- */
- BUG_ON(atomic_pool);
-
- /*
- * Set architecture specific coherent pool size only if
- * it has not been changed by kernel command line parameter.
- */
- if (atomic_pool_size == DEFAULT_DMA_COHERENT_POOL_SIZE)
- atomic_pool_size = size;
-}
-
/*
* Initialise the coherent pool for atomic allocations.
*/
@@ -443,7 +428,7 @@ static int __init atomic_pool_init(void)
gen_pool_set_algo(atomic_pool,
gen_pool_first_fit_order_align,
- (void *)PAGE_SHIFT);
+ NULL);
pr_info("DMA: preallocated %zu KiB pool for atomic coherent allocations\n",
atomic_pool_size / 1024);
return 0;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index ad80548325fe..81d4482b6861 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -580,16 +580,6 @@ void __init mem_init(void)
BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
#endif
-
- if (PAGE_SIZE >= 16384 && get_num_physpages() <= 128) {
- extern int sysctl_overcommit_memory;
- /*
- * On a machine this small we won't get
- * anywhere without overcommit, so turn
- * it on by default.
- */
- sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
- }
}
#ifdef CONFIG_STRICT_KERNEL_RWX
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 4c56b567cb47..e4370810f4f1 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -92,6 +92,11 @@ void __init arm_mm_memblock_reserve(void)
* reserved here.
*/
#endif
+ /*
+ * In any case, always ensure address 0 is never used as many things
+ * get very confused if 0 is returned as a legitimate address.
+ */
+ memblock_reserve(0, 1);
}
void __init adjust_lowmem_bounds(void)