diff options
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r-- | arch/xtensa/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/xtensa/kernel/align.S | 258 | ||||
-rw-r--r-- | arch/xtensa/kernel/hw_breakpoint.c | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/mcount.S | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/perf_event.c | 20 | ||||
-rw-r--r-- | arch/xtensa/kernel/platform.c | 29 | ||||
-rw-r--r-- | arch/xtensa/kernel/process.c | 6 | ||||
-rw-r--r-- | arch/xtensa/kernel/ptrace.c | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/setup.c | 60 | ||||
-rw-r--r-- | arch/xtensa/kernel/signal.c | 37 | ||||
-rw-r--r-- | arch/xtensa/kernel/smp.c | 7 | ||||
-rw-r--r-- | arch/xtensa/kernel/stacktrace.c | 8 | ||||
-rw-r--r-- | arch/xtensa/kernel/syscall.c | 21 | ||||
-rw-r--r-- | arch/xtensa/kernel/syscalls/syscall.tbl | 19 | ||||
-rw-r--r-- | arch/xtensa/kernel/time.c | 4 | ||||
-rw-r--r-- | arch/xtensa/kernel/traps.c | 106 | ||||
-rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 12 | ||||
-rw-r--r-- | arch/xtensa/kernel/xtensa_ksyms.c | 89 |
19 files changed, 414 insertions, 270 deletions
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 897c1c741058..d3ef0407401f 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -3,9 +3,9 @@ # Makefile for the Linux/Xtensa kernel. # -extra-y := head.o vmlinux.lds +always-$(KBUILD_BUILTIN) := vmlinux.lds -obj-y := align.o coprocessor.o entry.o irq.o platform.o process.o \ +obj-y := head.o align.o coprocessor.o entry.o irq.o platform.o process.o \ ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \ vectors.o diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index d062c732ef18..ee97edce2300 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -1,7 +1,7 @@ /* * arch/xtensa/kernel/align.S * - * Handle unalignment exceptions in kernel space. + * Handle unalignment and load/store exceptions. * * This file is subject to the terms and conditions of the GNU General * Public License. See the file "COPYING" in the main directory of @@ -22,13 +22,21 @@ #include <asm/asmmacro.h> #include <asm/processor.h> -#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION +#if XCHAL_UNALIGNED_LOAD_EXCEPTION || defined CONFIG_XTENSA_LOAD_STORE +#define LOAD_EXCEPTION_HANDLER +#endif -/* First-level exception handler for unaligned exceptions. - * - * Note: This handler works only for kernel exceptions. Unaligned user - * access should get a seg fault. - */ +#if XCHAL_UNALIGNED_STORE_EXCEPTION || defined CONFIG_XTENSA_LOAD_STORE +#define STORE_EXCEPTION_HANDLER +#endif + +#if defined LOAD_EXCEPTION_HANDLER || defined STORE_EXCEPTION_HANDLER +#define ANY_EXCEPTION_HANDLER +#endif + +#if XCHAL_HAVE_WINDOWED && defined CONFIG_MMU +#define UNALIGNED_USER_EXCEPTION +#endif /* Big and little endian 16-bit values are located in * different halves of a register. HWORD_START helps to @@ -58,10 +66,6 @@ * BE shift left / mask 0 0 X X */ -#if XCHAL_HAVE_WINDOWED -#define UNALIGNED_USER_EXCEPTION -#endif - #if XCHAL_HAVE_BE #define HWORD_START 16 @@ -103,7 +107,7 @@ * * 23 0 * ----------------------------- - * res 0000 0010 + * L8UI xxxx xxxx 0000 ssss tttt 0010 * L16UI xxxx xxxx 0001 ssss tttt 0010 * L32I xxxx xxxx 0010 ssss tttt 0010 * XXX 0011 ssss tttt 0010 @@ -128,9 +132,11 @@ #define OP0_L32I_N 0x8 /* load immediate narrow */ #define OP0_S32I_N 0x9 /* store immediate narrow */ +#define OP0_LSAI 0x2 /* load/store */ #define OP1_SI_MASK 0x4 /* OP1 bit set for stores */ #define OP1_SI_BIT 2 /* OP1 bit number for stores */ +#define OP1_L8UI 0x0 #define OP1_L32I 0x2 #define OP1_L16UI 0x1 #define OP1_L16SI 0x9 @@ -155,60 +161,72 @@ */ .literal_position -ENTRY(fast_unaligned) +#ifdef CONFIG_XTENSA_LOAD_STORE +ENTRY(fast_load_store) - /* Note: We don't expect the address to be aligned on a word - * boundary. After all, the processor generated that exception - * and it would be a hardware fault. - */ + call0 .Lsave_and_load_instruction - /* Save some working register */ + /* Analyze the instruction (load or store?). */ - s32i a4, a2, PT_AREG4 - s32i a5, a2, PT_AREG5 - s32i a6, a2, PT_AREG6 - s32i a7, a2, PT_AREG7 - s32i a8, a2, PT_AREG8 + extui a0, a4, INSN_OP0, 4 # get insn.op0 nibble - rsr a0, depc - s32i a0, a2, PT_AREG2 - s32i a3, a2, PT_AREG3 +#if XCHAL_HAVE_DENSITY + _beqi a0, OP0_L32I_N, 1f # L32I.N, jump +#endif + bnei a0, OP0_LSAI, .Linvalid_instruction + /* 'store indicator bit' set, jump */ + bbsi.l a4, OP1_SI_BIT + INSN_OP1, .Linvalid_instruction - rsr a3, excsave1 - movi a4, fast_unaligned_fixup - s32i a4, a3, EXC_TABLE_FIXUP +1: + movi a3, ~3 + and a3, a3, a8 # align memory address - /* Keep value of SAR in a0 */ + __ssa8 a8 - rsr a0, sar - rsr a8, excvaddr # load unaligned memory address +#ifdef CONFIG_MMU + /* l32e can't be used here even when it's available. */ + /* TODO access_ok(a3) could be used here */ + j .Linvalid_instruction +#endif + l32i a5, a3, 0 + l32i a6, a3, 4 + __src_b a3, a5, a6 # a3 has the data word - /* Now, identify one of the following load/store instructions. - * - * The only possible danger of a double exception on the - * following l32i instructions is kernel code in vmalloc - * memory. The processor was just executing at the EPC_1 - * address, and indeed, already fetched the instruction. That - * guarantees a TLB mapping, which hasn't been replaced by - * this unaligned exception handler that uses only static TLB - * mappings. However, high-level interrupt handlers might - * modify TLB entries, so for the generic case, we register a - * TABLE_FIXUP handler here, too. - */ +#if XCHAL_HAVE_DENSITY + addi a7, a7, 2 # increment PC (assume 16-bit insn) + _beqi a0, OP0_L32I_N, .Lload_w# l32i.n: jump + addi a7, a7, 1 +#else + addi a7, a7, 3 +#endif - /* a3...a6 saved on stack, a2 = SP */ + extui a5, a4, INSN_OP1, 4 + _beqi a5, OP1_L32I, .Lload_w + bnei a5, OP1_L8UI, .Lload16 + extui a3, a3, 0, 8 + j .Lload_w - /* Extract the instruction that caused the unaligned access. */ +ENDPROC(fast_load_store) +#endif - rsr a7, epc1 # load exception address - movi a3, ~3 - and a3, a3, a7 # mask lower bits +/* + * Entry condition: + * + * a0: trashed, original value saved on stack (PT_AREG0) + * a1: a1 + * a2: new stack pointer, original in DEPC + * a3: a3 + * depc: a2, original value saved on stack (PT_DEPC) + * excsave_1: dispatch table + * + * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC + * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception + */ - l32i a4, a3, 0 # load 2 words - l32i a5, a3, 4 +#ifdef ANY_EXCEPTION_HANDLER +ENTRY(fast_unaligned) - __ssa8 a7 - __src_b a4, a4, a5 # a4 has the instruction + call0 .Lsave_and_load_instruction /* Analyze the instruction (load or store?). */ @@ -222,12 +240,16 @@ ENTRY(fast_unaligned) /* 'store indicator bit' not set, jump */ _bbci.l a4, OP1_SI_BIT + INSN_OP1, .Lload +#ifdef STORE_EXCEPTION_HANDLER + /* Store: Jump to table entry to get the value in the source register.*/ .Lstore:movi a5, .Lstore_table # table extui a6, a4, INSN_T, 4 # get source register addx8 a5, a6, a5 jx a5 # jump into table +#endif +#ifdef LOAD_EXCEPTION_HANDLER /* Load: Load memory address. */ @@ -249,7 +271,7 @@ ENTRY(fast_unaligned) addi a7, a7, 2 # increment PC (assume 16-bit insn) extui a5, a4, INSN_OP0, 4 - _beqi a5, OP0_L32I_N, 1f # l32i.n: jump + _beqi a5, OP0_L32I_N, .Lload_w# l32i.n: jump addi a7, a7, 1 #else @@ -257,21 +279,26 @@ ENTRY(fast_unaligned) #endif extui a5, a4, INSN_OP1, 4 - _beqi a5, OP1_L32I, 1f # l32i: jump - + _beqi a5, OP1_L32I, .Lload_w # l32i: jump +#endif +#ifdef LOAD_EXCEPTION_HANDLER +.Lload16: extui a3, a3, 0, 16 # extract lower 16 bits - _beqi a5, OP1_L16UI, 1f + _beqi a5, OP1_L16UI, .Lload_w addi a5, a5, -OP1_L16SI - _bnez a5, .Linvalid_instruction_load + _bnez a5, .Linvalid_instruction /* sign extend value */ - +#if XCHAL_HAVE_SEXT + sext a3, a3, 15 +#else slli a3, a3, 16 srai a3, a3, 16 +#endif /* Set target register. */ -1: +.Lload_w: extui a4, a4, INSN_T, 4 # extract target register movi a5, .Lload_table addx8 a4, a4, a5 @@ -295,30 +322,31 @@ ENTRY(fast_unaligned) mov a13, a3 ; _j .Lexit; .align 8 mov a14, a3 ; _j .Lexit; .align 8 mov a15, a3 ; _j .Lexit; .align 8 - +#endif +#ifdef STORE_EXCEPTION_HANDLER .Lstore_table: - l32i a3, a2, PT_AREG0; _j 1f; .align 8 - mov a3, a1; _j 1f; .align 8 # fishy?? - l32i a3, a2, PT_AREG2; _j 1f; .align 8 - l32i a3, a2, PT_AREG3; _j 1f; .align 8 - l32i a3, a2, PT_AREG4; _j 1f; .align 8 - l32i a3, a2, PT_AREG5; _j 1f; .align 8 - l32i a3, a2, PT_AREG6; _j 1f; .align 8 - l32i a3, a2, PT_AREG7; _j 1f; .align 8 - l32i a3, a2, PT_AREG8; _j 1f; .align 8 - mov a3, a9 ; _j 1f; .align 8 - mov a3, a10 ; _j 1f; .align 8 - mov a3, a11 ; _j 1f; .align 8 - mov a3, a12 ; _j 1f; .align 8 - mov a3, a13 ; _j 1f; .align 8 - mov a3, a14 ; _j 1f; .align 8 - mov a3, a15 ; _j 1f; .align 8 + l32i a3, a2, PT_AREG0; _j .Lstore_w; .align 8 + mov a3, a1; _j .Lstore_w; .align 8 # fishy?? + l32i a3, a2, PT_AREG2; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG3; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG4; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG5; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG6; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG7; _j .Lstore_w; .align 8 + l32i a3, a2, PT_AREG8; _j .Lstore_w; .align 8 + mov a3, a9 ; _j .Lstore_w; .align 8 + mov a3, a10 ; _j .Lstore_w; .align 8 + mov a3, a11 ; _j .Lstore_w; .align 8 + mov a3, a12 ; _j .Lstore_w; .align 8 + mov a3, a13 ; _j .Lstore_w; .align 8 + mov a3, a14 ; _j .Lstore_w; .align 8 + mov a3, a15 ; _j .Lstore_w; .align 8 +#endif /* We cannot handle this exception. */ .extern _kernel_exception -.Linvalid_instruction_load: -.Linvalid_instruction_store: +.Linvalid_instruction: movi a4, 0 rsr a3, excsave1 @@ -326,6 +354,7 @@ ENTRY(fast_unaligned) /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ + l32i a0, a2, PT_SAR l32i a8, a2, PT_AREG8 l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 @@ -343,8 +372,10 @@ ENTRY(fast_unaligned) 2: movi a0, _user_exception jx a0 -1: # a7: instruction pointer, a4: instruction, a3: value +#ifdef STORE_EXCEPTION_HANDLER + # a7: instruction pointer, a4: instruction, a3: value +.Lstore_w: movi a6, 0 # mask: ffffffff:00000000 #if XCHAL_HAVE_DENSITY @@ -361,7 +392,7 @@ ENTRY(fast_unaligned) extui a5, a4, INSN_OP1, 4 # extract OP1 _beqi a5, OP1_S32I, 1f # jump if 32 bit store - _bnei a5, OP1_S16I, .Linvalid_instruction_store + _bnei a5, OP1_S16I, .Linvalid_instruction movi a5, -1 __extl a3, a3 # get 16-bit value @@ -406,6 +437,7 @@ ENTRY(fast_unaligned) #else s32i a6, a4, 4 #endif +#endif .Lexit: #if XCHAL_HAVE_LOOPS @@ -434,6 +466,7 @@ ENTRY(fast_unaligned) /* Restore working register */ + l32i a0, a2, PT_SAR l32i a8, a2, PT_AREG8 l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 @@ -448,6 +481,59 @@ ENTRY(fast_unaligned) l32i a2, a2, PT_AREG2 rfe + .align 4 +.Lsave_and_load_instruction: + + /* Save some working register */ + + s32i a3, a2, PT_AREG3 + s32i a4, a2, PT_AREG4 + s32i a5, a2, PT_AREG5 + s32i a6, a2, PT_AREG6 + s32i a7, a2, PT_AREG7 + s32i a8, a2, PT_AREG8 + + rsr a4, depc + s32i a4, a2, PT_AREG2 + + rsr a5, sar + s32i a5, a2, PT_SAR + + rsr a3, excsave1 + movi a4, fast_unaligned_fixup + s32i a4, a3, EXC_TABLE_FIXUP + + rsr a8, excvaddr # load unaligned memory address + + /* Now, identify one of the following load/store instructions. + * + * The only possible danger of a double exception on the + * following l32i instructions is kernel code in vmalloc + * memory. The processor was just executing at the EPC_1 + * address, and indeed, already fetched the instruction. That + * guarantees a TLB mapping, which hasn't been replaced by + * this unaligned exception handler that uses only static TLB + * mappings. However, high-level interrupt handlers might + * modify TLB entries, so for the generic case, we register a + * TABLE_FIXUP handler here, too. + */ + + /* a3...a6 saved on stack, a2 = SP */ + + /* Extract the instruction that caused the unaligned access. */ + + rsr a7, epc1 # load exception address + movi a3, ~3 + and a3, a3, a7 # mask lower bits + + l32i a4, a3, 0 # load 2 words + l32i a5, a3, 4 + + __ssa8 a7 + __src_b a4, a4, a5 # a4 has the instruction + + ret + ENDPROC(fast_unaligned) ENTRY(fast_unaligned_fixup) @@ -459,10 +545,11 @@ ENTRY(fast_unaligned_fixup) l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 l32i a5, a2, PT_AREG5 - l32i a4, a2, PT_AREG4 + l32i a4, a2, PT_SAR l32i a0, a2, PT_AREG2 - xsr a0, depc # restore depc and a0 - wsr a0, sar + wsr a4, sar + wsr a0, depc # restore depc and a0 + l32i a4, a2, PT_AREG4 rsr a0, exccause s32i a0, a2, PT_DEPC # mark as a regular exception @@ -483,5 +570,4 @@ ENTRY(fast_unaligned_fixup) jx a0 ENDPROC(fast_unaligned_fixup) - -#endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ +#endif diff --git a/arch/xtensa/kernel/hw_breakpoint.c b/arch/xtensa/kernel/hw_breakpoint.c index 285fb2942b06..1eeecd58eb0c 100644 --- a/arch/xtensa/kernel/hw_breakpoint.c +++ b/arch/xtensa/kernel/hw_breakpoint.c @@ -13,6 +13,7 @@ #include <linux/percpu.h> #include <linux/perf_event.h> #include <asm/core.h> +#include <asm/hw_breakpoint.h> /* Breakpoint currently in use for each IBREAKA. */ static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 42f106004400..b1e410f6b5ab 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -28,6 +28,7 @@ #include <asm/mxregs.h> #include <linux/uaccess.h> #include <asm/platform.h> +#include <asm/traps.h> DECLARE_PER_CPU(unsigned long, nmi_count); diff --git a/arch/xtensa/kernel/mcount.S b/arch/xtensa/kernel/mcount.S index 51daaf4e0b82..309b3298258f 100644 --- a/arch/xtensa/kernel/mcount.S +++ b/arch/xtensa/kernel/mcount.S @@ -78,6 +78,7 @@ ENTRY(_mcount) #error Unsupported Xtensa ABI #endif ENDPROC(_mcount) +EXPORT_SYMBOL(_mcount) ENTRY(ftrace_stub) abi_entry_default diff --git a/arch/xtensa/kernel/perf_event.c b/arch/xtensa/kernel/perf_event.c index a0d05c8598d0..223f1d452310 100644 --- a/arch/xtensa/kernel/perf_event.c +++ b/arch/xtensa/kernel/perf_event.c @@ -13,17 +13,26 @@ #include <linux/perf_event.h> #include <linux/platform_device.h> +#include <asm/core.h> #include <asm/processor.h> #include <asm/stacktrace.h> +#define XTENSA_HWVERSION_RG_2015_0 260000 + +#if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RG_2015_0 +#define XTENSA_PMU_ERI_BASE 0x00101000 +#else +#define XTENSA_PMU_ERI_BASE 0x00001000 +#endif + /* Global control/status for all perf counters */ -#define XTENSA_PMU_PMG 0x1000 +#define XTENSA_PMU_PMG XTENSA_PMU_ERI_BASE /* Perf counter values */ -#define XTENSA_PMU_PM(i) (0x1080 + (i) * 4) +#define XTENSA_PMU_PM(i) (XTENSA_PMU_ERI_BASE + 0x80 + (i) * 4) /* Perf counter control registers */ -#define XTENSA_PMU_PMCTRL(i) (0x1100 + (i) * 4) +#define XTENSA_PMU_PMCTRL(i) (XTENSA_PMU_ERI_BASE + 0x100 + (i) * 4) /* Perf counter status registers */ -#define XTENSA_PMU_PMSTAT(i) (0x1180 + (i) * 4) +#define XTENSA_PMU_PMSTAT(i) (XTENSA_PMU_ERI_BASE + 0x180 + (i) * 4) #define XTENSA_PMU_PMG_PMEN 0x1 @@ -379,8 +388,7 @@ irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id) struct pt_regs *regs = get_irq_regs(); perf_sample_data_init(&data, 0, last_period); - if (perf_event_overflow(event, &data, regs)) - xtensa_pmu_stop(event, 0); + perf_event_overflow(event, &data, regs); } rc = IRQ_HANDLED; diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c index ac1e0e566995..926b8bf0f14c 100644 --- a/arch/xtensa/kernel/platform.c +++ b/arch/xtensa/kernel/platform.c @@ -17,27 +17,28 @@ #include <asm/platform.h> #include <asm/timex.h> -#define _F(r,f,a,b) \ - r __platform_##f a b; \ - r platform_##f a __attribute__((weak, alias("__platform_"#f))) - /* * Default functions that are used if no platform specific function is defined. - * (Please, refer to include/asm-xtensa/platform.h for more information) + * (Please, refer to arch/xtensa/include/asm/platform.h for more information) */ -_F(void, init, (bp_tag_t *first), { }); -_F(void, setup, (char** cmd), { }); -_F(void, restart, (void), { while(1); }); -_F(void, halt, (void), { while(1); }); -_F(void, power_off, (void), { while(1); }); -_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); }); -_F(void, heartbeat, (void), { }); +void __weak __init platform_init(bp_tag_t *first) +{ +} + +void __weak __init platform_setup(char **cmd) +{ +} + +void __weak platform_idle(void) +{ + __asm__ __volatile__ ("waiti 0" ::: "memory"); +} #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT -_F(void, calibrate_ccount, (void), +void __weak platform_calibrate_ccount(void) { pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n"); ccount_freq = 10 * 1000000UL; -}); +} #endif diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 68e0e2f06d66..7bd66677f7b6 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -47,6 +47,7 @@ #include <asm/asm-offsets.h> #include <asm/regs.h> #include <asm/hw_breakpoint.h> +#include <asm/sections.h> #include <asm/traps.h> extern void ret_from_fork(void); @@ -183,6 +184,7 @@ void coprocessor_flush_release_all(struct thread_info *ti) void arch_cpu_idle(void) { platform_idle(); + raw_local_irq_disable(); } /* @@ -379,7 +381,7 @@ unsigned long __get_wchan(struct task_struct *p) int count = 0; sp = p->thread.sp; - pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp); + pc = MAKE_PC_FROM_RA(p->thread.ra, _text); do { if (sp < stack_page + sizeof(struct task_struct) || @@ -391,7 +393,7 @@ unsigned long __get_wchan(struct task_struct *p) /* Stack layout: sp-4: ra, sp-3: sp' */ - pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp); + pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text); sp = SPILL_SLOT(sp, 1); } while (count++ < 16); return 0; diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index f29477162ede..9056cd1a8302 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -541,7 +541,6 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -void do_syscall_trace_leave(struct pt_regs *regs); int do_syscall_trace_enter(struct pt_regs *regs) { if (regs->syscall == NO_SYSCALL) diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 9191738f9941..f72e280363be 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -19,9 +19,9 @@ #include <linux/init.h> #include <linux/mm.h> #include <linux/proc_fs.h> -#include <linux/screen_info.h> #include <linux/kernel.h> #include <linux/percpu.h> +#include <linux/reboot.h> #include <linux/cpu.h> #include <linux/of.h> #include <linux/of_fdt.h> @@ -46,17 +46,7 @@ #include <asm/smp.h> #include <asm/sysmem.h> #include <asm/timex.h> - -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -struct screen_info screen_info = { - .orig_x = 0, - .orig_y = 24, - .orig_video_cols = 80, - .orig_video_lines = 24, - .orig_video_isVGA = 1, - .orig_video_points = 16, -}; -#endif +#include <asm/traps.h> #ifdef CONFIG_BLK_DEV_INITRD extern unsigned long initrd_start; @@ -65,7 +55,7 @@ extern int initrd_below_start_ok; #endif #ifdef CONFIG_USE_OF -void *dtb_start = __dtb_start; +static void *dtb_start __initdata = __dtb_start; #endif extern unsigned long loops_per_jiffy; @@ -226,7 +216,7 @@ static int __init xtensa_dt_io_area(unsigned long node, const char *uname, void __init early_init_devtree(void *params) { - early_init_dt_scan(params); + early_init_dt_scan(params, __pa(params)); of_scan_flat_dt(xtensa_dt_io_area, NULL); if (!command_line[0]) @@ -241,6 +231,12 @@ void __init early_init_devtree(void *params) void __init init_arch(bp_tag_t *bp_start) { + /* Initialize basic exception handling if configuration may need it */ + + if (IS_ENABLED(CONFIG_KASAN) || + IS_ENABLED(CONFIG_XTENSA_LOAD_STORE)) + early_trap_init(); + /* Initialize MMU. */ init_mmu(); @@ -303,6 +299,9 @@ void __init setup_arch(char **cmdline_p) mem_reserve(__pa(_stext), __pa(_end)); #ifdef CONFIG_XIP_KERNEL +#ifdef CONFIG_VECTORS_ADDR + mem_reserve(__pa(_xip_text_start), __pa(_xip_text_end)); +#endif mem_reserve(__pa(_xip_start), __pa(_xip_end)); #endif @@ -522,19 +521,30 @@ void cpu_reset(void) void machine_restart(char * cmd) { - platform_restart(); + local_irq_disable(); + smp_send_stop(); + do_kernel_restart(cmd); + pr_err("Reboot failed -- System halted\n"); + while (1) + cpu_relax(); } void machine_halt(void) { - platform_halt(); - while (1); + local_irq_disable(); + smp_send_stop(); + do_kernel_power_off(); + while (1) + cpu_relax(); } void machine_power_off(void) { - platform_power_off(); - while (1); + local_irq_disable(); + smp_send_stop(); + do_kernel_power_off(); + while (1) + cpu_relax(); } #ifdef CONFIG_PROC_FS @@ -574,6 +584,12 @@ c_show(struct seq_file *f, void *slot) # if XCHAL_HAVE_OCD "ocd " # endif +#if XCHAL_HAVE_TRAX + "trax " +#endif +#if XCHAL_NUM_PERF_COUNTERS + "perf " +#endif #endif #if XCHAL_HAVE_DENSITY "density " @@ -623,11 +639,13 @@ c_show(struct seq_file *f, void *slot) seq_printf(f,"physical aregs\t: %d\n" "misc regs\t: %d\n" "ibreak\t\t: %d\n" - "dbreak\t\t: %d\n", + "dbreak\t\t: %d\n" + "perf counters\t: %d\n", XCHAL_NUM_AREGS, XCHAL_NUM_MISC_REGS, XCHAL_NUM_IBREAK, - XCHAL_NUM_DBREAK); + XCHAL_NUM_DBREAK, + XCHAL_NUM_PERF_COUNTERS); /* Interrupt. */ diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 876d5df157ed..81f0b106cfc1 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -26,6 +26,8 @@ #include <linux/uaccess.h> #include <asm/cacheflush.h> #include <asm/coprocessor.h> +#include <asm/processor.h> +#include <asm/syscall.h> #include <asm/unistd.h> extern struct task_struct *coproc_owners[]; @@ -343,7 +345,19 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, struct rt_sigframe *frame; int err = 0, sig = ksig->sig; unsigned long sp, ra, tp, ps; + unsigned long handler = (unsigned long)ksig->ka.sa.sa_handler; + unsigned long handler_fdpic_GOT = 0; unsigned int base; + bool fdpic = IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC) && + (current->personality & FDPIC_FUNCPTRS); + + if (fdpic) { + unsigned long __user *fdpic_func_desc = + (unsigned long __user *)handler; + if (__get_user(handler, &fdpic_func_desc[0]) || + __get_user(handler_fdpic_GOT, &fdpic_func_desc[1])) + return -EFAULT; + } sp = regs->areg[1]; @@ -373,20 +387,26 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); if (ksig->ka.sa.sa_flags & SA_RESTORER) { - ra = (unsigned long)ksig->ka.sa.sa_restorer; + if (fdpic) { + unsigned long __user *fdpic_func_desc = + (unsigned long __user *)ksig->ka.sa.sa_restorer; + + err |= __get_user(ra, fdpic_func_desc); + } else { + ra = (unsigned long)ksig->ka.sa.sa_restorer; + } } else { /* Create sys_rt_sigreturn syscall in stack frame */ err |= gen_return_code(frame->retcode); - - if (err) { - return -EFAULT; - } ra = (unsigned long) frame->retcode; } - /* + if (err) + return -EFAULT; + + /* * Create signal handler execution context. * Return context not modified until this point. */ @@ -394,8 +414,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, /* Set up registers for signal handler; preserve the threadptr */ tp = regs->threadptr; ps = regs->ps; - start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler, - (unsigned long) frame); + start_thread(regs, handler, (unsigned long)frame); /* Set up a stack frame for a call4 if userspace uses windowed ABI */ if (ps & PS_WOE_MASK) { @@ -413,6 +432,8 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, regs->areg[base + 4] = (unsigned long) &frame->uc; regs->threadptr = tp; regs->ps = ps; + if (fdpic) + regs->areg[base + 11] = handler_fdpic_GOT; pr_debug("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n", current->comm, current->pid, sig, frame, regs->pc); diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index 4dc109dd6214..94a23f100726 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -21,6 +21,7 @@ #include <linux/irq.h> #include <linux/kdebug.h> #include <linux/module.h> +#include <linux/profile.h> #include <linux/sched/mm.h> #include <linux/sched/hotplug.h> #include <linux/sched/task_stack.h> @@ -322,7 +323,7 @@ void __cpu_die(unsigned int cpu) pr_err("CPU%u: unable to kill\n", cpu); } -void arch_cpu_idle_dead(void) +void __noreturn arch_cpu_idle_dead(void) { cpu_die(); } @@ -341,6 +342,8 @@ void __ref cpu_die(void) __asm__ __volatile__( " movi a2, cpu_restart\n" " jx a2\n"); + + BUG(); } #endif /* CONFIG_HOTPLUG_CPU */ @@ -389,7 +392,7 @@ void arch_send_call_function_single_ipi(int cpu) send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC); } -void smp_send_reschedule(int cpu) +void arch_smp_send_reschedule(int cpu) { send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); } diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index 7f7755cd28f0..ed324fdf2a2f 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -12,6 +12,8 @@ #include <linux/sched.h> #include <linux/stacktrace.h> +#include <asm/ftrace.h> +#include <asm/sections.h> #include <asm/stacktrace.h> #include <asm/traps.h> #include <linux/uaccess.h> @@ -188,7 +190,7 @@ void walk_stackframe(unsigned long *sp, if (a1 <= (unsigned long)sp) break; - frame.pc = MAKE_PC_FROM_RA(a0, a1); + frame.pc = MAKE_PC_FROM_RA(a0, _text); frame.sp = a1; if (fn(&frame, data)) @@ -237,8 +239,6 @@ EXPORT_SYMBOL_GPL(save_stack_trace); #endif -#ifdef CONFIG_FRAME_POINTER - struct return_addr_data { unsigned long addr; unsigned skip; @@ -271,5 +271,3 @@ unsigned long return_address(unsigned level) return r.addr; } EXPORT_SYMBOL(return_address); - -#endif diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 201356faa7e6..dc54f854c2f5 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -55,9 +55,11 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, #ifdef CONFIG_MMU unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, - unsigned long len, unsigned long pgoff, unsigned long flags) + unsigned long len, unsigned long pgoff, unsigned long flags, + vm_flags_t vm_flags) { struct vm_area_struct *vmm; + struct vma_iterator vmi; if (flags & MAP_FIXED) { /* We do not accept a shared mapping if it would violate @@ -79,15 +81,20 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, else addr = PAGE_ALIGN(addr); - for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { - /* At this point: (!vmm || addr < vmm->vm_end). */ - if (TASK_SIZE - len < addr) - return -ENOMEM; - if (!vmm || addr + len <= vm_start_gap(vmm)) - return addr; + vma_iter_init(&vmi, current->mm, addr); + for_each_vma(vmi, vmm) { + /* At this point: (addr < vmm->vm_end). */ + if (addr + len <= vm_start_gap(vmm)) + break; + addr = vmm->vm_end; if (flags & MAP_SHARED) addr = COLOUR_ALIGN(addr, pgoff); } + + if (TASK_SIZE - len < addr) + return -ENOMEM; + + return addr; } #endif diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl index 52c94ab5c205..f657a77314f8 100644 --- a/arch/xtensa/kernel/syscalls/syscall.tbl +++ b/arch/xtensa/kernel/syscalls/syscall.tbl @@ -273,7 +273,7 @@ 252 common timer_getoverrun sys_timer_getoverrun # System 253 common reserved253 sys_ni_syscall -254 common lookup_dcookie sys_lookup_dcookie +254 common lookup_dcookie sys_ni_syscall 255 common available255 sys_ni_syscall 256 common add_key sys_add_key 257 common request_key sys_request_key @@ -421,3 +421,20 @@ 448 common process_mrelease sys_process_mrelease 449 common futex_waitv sys_futex_waitv 450 common set_mempolicy_home_node sys_set_mempolicy_home_node +451 common cachestat sys_cachestat +452 common fchmodat2 sys_fchmodat2 +453 common map_shadow_stack sys_map_shadow_stack +454 common futex_wake sys_futex_wake +455 common futex_wait sys_futex_wait +456 common futex_requeue sys_futex_requeue +457 common statmount sys_statmount +458 common listmount sys_listmount +459 common lsm_get_self_attr sys_lsm_get_self_attr +460 common lsm_set_self_attr sys_lsm_set_self_attr +461 common lsm_list_modules sys_lsm_list_modules +462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 16b8a6273772..1c3dfea843ec 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -121,10 +121,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) set_linux_timer(get_linux_timer()); evt->event_handler(evt); - - /* Allow platform to do something useful (Wdog). */ - platform_heartbeat(); - return IRQ_HANDLED; } diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 0c25e035ff10..44c07c4e0833 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -23,6 +23,7 @@ * for more details. */ +#include <linux/cpu.h> #include <linux/kernel.h> #include <linux/sched/signal.h> #include <linux/sched/debug.h> @@ -54,9 +55,10 @@ static void do_interrupt(struct pt_regs *regs); #if XTENSA_FAKE_NMI static void do_nmi(struct pt_regs *regs); #endif -#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION -static void do_unaligned_user(struct pt_regs *regs); +#ifdef CONFIG_XTENSA_LOAD_STORE +static void do_load_store(struct pt_regs *regs); #endif +static void do_unaligned_user(struct pt_regs *regs); static void do_multihit(struct pt_regs *regs); #if XTENSA_HAVE_COPROCESSORS static void do_coprocessor(struct pt_regs *regs); @@ -91,20 +93,24 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = { { EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user }, { EXCCAUSE_SYSTEM_CALL, 0, system_call }, /* EXCCAUSE_INSTRUCTION_FETCH unhandled */ -/* EXCCAUSE_LOAD_STORE_ERROR unhandled*/ +#ifdef CONFIG_XTENSA_LOAD_STORE +{ EXCCAUSE_LOAD_STORE_ERROR, USER|KRNL, fast_load_store }, +{ EXCCAUSE_LOAD_STORE_ERROR, 0, do_load_store }, +#endif { EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, #ifdef SUPPORT_WINDOWED { EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, #endif { EXCCAUSE_INTEGER_DIVIDE_BY_ZERO, 0, do_div0 }, /* EXCCAUSE_PRIVILEGED unhandled */ -#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION +#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION || \ + IS_ENABLED(CONFIG_XTENSA_LOAD_STORE) #ifdef CONFIG_XTENSA_UNALIGNED_USER { EXCCAUSE_UNALIGNED, USER, fast_unaligned }, #endif -{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, { EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, #endif +{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, #ifdef CONFIG_MMU { EXCCAUSE_ITLB_MISS, 0, do_page_fault }, { EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, @@ -171,6 +177,23 @@ __die_if_kernel(const char *str, struct pt_regs *regs, long err) die(str, regs, err); } +#ifdef CONFIG_PRINT_USER_CODE_ON_UNHANDLED_EXCEPTION +static inline void dump_user_code(struct pt_regs *regs) +{ + char buf[32]; + + if (copy_from_user(buf, (void __user *)(regs->pc & -16), sizeof(buf)) == 0) { + print_hex_dump(KERN_INFO, " ", DUMP_PREFIX_NONE, + 32, 1, buf, sizeof(buf), false); + + } +} +#else +static inline void dump_user_code(struct pt_regs *regs) +{ +} +#endif + /* * Unhandled Exceptions. Kill user task or panic if in kernel space. */ @@ -186,6 +209,7 @@ void do_unhandled(struct pt_regs *regs) "\tEXCCAUSE is %ld\n", current->comm, task_pid_nr(current), regs->pc, regs->exccause); + dump_user_code(regs); force_sig(SIGILL); } @@ -349,6 +373,19 @@ static void do_div0(struct pt_regs *regs) force_sig_fault(SIGFPE, FPE_INTDIV, (void __user *)regs->pc); } +#ifdef CONFIG_XTENSA_LOAD_STORE +static void do_load_store(struct pt_regs *regs) +{ + __die_if_kernel("Unhandled load/store exception in kernel", + regs, SIGKILL); + + pr_info_ratelimited("Load/store error to %08lx in '%s' (pid = %d, pc = %#010lx)\n", + regs->excvaddr, current->comm, + task_pid_nr(current), regs->pc); + force_sig_fault(SIGBUS, BUS_ADRERR, (void *)regs->excvaddr); +} +#endif + /* * Handle unaligned memory accesses from user space. Kill task. * @@ -356,21 +393,17 @@ static void do_div0(struct pt_regs *regs) * accesses causes from user space. */ -#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION static void do_unaligned_user(struct pt_regs *regs) { __die_if_kernel("Unhandled unaligned exception in kernel", regs, SIGKILL); - current->thread.bad_vaddr = regs->excvaddr; - current->thread.error_code = -3; pr_info_ratelimited("Unaligned memory access to %08lx in '%s' " "(pid = %d, pc = %#010lx)\n", regs->excvaddr, current->comm, task_pid_nr(current), regs->pc); force_sig_fault(SIGBUS, BUS_ADRALN, (void *) regs->excvaddr); } -#endif #if XTENSA_HAVE_COPROCESSORS static void do_coprocessor(struct pt_regs *regs) @@ -536,23 +569,58 @@ static void show_trace(struct task_struct *task, unsigned long *sp, } #define STACK_DUMP_ENTRY_SIZE 4 -#define STACK_DUMP_LINE_SIZE 32 +#define STACK_DUMP_LINE_SIZE 16 static size_t kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; -void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) +struct stack_fragment { size_t len; + size_t off; + u8 *sp; + const char *loglvl; +}; + +static int show_stack_fragment_cb(struct stackframe *frame, void *data) +{ + struct stack_fragment *sf = data; + + while (sf->off < sf->len) { + u8 line[STACK_DUMP_LINE_SIZE]; + size_t line_len = sf->len - sf->off > STACK_DUMP_LINE_SIZE ? + STACK_DUMP_LINE_SIZE : sf->len - sf->off; + bool arrow = sf->off == 0; + + if (frame && frame->sp == (unsigned long)(sf->sp + sf->off)) + arrow = true; + + __memcpy(line, sf->sp + sf->off, line_len); + print_hex_dump(sf->loglvl, arrow ? "> " : " ", DUMP_PREFIX_NONE, + STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE, + line, line_len, false); + sf->off += STACK_DUMP_LINE_SIZE; + if (arrow) + return 0; + } + return 1; +} + +void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl) +{ + struct stack_fragment sf; if (!sp) sp = stack_pointer(task); - len = min((-(size_t)sp) & (THREAD_SIZE - STACK_DUMP_ENTRY_SIZE), - kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE); + sf.len = min((-(size_t)sp) & (THREAD_SIZE - STACK_DUMP_ENTRY_SIZE), + kstack_depth_to_print * STACK_DUMP_ENTRY_SIZE); + sf.off = 0; + sf.sp = (u8 *)sp; + sf.loglvl = loglvl; printk("%sStack:\n", loglvl); - print_hex_dump(loglvl, " ", DUMP_PREFIX_NONE, - STACK_DUMP_LINE_SIZE, STACK_DUMP_ENTRY_SIZE, - sp, len, false); + walk_stackframe(sp, show_stack_fragment_cb, &sf); + while (sf.off < sf.len) + show_stack_fragment_cb(NULL, &sf); show_trace(task, sp, loglvl); } @@ -561,15 +629,11 @@ DEFINE_SPINLOCK(die_lock); void __noreturn die(const char * str, struct pt_regs * regs, long err) { static int die_counter; - const char *pr = ""; - - if (IS_ENABLED(CONFIG_PREEMPTION)) - pr = IS_ENABLED(CONFIG_PREEMPT_RT) ? " PREEMPT_RT" : " PREEMPT"; console_verbose(); spin_lock_irq(&die_lock); - pr_info("%s: sig: %ld [#%d]%s\n", str, err, ++die_counter, pr); + pr_info("%s: sig: %ld [#%d]\n", str, err, ++die_counter); show_regs(regs); if (!user_mode(regs)) show_stack(NULL, (unsigned long *)regs->areg[1], KERN_INFO); diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 965a3952c47b..f47e9bbbd291 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -118,6 +118,7 @@ SECTIONS SECTION_VECTOR2 (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR) *(.exception.text) + *(.xiptext) #endif IRQENTRY_TEXT @@ -125,7 +126,6 @@ SECTIONS ENTRY_TEXT TEXT_TEXT SCHED_TEXT - CPUIDLE_TEXT LOCK_TEXT *(.fixup) } @@ -202,6 +202,9 @@ SECTIONS .DebugInterruptVector.text); RELOCATE_ENTRY(_exception_text, .exception.text); +#ifdef CONFIG_XIP_KERNEL + RELOCATE_ENTRY(_xip_text, .xiptext); +#endif #endif #ifdef CONFIG_XIP_KERNEL RELOCATE_ENTRY(_xip_data, .data); @@ -320,7 +323,12 @@ SECTIONS LAST) #undef LAST #define LAST .exception.text - + SECTION_VECTOR4 (_xip_text, + .xiptext, + , + LAST) +#undef LAST +#define LAST .xiptext #endif . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3; diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index b0bc8897c924..62d81e76e18e 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -13,65 +13,10 @@ */ #include <linux/module.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <asm/irq.h> -#include <linux/in6.h> - -#include <linux/uaccess.h> -#include <asm/cacheflush.h> -#include <asm/checksum.h> -#include <asm/dma.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/ftrace.h> -#ifdef CONFIG_BLK_DEV_FD -#include <asm/floppy.h> -#endif -#ifdef CONFIG_NET -#include <net/checksum.h> -#endif /* CONFIG_NET */ - - -/* - * String functions - */ -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(__memset); -EXPORT_SYMBOL(__memcpy); -EXPORT_SYMBOL(__memmove); -#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER -EXPORT_SYMBOL(__strncpy_user); -#endif -EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); +#include <asm/pgtable.h> EXPORT_SYMBOL(empty_zero_page); -/* - * gcc internal math functions - */ -extern long long __ashrdi3(long long, int); -extern long long __ashldi3(long long, int); -extern long long __lshrdi3(long long, int); -extern int __divsi3(int, int); -extern int __modsi3(int, int); -extern int __mulsi3(int, int); -extern unsigned int __udivsi3(unsigned int, unsigned int); -extern unsigned int __umodsi3(unsigned int, unsigned int); - -EXPORT_SYMBOL(__ashldi3); -EXPORT_SYMBOL(__ashrdi3); -EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__divsi3); -EXPORT_SYMBOL(__modsi3); -EXPORT_SYMBOL(__mulsi3); -EXPORT_SYMBOL(__udivsi3); -EXPORT_SYMBOL(__umodsi3); - unsigned int __sync_fetch_and_and_4(volatile void *p, unsigned int v) { BUG(); @@ -83,35 +28,3 @@ unsigned int __sync_fetch_and_or_4(volatile void *p, unsigned int v) BUG(); } EXPORT_SYMBOL(__sync_fetch_and_or_4); - -/* - * Networking support - */ -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_generic); - -/* - * Architecture-specific symbols - */ -EXPORT_SYMBOL(__xtensa_copy_user); -EXPORT_SYMBOL(__invalidate_icache_range); - -/* - * Kernel hacking ... - */ - -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -// FIXME EXPORT_SYMBOL(screen_info); -#endif - -extern long common_exception_return; -EXPORT_SYMBOL(common_exception_return); - -#ifdef CONFIG_FUNCTION_TRACER -EXPORT_SYMBOL(_mcount); -#endif - -EXPORT_SYMBOL(__invalidate_dcache_range); -#if XCHAL_DCACHE_IS_WRITEBACK -EXPORT_SYMBOL(__flush_dcache_range); -#endif |