summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/asm-offsets.c4
-rw-r--r--arch/s390/kernel/diag.c21
-rw-r--r--arch/s390/kernel/dis.c1
-rw-r--r--arch/s390/kernel/entry.S3
-rw-r--r--arch/s390/kernel/entry64.S3
-rw-r--r--arch/s390/kernel/irq.c1
-rw-r--r--arch/s390/kernel/jump_label.c59
-rw-r--r--arch/s390/kernel/process.c19
-rw-r--r--arch/s390/kernel/setup.c31
-rw-r--r--arch/s390/kernel/smp.c36
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/topology.c16
-rw-r--r--arch/s390/kernel/vdso32/Makefile3
-rw-r--r--arch/s390/kernel/vdso64/Makefile3
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
16 files changed, 106 insertions, 102 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 64230bc392f..5ff15dacb57 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -23,7 +23,7 @@ CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
- vdso.o vtime.o sysinfo.o nmi.o sclp.o
+ vdso.o vtime.o sysinfo.o nmi.o sclp.o jump_label.o
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index fe03c140002..edfbd17d708 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -124,13 +124,11 @@ int main(void)
DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
+ DEFINE(__LC_CURRENT_PID, offsetof(struct _lowcore, current_pid));
DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
- DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
- DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
- DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce));
DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index c032d11da8a..8237fc07ac7 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -9,27 +9,6 @@
#include <asm/diag.h>
/*
- * Diagnose 10: Release pages
- */
-void diag10(unsigned long addr)
-{
- if (addr >= 0x7ff00000)
- return;
- asm volatile(
-#ifdef CONFIG_64BIT
- " sam31\n"
- " diag %0,%0,0x10\n"
- "0: sam64\n"
-#else
- " diag %0,%0,0x10\n"
- "0:\n"
-#endif
- EX_TABLE(0b, 0b)
- : : "a" (addr));
-}
-EXPORT_SYMBOL(diag10);
-
-/*
* Diagnose 14: Input spool file manipulation
*/
int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index c83726c9fe0..3d4a78fc1ad 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -672,6 +672,7 @@ static struct insn opcode_b2[] = {
{ "rp", 0x77, INSTR_S_RD },
{ "stcke", 0x78, INSTR_S_RD },
{ "sacf", 0x79, INSTR_S_RD },
+ { "spp", 0x80, INSTR_S_RD },
{ "stsi", 0x7d, INSTR_S_RD },
{ "srnm", 0x99, INSTR_S_RD },
{ "stfpc", 0x9c, INSTR_S_RD },
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 648f64239a9..0476174dfff 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -212,6 +212,7 @@ __switch_to:
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
st %r3,__LC_CURRENT # store task struct of next
+ mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
st %r5,__LC_THREAD_INFO # store thread info of next
ahi %r5,STACK_SIZE # end of kernel stack of next
st %r5,__LC_KERNEL_STACK # store end of kernel stack
@@ -836,7 +837,7 @@ restart_base:
stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on
basr %r14,0
l %r14,restart_addr-.(%r14)
- br %r14 # branch to start_secondary
+ basr %r14,%r14 # branch to start_secondary
restart_addr:
.long start_secondary
.align 8
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 9d3603d6c51..d61967e2eab 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -220,6 +220,7 @@ __switch_to:
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
stg %r3,__LC_CURRENT # store task struct of next
+ mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
stg %r5,__LC_THREAD_INFO # store thread info of next
aghi %r5,STACK_SIZE # end of kernel stack of next
stg %r5,__LC_KERNEL_STACK # store end of kernel stack
@@ -841,7 +842,7 @@ restart_base:
mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on
- jg start_secondary
+ brasl %r14,start_secondary
.align 8
restart_vtime:
.long 0x7fffffff,0xffffffff
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index ea5099c9709..e204f9597aa 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -32,6 +32,7 @@ static const struct irq_class intrclass_names[] = {
{.name = "VRT", .desc = "[EXT] Virtio" },
{.name = "SCP", .desc = "[EXT] Service Call" },
{.name = "IUC", .desc = "[EXT] IUCV" },
+ {.name = "CPM", .desc = "[EXT] CPU Measurement" },
{.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" },
{.name = "QDI", .desc = "[I/O] QDIO Interrupt" },
{.name = "DAS", .desc = "[I/O] DASD" },
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c
new file mode 100644
index 00000000000..44cc06bedf7
--- /dev/null
+++ b/arch/s390/kernel/jump_label.c
@@ -0,0 +1,59 @@
+/*
+ * Jump label s390 support
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
+ */
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/stop_machine.h>
+#include <linux/jump_label.h>
+#include <asm/ipl.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+struct insn {
+ u16 opcode;
+ s32 offset;
+} __packed;
+
+struct insn_args {
+ unsigned long *target;
+ struct insn *insn;
+ ssize_t size;
+};
+
+static int __arch_jump_label_transform(void *data)
+{
+ struct insn_args *args = data;
+ int rc;
+
+ rc = probe_kernel_write(args->target, args->insn, args->size);
+ WARN_ON_ONCE(rc < 0);
+ return 0;
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ struct insn_args args;
+ struct insn insn;
+
+ if (type == JUMP_LABEL_ENABLE) {
+ /* brcl 15,offset */
+ insn.opcode = 0xc0f4;
+ insn.offset = (entry->target - entry->code) >> 1;
+ } else {
+ /* brcl 0,0 */
+ insn.opcode = 0xc004;
+ insn.offset = 0;
+ }
+
+ args.target = (void *) entry->code;
+ args.insn = &insn;
+ args.size = JUMP_LABEL_NOP_SIZE;
+
+ stop_machine(__arch_jump_label_transform, &args, NULL);
+}
+
+#endif
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index a895e69379f..541a7509fae 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -9,41 +9,26 @@
#include <linux/compiler.h>
#include <linux/cpu.h>
-#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/fs.h>
#include <linux/smp.h>
-#include <linux/stddef.h>
#include <linux/slab.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/vmalloc.h>
-#include <linux/user.h>
#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/notifier.h>
#include <linux/tick.h>
-#include <linux/elfcore.h>
-#include <linux/kernel_stat.h>
#include <linux/personality.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/kprobes.h>
#include <linux/random.h>
-#include <asm/compat.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/nmi.h>
+#include <asm/compat.h>
#include <asm/smp.h>
#include "entry.h"
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f5434d1ecb3..0c35dee10b0 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -305,8 +305,7 @@ static int set_amode_and_uaccess(unsigned long user_amode,
*/
static int __init early_parse_switch_amode(char *p)
{
- if (user_mode != SECONDARY_SPACE_MODE)
- user_mode = PRIMARY_SPACE_MODE;
+ user_mode = PRIMARY_SPACE_MODE;
return 0;
}
early_param("switch_amode", early_parse_switch_amode);
@@ -315,10 +314,6 @@ static int __init early_parse_user_mode(char *p)
{
if (p && strcmp(p, "primary") == 0)
user_mode = PRIMARY_SPACE_MODE;
-#ifdef CONFIG_S390_EXEC_PROTECT
- else if (p && strcmp(p, "secondary") == 0)
- user_mode = SECONDARY_SPACE_MODE;
-#endif
else if (!p || strcmp(p, "home") == 0)
user_mode = HOME_SPACE_MODE;
else
@@ -327,31 +322,9 @@ static int __init early_parse_user_mode(char *p)
}
early_param("user_mode", early_parse_user_mode);
-#ifdef CONFIG_S390_EXEC_PROTECT
-/*
- * Enable execute protection?
- */
-static int __init early_parse_noexec(char *p)
-{
- if (!strncmp(p, "off", 3))
- return 0;
- user_mode = SECONDARY_SPACE_MODE;
- return 0;
-}
-early_param("noexec", early_parse_noexec);
-#endif /* CONFIG_S390_EXEC_PROTECT */
-
static void setup_addressing_mode(void)
{
- if (user_mode == SECONDARY_SPACE_MODE) {
- if (set_amode_and_uaccess(PSW_ASC_SECONDARY,
- PSW32_ASC_SECONDARY))
- pr_info("Execute protection active, "
- "mvcos available\n");
- else
- pr_info("Execute protection active, "
- "mvcos not available\n");
- } else if (user_mode == PRIMARY_SPACE_MODE) {
+ if (user_mode == PRIMARY_SPACE_MODE) {
if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY))
pr_info("Address spaces switched, "
"mvcos available\n");
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 63a97db83f9..f8e85ecbc45 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -165,12 +165,12 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++;
/*
* handle bit signal external calls
- *
- * For the ec_schedule signal we have to do nothing. All the work
- * is done automatically when we return from the interrupt.
*/
bits = xchg(&S390_lowcore.ext_call_fast, 0);
+ if (test_bit(ec_schedule, &bits))
+ scheduler_ipi();
+
if (test_bit(ec_call_function, &bits))
generic_smp_call_function_interrupt();
@@ -335,7 +335,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
if (!cpu_stopped(logical_cpu))
continue;
- cpu_set(logical_cpu, cpu_present_map);
+ set_cpu_present(logical_cpu, true);
smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
logical_cpu = cpumask_next(logical_cpu, &avail);
if (logical_cpu >= nr_cpu_ids)
@@ -367,7 +367,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
continue;
__cpu_logical_map[logical_cpu] = cpu_id;
smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
- cpu_set(logical_cpu, cpu_present_map);
+ set_cpu_present(logical_cpu, true);
if (cpu >= info->configured)
smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
else
@@ -385,7 +385,7 @@ static int __smp_rescan_cpus(void)
{
cpumask_t avail;
- cpus_xor(avail, cpu_possible_map, cpu_present_map);
+ cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask);
if (smp_use_sigp_detection)
return smp_rescan_cpus_sigp(avail);
else
@@ -467,7 +467,7 @@ int __cpuinit start_secondary(void *cpuvoid)
notify_cpu_starting(smp_processor_id());
/* Mark this cpu as online */
ipi_call_lock();
- cpu_set(smp_processor_id(), cpu_online_map);
+ set_cpu_online(smp_processor_id(), true);
ipi_call_unlock();
/* Switch on interrupts */
local_irq_enable();
@@ -644,7 +644,7 @@ int __cpu_disable(void)
struct ec_creg_mask_parms cr_parms;
int cpu = smp_processor_id();
- cpu_clear(cpu, cpu_online_map);
+ set_cpu_online(cpu, false);
/* Disable pfault pseudo page faults on this cpu. */
pfault_fini();
@@ -654,8 +654,8 @@ int __cpu_disable(void)
/* disable all external interrupts */
cr_parms.orvals[0] = 0;
- cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 12 |
- 1 << 11 | 1 << 10 | 1 << 6 | 1 << 4);
+ cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 11 |
+ 1 << 10 | 1 << 9 | 1 << 6 | 1 << 4);
/* disable all I/O interrupts */
cr_parms.orvals[6] = 0;
cr_parms.andvals[6] = ~(1 << 31 | 1 << 30 | 1 << 29 | 1 << 28 |
@@ -681,7 +681,7 @@ void __cpu_die(unsigned int cpu)
atomic_dec(&init_mm.context.attach_count);
}
-void cpu_die(void)
+void __noreturn cpu_die(void)
{
idle_task_exit();
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
@@ -738,8 +738,8 @@ void __init smp_prepare_boot_cpu(void)
BUG_ON(smp_processor_id() != 0);
current_thread_info()->cpu = 0;
- cpu_set(0, cpu_present_map);
- cpu_set(0, cpu_online_map);
+ set_cpu_present(0, true);
+ set_cpu_online(0, true);
S390_lowcore.percpu_offset = __per_cpu_offset[0];
current_set[0] = current;
smp_cpu_state[0] = CPU_STATE_CONFIGURED;
@@ -1016,21 +1016,21 @@ int __ref smp_rescan_cpus(void)
get_online_cpus();
mutex_lock(&smp_cpu_state_mutex);
- newcpus = cpu_present_map;
+ cpumask_copy(&newcpus, cpu_present_mask);
rc = __smp_rescan_cpus();
if (rc)
goto out;
- cpus_andnot(newcpus, cpu_present_map, newcpus);
- for_each_cpu_mask(cpu, newcpus) {
+ cpumask_andnot(&newcpus, cpu_present_mask, &newcpus);
+ for_each_cpu(cpu, &newcpus) {
rc = smp_add_present_cpu(cpu);
if (rc)
- cpu_clear(cpu, cpu_present_map);
+ set_cpu_present(cpu, false);
}
rc = 0;
out:
mutex_unlock(&smp_cpu_state_mutex);
put_online_cpus();
- if (!cpus_empty(newcpus))
+ if (!cpumask_empty(&newcpus))
topology_schedule_update();
return rc;
}
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 87be655557a..a59557f1fb5 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -810,7 +810,7 @@ static int etr_sync_clock_stop(struct etr_aib *aib, int port)
etr_sync.etr_port = port;
get_online_cpus();
atomic_set(&etr_sync.cpus, num_online_cpus() - 1);
- rc = stop_machine(etr_sync_clock, &etr_sync, &cpu_online_map);
+ rc = stop_machine(etr_sync_clock, &etr_sync, cpu_online_mask);
put_online_cpus();
return rc;
}
@@ -1579,7 +1579,7 @@ static void stp_work_fn(struct work_struct *work)
memset(&stp_sync, 0, sizeof(stp_sync));
get_online_cpus();
atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
- stop_machine(stp_sync_clock, &stp_sync, &cpu_online_map);
+ stop_machine(stp_sync_clock, &stp_sync, cpu_online_mask);
put_online_cpus();
if (!check_sync_clock())
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 94b06c31fc8..2eafb8c7a74 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -52,20 +52,20 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
{
cpumask_t mask;
- cpus_clear(mask);
+ cpumask_clear(&mask);
if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
cpumask_copy(&mask, cpumask_of(cpu));
return mask;
}
while (info) {
- if (cpu_isset(cpu, info->mask)) {
+ if (cpumask_test_cpu(cpu, &info->mask)) {
mask = info->mask;
break;
}
info = info->next;
}
- if (cpus_empty(mask))
- mask = cpumask_of_cpu(cpu);
+ if (cpumask_empty(&mask))
+ cpumask_copy(&mask, cpumask_of(cpu));
return mask;
}
@@ -85,10 +85,10 @@ static void add_cpus_to_mask(struct topology_cpu *tl_cpu,
if (cpu_logical_map(lcpu) != rcpu)
continue;
#ifdef CONFIG_SCHED_BOOK
- cpu_set(lcpu, book->mask);
+ cpumask_set_cpu(lcpu, &book->mask);
cpu_book_id[lcpu] = book->id;
#endif
- cpu_set(lcpu, core->mask);
+ cpumask_set_cpu(lcpu, &core->mask);
cpu_core_id[lcpu] = core->id;
smp_cpu_polarization[lcpu] = tl_cpu->pp;
}
@@ -101,13 +101,13 @@ static void clear_masks(void)
info = &core_info;
while (info) {
- cpus_clear(info->mask);
+ cpumask_clear(&info->mask);
info = info->next;
}
#ifdef CONFIG_SCHED_BOOK
info = &book_info;
while (info) {
- cpus_clear(info->mask);
+ cpumask_clear(&info->mask);
info = info->next;
}
#endif
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index d13e8755a8c..8ad2b34ad15 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -22,6 +22,9 @@ obj-y += vdso32_wrapper.o
extra-y += vdso32.lds
CPPFLAGS_vdso32.lds += -P -C -U$(ARCH)
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
# Force dependency (incbin is bad)
$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index 449352dda9c..2a8ddfd12a5 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -22,6 +22,9 @@ obj-y += vdso64_wrapper.o
extra-y += vdso64.lds
CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
# Force dependency (incbin is bad)
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 1bc18cdb525..56fe6bc81fe 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -77,7 +77,7 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
INIT_DATA_SECTION(0x100)
- PERCPU(0x100, PAGE_SIZE)
+ PERCPU_SECTION(0x100)
. = ALIGN(PAGE_SIZE);
__init_end = .; /* freed after init ends here */