mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge branches 'devel-stable' and 'misc' into for-linus
This commit is contained in:
@@ -91,7 +91,7 @@ config ARM
|
||||
select HAVE_FAST_GUP if ARM_LPAE
|
||||
select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
|
||||
select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
|
||||
select HAVE_FUNCTION_TRACER if !XIP_KERNEL
|
||||
select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG)
|
||||
select HAVE_FUTEX_CMPXCHG if FUTEX
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
|
||||
@@ -126,6 +126,7 @@ config ARM
|
||||
select PERF_USE_VMALLOC
|
||||
select RTC_LIB
|
||||
select SYS_SUPPORTS_APM_EMULATION
|
||||
select THREAD_INFO_IN_TASK if CURRENT_POINTER_IN_TPIDRURO
|
||||
select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
|
||||
# Above selects are sorted alphabetically; please add new ones
|
||||
# according to that. Thanks.
|
||||
@@ -265,10 +266,12 @@ config PHYS_OFFSET
|
||||
hex "Physical address of main memory" if MMU
|
||||
depends on !ARM_PATCH_PHYS_VIRT
|
||||
default DRAM_BASE if !MMU
|
||||
default 0x00000000 if ARCH_FOOTBRIDGE
|
||||
default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX
|
||||
default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
|
||||
default 0x20000000 if ARCH_S5PV210
|
||||
default 0xc0000000 if ARCH_SA1100
|
||||
default 0x30000000 if ARCH_S3C24XX
|
||||
default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
|
||||
default 0xc0000000 if ARCH_EP93XX || ARCH_SA1100
|
||||
default 0
|
||||
help
|
||||
Please provide the physical address corresponding to the
|
||||
location of main memory in your system.
|
||||
@@ -433,6 +436,7 @@ config ARCH_PXA
|
||||
config ARCH_RPC
|
||||
bool "RiscPC"
|
||||
depends on MMU
|
||||
depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 60000
|
||||
select ARCH_ACORN
|
||||
select ARCH_MAY_HAVE_PC_FDC
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
@@ -1158,6 +1162,11 @@ config SMP_ON_UP
|
||||
|
||||
If you don't know what to do here, say Y.
|
||||
|
||||
|
||||
config CURRENT_POINTER_IN_TPIDRURO
|
||||
def_bool y
|
||||
depends on SMP && CPU_32v6K && !CPU_V6
|
||||
|
||||
config ARM_CPU_TOPOLOGY
|
||||
bool "Support cpu topology definition"
|
||||
depends on SMP && CPU_V7
|
||||
@@ -1601,7 +1610,7 @@ config XEN
|
||||
|
||||
config STACKPROTECTOR_PER_TASK
|
||||
bool "Use a unique stack canary value for each task"
|
||||
depends on GCC_PLUGINS && STACKPROTECTOR && SMP && !XIP_DEFLATED_DATA
|
||||
depends on GCC_PLUGINS && STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
|
||||
select GCC_PLUGIN_ARM_SSP_PER_TASK
|
||||
default y
|
||||
help
|
||||
|
||||
@@ -113,6 +113,10 @@ ifeq ($(CONFIG_CC_IS_CLANG),y)
|
||||
CFLAGS_ABI += -meabi gnu
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CURRENT_POINTER_IN_TPIDRURO),y)
|
||||
CFLAGS_ABI += -mtp=cp15
|
||||
endif
|
||||
|
||||
# Accept old syntax despite ".syntax unified"
|
||||
AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
|
||||
|
||||
@@ -273,11 +277,8 @@ ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
|
||||
prepare: stack_protector_prepare
|
||||
stack_protector_prepare: prepare0
|
||||
$(eval SSP_PLUGIN_CFLAGS := \
|
||||
-fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \
|
||||
awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\
|
||||
include/generated/asm-offsets.h) \
|
||||
-fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \
|
||||
awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\
|
||||
awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
|
||||
include/generated/asm-offsets.h))
|
||||
$(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS))
|
||||
$(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS))
|
||||
|
||||
@@ -55,16 +55,17 @@ static uint64_t get_val(const fdt32_t *cells, uint32_t ncells)
|
||||
* DTB, and, if out-of-range, replace it by the real start address.
|
||||
* To preserve backwards compatibility (systems reserving a block of memory
|
||||
* at the start of physical memory, kdump, ...), the traditional method is
|
||||
* always used if it yields a valid address.
|
||||
* used if it yields a valid address, unless the "linux,usable-memory-range"
|
||||
* property is present.
|
||||
*
|
||||
* Return value: start address of physical memory to use
|
||||
*/
|
||||
uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
|
||||
{
|
||||
uint32_t addr_cells, size_cells, base;
|
||||
uint32_t addr_cells, size_cells, usable_base, base;
|
||||
uint32_t fdt_mem_start = 0xffffffff;
|
||||
const fdt32_t *reg, *endp;
|
||||
uint64_t size, end;
|
||||
const fdt32_t *usable, *reg, *endp;
|
||||
uint64_t size, usable_end, end;
|
||||
const char *type;
|
||||
int offset, len;
|
||||
|
||||
@@ -80,6 +81,27 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
|
||||
if (addr_cells > 2 || size_cells > 2)
|
||||
return mem_start;
|
||||
|
||||
/*
|
||||
* Usable memory in case of a crash dump kernel
|
||||
* This property describes a limitation: memory within this range is
|
||||
* only valid when also described through another mechanism
|
||||
*/
|
||||
usable = get_prop(fdt, "/chosen", "linux,usable-memory-range",
|
||||
(addr_cells + size_cells) * sizeof(fdt32_t));
|
||||
if (usable) {
|
||||
size = get_val(usable + addr_cells, size_cells);
|
||||
if (!size)
|
||||
return mem_start;
|
||||
|
||||
if (addr_cells > 1 && fdt32_ld(usable)) {
|
||||
/* Outside 32-bit address space */
|
||||
return mem_start;
|
||||
}
|
||||
|
||||
usable_base = fdt32_ld(usable + addr_cells - 1);
|
||||
usable_end = usable_base + size;
|
||||
}
|
||||
|
||||
/* Walk all memory nodes and regions */
|
||||
for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0;
|
||||
offset = fdt_next_node(fdt, offset, NULL)) {
|
||||
@@ -107,7 +129,20 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
|
||||
|
||||
base = fdt32_ld(reg + addr_cells - 1);
|
||||
end = base + size;
|
||||
if (mem_start >= base && mem_start < end) {
|
||||
if (usable) {
|
||||
/*
|
||||
* Clip to usable range, which takes precedence
|
||||
* over mem_start
|
||||
*/
|
||||
if (base < usable_base)
|
||||
base = usable_base;
|
||||
|
||||
if (end > usable_end)
|
||||
end = usable_end;
|
||||
|
||||
if (end <= base)
|
||||
continue;
|
||||
} else if (mem_start >= base && mem_start < end) {
|
||||
/* Calculated address is valid, use it */
|
||||
return mem_start;
|
||||
}
|
||||
@@ -123,7 +158,8 @@ uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt)
|
||||
}
|
||||
|
||||
/*
|
||||
* The calculated address is not usable.
|
||||
* The calculated address is not usable, or was overridden by the
|
||||
* "linux,usable-memory-range" property.
|
||||
* Use the lowest usable physical memory address from the DTB instead,
|
||||
* and make sure this is a multiple of 2 MiB for phys/virt patching.
|
||||
*/
|
||||
|
||||
@@ -240,9 +240,6 @@ static int scoop_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct scoop_dev *sdev = platform_get_drvdata(pdev);
|
||||
|
||||
if (!sdev)
|
||||
return -EINVAL;
|
||||
|
||||
if (sdev->gpio.base != -1)
|
||||
gpiochip_remove(&sdev->gpio);
|
||||
|
||||
|
||||
@@ -199,14 +199,43 @@
|
||||
.endm
|
||||
.endr
|
||||
|
||||
.macro get_current, rd
|
||||
#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
|
||||
mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
|
||||
#else
|
||||
get_thread_info \rd
|
||||
ldr \rd, [\rd, #TI_TASK]
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro set_current, rn
|
||||
#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
|
||||
mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro reload_current, t1:req, t2:req
|
||||
#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
|
||||
adr_l \t1, __entry_task @ get __entry_task base address
|
||||
mrc p15, 0, \t2, c13, c0, 4 @ get per-CPU offset
|
||||
ldr \t1, [\t1, \t2] @ load variable
|
||||
mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Get current thread_info.
|
||||
*/
|
||||
.macro get_thread_info, rd
|
||||
#ifdef CONFIG_THREAD_INFO_IN_TASK
|
||||
/* thread_info is the first member of struct task_struct */
|
||||
get_current \rd
|
||||
#else
|
||||
ARM( mov \rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT )
|
||||
THUMB( mov \rd, sp )
|
||||
THUMB( lsr \rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT )
|
||||
mov \rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
|
||||
55
arch/arm/include/asm/current.h
Normal file
55
arch/arm/include/asm/current.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021 Keith Packard <keithp@keithp.com>
|
||||
* Copyright (c) 2021 Google, LLC <ardb@kernel.org>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_ARM_CURRENT_H
|
||||
#define _ASM_ARM_CURRENT_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct task_struct;
|
||||
|
||||
static inline void set_current(struct task_struct *cur)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO))
|
||||
return;
|
||||
|
||||
/* Set TPIDRURO */
|
||||
asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
|
||||
|
||||
static inline struct task_struct *get_current(void)
|
||||
{
|
||||
struct task_struct *cur;
|
||||
|
||||
#if __has_builtin(__builtin_thread_pointer) && \
|
||||
!(defined(CONFIG_THUMB2_KERNEL) && \
|
||||
defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 130001)
|
||||
/*
|
||||
* Use the __builtin helper when available - this results in better
|
||||
* code, especially when using GCC in combination with the per-task
|
||||
* stack protector, as the compiler will recognize that it needs to
|
||||
* load the TLS register only once in every function.
|
||||
*
|
||||
* Clang < 13.0.1 gets this wrong for Thumb2 builds:
|
||||
* https://github.com/ClangBuiltLinux/linux/issues/1485
|
||||
*/
|
||||
cur = __builtin_thread_pointer();
|
||||
#else
|
||||
asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(cur));
|
||||
#endif
|
||||
return cur;
|
||||
}
|
||||
|
||||
#define current get_current()
|
||||
#else
|
||||
#include <asm-generic/current.h>
|
||||
#endif /* CONFIG_CURRENT_POINTER_IN_TPIDRURO */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_ARM_CURRENT_H */
|
||||
@@ -138,6 +138,7 @@ extern void __iomem *__arm_ioremap_caller(phys_addr_t, size_t, unsigned int,
|
||||
void *);
|
||||
extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
|
||||
extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached);
|
||||
void __arm_iomem_set_ro(void __iomem *ptr, size_t size);
|
||||
extern void __iounmap(volatile void __iomem *addr);
|
||||
|
||||
extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
|
||||
|
||||
@@ -110,12 +110,17 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
|
||||
#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x)
|
||||
#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x)
|
||||
#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x)
|
||||
#ifndef CONFIG_CPU_ENDIAN_BE32
|
||||
#ifdef CONFIG_CPU_ENDIAN_BE32
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* On BE32 systems, using 32-bit accesses to store Thumb instructions will not
|
||||
* work in all cases, due to alignment constraints. For now, a correct
|
||||
* version is not provided for BE32.
|
||||
* version is not provided for BE32, but the prototype needs to be there
|
||||
* to compile patch.c.
|
||||
*/
|
||||
extern __u32 __opcode_to_mem_thumb32(__u32);
|
||||
#endif
|
||||
#else
|
||||
#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x)
|
||||
#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
static const struct tagtable __tagtable_##fn __tag = { tag, fn }
|
||||
|
||||
extern int arm_add_memory(u64 start, u64 size);
|
||||
extern void early_print(const char *str, ...);
|
||||
extern __printf(1, 2) void early_print(const char *str, ...);
|
||||
extern void dump_machine_table(void);
|
||||
|
||||
#ifdef CONFIG_ATAGS_PROC
|
||||
|
||||
@@ -48,7 +48,7 @@ extern void set_smp_ipi_range(int ipi_base, int nr_ipi);
|
||||
* Called from platform specific assembly code, this is the
|
||||
* secondary CPU entry point.
|
||||
*/
|
||||
asmlinkage void secondary_start_kernel(void);
|
||||
asmlinkage void secondary_start_kernel(struct task_struct *task);
|
||||
|
||||
|
||||
/*
|
||||
@@ -61,6 +61,7 @@ struct secondary_data {
|
||||
};
|
||||
unsigned long swapper_pg_dir;
|
||||
void *stack;
|
||||
struct task_struct *task;
|
||||
};
|
||||
extern struct secondary_data secondary_data;
|
||||
extern void secondary_startup(void);
|
||||
|
||||
@@ -39,8 +39,6 @@ static __always_inline void boot_init_stack_canary(void)
|
||||
current->stack_canary = canary;
|
||||
#ifndef CONFIG_STACKPROTECTOR_PER_TASK
|
||||
__stack_chk_guard = current->stack_canary;
|
||||
#else
|
||||
current_thread_info()->stack_canary = current->stack_canary;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,25 @@
|
||||
*/
|
||||
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)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
struct task_struct;
|
||||
|
||||
DECLARE_PER_CPU(struct task_struct *, __entry_task);
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
struct cpu_context_save {
|
||||
@@ -52,12 +54,11 @@ struct cpu_context_save {
|
||||
struct thread_info {
|
||||
unsigned long flags; /* low level flags */
|
||||
int preempt_count; /* 0 => preemptable, <0 => bug */
|
||||
#ifndef CONFIG_THREAD_INFO_IN_TASK
|
||||
struct task_struct *task; /* main task structure */
|
||||
#endif
|
||||
__u32 cpu; /* cpu */
|
||||
__u32 cpu_domain; /* cpu domain */
|
||||
#ifdef CONFIG_STACKPROTECTOR_PER_TASK
|
||||
unsigned long stack_canary;
|
||||
#endif
|
||||
struct cpu_context_save cpu_context; /* cpu context */
|
||||
__u32 abi_syscall; /* ABI type and syscall nr */
|
||||
__u8 used_cp[16]; /* thread used copro */
|
||||
@@ -71,11 +72,27 @@ struct thread_info {
|
||||
|
||||
#define INIT_THREAD_INFO(tsk) \
|
||||
{ \
|
||||
.task = &tsk, \
|
||||
INIT_THREAD_INFO_TASK(tsk) \
|
||||
.flags = 0, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THREAD_INFO_IN_TASK
|
||||
#define INIT_THREAD_INFO_TASK(tsk)
|
||||
|
||||
static inline struct task_struct *thread_task(struct thread_info* ti)
|
||||
{
|
||||
return (struct task_struct *)ti;
|
||||
}
|
||||
|
||||
#else
|
||||
#define INIT_THREAD_INFO_TASK(tsk) .task = &(tsk),
|
||||
|
||||
static inline struct task_struct *thread_task(struct thread_info* ti)
|
||||
{
|
||||
return ti->task;
|
||||
}
|
||||
|
||||
/*
|
||||
* how to get the thread information struct from C
|
||||
*/
|
||||
@@ -86,6 +103,7 @@ static inline struct thread_info *current_thread_info(void)
|
||||
return (struct thread_info *)
|
||||
(current_stack_pointer & ~(THREAD_SIZE - 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define thread_saved_pc(tsk) \
|
||||
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
.macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
|
||||
mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
|
||||
mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
|
||||
mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register
|
||||
@ TLS register update is deferred until return to user space
|
||||
mcr p15, 0, \tpuser, c13, c0, 2 @ set the user r/w register
|
||||
str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
|
||||
.endm
|
||||
|
||||
@@ -38,18 +38,22 @@
|
||||
#ifdef CONFIG_TLS_REG_EMUL
|
||||
#define tls_emu 1
|
||||
#define has_tls_reg 1
|
||||
#define defer_tls_reg_update 0
|
||||
#define switch_tls switch_tls_none
|
||||
#elif defined(CONFIG_CPU_V6)
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
|
||||
#define defer_tls_reg_update 0
|
||||
#define switch_tls switch_tls_v6
|
||||
#elif defined(CONFIG_CPU_32v6K)
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg 1
|
||||
#define defer_tls_reg_update 1
|
||||
#define switch_tls switch_tls_v6k
|
||||
#else
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg 0
|
||||
#define defer_tls_reg_update 0
|
||||
#define switch_tls switch_tls_software
|
||||
#endif
|
||||
|
||||
@@ -77,7 +81,7 @@ static inline void set_tls(unsigned long val)
|
||||
*/
|
||||
barrier();
|
||||
|
||||
if (!tls_emu) {
|
||||
if (!tls_emu && !defer_tls_reg_update) {
|
||||
if (has_tls_reg) {
|
||||
asm("mcr p15, 0, %0, c13, c0, 3"
|
||||
: : "r" (val));
|
||||
|
||||
@@ -43,7 +43,9 @@ int main(void)
|
||||
BLANK();
|
||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
|
||||
#ifndef CONFIG_THREAD_INFO_IN_TASK
|
||||
DEFINE(TI_TASK, offsetof(struct thread_info, task));
|
||||
#endif
|
||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
||||
DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain));
|
||||
DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
|
||||
@@ -63,10 +65,6 @@ int main(void)
|
||||
#ifdef CONFIG_IWMMXT
|
||||
DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt));
|
||||
#endif
|
||||
#ifdef CONFIG_STACKPROTECTOR_PER_TASK
|
||||
DEFINE(TI_STACK_CANARY, offsetof(struct thread_info, stack_canary));
|
||||
#endif
|
||||
DEFINE(THREAD_SZ_ORDER, THREAD_SIZE_ORDER);
|
||||
BLANK();
|
||||
DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
|
||||
DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
|
||||
|
||||
@@ -384,6 +384,8 @@ ENDPROC(__fiq_abt)
|
||||
ATRAP( teq r8, r7)
|
||||
ATRAP( mcrne p15, 0, r8, c1, c0, 0)
|
||||
|
||||
reload_current r7, r8
|
||||
|
||||
@
|
||||
@ Clear FP to mark the first stack frame
|
||||
@
|
||||
@@ -762,6 +764,8 @@ ENTRY(__switch_to)
|
||||
add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK
|
||||
.endif
|
||||
ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]
|
||||
#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
|
||||
mov r7, r2 @ Preserve 'next'
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
|
||||
@@ -776,6 +780,7 @@ ENTRY(__switch_to)
|
||||
#endif
|
||||
THUMB( mov ip, r4 )
|
||||
mov r0, r5
|
||||
set_current r7
|
||||
ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
|
||||
THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
|
||||
THUMB( ldr sp, [ip], #4 )
|
||||
|
||||
@@ -170,6 +170,7 @@ ENTRY(vector_swi)
|
||||
str saved_psr, [sp, #S_PSR] @ Save CPSR
|
||||
str r0, [sp, #S_OLD_R0] @ Save OLD_R0
|
||||
#endif
|
||||
reload_current r10, ip
|
||||
zero_fp
|
||||
alignment_trap r10, ip, __cr_alignment
|
||||
asm_trace_hardirqs_on save=0
|
||||
|
||||
@@ -292,6 +292,14 @@
|
||||
|
||||
|
||||
.macro restore_user_regs, fast = 0, offset = 0
|
||||
#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
|
||||
@ The TLS register update is deferred until return to user space so we
|
||||
@ can use it for other things while running in the kernel
|
||||
get_thread_info r1
|
||||
ldr r1, [r1, #TI_TP_VALUE]
|
||||
mcr p15, 0, r1, c13, c0, 3 @ set TLS register
|
||||
#endif
|
||||
|
||||
uaccess_enable r1, isb=0
|
||||
#ifndef CONFIG_THUMB2_KERNEL
|
||||
@ ARM mode restore
|
||||
|
||||
@@ -105,6 +105,11 @@ __mmap_switched:
|
||||
mov r1, #0
|
||||
bl __memset @ clear .bss
|
||||
|
||||
#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
|
||||
adr_l r0, init_task @ get swapper task_struct
|
||||
set_current r0
|
||||
#endif
|
||||
|
||||
ldmia r4, {r0, r1, r2, r3}
|
||||
str r9, [r0] @ Save processor ID
|
||||
str r7, [r1] @ Save machine type
|
||||
|
||||
@@ -115,6 +115,7 @@ ENTRY(secondary_startup)
|
||||
ret r12
|
||||
1: bl __after_proc_init
|
||||
ldr sp, [r7, #12] @ set up the stack pointer
|
||||
ldr r0, [r7, #16] @ set up task pointer
|
||||
mov fp, #0
|
||||
b secondary_start_kernel
|
||||
ENDPROC(secondary_startup)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user