Commit 8d20a3dd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:
 "Various arm64 fixes:
   - ftrace branch generation fix
   - branch instruction encoding fix
   - include files, guards and unused prototypes clean-up
   - minor VDSO ABI fix (clock_getres)
   - PSCI functions moved to .S to avoid compilation error with gcc 5
   - pte_modify fix to not ignore the mapping type
   - crypto: AES interleaved increased to 4x (for performance reasons)
   - text patching fix for modules
   - swiotlb increased back to 64MB
   - copy_siginfo_to_user32() fix for big endian"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  arm64: cpuidle: add asm/proc-fns.h inclusion
  arm64: compat Fix siginfo_t -> compat_siginfo_t conversion on big endian
  arm64: Increase the swiotlb buffer size 64MB
  arm64: Fix text patching logic when using fixmap
  arm64: crypto: increase AES interleave to 4x
  arm64: enable PTE type bit in the mask for pte_modify
  arm64: mm: remove unused functions and variable protoypes
  arm64: psci: move psci firmware calls out of line
  arm64: vdso: minor ABI fix for clock_getres
  arm64: guard asm/assembler.h against multiple inclusions
  arm64: insn: fix compare-and-branch encodings
  arm64: ftrace: fix ftrace_modify_graph_caller for branch replace
parents 1c070515 af4819af
...@@ -29,7 +29,7 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o ...@@ -29,7 +29,7 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o
obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
aes-neon-blk-y := aes-glue-neon.o aes-neon.o aes-neon-blk-y := aes-glue-neon.o aes-neon.o
AFLAGS_aes-ce.o := -DINTERLEAVE=2 -DINTERLEAVE_INLINE AFLAGS_aes-ce.o := -DINTERLEAVE=4
AFLAGS_aes-neon.o := -DINTERLEAVE=4 AFLAGS_aes-neon.o := -DINTERLEAVE=4
CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS CFLAGS_aes-glue-ce.o := -DUSE_V8_CRYPTO_EXTENSIONS
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
#error "Only include this from assembly code" #error "Only include this from assembly code"
#endif #endif
#ifndef __ASM_ASSEMBLER_H
#define __ASM_ASSEMBLER_H
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
...@@ -155,3 +158,5 @@ lr .req x30 // link register ...@@ -155,3 +158,5 @@ lr .req x30 // link register
#endif #endif
orr \rd, \lbits, \hbits, lsl #32 orr \rd, \lbits, \hbits, lsl #32
.endm .endm
#endif /* __ASM_ASSEMBLER_H */
#ifndef __ASM_CPUIDLE_H #ifndef __ASM_CPUIDLE_H
#define __ASM_CPUIDLE_H #define __ASM_CPUIDLE_H
#include <asm/proc-fns.h>
#ifdef CONFIG_CPU_IDLE #ifdef CONFIG_CPU_IDLE
extern int cpu_init_idle(unsigned int cpu); extern int cpu_init_idle(unsigned int cpu);
extern int cpu_suspend(unsigned long arg); extern int cpu_suspend(unsigned long arg);
......
...@@ -264,8 +264,10 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000) ...@@ -264,8 +264,10 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000)
__AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000) __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000)
__AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000) __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
__AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000) __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
__AARCH64_INSN_FUNCS(cbz, 0xFE000000, 0x34000000) __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000)
__AARCH64_INSN_FUNCS(cbnz, 0xFE000000, 0x35000000) __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000)
__AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000)
__AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000)
__AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000)
__AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001)
__AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002)
......
...@@ -460,7 +460,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr) ...@@ -460,7 +460,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ {
const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
PTE_PROT_NONE | PTE_VALID | PTE_WRITE; PTE_PROT_NONE | PTE_WRITE | PTE_TYPE_MASK;
pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
return pte; return pte;
} }
......
...@@ -45,7 +45,8 @@ ...@@ -45,7 +45,8 @@
#define STACK_TOP STACK_TOP_MAX #define STACK_TOP STACK_TOP_MAX
#endif /* CONFIG_COMPAT */ #endif /* CONFIG_COMPAT */
#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK extern phys_addr_t arm64_dma_phys_limit;
#define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
struct debug_info { struct debug_info {
......
...@@ -24,11 +24,6 @@ ...@@ -24,11 +24,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <asm/cputype.h> #include <asm/cputype.h>
extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
extern struct cpu_tlb_fns cpu_tlb;
/* /*
* TLB Management * TLB Management
* ============== * ==============
......
...@@ -15,8 +15,9 @@ CFLAGS_REMOVE_return_address.o = -pg ...@@ -15,8 +15,9 @@ CFLAGS_REMOVE_return_address.o = -pg
arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \ arm64-obj-y := cputable.o debug-monitors.o entry.o irq.o fpsimd.o \
entry-fpsimd.o process.o ptrace.o setup.o signal.o \ entry-fpsimd.o process.o ptrace.o setup.o signal.o \
sys.o stacktrace.o time.o traps.o io.o vdso.o \ sys.o stacktrace.o time.o traps.o io.o vdso.o \
hyp-stub.o psci.o cpu_ops.o insn.o return_address.o \ hyp-stub.o psci.o psci-call.o cpu_ops.o insn.o \
cpuinfo.o cpu_errata.o alternative.o cacheinfo.o return_address.o cpuinfo.o cpu_errata.o \
alternative.o cacheinfo.o
arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
sys_compat.o entry32.o \ sys_compat.o entry32.o \
......
...@@ -156,7 +156,7 @@ static int ftrace_modify_graph_caller(bool enable) ...@@ -156,7 +156,7 @@ static int ftrace_modify_graph_caller(bool enable)
branch = aarch64_insn_gen_branch_imm(pc, branch = aarch64_insn_gen_branch_imm(pc,
(unsigned long)ftrace_graph_caller, (unsigned long)ftrace_graph_caller,
AARCH64_INSN_BRANCH_LINK); AARCH64_INSN_BRANCH_NOLINK);
nop = aarch64_insn_gen_nop(); nop = aarch64_insn_gen_nop();
if (enable) if (enable)
......
...@@ -87,8 +87,10 @@ static void __kprobes *patch_map(void *addr, int fixmap) ...@@ -87,8 +87,10 @@ static void __kprobes *patch_map(void *addr, int fixmap)
if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX)) if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
page = vmalloc_to_page(addr); page = vmalloc_to_page(addr);
else else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
page = virt_to_page(addr); page = virt_to_page(addr);
else
return addr;
BUG_ON(!page); BUG_ON(!page);
set_fixmap(fixmap, page_to_phys(page)); set_fixmap(fixmap, page_to_phys(page));
......
/*
* 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: Will Deacon <will.deacon@arm.com>
*/
#include <linux/linkage.h>
/* int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
ENTRY(__invoke_psci_fn_hvc)
hvc #0
ret
ENDPROC(__invoke_psci_fn_hvc)
/* int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) */
ENTRY(__invoke_psci_fn_smc)
smc #0
ret
ENDPROC(__invoke_psci_fn_smc)
...@@ -57,6 +57,9 @@ static struct psci_operations psci_ops; ...@@ -57,6 +57,9 @@ static struct psci_operations psci_ops;
static int (*invoke_psci_fn)(u64, u64, u64, u64); static int (*invoke_psci_fn)(u64, u64, u64, u64);
typedef int (*psci_initcall_t)(const struct device_node *); typedef int (*psci_initcall_t)(const struct device_node *);
asmlinkage int __invoke_psci_fn_hvc(u64, u64, u64, u64);
asmlinkage int __invoke_psci_fn_smc(u64, u64, u64, u64);
enum psci_function { enum psci_function {
PSCI_FN_CPU_SUSPEND, PSCI_FN_CPU_SUSPEND,
PSCI_FN_CPU_ON, PSCI_FN_CPU_ON,
...@@ -109,40 +112,6 @@ static void psci_power_state_unpack(u32 power_state, ...@@ -109,40 +112,6 @@ static void psci_power_state_unpack(u32 power_state,
PSCI_0_2_POWER_STATE_AFFL_SHIFT; PSCI_0_2_POWER_STATE_AFFL_SHIFT;
} }
/*
* The following two functions are invoked via the invoke_psci_fn pointer
* and will not be inlined, allowing us to piggyback on the AAPCS.
*/
static noinline int __invoke_psci_fn_hvc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"hvc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2));
return function_id;
}
static noinline int __invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
u64 arg2)
{
asm volatile(
__asmeq("%0", "x0")
__asmeq("%1", "x1")
__asmeq("%2", "x2")
__asmeq("%3", "x3")
"smc #0\n"
: "+r" (function_id)
: "r" (arg0), "r" (arg1), "r" (arg2));
return function_id;
}
static int psci_get_version(void) static int psci_get_version(void)
{ {
int err; int err;
......
...@@ -154,8 +154,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) ...@@ -154,8 +154,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
case __SI_TIMER: case __SI_TIMER:
err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_tid, &to->si_tid);
err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_overrun, &to->si_overrun);
err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, err |= __put_user(from->si_int, &to->si_int);
&to->si_ptr);
break; break;
case __SI_POLL: case __SI_POLL:
err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_band, &to->si_band);
...@@ -184,7 +183,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) ...@@ -184,7 +183,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
case __SI_MESGQ: /* But this is */ case __SI_MESGQ: /* But this is */
err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_pid, &to->si_pid);
err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_uid, &to->si_uid);
err |= __put_user((compat_uptr_t)(unsigned long)from->si_ptr, &to->si_ptr); err |= __put_user(from->si_int, &to->si_int);
break; break;
case __SI_SYS: case __SI_SYS:
err |= __put_user((compat_uptr_t)(unsigned long) err |= __put_user((compat_uptr_t)(unsigned long)
......
...@@ -174,8 +174,6 @@ ENDPROC(__kernel_clock_gettime) ...@@ -174,8 +174,6 @@ ENDPROC(__kernel_clock_gettime)
/* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */ /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
ENTRY(__kernel_clock_getres) ENTRY(__kernel_clock_getres)
.cfi_startproc .cfi_startproc
cbz w1, 3f
cmp w0, #CLOCK_REALTIME cmp w0, #CLOCK_REALTIME
ccmp w0, #CLOCK_MONOTONIC, #0x4, ne ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
b.ne 1f b.ne 1f
...@@ -188,6 +186,7 @@ ENTRY(__kernel_clock_getres) ...@@ -188,6 +186,7 @@ ENTRY(__kernel_clock_getres)
b.ne 4f b.ne 4f
ldr x2, 6f ldr x2, 6f
2: 2:
cbz w1, 3f
stp xzr, x2, [x1] stp xzr, x2, [x1]
3: /* res == NULL. */ 3: /* res == NULL. */
......
...@@ -348,8 +348,6 @@ static struct dma_map_ops swiotlb_dma_ops = { ...@@ -348,8 +348,6 @@ static struct dma_map_ops swiotlb_dma_ops = {
.mapping_error = swiotlb_dma_mapping_error, .mapping_error = swiotlb_dma_mapping_error,
}; };
extern int swiotlb_late_init_with_default_size(size_t default_size);
static int __init atomic_pool_init(void) static int __init atomic_pool_init(void)
{ {
pgprot_t prot = __pgprot(PROT_NORMAL_NC); pgprot_t prot = __pgprot(PROT_NORMAL_NC);
...@@ -411,21 +409,13 @@ static int __init atomic_pool_init(void) ...@@ -411,21 +409,13 @@ static int __init atomic_pool_init(void)
return -ENOMEM; return -ENOMEM;
} }
static int __init swiotlb_late_init(void) static int __init arm64_dma_init(void)
{ {
size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); int ret;
dma_ops = &swiotlb_dma_ops; dma_ops = &swiotlb_dma_ops;
return swiotlb_late_init_with_default_size(swiotlb_size); ret = atomic_pool_init();
}
static int __init arm64_dma_init(void)
{
int ret = 0;
ret |= swiotlb_late_init();
ret |= atomic_pool_init();
return ret; return ret;
} }
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dma-contiguous.h> #include <linux/dma-contiguous.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/swiotlb.h>
#include <asm/fixmap.h> #include <asm/fixmap.h>
#include <asm/memory.h> #include <asm/memory.h>
...@@ -45,6 +46,7 @@ ...@@ -45,6 +46,7 @@
#include "mm.h" #include "mm.h"
phys_addr_t memstart_addr __read_mostly = 0; phys_addr_t memstart_addr __read_mostly = 0;
phys_addr_t arm64_dma_phys_limit __read_mostly;
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p) static int __init early_initrd(char *p)
...@@ -85,7 +87,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) ...@@ -85,7 +87,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
/* 4GB maximum for 32-bit only capable devices */ /* 4GB maximum for 32-bit only capable devices */
if (IS_ENABLED(CONFIG_ZONE_DMA)) { if (IS_ENABLED(CONFIG_ZONE_DMA)) {
max_dma = PFN_DOWN(max_zone_dma_phys()); max_dma = PFN_DOWN(arm64_dma_phys_limit);
zone_size[ZONE_DMA] = max_dma - min; zone_size[ZONE_DMA] = max_dma - min;
} }
zone_size[ZONE_NORMAL] = max - max_dma; zone_size[ZONE_NORMAL] = max - max_dma;
...@@ -156,8 +158,6 @@ early_param("mem", early_mem); ...@@ -156,8 +158,6 @@ early_param("mem", early_mem);
void __init arm64_memblock_init(void) void __init arm64_memblock_init(void)
{ {
phys_addr_t dma_phys_limit = 0;
memblock_enforce_memory_limit(memory_limit); memblock_enforce_memory_limit(memory_limit);
/* /*
...@@ -174,8 +174,10 @@ void __init arm64_memblock_init(void) ...@@ -174,8 +174,10 @@ void __init arm64_memblock_init(void)
/* 4GB maximum for 32-bit only capable devices */ /* 4GB maximum for 32-bit only capable devices */
if (IS_ENABLED(CONFIG_ZONE_DMA)) if (IS_ENABLED(CONFIG_ZONE_DMA))
dma_phys_limit = max_zone_dma_phys(); arm64_dma_phys_limit = max_zone_dma_phys();
dma_contiguous_reserve(dma_phys_limit); else
arm64_dma_phys_limit = PHYS_MASK + 1;
dma_contiguous_reserve(arm64_dma_phys_limit);
memblock_allow_resize(); memblock_allow_resize();
memblock_dump_all(); memblock_dump_all();
...@@ -276,6 +278,8 @@ static void __init free_unused_memmap(void) ...@@ -276,6 +278,8 @@ static void __init free_unused_memmap(void)
*/ */
void __init mem_init(void) void __init mem_init(void)
{ {
swiotlb_init(1);
set_max_mapnr(pfn_to_page(max_pfn) - mem_map); set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
#ifndef CONFIG_SPARSEMEM_VMEMMAP #ifndef CONFIG_SPARSEMEM_VMEMMAP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment