Skip to content

Commit

Permalink
Merge branch 'devel-stable' into for-next
Browse files Browse the repository at this point in the history
  • Loading branch information
Russell King committed Nov 8, 2017
2 parents 7f3d1f9 + fe9c058 commit 0219614
Show file tree
Hide file tree
Showing 33 changed files with 1,137 additions and 455 deletions.
20 changes: 11 additions & 9 deletions arch/arm/Kconfig
Expand Up @@ -240,15 +240,6 @@ config NEED_RET_TO_USER
config ARCH_MTD_XIP
bool

config VECTORS_BASE
hex
default 0xffff0000 if MMU || CPU_HIGH_VECTOR
default DRAM_BASE if REMAP_VECTORS_TO_RAM
default 0x00000000
help
The base address of exception vectors. This must be two pages
in size.

config ARM_PATCH_PHYS_VIRT
bool "Patch physical to virtual translations at runtime" if EMBEDDED
default y
Expand Down Expand Up @@ -2006,6 +1997,17 @@ config XIP_PHYS_ADDR
be linked for and stored to. This address is dependent on your
own flash usage.

config XIP_DEFLATED_DATA
bool "Store kernel .data section compressed in ROM"
depends on XIP_KERNEL
select ZLIB_INFLATE
help
Before the kernel is actually executed, its .data section has to be
copied to RAM from ROM. This option allows for storing that data
in compressed form and decompressed to RAM rather than merely being
copied, saving some precious ROM space. A possible drawback is a
slightly longer boot delay.

config KEXEC
bool "Kexec system call (EXPERIMENTAL)"
depends on (!SMP || PM_SLEEP_SMP)
Expand Down
4 changes: 2 additions & 2 deletions arch/arm/Kconfig-nommu
Expand Up @@ -52,8 +52,8 @@ config REMAP_VECTORS_TO_RAM

config ARM_MPU
bool 'Use the ARM v7 PMSA Compliant MPU'
depends on CPU_V7
default y
depends on CPU_V7 || CPU_V7M
default y if CPU_V7
help
Some ARM systems without an MMU have instead a Memory Protection
Unit (MPU) that defines the type and permissions for regions of
Expand Down
13 changes: 12 additions & 1 deletion arch/arm/boot/Makefile
Expand Up @@ -31,8 +31,19 @@ targets := Image zImage xipImage bootpImage uImage

ifeq ($(CONFIG_XIP_KERNEL),y)

cmd_deflate_xip_data = $(CONFIG_SHELL) -c \
'$(srctree)/$(src)/deflate_xip_data.sh $< $@ || { rm -f $@; false; }'

ifeq ($(CONFIG_XIP_DEFLATED_DATA),y)
quiet_cmd_mkxip = XIPZ $@
cmd_mkxip = $(cmd_objcopy) && $(cmd_deflate_xip_data)
else
quiet_cmd_mkxip = $(quiet_cmd_objcopy)
cmd_mkxip = $(cmd_objcopy)
endif

$(obj)/xipImage: vmlinux FORCE
$(call if_changed,objcopy)
$(call if_changed,mkxip)
@$(kecho) ' Physical Address of xipImage: $(CONFIG_XIP_PHYS_ADDR)'

$(obj)/Image $(obj)/zImage: FORCE
Expand Down
64 changes: 64 additions & 0 deletions arch/arm/boot/deflate_xip_data.sh
@@ -0,0 +1,64 @@
#!/bin/sh

# XIP kernel .data segment compressor
#
# Created by: Nicolas Pitre, August 2017
# Copyright: (C) 2017 Linaro Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.

# This script locates the start of the .data section in xipImage and
# substitutes it with a compressed version. The needed offsets are obtained
# from symbol addresses in vmlinux. It is expected that .data extends to
# the end of xipImage.

set -e

VMLINUX="$1"
XIPIMAGE="$2"

DD="dd status=none"

# Use "make V=1" to debug this script.
case "$KBUILD_VERBOSE" in
*1*)
set -x
;;
esac

sym_val() {
# extract hex value for symbol in $1
local val=$($NM "$VMLINUX" | sed -n "/ $1$/{s/ .*$//p;q}")
[ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; }
# convert from hex to decimal
echo $((0x$val))
}

__data_loc=$(sym_val __data_loc)
_edata_loc=$(sym_val _edata_loc)
base_offset=$(sym_val _xiprom)

# convert to file based offsets
data_start=$(($__data_loc - $base_offset))
data_end=$(($_edata_loc - $base_offset))

# Make sure data occupies the last part of the file.
file_end=$(stat -c "%s" "$XIPIMAGE")
if [ "$file_end" != "$data_end" ]; then
printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \
$(($file_end + $base_offset)) $_edata_loc 2>&1
exit 1;
fi

# be ready to clean up
trap 'rm -f "$XIPIMAGE.tmp"' 0 1 2 3

# substitute the data section by a compressed version
$DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp"
$DD if="$XIPIMAGE" skip=$data_start iflag=skip_bytes |
gzip -9 >> "$XIPIMAGE.tmp"

# replace kernel binary
mv -f "$XIPIMAGE.tmp" "$XIPIMAGE"
10 changes: 10 additions & 0 deletions arch/arm/include/asm/cputype.h
Expand Up @@ -173,6 +173,11 @@ static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
return read_cpuid(CPUID_CACHETYPE);
}

static inline unsigned int __attribute_const__ read_cpuid_mputype(void)
{
return read_cpuid(CPUID_MPUIR);
}

#elif defined(CONFIG_CPU_V7M)

static inline unsigned int __attribute_const__ read_cpuid_id(void)
Expand All @@ -185,6 +190,11 @@ static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
return readl(BASEADDR_V7M_SCB + V7M_SCB_CTR);
}

static inline unsigned int __attribute_const__ read_cpuid_mputype(void)
{
return readl(BASEADDR_V7M_SCB + MPU_TYPE);
}

#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */

static inline unsigned int __attribute_const__ read_cpuid_id(void)
Expand Down
16 changes: 14 additions & 2 deletions arch/arm/include/asm/elf.h
Expand Up @@ -100,10 +100,15 @@ struct elf32_hdr;
extern int elf_check_arch(const struct elf32_hdr *);
#define elf_check_arch elf_check_arch

#define ELFOSABI_ARM_FDPIC 65 /* ARM FDPIC platform */
#define elf_check_fdpic(x) ((x)->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC)
#define elf_check_const_displacement(x) ((x)->e_flags & EF_ARM_PIC)
#define ELF_FDPIC_CORE_EFLAGS 0

#define vmcore_elf64_check_arch(x) (0)

extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
extern int arm_elf_read_implies_exec(int);
#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(stk)

struct task_struct;
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
Expand All @@ -120,6 +125,13 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
have no such handler. */
#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0

#define ELF_FDPIC_PLAT_INIT(_r, _exec_map_addr, _interp_map_addr, dynamic_addr) \
do { \
(_r)->ARM_r7 = _exec_map_addr; \
(_r)->ARM_r8 = _interp_map_addr; \
(_r)->ARM_r9 = dynamic_addr; \
} while(0)

extern void elf_set_personality(const struct elf32_hdr *);
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))

Expand Down
8 changes: 8 additions & 0 deletions arch/arm/include/asm/mmu.h
Expand Up @@ -14,6 +14,10 @@ typedef struct {
#ifdef CONFIG_VDSO
unsigned long vdso;
#endif
#ifdef CONFIG_BINFMT_ELF_FDPIC
unsigned long exec_fdpic_loadmap;
unsigned long interp_fdpic_loadmap;
#endif
} mm_context_t;

#ifdef CONFIG_CPU_HAS_ASID
Expand All @@ -33,6 +37,10 @@ typedef struct {
*/
typedef struct {
unsigned long end_brk;
#ifdef CONFIG_BINFMT_ELF_FDPIC
unsigned long exec_fdpic_loadmap;
unsigned long interp_fdpic_loadmap;
#endif
} mm_context_t;

#endif
Expand Down
26 changes: 20 additions & 6 deletions arch/arm/include/asm/mpu.h
@@ -1,8 +1,6 @@
#ifndef __ARM_MPU_H
#define __ARM_MPU_H

#ifdef CONFIG_ARM_MPU

/* MPUIR layout */
#define MPUIR_nU 1
#define MPUIR_DREGION 8
Expand All @@ -17,6 +15,11 @@
/* MPU D/I Size Register fields */
#define MPU_RSR_SZ 1
#define MPU_RSR_EN 0
#define MPU_RSR_SD 8

/* Number of subregions (SD) */
#define MPU_NR_SUBREGS 8
#define MPU_MIN_SUBREG_SIZE 256

/* The D/I RSR value for an enabled region spanning the whole of memory */
#define MPU_RSR_ALL_MEM 63
Expand All @@ -38,6 +41,7 @@
#endif

/* Access permission bits of ACR (only define those that we use)*/
#define MPU_AP_PL1RO_PL0NA (0x5 << 8)
#define MPU_AP_PL1RW_PL0RW (0x3 << 8)
#define MPU_AP_PL1RW_PL0R0 (0x2 << 8)
#define MPU_AP_PL1RW_PL0NA (0x1 << 8)
Expand All @@ -46,7 +50,7 @@
#define MPU_PROBE_REGION 0
#define MPU_BG_REGION 1
#define MPU_RAM_REGION 2
#define MPU_VECTORS_REGION 3
#define MPU_ROM_REGION 3

/* Maximum number of regions Linux is interested in */
#define MPU_MAX_REGIONS 16
Expand All @@ -64,13 +68,23 @@ struct mpu_rgn {
};

struct mpu_rgn_info {
u32 mpuir;
unsigned int used;
struct mpu_rgn rgns[MPU_MAX_REGIONS];
};
extern struct mpu_rgn_info mpu_rgn_info;

#endif /* __ASSEMBLY__ */
#ifdef CONFIG_ARM_MPU

extern void __init adjust_lowmem_bounds_mpu(void);
extern void __init mpu_setup(void);

#endif /* CONFIG_ARM_MPU */
#else

static inline void adjust_lowmem_bounds_mpu(void) {}
static inline void mpu_setup(void) {}

#endif /* !CONFIG_ARM_MPU */

#endif /* __ASSEMBLY__ */

#endif
22 changes: 15 additions & 7 deletions arch/arm/include/asm/processor.h
Expand Up @@ -47,15 +47,24 @@ struct thread_struct {

#define INIT_THREAD { }

#ifdef CONFIG_MMU
#define nommu_start_thread(regs) do { } while (0)
#else
#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
#endif

#define start_thread(regs,pc,sp) \
({ \
unsigned long r7, r8, r9; \
\
if (IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC)) { \
r7 = regs->ARM_r7; \
r8 = regs->ARM_r8; \
r9 = regs->ARM_r9; \
} \
memset(regs->uregs, 0, sizeof(regs->uregs)); \
if (IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC) && \
current->personality & FDPIC_FUNCPTRS) { \
regs->ARM_r7 = r7; \
regs->ARM_r8 = r8; \
regs->ARM_r9 = r9; \
regs->ARM_r10 = current->mm->start_data; \
} else if (!IS_ENABLED(CONFIG_MMU)) \
regs->ARM_r10 = current->mm->start_data; \
if (current->personality & ADDR_LIMIT_32BIT) \
regs->ARM_cpsr = USR_MODE; \
else \
Expand All @@ -65,7 +74,6 @@ struct thread_struct {
regs->ARM_cpsr |= PSR_ENDSTATE; \
regs->ARM_pc = pc & ~1; /* pc */ \
regs->ARM_sp = sp; /* sp */ \
nommu_start_thread(regs); \
})

/* Forward declaration, a strange C thing */
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/include/asm/smp.h
Expand Up @@ -60,7 +60,7 @@ asmlinkage void secondary_start_kernel(void);
*/
struct secondary_data {
union {
unsigned long mpu_rgn_szr;
struct mpu_rgn_info *mpu_rgn_info;
u64 pgdir;
};
unsigned long swapper_pg_dir;
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/ucontext.h
Expand Up @@ -2,6 +2,7 @@
#define _ASMARM_UCONTEXT_H

#include <asm/fpstate.h>
#include <asm/user.h>

/*
* struct sigcontext only has room for the basic registers, but struct
Expand Down
10 changes: 10 additions & 0 deletions arch/arm/include/asm/v7m.h
Expand Up @@ -57,6 +57,16 @@
#define V7M_SCB_CCSIDR 0x80 /* Cache size ID register */
#define V7M_SCB_CSSELR 0x84 /* Cache size selection register */

/* Memory-mapped MPU registers for M-class */
#define MPU_TYPE 0x90
#define MPU_CTRL 0x94
#define MPU_CTRL_ENABLE 1
#define MPU_CTRL_PRIVDEFENA (1 << 2)

#define MPU_RNR 0x98
#define MPU_RBAR 0x9c
#define MPU_RASR 0xa0

/* Cache opeartions */
#define V7M_SCB_ICIALLU 0x250 /* I-cache invalidate all to PoU */
#define V7M_SCB_ICIMVAU 0x258 /* I-cache invalidate by MVA to PoU */
Expand Down
4 changes: 4 additions & 0 deletions arch/arm/include/uapi/asm/ptrace.h
Expand Up @@ -31,6 +31,10 @@
#define PTRACE_SETVFPREGS 28
#define PTRACE_GETHBPREGS 29
#define PTRACE_SETHBPREGS 30
#define PTRACE_GETFDPIC 31

#define PTRACE_GETFDPIC_EXEC 0
#define PTRACE_GETFDPIC_INTERP 1

/*
* PSR bits
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/uapi/asm/unistd.h
Expand Up @@ -35,5 +35,6 @@
#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
#define __ARM_NR_get_tls (__ARM_NR_BASE+6)

#endif /* _UAPI__ASM_ARM_UNISTD_H */
5 changes: 5 additions & 0 deletions arch/arm/kernel/Makefile
Expand Up @@ -87,6 +87,11 @@ head-y := head$(MMUEXT).o
obj-$(CONFIG_DEBUG_LL) += debug.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o

# This is executed very early using a temporary stack when no memory allocator
# nor global data is available. Everything has to be allocated on the stack.
CFLAGS_head-inflate-data.o := $(call cc-option,-Wframe-larger-than=10240)
obj-$(CONFIG_XIP_DEFLATED_DATA) += head-inflate-data.o

obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
AFLAGS_hyp-stub.o :=-Wa,-march=armv7-a
ifeq ($(CONFIG_ARM_PSCI),y)
Expand Down

0 comments on commit 0219614

Please sign in to comment.