aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile4
-rw-r--r--arch/arm/kernel/calls.S10
-rw-r--r--arch/arm/kernel/crunch.c13
-rw-r--r--arch/arm/kernel/entry-common.S10
-rw-r--r--arch/arm/kernel/irq.c24
-rw-r--r--arch/arm/kernel/return_address.c71
-rw-r--r--arch/arm/kernel/signal.c86
-rw-r--r--arch/arm/kernel/stacktrace.c4
-rw-r--r--arch/arm/kernel/vmlinux.lds.S15
9 files changed, 141 insertions, 96 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ff89d0b3abc5..3213c9382b17 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE
8CFLAGS_REMOVE_ftrace.o = -pg 8CFLAGS_REMOVE_ftrace.o = -pg
9endif 9endif
10 10
11CFLAGS_REMOVE_return_address.o = -pg
12
11# Object file lists. 13# Object file lists.
12 14
13obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ 15obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
14 process.o ptrace.o setup.o signal.o \ 16 process.o ptrace.o return_address.o setup.o signal.o \
15 sys_arm.o stacktrace.o time.o traps.o 17 sys_arm.o stacktrace.o time.o traps.o
16 18
17obj-$(CONFIG_ISA_DMA_API) += dma.o 19obj-$(CONFIG_ISA_DMA_API) += dma.o
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f776e72a4cb8..ecfa98954d1d 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -81,7 +81,7 @@
81 CALL(sys_ni_syscall) /* was sys_ssetmask */ 81 CALL(sys_ni_syscall) /* was sys_ssetmask */
82/* 70 */ CALL(sys_setreuid16) 82/* 70 */ CALL(sys_setreuid16)
83 CALL(sys_setregid16) 83 CALL(sys_setregid16)
84 CALL(sys_sigsuspend_wrapper) 84 CALL(sys_sigsuspend)
85 CALL(sys_sigpending) 85 CALL(sys_sigpending)
86 CALL(sys_sethostname) 86 CALL(sys_sethostname)
87/* 75 */ CALL(sys_setrlimit) 87/* 75 */ CALL(sys_setrlimit)
@@ -188,7 +188,7 @@
188 CALL(sys_rt_sigpending) 188 CALL(sys_rt_sigpending)
189 CALL(sys_rt_sigtimedwait) 189 CALL(sys_rt_sigtimedwait)
190 CALL(sys_rt_sigqueueinfo) 190 CALL(sys_rt_sigqueueinfo)
191 CALL(sys_rt_sigsuspend_wrapper) 191 CALL(sys_rt_sigsuspend)
192/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64)) 192/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
193 CALL(ABI(sys_pwrite64, sys_oabi_pwrite64)) 193 CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
194 CALL(sys_chown16) 194 CALL(sys_chown16)
@@ -344,8 +344,8 @@
344 CALL(sys_readlinkat) 344 CALL(sys_readlinkat)
345 CALL(sys_fchmodat) 345 CALL(sys_fchmodat)
346 CALL(sys_faccessat) 346 CALL(sys_faccessat)
347/* 335 */ CALL(sys_ni_syscall) /* eventually pselect6 */ 347/* 335 */ CALL(sys_pselect6)
348 CALL(sys_ni_syscall) /* eventually ppoll */ 348 CALL(sys_ppoll)
349 CALL(sys_unshare) 349 CALL(sys_unshare)
350 CALL(sys_set_robust_list) 350 CALL(sys_set_robust_list)
351 CALL(sys_get_robust_list) 351 CALL(sys_get_robust_list)
@@ -355,7 +355,7 @@
355 CALL(sys_vmsplice) 355 CALL(sys_vmsplice)
356 CALL(sys_move_pages) 356 CALL(sys_move_pages)
357/* 345 */ CALL(sys_getcpu) 357/* 345 */ CALL(sys_getcpu)
358 CALL(sys_ni_syscall) /* eventually epoll_pwait */ 358 CALL(sys_epoll_pwait)
359 CALL(sys_kexec_load) 359 CALL(sys_kexec_load)
360 CALL(sys_utimensat) 360 CALL(sys_utimensat)
361 CALL(sys_signalfd) 361 CALL(sys_signalfd)
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index 99995c2b2312..769abe15cf91 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread)
31 31
32static int crunch_enabled(u32 devcfg) 32static int crunch_enabled(u32 devcfg)
33{ 33{
34 return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); 34 return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
35} 35}
36 36
37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) 37static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
@@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
56 break; 56 break;
57 57
58 case THREAD_NOTIFY_SWITCH: 58 case THREAD_NOTIFY_SWITCH:
59 devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); 59 devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { 60 if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
61 devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; 61 /*
62 * We don't use ep93xx_syscon_swlocked_write() here
63 * because we are on the context switch path and
64 * preemption is already disabled.
65 */
66 devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
62 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); 67 __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
63 __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); 68 __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
64 } 69 }
65 break; 70 break;
66 } 71 }
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 366e5097a41a..bfa7f0af7ede 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -373,16 +373,6 @@ sys_clone_wrapper:
373 b sys_clone 373 b sys_clone
374ENDPROC(sys_clone_wrapper) 374ENDPROC(sys_clone_wrapper)
375 375
376sys_sigsuspend_wrapper:
377 add r3, sp, #S_OFF
378 b sys_sigsuspend
379ENDPROC(sys_sigsuspend_wrapper)
380
381sys_rt_sigsuspend_wrapper:
382 add r2, sp, #S_OFF
383 b sys_rt_sigsuspend
384ENDPROC(sys_rt_sigsuspend_wrapper)
385
386sys_sigreturn_wrapper: 376sys_sigreturn_wrapper:
387 add r0, sp, #S_OFF 377 add r0, sp, #S_OFF
388 b sys_sigreturn 378 b sys_sigreturn
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 096f600dc8d8..b7c3490eaa24 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -98,17 +98,6 @@ unlock:
98 return 0; 98 return 0;
99} 99}
100 100
101/* Handle bad interrupts */
102static struct irq_desc bad_irq_desc = {
103 .handle_irq = handle_bad_irq,
104 .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
105};
106
107#ifdef CONFIG_CPUMASK_OFFSTACK
108/* We are not allocating bad_irq_desc.affinity or .pending_mask */
109#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK."
110#endif
111
112/* 101/*
113 * do_IRQ handles all hardware IRQ's. Decoded IRQs should not 102 * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
114 * come via this function. Instead, they should provide their 103 * come via this function. Instead, they should provide their
@@ -124,10 +113,13 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
124 * Some hardware gives randomly wrong interrupts. Rather 113 * Some hardware gives randomly wrong interrupts. Rather
125 * than crashing, do something sensible. 114 * than crashing, do something sensible.
126 */ 115 */
127 if (irq >= NR_IRQS) 116 if (unlikely(irq >= NR_IRQS)) {
128 handle_bad_irq(irq, &bad_irq_desc); 117 if (printk_ratelimit())
129 else 118 printk(KERN_WARNING "Bad IRQ%u\n", irq);
119 ack_bad_irq(irq);
120 } else {
130 generic_handle_irq(irq); 121 generic_handle_irq(irq);
122 }
131 123
132 /* AT91 specific workaround */ 124 /* AT91 specific workaround */
133 irq_finish(irq); 125 irq_finish(irq);
@@ -165,10 +157,6 @@ void __init init_IRQ(void)
165 for (irq = 0; irq < NR_IRQS; irq++) 157 for (irq = 0; irq < NR_IRQS; irq++)
166 irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE; 158 irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
167 159
168#ifdef CONFIG_SMP
169 cpumask_setall(bad_irq_desc.affinity);
170 bad_irq_desc.node = smp_processor_id();
171#endif
172 init_arch_irq(); 160 init_arch_irq();
173} 161}
174 162
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
new file mode 100644
index 000000000000..df246da4ceca
--- /dev/null
+++ b/arch/arm/kernel/return_address.c
@@ -0,0 +1,71 @@
1/*
2 * arch/arm/kernel/return_address.c
3 *
4 * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
5 * for Pengutronix
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/module.h>
12
13#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
14#include <linux/sched.h>
15
16#include <asm/stacktrace.h>
17
18struct return_address_data {
19 unsigned int level;
20 void *addr;
21};
22
23static int save_return_addr(struct stackframe *frame, void *d)
24{
25 struct return_address_data *data = d;
26
27 if (!data->level) {
28 data->addr = (void *)frame->lr;
29
30 return 1;
31 } else {
32 --data->level;
33 return 0;
34 }
35}
36
37void *return_address(unsigned int level)
38{
39 struct return_address_data data;
40 struct stackframe frame;
41 register unsigned long current_sp asm ("sp");
42
43 data.level = level + 1;
44
45 frame.fp = (unsigned long)__builtin_frame_address(0);
46 frame.sp = current_sp;
47 frame.lr = (unsigned long)__builtin_return_address(0);
48 frame.pc = (unsigned long)return_address;
49
50 walk_stackframe(&frame, save_return_addr, &data);
51
52 if (!data.level)
53 return data.addr;
54 else
55 return NULL;
56}
57
58#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
59
60#if defined(CONFIG_ARM_UNWIND)
61#warning "TODO: return_address should use unwind tables"
62#endif
63
64void *return_address(unsigned int level)
65{
66 return NULL;
67}
68
69#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
70
71EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 93bb4247b7ed..e27ee1f701d5 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -47,57 +47,22 @@ const unsigned long sigreturn_codes[7] = {
47 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, 47 MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
48}; 48};
49 49
50static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
51
52/* 50/*
53 * atomically swap in the new signal mask, and wait for a signal. 51 * atomically swap in the new signal mask, and wait for a signal.
54 */ 52 */
55asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs) 53asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
56{ 54{
57 sigset_t saveset;
58
59 mask &= _BLOCKABLE; 55 mask &= _BLOCKABLE;
60 spin_lock_irq(&current->sighand->siglock); 56 spin_lock_irq(&current->sighand->siglock);
61 saveset = current->blocked; 57 current->saved_sigmask = current->blocked;
62 siginitset(&current->blocked, mask); 58 siginitset(&current->blocked, mask);
63 recalc_sigpending(); 59 recalc_sigpending();
64 spin_unlock_irq(&current->sighand->siglock); 60 spin_unlock_irq(&current->sighand->siglock);
65 regs->ARM_r0 = -EINTR;
66
67 while (1) {
68 current->state = TASK_INTERRUPTIBLE;
69 schedule();
70 if (do_signal(&saveset, regs, 0))
71 return regs->ARM_r0;
72 }
73}
74
75asmlinkage int
76sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
77{
78 sigset_t saveset, newset;
79
80 /* XXX: Don't preclude handling different sized sigset_t's. */
81 if (sigsetsize != sizeof(sigset_t))
82 return -EINVAL;
83
84 if (copy_from_user(&newset, unewset, sizeof(newset)))
85 return -EFAULT;
86 sigdelsetmask(&newset, ~_BLOCKABLE);
87
88 spin_lock_irq(&current->sighand->siglock);
89 saveset = current->blocked;
90 current->blocked = newset;
91 recalc_sigpending();
92 spin_unlock_irq(&current->sighand->siglock);
93 regs->ARM_r0 = -EINTR;
94 61
95 while (1) { 62 current->state = TASK_INTERRUPTIBLE;
96 current->state = TASK_INTERRUPTIBLE; 63 schedule();
97 schedule(); 64 set_restore_sigmask();
98 if (do_signal(&saveset, regs, 0)) 65 return -ERESTARTNOHAND;
99 return regs->ARM_r0;
100 }
101} 66}
102 67
103asmlinkage int 68asmlinkage int
@@ -545,7 +510,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
545/* 510/*
546 * OK, we're invoking a handler 511 * OK, we're invoking a handler
547 */ 512 */
548static void 513static int
549handle_signal(unsigned long sig, struct k_sigaction *ka, 514handle_signal(unsigned long sig, struct k_sigaction *ka,
550 siginfo_t *info, sigset_t *oldset, 515 siginfo_t *info, sigset_t *oldset,
551 struct pt_regs * regs, int syscall) 516 struct pt_regs * regs, int syscall)
@@ -596,7 +561,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
596 561
597 if (ret != 0) { 562 if (ret != 0) {
598 force_sigsegv(sig, tsk); 563 force_sigsegv(sig, tsk);
599 return; 564 return ret;
600 } 565 }
601 566
602 /* 567 /*
@@ -610,6 +575,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
610 recalc_sigpending(); 575 recalc_sigpending();
611 spin_unlock_irq(&tsk->sighand->siglock); 576 spin_unlock_irq(&tsk->sighand->siglock);
612 577
578 return 0;
613} 579}
614 580
615/* 581/*
@@ -621,7 +587,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
621 * the kernel can handle, and then we build all the user-level signal handling 587 * the kernel can handle, and then we build all the user-level signal handling
622 * stack-frames in one go after that. 588 * stack-frames in one go after that.
623 */ 589 */
624static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) 590static void do_signal(struct pt_regs *regs, int syscall)
625{ 591{
626 struct k_sigaction ka; 592 struct k_sigaction ka;
627 siginfo_t info; 593 siginfo_t info;
@@ -634,7 +600,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
634 * if so. 600 * if so.
635 */ 601 */
636 if (!user_mode(regs)) 602 if (!user_mode(regs))
637 return 0; 603 return;
638 604
639 if (try_to_freeze()) 605 if (try_to_freeze())
640 goto no_signal; 606 goto no_signal;
@@ -643,9 +609,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
643 609
644 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 610 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
645 if (signr > 0) { 611 if (signr > 0) {
646 handle_signal(signr, &ka, &info, oldset, regs, syscall); 612 sigset_t *oldset;
613
614 if (test_thread_flag(TIF_RESTORE_SIGMASK))
615 oldset = &current->saved_sigmask;
616 else
617 oldset = &current->blocked;
618 if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
619 /*
620 * A signal was successfully delivered; the saved
621 * sigmask will have been stored in the signal frame,
622 * and will be restored by sigreturn, so we can simply
623 * clear the TIF_RESTORE_SIGMASK flag.
624 */
625 if (test_thread_flag(TIF_RESTORE_SIGMASK))
626 clear_thread_flag(TIF_RESTORE_SIGMASK);
627 }
647 single_step_set(current); 628 single_step_set(current);
648 return 1; 629 return;
649 } 630 }
650 631
651 no_signal: 632 no_signal:
@@ -697,14 +678,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
697 regs->ARM_r0 == -ERESTARTNOINTR) { 678 regs->ARM_r0 == -ERESTARTNOINTR) {
698 setup_syscall_restart(regs); 679 setup_syscall_restart(regs);
699 } 680 }
681
682 /* If there's no signal to deliver, we just put the saved sigmask
683 * back.
684 */
685 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
686 clear_thread_flag(TIF_RESTORE_SIGMASK);
687 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
688 }
700 } 689 }
701 single_step_set(current); 690 single_step_set(current);
702 return 0;
703} 691}
704 692
705asmlinkage void 693asmlinkage void
706do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) 694do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
707{ 695{
708 if (thread_flags & _TIF_SIGPENDING) 696 if (thread_flags & _TIF_SIGPENDING)
709 do_signal(&current->blocked, regs, syscall); 697 do_signal(regs, syscall);
710} 698}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 9f444e5cc165..20b7411e47fd 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -21,7 +21,7 @@
21 * Note that with framepointer enabled, even the leaf functions have the same 21 * Note that with framepointer enabled, even the leaf functions have the same
22 * prologue and epilogue, therefore we can ignore the LR value in this case. 22 * prologue and epilogue, therefore we can ignore the LR value in this case.
23 */ 23 */
24int unwind_frame(struct stackframe *frame) 24int notrace unwind_frame(struct stackframe *frame)
25{ 25{
26 unsigned long high, low; 26 unsigned long high, low;
27 unsigned long fp = frame->fp; 27 unsigned long fp = frame->fp;
@@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame)
43} 43}
44#endif 44#endif
45 45
46void walk_stackframe(struct stackframe *frame, 46void notrace walk_stackframe(struct stackframe *frame,
47 int (*fn)(struct stackframe *, void *), void *data) 47 int (*fn)(struct stackframe *, void *), void *data)
48{ 48{
49 while (1) { 49 while (1) {
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 4340bf3d2c84..69371028a202 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
6#include <asm-generic/vmlinux.lds.h> 6#include <asm-generic/vmlinux.lds.h>
7#include <asm/thread_info.h> 7#include <asm/thread_info.h>
8#include <asm/memory.h> 8#include <asm/memory.h>
9#include <asm/page.h>
9 10
10OUTPUT_ARCH(arm) 11OUTPUT_ARCH(arm)
11ENTRY(stext) 12ENTRY(stext)
@@ -63,7 +64,7 @@ SECTIONS
63 usr/built-in.o(.init.ramfs) 64 usr/built-in.o(.init.ramfs)
64 __initramfs_end = .; 65 __initramfs_end = .;
65#endif 66#endif
66 . = ALIGN(4096); 67 . = ALIGN(PAGE_SIZE);
67 __per_cpu_load = .; 68 __per_cpu_load = .;
68 __per_cpu_start = .; 69 __per_cpu_start = .;
69 *(.data.percpu.page_aligned) 70 *(.data.percpu.page_aligned)
@@ -73,7 +74,7 @@ SECTIONS
73#ifndef CONFIG_XIP_KERNEL 74#ifndef CONFIG_XIP_KERNEL
74 __init_begin = _stext; 75 __init_begin = _stext;
75 INIT_DATA 76 INIT_DATA
76 . = ALIGN(4096); 77 . = ALIGN(PAGE_SIZE);
77 __init_end = .; 78 __init_end = .;
78#endif 79#endif
79 } 80 }
@@ -118,7 +119,7 @@ SECTIONS
118 *(.got) /* Global offset table */ 119 *(.got) /* Global offset table */
119 } 120 }
120 121
121 RODATA 122 RO_DATA(PAGE_SIZE)
122 123
123 _etext = .; /* End of text and rodata section */ 124 _etext = .; /* End of text and rodata section */
124 125
@@ -158,17 +159,17 @@ SECTIONS
158 *(.data.init_task) 159 *(.data.init_task)
159 160
160#ifdef CONFIG_XIP_KERNEL 161#ifdef CONFIG_XIP_KERNEL
161 . = ALIGN(4096); 162 . = ALIGN(PAGE_SIZE);
162 __init_begin = .; 163 __init_begin = .;
163 INIT_DATA 164 INIT_DATA
164 . = ALIGN(4096); 165 . = ALIGN(PAGE_SIZE);
165 __init_end = .; 166 __init_end = .;
166#endif 167#endif
167 168
168 . = ALIGN(4096); 169 . = ALIGN(PAGE_SIZE);
169 __nosave_begin = .; 170 __nosave_begin = .;
170 *(.data.nosave) 171 *(.data.nosave)
171 . = ALIGN(4096); 172 . = ALIGN(PAGE_SIZE);
172 __nosave_end = .; 173 __nosave_end = .;
173 174
174 /* 175 /*