diff options
Diffstat (limited to 'arch/s390')
29 files changed, 408 insertions, 269 deletions
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h index e806a8922bbb..71d65eb30650 100644 --- a/arch/s390/appldata/appldata.h +++ b/arch/s390/appldata/appldata.h @@ -3,9 +3,9 @@ * * Definitions and interface for Linux - z/VM Monitor Stream. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ //#define APPLDATA_DEBUG /* Debug messages on/off */ @@ -29,6 +29,22 @@ #define CTL_APPLDATA_NET_SUM 2125 #define CTL_APPLDATA_PROC 2126 +#ifndef CONFIG_64BIT + +#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ +#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ +#define APPLDATA_GEN_EVENT_RECORD 0x02 +#define APPLDATA_START_CONFIG_REC 0x03 + +#else + +#define APPLDATA_START_INTERVAL_REC 0x80 +#define APPLDATA_STOP_REC 0x81 +#define APPLDATA_GEN_EVENT_RECORD 0x82 +#define APPLDATA_START_CONFIG_REC 0x83 + +#endif /* CONFIG_64BIT */ + #define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) @@ -53,7 +69,11 @@ struct appldata_ops { void *data; /* record data */ unsigned int size; /* size of record */ struct module *owner; /* THIS_MODULE */ + char mod_lvl[2]; /* modification level, EBCDIC */ }; extern int appldata_register_ops(struct appldata_ops *ops); extern void appldata_unregister_ops(struct appldata_ops *ops); +extern int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl); + diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 54d35c130907..d0f82c995af6 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -5,12 +5,11 @@ * Exports appldata_register_ops() and appldata_unregister_ops() for the * data gathering modules. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -40,22 +39,6 @@ #define TOD_MICRO 0x01000 /* nr. of TOD clock units for 1 microsecond */ -#ifndef CONFIG_64BIT - -#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ -#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ -#define APPLDATA_GEN_EVENT_RECORD 0x02 -#define APPLDATA_START_CONFIG_REC 0x03 - -#else - -#define APPLDATA_START_INTERVAL_REC 0x80 -#define APPLDATA_STOP_REC 0x81 -#define APPLDATA_GEN_EVENT_RECORD 0x82 -#define APPLDATA_START_CONFIG_REC 0x83 - -#endif /* CONFIG_64BIT */ - /* * Parameter list for DIAGNOSE X'DC' @@ -195,8 +178,8 @@ static void appldata_work_fn(void *data) * * prepare parameter list, issue DIAG 0xDC */ -static int appldata_diag(char record_nr, u16 function, unsigned long buffer, - u16 length) +int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl) { unsigned long ry; struct appldata_product_id { @@ -214,7 +197,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, .record_nr = record_nr, .version_nr = {0xF2, 0xF6}, /* "26" */ .release_nr = {0xF0, 0xF1}, /* "01" */ - .mod_lvl = {0xF0, 0xF0}, /* "00" */ + .mod_lvl = {mod_lvl[0], mod_lvl[1]}, }; struct appldata_parameter_list appldata_parameter_list = { .diag = 0xDC, @@ -467,24 +450,25 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, module_put(ops->owner); return -ENODEV; } - ops->active = 1; ops->callback(ops->data); // init record rc = appldata_diag(ops->record_nr, APPLDATA_START_INTERVAL_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("START DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); module_put(ops->owner); - ops->active = 0; } else { P_INFO("Monitoring %s data enabled, " "DIAG 0xDC started.\n", ops->name); + ops->active = 1; } } else if ((buf[0] == '0') && (ops->active == 1)) { ops->active = 0; rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -633,7 +617,7 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -static int +static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { @@ -710,7 +694,8 @@ static void __exit appldata_exit(void) list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -739,6 +724,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); +EXPORT_SYMBOL_GPL(appldata_diag); #ifdef MODULE /* @@ -779,8 +765,6 @@ unsigned long nr_iowait(void) #endif /* MODULE */ EXPORT_SYMBOL_GPL(si_swapinfo); EXPORT_SYMBOL_GPL(nr_threads); -EXPORT_SYMBOL_GPL(avenrun); -EXPORT_SYMBOL_GPL(get_full_page_state); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); //EXPORT_SYMBOL_GPL(nr_context_switches); diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index f0e2fbed3d4c..ab3b0765a64e 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -4,12 +4,11 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects data related to memory management. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -107,21 +106,21 @@ static void appldata_get_mem_data(void *data) * serialized through the appldata_ops_lock and can use static */ static struct sysinfo val; - static struct page_state ps; + unsigned long ev[NR_VM_EVENT_ITEMS]; struct appldata_mem_data *mem_data; mem_data = data; mem_data->sync_count_1++; - get_full_page_state(&ps); - mem_data->pgpgin = ps.pgpgin >> 1; - mem_data->pgpgout = ps.pgpgout >> 1; - mem_data->pswpin = ps.pswpin; - mem_data->pswpout = ps.pswpout; - mem_data->pgalloc = ps.pgalloc_high + ps.pgalloc_normal + - ps.pgalloc_dma; - mem_data->pgfault = ps.pgfault; - mem_data->pgmajfault = ps.pgmajfault; + all_vm_events(ev); + mem_data->pgpgin = ev[PGPGIN] >> 1; + mem_data->pgpgout = ev[PGPGOUT] >> 1; + mem_data->pswpin = ev[PSWPIN]; + mem_data->pswpout = ev[PSWPOUT]; + mem_data->pgalloc = ev[PGALLOC_HIGH] + ev[PGALLOC_NORMAL] + + ev[PGALLOC_DMA]; + mem_data->pgfault = ev[PGFAULT]; + mem_data->pgmajfault = ev[PGMAJFAULT]; si_meminfo(&val); mem_data->sharedram = val.sharedram; @@ -130,7 +129,8 @@ static void appldata_get_mem_data(void *data) mem_data->totalhigh = P2K(val.totalhigh); mem_data->freehigh = P2K(val.freehigh); mem_data->bufferram = P2K(val.bufferram); - mem_data->cached = P2K(atomic_read(&nr_pagecache) - val.bufferram); + mem_data->cached = P2K(global_page_state(NR_FILE_PAGES) + - val.bufferram); si_swapinfo(&val); mem_data->totalswap = P2K(val.totalswap); @@ -152,6 +152,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_mem_data, .data = &appldata_mem_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 2a4c7432db4a..075e619bf37d 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -5,12 +5,11 @@ * Collects accumulated network statistics (Packets received/transmitted, * dropped, errors, ...). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -152,6 +151,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_net_sum_data, .data = &appldata_net_sum_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index 99ddd3bf2fba..161acc5c8a1b 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/arch/s390/appldata/appldata_os.c @@ -4,12 +4,11 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects misc. OS related data (CPU utilization, running processes). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer <geraldsc@de.ibm.com> + * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -44,11 +43,14 @@ struct appldata_os_per_cpu { u32 per_cpu_system; /* ... spent in kernel mode */ u32 per_cpu_idle; /* ... spent in idle mode */ -// New in 2.6 --> + /* New in 2.6 */ u32 per_cpu_irq; /* ... spent in interrupts */ u32 per_cpu_softirq; /* ... spent in softirqs */ u32 per_cpu_iowait; /* ... spent while waiting for I/O */ -// <-- New in 2.6 + + /* New in modification level 01 */ + u32 per_cpu_steal; /* ... stolen by hypervisor */ + u32 cpu_id; /* number of this CPU */ } __attribute__((packed)); struct appldata_os_data { @@ -68,10 +70,9 @@ struct appldata_os_data { u32 avenrun[3]; /* average nr. of running processes during */ /* the last 1, 5 and 15 minutes */ -// New in 2.6 --> + /* New in 2.6 */ u32 nr_iowait; /* number of blocked threads (waiting for I/O) */ -// <-- New in 2.6 /* per cpu data */ struct appldata_os_per_cpu os_cpu[0]; @@ -79,6 +80,14 @@ struct appldata_os_data { static struct appldata_os_data *appldata_os_data; +static struct appldata_ops ops = { + .ctl_nr = CTL_APPLDATA_OS, + .name = "os", + .record_nr = APPLDATA_RECORD_OS_ID, + .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */ +}; + static inline void appldata_print_debug(struct appldata_os_data *os_data) { @@ -100,15 +109,17 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); for (i = 0; i < os_data->nr_cpus; i++) { P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " - "idle = %u, irq = %u, softirq = %u, iowait = %u\n", - i, + "idle = %u, irq = %u, softirq = %u, iowait = %u, " + "steal = %u\n", + os_data->os_cpu[i].cpu_id, os_data->os_cpu[i].per_cpu_user, os_data->os_cpu[i].per_cpu_nice, os_data->os_cpu[i].per_cpu_system, os_data->os_cpu[i].per_cpu_idle, os_data->os_cpu[i].per_cpu_irq, os_data->os_cpu[i].per_cpu_softirq, - os_data->os_cpu[i].per_cpu_iowait); + os_data->os_cpu[i].per_cpu_iowait, + os_data->os_cpu[i].per_cpu_steal); } P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); @@ -123,14 +134,13 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) */ static void appldata_get_os_data(void *data) { - int i, j; + int i, j, rc; struct appldata_os_data *os_data; + unsigned int new_size; os_data = data; os_data->sync_count_1++; - os_data->nr_cpus = num_online_cpus(); - os_data->nr_threads = nr_threads; os_data->nr_running = nr_running(); os_data->nr_iowait = nr_iowait(); @@ -154,9 +164,44 @@ static void appldata_get_os_data(void *data) cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); os_data->os_cpu[j].per_cpu_iowait = cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); + os_data->os_cpu[j].per_cpu_steal = + cputime_to_jiffies(kstat_cpu(i).cpustat.steal); + os_data->os_cpu[j].cpu_id = i; j++; } + os_data->nr_cpus = j; + + new_size = sizeof(struct appldata_os_data) + + (os_data->nr_cpus * sizeof(struct appldata_os_per_cpu)); + if (ops.size != new_size) { + if (ops.active) { + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_START_INTERVAL_REC, + (unsigned long) ops.data, new_size, + ops.mod_lvl); + if (rc != 0) { + P_ERROR("os: START NEW DIAG 0xDC failed, " + "return code: %d, new size = %i\n", rc, + new_size); + P_INFO("os: stopping old record now\n"); + } else + P_INFO("os: new record size = %i\n", new_size); + + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_STOP_REC, + (unsigned long) ops.data, ops.size, + ops.mod_lvl); + if (rc != 0) + P_ERROR("os: STOP OLD DIAG 0xDC failed, " + "return code: %d, old size = %i\n", rc, + ops.size); + else + P_INFO("os: old record size = %i stopped\n", + ops.size); + } + ops.size = new_size; + } os_data->timestamp = get_clock(); os_data->sync_count_2++; #ifdef APPLDATA_DEBUG @@ -165,15 +210,6 @@ static void appldata_get_os_data(void *data) } -static struct appldata_ops ops = { - .ctl_nr = CTL_APPLDATA_OS, - .name = "os", - .record_nr = APPLDATA_RECORD_OS_ID, - .callback = &appldata_get_os_data, - .owner = THIS_MODULE, -}; - - /* * appldata_os_init() * @@ -181,26 +217,25 @@ static struct appldata_ops ops = { */ static int __init appldata_os_init(void) { - int rc, size; + int rc, max_size; - size = sizeof(struct appldata_os_data) + - (NR_CPUS * sizeof(struct appldata_os_per_cpu)); - if (size > APPLDATA_MAX_REC_SIZE) { - P_ERROR("Size of record = %i, bigger than maximum (%i)!\n", - size, APPLDATA_MAX_REC_SIZE); + max_size = sizeof(struct appldata_os_data) + + (NR_CPUS * sizeof(struct appldata_os_per_cpu)); + if (max_size > APPLDATA_MAX_REC_SIZE) { + P_ERROR("Max. size of OS record = %i, bigger than maximum " + "record size (%i)\n", max_size, APPLDATA_MAX_REC_SIZE); rc = -ENOMEM; goto out; } - P_DEBUG("sizeof(os) = %i, sizeof(os_cpu) = %lu\n", size, + P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size, sizeof(struct appldata_os_per_cpu)); - appldata_os_data = kmalloc(size, GFP_DMA); + appldata_os_data = kzalloc(max_size, GFP_DMA); if (appldata_os_data == NULL) { P_ERROR("No memory for %s!\n", ops.name); rc = -ENOMEM; goto out; } - memset(appldata_os_data, 0, size); appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, @@ -208,7 +243,7 @@ static int __init appldata_os_init(void) P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); ops.data = appldata_os_data; - ops.size = size; + ops.callback = &appldata_get_os_data; rc = appldata_register_ops(&ops); if (rc != 0) { P_ERROR("Error registering ops, rc = %i\n", rc); diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 3f7018e9dbe4..ec514fe5ccd0 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -4,7 +4,6 @@ * and format the required data. */ -#include <linux/config.h> #include <linux/sched.h> /* Use marker if you need to separate the values later */ diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c index 1f451c2cb071..9565a2dcfadc 100644 --- a/arch/s390/kernel/binfmt_elf32.c +++ b/arch/s390/kernel/binfmt_elf32.c @@ -135,7 +135,6 @@ static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) #include <asm/processor.h> #include <linux/module.h> -#include <linux/config.h> #include <linux/elfcore.h> #include <linux/binfmts.h> #include <linux/compat.h> @@ -177,11 +176,6 @@ struct elf_prpsinfo32 #include <linux/highuid.h> -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) - #define elf_addr_t u32 /* #define init_elf_binfmt init_elf32_binfmt diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 5e14de37c17b..cabb4ff54cd7 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -16,7 +16,6 @@ */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/fs.h> diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 3898f66d0b2f..1a18e29668ef 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -1,7 +1,6 @@ #ifndef _ASM_S390X_S390_H #define _ASM_S390X_S390_H -#include <linux/config.h> #include <linux/compat.h> #include <linux/socket.h> #include <linux/syscalls.h> diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index b4c815d8ef75..d49b876a83bf 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -10,7 +10,6 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson */ -#include <linux/config.h> #include <linux/compat.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 06a3fbc12536..7ba20922a535 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -10,7 +10,6 @@ * Bugreports to: <Linux390@de.ibm.com> */ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index b2448487854c..d8948c342caf 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -11,7 +11,6 @@ #include <linux/sys.h> #include <linux/linkage.h> -#include <linux/config.h> #include <asm/cache.h> #include <asm/lowcore.h> #include <asm/errno.h> @@ -93,13 +92,22 @@ STACK_SIZE = 1 << STACK_SHIFT l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit bz BASED(2f) # skip stack setup save l %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + b BASED(3f) +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + bz BASED(stack_overflow) +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit bnz BASED(1f) # from user -> load async stack clc \psworg+4(4),BASED(.Lcritical_end) @@ -115,7 +123,6 @@ STACK_SIZE = 1 << STACK_SHIFT sra %r14,STACK_SHIFT be BASED(2f) 1: l %r15,__LC_ASYNC_STACK - .endif #ifdef CONFIG_CHECK_STACK b BASED(3f) 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -196,7 +203,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lh %r7,0x8a # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -221,8 +228,9 @@ sysc_do_svc: sysc_nr_ok: mvc SP_ARGS(4,%r15),SP_R7(%r15) sysc_do_restart: + l %r8,BASED(.Lsysc_table) tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. + l %r8,0(%r7,%r8) # get system call addr. bnz BASED(sysc_tracesys) basr %r14,%r8 # call sys_xxxx st %r2,SP_R2(%r15) # store return value (change R2 on stack) @@ -323,9 +331,10 @@ sysc_tracesys: basr %r14,%r1 clc SP_R2(4,%r15),BASED(.Lnr_syscalls) bnl BASED(sysc_tracenogo) + l %r8,BASED(.Lsysc_table) l %r7,SP_R2(%r15) # strace might have changed the sll %r7,2 # system call - l %r8,sys_call_table-system_call(%r7,%r13) + l %r8,0(%r7,%r8) sysc_tracego: lm %r3,%r6,SP_R3(%r15) l %r2,SP_ORIG_R2(%r15) @@ -425,7 +434,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception bnz BASED(pgm_per) # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -464,7 +473,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -490,7 +499,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -519,7 +528,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -631,7 +640,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -657,21 +666,31 @@ __critical_end: .globl mcck_int_handler mcck_int_handler: spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - bo BASED(0f) - spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + bo BASED(1f) + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + bl BASED(0f) + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + bl BASED(0f) + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + bl BASED(0f) + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? bno BASED(mcck_int_main) # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit bnz BASED(mcck_int_main) # from user -> load async stack @@ -691,7 +710,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -715,6 +734,20 @@ mcck_no_vtime: l %r1,BASED(.Ls390_handle_mcck) basr %r14,%r1 # call machine check handler mcck_return: + mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + bno BASED(0f) + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + stpt __LC_EXIT_TIMER + lpsw __LC_RETURN_MCCK_PSW # back to caller +0: +#endif + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + lpsw __LC_RETURN_MCCK_PSW # back to caller + RESTORE_ALL __LC_RETURN_MCCK_PSW,0 #ifdef CONFIG_SMP @@ -781,6 +814,8 @@ cleanup_table_sysc_leave: .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 cleanup_table_sysc_work_loop: .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 +cleanup_table_io_return: + .long io_return + 0x80000000, io_leave + 0x80000000 cleanup_table_io_leave: .long io_leave + 0x80000000, io_done + 0x80000000 cleanup_table_io_work_loop: @@ -807,6 +842,11 @@ cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) bl BASED(cleanup_sysc_return) 0: + clc 4(4,%r12),BASED(cleanup_table_io_return) + bl BASED(0f) + clc 4(4,%r12),BASED(cleanup_table_io_return+4) + bl BASED(cleanup_io_return) +0: clc 4(4,%r12),BASED(cleanup_table_io_leave) bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_io_leave+4) @@ -839,7 +879,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(16),0(%r12) 0: st %r13,4(%r12) st %r12,__LC_SAVE_AREA+48 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA l %r12,__LC_SAVE_AREA+48 # argh st %r15,12(%r12) @@ -971,6 +1011,7 @@ cleanup_io_leave_insn: .Ltrace: .long syscall_trace .Lvfork: .long sys_vfork .Lschedtail: .long schedule_tail +.Lsysc_table: .long sys_call_table .Lcritical_start: .long __critical_start + 0x80000000 @@ -979,9 +1020,8 @@ cleanup_io_leave_insn: .Lcleanup_critical: .long cleanup_critical + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esa - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL - diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 2ac095bc0e25..1ca499fa54b4 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -11,7 +11,6 @@ #include <linux/sys.h> #include <linux/linkage.h> -#include <linux/config.h> #include <asm/cache.h> #include <asm/lowcore.h> #include <asm/errno.h> @@ -87,13 +86,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ larl %r13,system_call .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit jz 2f # skip stack setup save lg %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + j 3f +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + jz stack_overflow +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit jnz 1f # from user -> load kernel stack clc \psworg+8(8),BASED(.Lcritical_end) @@ -108,7 +116,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ srag %r14,%r14,STACK_SHIFT jz 2f 1: lg %r15,__LC_ASYNC_STACK # load async stack - .endif #ifdef CONFIG_CHECK_STACK j 3f 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -187,7 +194,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -446,7 +453,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception jnz pgm_per # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -485,7 +492,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -511,7 +518,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -539,7 +546,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -647,7 +654,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -672,21 +679,32 @@ __critical_end: mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1) lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+64 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - jo 0f - spt __LC_LAST_UPDATE_TIMER #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + la %r14,4095 + mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + jo 1f + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + jl 0f + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + jl 0f + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + jl 0f + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit jnz mcck_int_main # from user -> load kernel stack @@ -705,7 +723,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? jno mcck_no_vtime # no -> no timer update - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz mcck_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -727,7 +745,17 @@ mcck_no_vtime: jno mcck_return brasl %r14,s390_handle_mcck mcck_return: - RESTORE_ALL __LC_RETURN_MCCK_PSW,0 + mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit + lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + jno 0f + stpt __LC_EXIT_TIMER +0: +#endif + lpswe __LC_RETURN_MCCK_PSW # back to caller #ifdef CONFIG_SMP /* @@ -789,6 +817,8 @@ cleanup_table_sysc_leave: .quad sysc_leave, sysc_work_loop cleanup_table_sysc_work_loop: .quad sysc_work_loop, sysc_reschedule +cleanup_table_io_return: + .quad io_return, io_leave cleanup_table_io_leave: .quad io_leave, io_done cleanup_table_io_work_loop: @@ -815,6 +845,11 @@ cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) jl cleanup_sysc_return 0: + clc 8(8,%r12),BASED(cleanup_table_io_return) + jl 0f + clc 8(8,%r12),BASED(cleanup_table_io_return+8) + jl cleanup_io_return +0: clc 8(8,%r12),BASED(cleanup_table_io_leave) jl 0f clc 8(8,%r12),BASED(cleanup_table_io_leave+8) @@ -847,7 +882,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(32),0(%r12) 0: stg %r13,8(%r12) stg %r12,__LC_SAVE_AREA+96 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lg %r12,__LC_SAVE_AREA+96 # argh stg %r15,24(%r12) @@ -956,8 +991,8 @@ cleanup_io_leave_insn: .Lcritical_end: .quad __critical_end + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esame - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL @@ -965,7 +1000,6 @@ sys_call_table: #ifdef CONFIG_COMPAT #define SYSCALL(esa,esame,emu) .long emu - .globl sys_call_table_emu sys_call_table_emu: #include "syscalls.S" #undef SYSCALL diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ea88d066bf04..adad8863ee2f 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head.S * - * (C) Copyright IBM Corp. 1999, 2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -23,7 +23,6 @@ * */ -#include <linux/config.h> #include <asm/setup.h> #include <asm/lowcore.h> #include <asm/asm-offsets.h> @@ -482,24 +481,23 @@ start: .macro GET_IPL_DEVICE .Lget_ipl_device: - basr %r12,0 -.LGID: l %r1,0xb8 # get sid + l %r1,0xb8 # get sid sll %r1,15 # test if subchannel is enabled srl %r1,31 ltr %r1,%r1 - bz 0(%r14) # subchannel disabled + bz 2f-.LPG1(%r13) # subchannel disabled l %r1,0xb8 - la %r5,.Lipl_schib-.LGID(%r12) + la %r5,.Lipl_schib-.LPG1(%r13) stsch 0(%r5) # get schib of subchannel - bnz 0(%r14) # schib not available + bnz 2f-.LPG1(%r13) # schib not available tm 5(%r5),0x01 # devno valid? - bno 0(%r14) - la %r6,ipl_parameter_flags-.LGID(%r12) + bno 2f-.LPG1(%r13) + la %r6,ipl_parameter_flags-.LPG1(%r13) oi 3(%r6),0x01 # set flag - la %r2,ipl_devno-.LGID(%r12) + la %r2,ipl_devno-.LPG1(%r13) mvc 0(2,%r2),6(%r5) # store devno tm 4(%r5),0x80 # qdio capable device? - bno 0(%r14) + bno 2f-.LPG1(%r13) oi 3(%r6),0x02 # set flag # copy ipl parameters @@ -523,7 +521,7 @@ start: ar %r2,%r1 sr %r0,%r4 jne 1b - b 0(%r14) + b 2f-.LPG1(%r13) .align 4 .Lipl_schib: @@ -537,6 +535,7 @@ ipl_parameter_flags: .globl ipl_devno ipl_devno: .word 0 +2: .endm #ifdef CONFIG_64BIT diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2d3b089bfb83..d00de17b3778 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head31.S * - * (C) Copyright IBM Corp. 2005 + * Copyright (C) IBM Corp. 2005,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -16,12 +16,31 @@ # or linload or SALIPL # .org 0x10000 -startup:basr %r13,0 # get base -.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) - basr %r14, %r1 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .long 0,0 # IPL_DEVICE + .long 0,RAMDISK_ORIGIN # INITRD_START + .long 0,RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base +.LPG1: GET_IPL_DEVICE lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - la %r12,_pstart-.LPG1(%r13) # pointer to parameter area - # move IPL device to lowcore + l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area + # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) # @@ -51,8 +70,8 @@ startup:basr %r13,0 # get base a %r1,__LC_EXT_NEW_PSW+4 # set handler st %r1,__LC_EXT_NEW_PSW+4 - la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff - la %r1, .Lsccb-PARMAREA(%r4) # our sccb + l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff + lr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -63,7 +82,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpsw .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -74,7 +93,7 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lhi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd lhi %r1,0x800 # otherwise report 2GB .Lscnd: @@ -84,10 +103,10 @@ startup:basr %r13,0 # get base lr %r1,%r3 .Lno2gb: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -95,8 +114,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,6 +259,8 @@ startup:basr %r13,0 # get base .long 0 # cr13: home space segment table .long 0xc0000000 # cr14: machine check handling off .long 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp @@ -252,25 +271,9 @@ startup:basr %r13,0 # get base .Lmflags:.long machine_flags .Lbss_bgn: .long __bss_start .Lbss_end: .long _end - - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .long 0,0 # IPL_DEVICE - .long 0,RAMDISK_ORIGIN # INITRD_START - .long 0,RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 +.Lparmaddr: .long PARMAREA +.Lsccbaddr: .long .Lsccb + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -287,18 +290,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f08c06f45d5c..47744fcca930 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head64.S * - * (C) Copyright IBM Corp. 1999,2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner <hp@de.ibm.com> * Martin Schwidefsky <schwidefsky@de.ibm.com> @@ -15,18 +15,37 @@ # this is called either by the ipl loader or directly by PSW restart # or linload or SALIPL # - .org 0x10000 -startup:basr %r13,0 # get base + .org 0x10000 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .quad 0 # IPL_DEVICE + .quad RAMDISK_ORIGIN # INITRD_START + .quad RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base .LPG1: sll %r13,1 # remove high order bit srl %r13,1 - l %r1,.Lget_ipl_device_addr-.LPG1(%r13) - basr %r14,%r1 + GET_IPL_DEVICE lhi %r1,1 # mode 1 = esame slr %r0,%r0 # set cpuid to zero sigp %r1,%r0,0x12 # switch to esame mode sam64 # switch to 64 bit mode lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - larl %r12,_pstart # pointer to parameter area + lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) @@ -55,8 +74,8 @@ startup:basr %r13,0 # get base larl %r1,.Lsclph stg %r1,__LC_EXT_NEW_PSW+8 # set handler - larl %r4,_pstart # %r4 is our index for sccb stuff - la %r1,.Lsccb-PARMAREA(%r4) # our sccb + larl %r4,.Lsccb # %r4 is our index for sccb stuff + lgr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -67,7 +86,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpswe .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -78,15 +97,15 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lghi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd - lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one + lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one .Lscnd: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mlgr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -94,8 +113,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,29 +259,16 @@ startup:basr %r13,0 # get base .quad 0 # cr13: home space segment table .quad 0xc0000000 # cr14: machine check handling off .quad 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmsk:.quad 0x0000000180000000 .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 +.Lparmaddr: + .quad PARMAREA - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .quad 0 # IPL_DEVICE - .quad RAMDISK_ORIGIN # INITRD_START - .quad RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -281,18 +285,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base @@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base .align 8 .Ldw: .quad 0x0002000180000000,0x0000000000000000 .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 4a0f5a1551ea..1f9399191794 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -15,7 +15,6 @@ * This file handles the architecture-dependent parts of process handling.. */ -#include <linux/config.h> #include <linux/compiler.h> #include <linux/cpu.h> #include <linux/errno.h> diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 4176c77670c4..c73a45467fa4 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -3,7 +3,6 @@ * * S390 version */ -#include <linux/config.h> #include <linux/highuid.h> #include <linux/module.h> #include <linux/mm.h> @@ -46,8 +45,6 @@ EXPORT_SYMBOL(__down_interruptible); */ extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(overflowuid); -EXPORT_SYMBOL(overflowgid); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b282034452a4..1ca34f54ea8a 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -28,7 +28,6 @@ #include <linux/tty.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/initrd.h> #include <linux/bootmem.h> @@ -37,6 +36,7 @@ #include <linux/seq_file.h> #include <linux/kernel_stat.h> #include <linux/device.h> +#include <linux/notifier.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -115,6 +115,7 @@ void __devinit cpu_init (void) */ char vmhalt_cmd[128] = ""; char vmpoff_cmd[128] = ""; +char vmpanic_cmd[128] = ""; static inline void strncpy_skip_quote(char *dst, char *src, int n) { @@ -146,6 +147,38 @@ static int __init vmpoff_setup(char *str) __setup("vmpoff=", vmpoff_setup); +static int vmpanic_notify(struct notifier_block *self, unsigned long event, + void *data) +{ + if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) + cpcmd(vmpanic_cmd, NULL, 0, NULL); + + return NOTIFY_OK; +} + +#define PANIC_PRI_VMPANIC 0 + +static struct notifier_block vmpanic_nb = { + .notifier_call = vmpanic_notify, + .priority = PANIC_PRI_VMPANIC +}; + +static int __init vmpanic_setup(char *str) +{ + static int register_done __initdata = 0; + + strncpy_skip_quote(vmpanic_cmd, str, 127); + vmpanic_cmd[127] = 0; + if (!register_done) { + register_done = 1; + atomic_notifier_chain_register(&panic_notifier_list, + &vmpanic_nb); + } + return 1; +} + +__setup("vmpanic=", vmpanic_setup); + /* * condev= and conmode= setup parameter. */ @@ -289,19 +322,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; void machine_restart(char *command) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_restart(command); } void machine_halt(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_halt(); } void machine_power_off(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_power_off(); } diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index d48cfc726b68..a887b686f279 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -11,7 +11,6 @@ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <linux/smp.h> diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 2a6c6efb6865..f7fe9bc43397 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -12,7 +12,6 @@ * Copyright (C) 1991, 1992, 1995 Linus Torvalds */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/sched.h> diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index a46793beeddd..12240c03a6dd 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -14,7 +14,6 @@ * 'Traps.c' handles hardware traps and faults after we have saved some * state in 'asm.s'. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/string.h> @@ -150,13 +149,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) unsigned long *stack; int i; - // debugging aid: "show_stack(NULL);" prints the - // back trace for this cpu. - if (!sp) - sp = task ? (unsigned long *) task->thread.ksp : __r15; + stack = task ? (unsigned long *) task->thread.ksp : __r15; + else + stack = sp; - stack = sp; for (i = 0; i < kstack_depth_to_print; i++) { if (((addr_t) stack & (THREAD_SIZE-1)) == 0) break; diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 9f34bb54c051..ff5f7bb34f75 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -3,7 +3,6 @@ */ #include <asm-generic/vmlinux.lds.h> -#include <linux/config.h> #ifndef CONFIG_64BIT OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 1f0439dc245a..2306cd83fca1 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -7,7 +7,6 @@ * Author(s): Jan Glauber <jan.glauber@de.ibm.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/time.h> diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 71f0a2fb3078..468f4ea33f99 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -11,7 +11,6 @@ * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/delay.h> diff --git a/arch/s390/math-emu/math.c b/arch/s390/math-emu/math.c index 648df7140335..b4957c84e4d6 100644 --- a/arch/s390/math-emu/math.c +++ b/arch/s390/math-emu/math.c @@ -9,7 +9,6 @@ * that does not have the IEEE fpu (all processors before G5). */ -#include <linux/config.h> #include <linux/types.h> #include <linux/sched.h> #include <linux/mm.h> diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 51596f429235..81be2fec7dc5 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -8,7 +8,6 @@ * Collaborative memory management interface. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/fs.h> #include <linux/init.h> diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 81ade401b073..833d5941746a 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -10,7 +10,6 @@ * Copyright (C) 1995 Linus Torvalds */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index a055894f3bd8..eb6ebfef134a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -9,7 +9,6 @@ * Copyright (C) 1995 Linus Torvalds */ -#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -24,6 +23,7 @@ #include <linux/init.h> #include <linux/pagemap.h> #include <linux/bootmem.h> +#include <linux/pfn.h> #include <asm/processor.h> #include <asm/system.h> @@ -34,6 +34,7 @@ #include <asm/lowcore.h> #include <asm/tlb.h> #include <asm/tlbflush.h> +#include <asm/sections.h> DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -90,17 +91,6 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } -/* References to section boundaries */ - -extern unsigned long _text; -extern unsigned long _etext; -extern unsigned long _edata; -extern unsigned long __bss_start; -extern unsigned long _end; - -extern unsigned long __init_begin; -extern unsigned long __init_end; - extern unsigned long __initdata zholes_size[]; /* * paging_init() sets up the page tables @@ -117,6 +107,10 @@ void __init paging_init(void) unsigned long pfn = 0; unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; static const int ssm_mask = 0x04000000L; + unsigned long ro_start_pfn, ro_end_pfn; + + ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); + ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); /* unmap whole virtual address space */ @@ -144,7 +138,10 @@ void __init paging_init(void) pg_dir++; for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { - pte = pfn_pte(pfn, PAGE_KERNEL); + if (pfn >= ro_start_pfn && pfn < ro_end_pfn) + pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); + else + pte = pfn_pte(pfn, PAGE_KERNEL); if (pfn >= max_low_pfn) pte_clear(&init_mm, 0, &pte); set_pte(pg_table, pte); @@ -176,6 +173,7 @@ void __init paging_init(void) } #else /* CONFIG_64BIT */ + void __init paging_init(void) { pgd_t * pg_dir; @@ -187,13 +185,15 @@ void __init paging_init(void) unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; static const int ssm_mask = 0x04000000L; - unsigned long zones_size[MAX_NR_ZONES]; unsigned long dma_pfn, high_pfn; + unsigned long ro_start_pfn, ro_end_pfn; memset(zones_size, 0, sizeof(zones_size)); dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; high_pfn = max_low_pfn; + ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); + ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); if (dma_pfn > high_pfn) zones_size[ZONE_DMA] = high_pfn; @@ -232,7 +232,10 @@ void __init paging_init(void) pmd_populate_kernel(&init_mm, pm_dir, pt_dir); for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { - pte = pfn_pte(pfn, PAGE_KERNEL); + if (pfn >= ro_start_pfn && pfn < ro_end_pfn) + pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); + else + pte = pfn_pte(pfn, PAGE_KERNEL); if (pfn >= max_low_pfn) { pte_clear(&init_mm, 0, &pte); continue; @@ -283,6 +286,9 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT-10), datasize >>10, initsize >> 10); + printk("Write protected kernel read-only data: %#lx - %#lx\n", + (unsigned long)&__start_rodata, + PFN_ALIGN((unsigned long)&__end_rodata) - 1); } void free_initmem(void) |