Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm

Pull ARM updates from Russell King:

 - UEFI boot and runtime services support for ARM from Ard Biesheuvel
   and Roy Franz.

 - DT compatibility with old atags booting protocol for Nokia N900
   devices from Ivaylo Dimitrov.

 - PSCI firmware interface using new arm-smc calling convention from
   Jens Wiklander.

 - Runtime patching for udiv/sdiv instructions for ARMv7 CPUs that
   support these instructions from Nicolas Pitre.

 - L2x0 cache updates from Dirk B and Linus Walleij.

 - Randconfig fixes from Arnd Bergmann.

 - ARMv7M (nommu) updates from Ezequiel Garcia

* 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (34 commits)
  ARM: 8481/2: drivers: psci: replace psci firmware calls
  ARM: 8480/2: arm64: add implementation for arm-smccc
  ARM: 8479/2: add implementation for arm-smccc
  ARM: 8478/2: arm/arm64: add arm-smccc
  ARM: 8494/1: mm: Enable PXN when running non-LPAE kernel on LPAE processor
  ARM: 8496/1: OMAP: RX51: save ATAGS data in the early boot stage
  ARM: 8495/1: ATAGS: move save_atags() to arch/arm/include/asm/setup.h
  ARM: 8452/3: PJ4: make coprocessor access sequences buildable in Thumb2 mode
  ARM: 8482/1: l2x0: make it possible to disable outer sync from DT
  ARM: 8488/1: Make IPI_CPU_BACKTRACE a "non-secure" SGI
  ARM: 8487/1: Remove IPI_CALL_FUNC_SINGLE
  ARM: 8485/1: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook
  ARM: 8484/1: Documentation: l2c2x0: Mention separate controllers explicitly
  ARM: 8483/1: Documentation: l2c: Rename l2cc to l2c2x0
  ARM: 8477/1: runtime patch udiv/sdiv instructions into __aeabi_{u}idiv()
  ARM: 8476/1: VDSO: use PTR_ERR_OR_ZERO for vma check
  ARM: 8453/2: proc-v7.S: don't locate temporary stack space in .text section
  ARM: add UEFI stub support
  ARM: wire up UEFI init and runtime support
  ARM: only consider memblocks with NOMAP cleared for linear mapping
  ...
This commit is contained in:
Linus Torvalds
2016-01-12 12:39:07 -08:00
51 changed files with 1036 additions and 191 deletions

View File

@@ -73,10 +73,10 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
perf_event_v7.o
CFLAGS_pj4-cp0.o := -marm
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_VDSO) += vdso.o
obj-$(CONFIG_EFI) += efi.o
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
@@ -88,8 +88,9 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
ifeq ($(CONFIG_ARM_PSCI),y)
obj-y += psci-call.o
obj-$(CONFIG_SMP) += psci_smp.o
endif
obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
extra-y := $(head-y) vmlinux.lds

View File

@@ -16,6 +16,7 @@
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/arm-smccc.h>
#include <asm/checksum.h>
#include <asm/ftrace.h>
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
EXPORT_SYMBOL(__pv_phys_pfn_offset);
EXPORT_SYMBOL(__pv_offset);
#endif
#ifdef CONFIG_HAVE_ARM_SMCCC
EXPORT_SYMBOL(arm_smccc_smc);
EXPORT_SYMBOL(arm_smccc_hvc);
#endif

View File

@@ -1,9 +1,3 @@
#ifdef CONFIG_ATAGS_PROC
extern void save_atags(struct tag *tags);
#else
static inline void save_atags(struct tag *tags) { }
#endif
void convert_to_tag_list(struct tag *tags);
#ifdef CONFIG_ATAGS

View File

@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
int cpu = smp_processor_id();
if (cpuidle_ops[cpu].suspend)
ret = cpuidle_ops[cpu].suspend(cpu, index);
ret = cpuidle_ops[cpu].suspend(index);
return ret;
}

38
arch/arm/kernel/efi.c Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
*
* 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.
*/
#include <linux/efi.h>
#include <asm/efi.h>
#include <asm/mach/map.h>
#include <asm/mmu_context.h>
int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
{
struct map_desc desc = {
.virtual = md->virt_addr,
.pfn = __phys_to_pfn(md->phys_addr),
.length = md->num_pages * EFI_PAGE_SIZE,
};
/*
* Order is important here: memory regions may have all of the
* bits below set (and usually do), so we check them in order of
* preference.
*/
if (md->attribute & EFI_MEMORY_WB)
desc.type = MT_MEMORY_RWX;
else if (md->attribute & EFI_MEMORY_WT)
desc.type = MT_MEMORY_RWX_NONCACHED;
else if (md->attribute & EFI_MEMORY_WC)
desc.type = MT_DEVICE_WC;
else
desc.type = MT_DEVICE;
create_mapping_late(mm, &desc, true);
return 0;
}

View File

@@ -88,7 +88,7 @@ __pendsv_entry:
@ execute the pending work, including reschedule
get_thread_info tsk
mov why, #0
b ret_to_user
b ret_to_user_from_irq
ENDPROC(__pendsv_entry)
/*

View File

@@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
__asm__ __volatile__ (
"mcr p15, 0, %1, c1, c0, 2\n\t"
#ifdef CONFIG_THUMB2_KERNEL
"isb\n\t"
#else
"mrc p15, 0, %0, c1, c0, 2\n\t"
"mov %0, %0\n\t"
"sub pc, pc, #4\n\t"
#endif
: "=r" (temp) : "r" (value));
}

View File

@@ -1,31 +0,0 @@
/*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Copyright (C) 2015 ARM Limited
*
* Author: Mark Rutland <mark.rutland@arm.com>
*/
#include <linux/linkage.h>
#include <asm/opcodes-sec.h>
#include <asm/opcodes-virt.h>
/* int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
ENTRY(__invoke_psci_fn_hvc)
__HVC(0)
bx lr
ENDPROC(__invoke_psci_fn_hvc)
/* int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
ENTRY(__invoke_psci_fn_smc)
__SMC(0)
bx lr
ENDPROC(__invoke_psci_fn_smc)

View File

@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/efi.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
@@ -37,7 +38,9 @@
#include <asm/cp15.h>
#include <asm/cpu.h>
#include <asm/cputype.h>
#include <asm/efi.h>
#include <asm/elf.h>
#include <asm/early_ioremap.h>
#include <asm/fixmap.h>
#include <asm/procinfo.h>
#include <asm/psci.h>
@@ -375,6 +378,72 @@ void __init early_print(const char *str, ...)
printk("%s", buf);
}
#ifdef CONFIG_ARM_PATCH_IDIV
static inline u32 __attribute_const__ sdiv_instruction(void)
{
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
/* "sdiv r0, r0, r1" */
u32 insn = __opcode_thumb32_compose(0xfb90, 0xf0f1);
return __opcode_to_mem_thumb32(insn);
}
/* "sdiv r0, r0, r1" */
return __opcode_to_mem_arm(0xe710f110);
}
static inline u32 __attribute_const__ udiv_instruction(void)
{
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
/* "udiv r0, r0, r1" */
u32 insn = __opcode_thumb32_compose(0xfbb0, 0xf0f1);
return __opcode_to_mem_thumb32(insn);
}
/* "udiv r0, r0, r1" */
return __opcode_to_mem_arm(0xe730f110);
}
static inline u32 __attribute_const__ bx_lr_instruction(void)
{
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
/* "bx lr; nop" */
u32 insn = __opcode_thumb32_compose(0x4770, 0x46c0);
return __opcode_to_mem_thumb32(insn);
}
/* "bx lr" */
return __opcode_to_mem_arm(0xe12fff1e);
}
static void __init patch_aeabi_idiv(void)
{
extern void __aeabi_uidiv(void);
extern void __aeabi_idiv(void);
uintptr_t fn_addr;
unsigned int mask;
mask = IS_ENABLED(CONFIG_THUMB2_KERNEL) ? HWCAP_IDIVT : HWCAP_IDIVA;
if (!(elf_hwcap & mask))
return;
pr_info("CPU: div instructions available: patching division code\n");
fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
((u32 *)fn_addr)[0] = udiv_instruction();
((u32 *)fn_addr)[1] = bx_lr_instruction();
flush_icache_range(fn_addr, fn_addr + 8);
fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
((u32 *)fn_addr)[0] = sdiv_instruction();
((u32 *)fn_addr)[1] = bx_lr_instruction();
flush_icache_range(fn_addr, fn_addr + 8);
}
#else
static inline void patch_aeabi_idiv(void) { }
#endif
static void __init cpuid_init_hwcaps(void)
{
int block;
@@ -642,6 +711,7 @@ static void __init setup_processor(void)
elf_hwcap = list->elf_hwcap;
cpuid_init_hwcaps();
patch_aeabi_idiv();
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
@@ -956,8 +1026,8 @@ void __init setup_arch(char **cmdline_p)
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM))
early_fixmap_init();
early_fixmap_init();
early_ioremap_init();
parse_early_param();
@@ -965,9 +1035,12 @@ void __init setup_arch(char **cmdline_p)
early_paging_init(mdesc);
#endif
setup_dma_zone(mdesc);
efi_init();
sanity_check_meminfo();
arm_memblock_init(mdesc);
early_ioremap_reset();
paging_init(mdesc);
request_standard_resources(mdesc);

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Linaro Limited
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/linkage.h>
#include <asm/opcodes-sec.h>
#include <asm/opcodes-virt.h>
#include <asm/unwind.h>
/*
* Wrap c macros in asm macros to delay expansion until after the
* SMCCC asm macro is expanded.
*/
.macro SMCCC_SMC
__SMC(0)
.endm
.macro SMCCC_HVC
__HVC(0)
.endm
.macro SMCCC instr
UNWIND( .fnstart)
mov r12, sp
push {r4-r7}
UNWIND( .save {r4-r7})
ldm r12, {r4-r7}
\instr
pop {r4-r7}
ldr r12, [sp, #(4 * 4)]
stm r12, {r0-r3}
bx lr
UNWIND( .fnend)
.endm
/*
* void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
* unsigned long a3, unsigned long a4, unsigned long a5,
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
*/
ENTRY(arm_smccc_smc)
SMCCC SMCCC_SMC
ENDPROC(arm_smccc_smc)
/*
* void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
* unsigned long a3, unsigned long a4, unsigned long a5,
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
*/
ENTRY(arm_smccc_hvc)
SMCCC SMCCC_HVC
ENDPROC(arm_smccc_hvc)

View File

@@ -69,11 +69,15 @@ enum ipi_msg_type {
IPI_TIMER,
IPI_RESCHEDULE,
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
IPI_CPU_STOP,
IPI_IRQ_WORK,
IPI_COMPLETION,
IPI_CPU_BACKTRACE = 15,
IPI_CPU_BACKTRACE,
/*
* SGI8-15 can be reserved by secure firmware, and thus may
* not be usable by the kernel. Please keep the above limited
* to at most 8 entries.
*/
};
static DECLARE_COMPLETION(cpu_running);
@@ -475,7 +479,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
S(IPI_TIMER, "Timer broadcast interrupts"),
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
S(IPI_CALL_FUNC, "Function call interrupts"),
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
S(IPI_CPU_STOP, "CPU stop interrupts"),
S(IPI_IRQ_WORK, "IRQ work interrupts"),
S(IPI_COMPLETION, "completion interrupts"),
@@ -525,7 +528,7 @@ void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
void arch_send_call_function_single_ipi(int cpu)
{
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
}
#ifdef CONFIG_IRQ_WORK
@@ -620,12 +623,6 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
irq_exit();
break;
case IPI_CALL_FUNC_SINGLE:
irq_enter();
generic_smp_call_function_single_interrupt();
irq_exit();
break;
case IPI_CPU_STOP:
irq_enter();
ipi_cpu_stop(cpu);

View File

@@ -224,7 +224,7 @@ static int install_vvar(struct mm_struct *mm, unsigned long addr)
VM_READ | VM_MAYREAD,
&vdso_data_mapping);
return IS_ERR(vma) ? PTR_ERR(vma) : 0;
return PTR_ERR_OR_ZERO(vma);
}
/* assumes mmap_sem is write-locked */