Skip to content

Commit

Permalink
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
Browse files Browse the repository at this point in the history
Pull ARM updates from Russell King:

 - amba bus irq rework

 - add kfence support

 - support for Cortex M33 and M55 CPUs

 - kbuild updates for decompressor

 - let core code manage thread_info::cpu

 - avoid unpredictable NOP encoding in decompressor

 - reduce information printed in calltraces

* tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: reduce the information printed in call traces
  ARM: 9168/1: Add support for Cortex-M55 processor
  ARM: 9167/1: Add support for Cortex-M33 processor
  ARM: 9166/1: Support KFENCE for ARM
  ARM: 9165/1: mm: Provide is_write_fault()
  ARM: 9164/1: mm: Provide set_memory_valid()
  ARM: 9163/1: amba: Move of_amba_device_decode_irq() into amba_probe()
  ARM: 9162/1: amba: Kill sysfs attribute file of irq
  ARM: 9161/1: mm: mark private VM_FAULT_X defines as vm_fault_t
  ARM: 9159/1: decompressor: Avoid UNPREDICTABLE NOP encoding
  ARM: 9158/1: leave it to core code to manage thread_info::cpu
  ARM: 9154/1: decompressor: do not copy source files while building
  • Loading branch information
torvalds committed Jan 12, 2022
2 parents c1eb8f6 + b0343ab commit 3e3a138
Show file tree
Hide file tree
Showing 22 changed files with 200 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
-----------------------
| alpha: | TODO |
| arc: | TODO |
| arm: | TODO |
| arm: | ok |
| arm64: | ok |
| csky: | TODO |
| h8300: | TODO |
Expand Down
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ config ARM
select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL
select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
select HAVE_ARCH_MMAP_RND_BITS if MMU
Expand Down
11 changes: 11 additions & 0 deletions arch/arm/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ endchoice
config ARM_UNWIND
bool

config BACKTRACE_VERBOSE
bool "Verbose backtrace"
depends on EXPERT
help
When the kernel produces a warning or oops, the kernel prints a
trace of the call chain. This option controls whether we include
the numeric addresses or only include the symbolic information.

In most cases, say N here, unless you are intending to debug the
kernel and have access to the kernel binary image.

config FRAME_POINTER
bool

Expand Down
5 changes: 0 additions & 5 deletions arch/arm/boot/compressed/.gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
ashldi3.S
bswapsdi2.S
font.c
lib1funcs.S
hyp-stub.S
piggy_data
vmlinux
vmlinux.lds
33 changes: 3 additions & 30 deletions arch/arm/boot/compressed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS += debug.o
AFLAGS_head.o += -DDEBUG
endif
FONTC = $(srctree)/lib/fonts/font_acorn_8x8.c

# string library code (-Os is enforced to keep it much smaller)
OBJS += string.o
Expand Down Expand Up @@ -99,11 +98,8 @@ $(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \
$(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector))

targets := vmlinux vmlinux.lds piggy_data piggy.o \
lib1funcs.o ashldi3.o bswapsdi2.o \
head.o $(OBJS)

clean-files += lib1funcs.S ashldi3.S bswapsdi2.S hyp-stub.S

KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING

ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \
Expand Down Expand Up @@ -134,23 +130,7 @@ endif
# Next argument is a linker script
LDFLAGS_vmlinux += -T

# For __aeabi_uidivmod
lib1funcs = $(obj)/lib1funcs.o

$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
$(call cmd,shipped)

# For __aeabi_llsl
ashldi3 = $(obj)/ashldi3.o

$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
$(call cmd,shipped)

# For __bswapsi2, __bswapdi2
bswapsdi2 = $(obj)/bswapsdi2.o

$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S
$(call cmd,shipped)
OBJS += lib1funcs.o ashldi3.o bswapsdi2.o

# We need to prevent any GOTOFF relocs being used with references
# to symbols in the .bss section since we cannot relocate them
Expand All @@ -175,8 +155,8 @@ fi
efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \
$(bswapsdi2) $(efi-obj-y) FORCE
$(addprefix $(obj)/, $(OBJS)) \
$(efi-obj-y) FORCE
@$(check_for_multiple_zreladdr)
$(call if_changed,ld)
@$(check_for_bad_syms)
Expand All @@ -187,11 +167,4 @@ $(obj)/piggy_data: $(obj)/../Image FORCE
$(obj)/piggy.o: $(obj)/piggy_data

CFLAGS_font.o := -Dstatic=

$(obj)/font.c: $(FONTC)
$(call cmd,shipped)

AFLAGS_hyp-stub.o := -Wa,-march=armv7-a

$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
$(call cmd,shipped)
3 changes: 3 additions & 0 deletions arch/arm/boot/compressed/ashldi3.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __aeabi_llsl */
#include "../../lib/ashldi3.S"
3 changes: 3 additions & 0 deletions arch/arm/boot/compressed/bswapsdi2.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __bswapsi2, __bswapdi2 */
#include "../../lib/bswapsdi2.S"
22 changes: 14 additions & 8 deletions arch/arm/boot/compressed/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@
#include <linux/sizes.h>

.macro __nop
#ifdef CONFIG_EFI_STUB
@ This is almost but not quite a NOP, since it does clobber the
@ condition flags. But it is the best we can do for EFI, since
@ PE/COFF expects the magic string "MZ" at offset 0, while the
@ ARM/Linux boot protocol expects an executable instruction
@ there.
.inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000
#else
AR_CLASS( mov r0, r0 )
M_CLASS( nop.w )
.endm

.macro __initial_nops
#ifdef CONFIG_EFI_STUB
@ This is a two-instruction NOP, which happens to bear the
@ PE/COFF signature "MZ" in the first two bytes, so the kernel
@ is accepted as an EFI binary. Booting via the UEFI stub
@ will not execute those instructions, but the ARM/Linux
@ boot protocol does, so we need some NOPs here.
.inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000
eor r5, r5, 0x4d000 @ undo previous insn
#else
__nop
__nop
#endif
.endm

Expand Down
2 changes: 2 additions & 0 deletions arch/arm/boot/compressed/font.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "../../../../lib/fonts/font_acorn_8x8.c"
3 changes: 2 additions & 1 deletion arch/arm/boot/compressed/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ start:
* were patching the initial instructions of the kernel, i.e
* had started to exploit this "patch area".
*/
.rept 7
__initial_nops
.rept 5
__nop
.endr
#ifndef CONFIG_THUMB2_KERNEL
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/boot/compressed/hyp-stub.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include "../../kernel/hyp-stub.S"
3 changes: 3 additions & 0 deletions arch/arm/boot/compressed/lib1funcs.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* For __aeabi_uidivmod */
#include "../../lib/lib1funcs.S"
53 changes: 53 additions & 0 deletions arch/arm/include/asm/kfence.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __ASM_ARM_KFENCE_H
#define __ASM_ARM_KFENCE_H

#include <linux/kfence.h>

#include <asm/pgalloc.h>
#include <asm/set_memory.h>

static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
{
int i;
unsigned long pfn = PFN_DOWN(__pa(addr));
pte_t *pte = pte_alloc_one_kernel(&init_mm);

if (!pte)
return -ENOMEM;

for (i = 0; i < PTRS_PER_PTE; i++)
set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0);
pmd_populate_kernel(&init_mm, pmd, pte);

flush_tlb_kernel_range(addr, addr + PMD_SIZE);
return 0;
}

static inline bool arch_kfence_init_pool(void)
{
unsigned long addr;
pmd_t *pmd;

for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
addr += PAGE_SIZE) {
pmd = pmd_off_k(addr);

if (pmd_leaf(*pmd)) {
if (split_pmd_page(pmd, addr & PMD_MASK))
return false;
}
}

return true;
}

static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
set_memory_valid(addr, 1, !protect);

return true;
}

#endif /* __ASM_ARM_KFENCE_H */
1 change: 1 addition & 0 deletions arch/arm/include/asm/set_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ int set_memory_ro(unsigned long addr, int numpages);
int set_memory_rw(unsigned long addr, int numpages);
int set_memory_x(unsigned long addr, int numpages);
int set_memory_nx(unsigned long addr, int numpages);
int set_memory_valid(unsigned long addr, int numpages, int enable);
#else
static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; }
static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; }
Expand Down
14 changes: 0 additions & 14 deletions arch/arm/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,9 @@
*/
extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);

static inline void set_ti_cpu(struct task_struct *p)
{
#ifdef CONFIG_THREAD_INFO_IN_TASK
/*
* The core code no longer maintains the thread_info::cpu field once
* CONFIG_THREAD_INFO_IN_TASK is in effect, but we rely on it for
* raw_smp_processor_id(), which cannot access struct task_struct*
* directly for reasons of circular #inclusion hell.
*/
task_thread_info(p)->cpu = task_cpu(p);
#endif
}

#define switch_to(prev,next,last) \
do { \
__complete_pending_tlbi(); \
set_ti_cpu(next); \
if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO)) \
__this_cpu_write(__entry_task, next); \
last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
Expand Down
3 changes: 0 additions & 3 deletions arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir);
#endif
secondary_data.task = idle;
if (IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK))
task_thread_info(idle)->cpu = cpu;

sync_cache_w(&secondary_data);

/*
Expand Down
8 changes: 5 additions & 3 deletions arch/arm/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ void dump_backtrace_entry(unsigned long where, unsigned long from,
{
unsigned long end = frame + 4 + sizeof(struct pt_regs);

#ifdef CONFIG_KALLSYMS
#ifndef CONFIG_KALLSYMS
printk("%sFunction entered at [<%08lx>] from [<%08lx>]\n",
loglvl, where, from);
#elif defined CONFIG_BACKTRACE_VERBOSE
printk("%s[<%08lx>] (%ps) from [<%08lx>] (%pS)\n",
loglvl, where, (void *)where, from, (void *)from);
#else
printk("%sFunction entered at [<%08lx>] from [<%08lx>]\n",
loglvl, where, from);
printk("%s %ps from %pS\n", loglvl, (void *)where, (void *)from);
#endif

if (in_entry_text(from) && end <= ALIGN(frame, THREAD_SIZE))
Expand Down
20 changes: 15 additions & 5 deletions arch/arm/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/sched/debug.h>
#include <linux/highmem.h>
#include <linux/perf_event.h>
#include <linux/kfence.h>

#include <asm/system_misc.h>
#include <asm/system_info.h>
Expand Down Expand Up @@ -99,6 +100,11 @@ void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr)
{ }
#endif /* CONFIG_MMU */

static inline bool is_write_fault(unsigned int fsr)
{
return (fsr & FSR_WRITE) && !(fsr & FSR_CM);
}

static void die_kernel_fault(const char *msg, struct mm_struct *mm,
unsigned long addr, unsigned int fsr,
struct pt_regs *regs)
Expand Down Expand Up @@ -131,10 +137,14 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
/*
* No handler, we'll have to terminate things with extreme prejudice.
*/
if (addr < PAGE_SIZE)
if (addr < PAGE_SIZE) {
msg = "NULL pointer dereference";
else
} else {
if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
return;

msg = "paging request";
}

die_kernel_fault(msg, mm, addr, fsr, regs);
}
Expand Down Expand Up @@ -191,8 +201,8 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
}

#ifdef CONFIG_MMU
#define VM_FAULT_BADMAP 0x010000
#define VM_FAULT_BADACCESS 0x020000
#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000)
#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000)

static inline bool is_permission_fault(unsigned int fsr)
{
Expand Down Expand Up @@ -261,7 +271,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (user_mode(regs))
flags |= FAULT_FLAG_USER;

if ((fsr & FSR_WRITE) && !(fsr & FSR_CM)) {
if (is_write_fault(fsr)) {
flags |= FAULT_FLAG_WRITE;
vm_flags = VM_WRITE;
}
Expand Down
Loading

0 comments on commit 3e3a138

Please sign in to comment.