Commit c1997c8d authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s/390 patches for 2.5.20 (1 of 4).

This first patch contains the changes to arch/{s390,s390x}
parent 0af38de4
......@@ -155,7 +155,10 @@ CONFIG_IPL
IPL device.
CONFIG_IPL_TAPE
Select this option if you want to IPL the image from a Tape.
Select "tape" if you want to IPL the image from a Tape.
Select "vm_reader" if you are running under VM/ESA and want
to IPL the image from the emulated card reader.
CONFIG_FAST_IRQ
Select this option in order to get the interrupts processed faster
......@@ -164,8 +167,57 @@ CONFIG_FAST_IRQ
interrupts which will also be processed before leaving the interrupt
context. This speeds up the I/O a lot. Say "Y".
CONFIG_MACHCHK_WARNING
Select this option if you want the machine check handler on IBM S/390 or
zSeries to process warning machine checks (e.g. on power failures).
If unsure, say "Y".
CONFIG_CHSC
Select this option if you want the s390 common I/O layer to use information
obtained by channel subsystem calls. This will enable Linux to process link
failures and resource accessibility events. Moreover, if you have procfs
enabled, you'll be able to toggle chpids logically offline and online. Even
if you don't understand what this means, you should say "Y".
CONFIG_PROCESS_DEBUG
Say Y to print all process fault locations to the console. This is
a debugging option; you probably do not want to set it unless you
are an S390 port maintainer.
CONFIG_PFAULT
Select this option, if you want to use PFAULT pseudo page fault
handling under VM. If running native or in LPAR, this option
has no effect. If your VM does not support PFAULT, PAGEEX
pseudo page fault handling will be used.
Note that VM 4.2 supports PFAULT but has a bug in its
implementation that causes some problems.
Everybody who wants to run Linux under VM != VM4.2 should select
this option.
CONFIG_SHARED_KERNEL
Select this option, if you want to share the text segment of the
Linux kernel between different VM guests. This reduces memory
usage with lots of guests but greatly increases kernel size.
You should only select this option if you know what you are
doing and want to exploit this feature.
CONFIG_QDIO
This driver provides the Queued Direct I/O base support for the
IBM S/390 (G5 and G6) and eServer zSeries (z800 and z900).
For details please refer to the documentation provided by IBM at
<http://www10.software.ibm.com/developerworks/opensource/linux390>
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called qdio.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
If unsure, say Y.
Performance statistics for QDIO base support
CONFIG_QDIO_PERF_STATS
Say Y here to get performance statistics in /proc/qdio_perf
If unsure, say N.
#
# s390/Makefile
#
# This file is included by the global makefile so that you can add your own
......@@ -14,14 +14,14 @@
#
LD=$(CROSS_COMPILE)ld -m elf_s390
CPP=$(CC) -E
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e start
ifeq ($(CONFIG_SHARED_KERNEL),y)
LINKFLAGS =-T $(TOPDIR)/arch/s390/vmlinux-shared.lds $(LDFLAGS)
LINKSCRIPT := arch/s390/vmlinux-shared.lds
else
LINKFLAGS =-T $(TOPDIR)/arch/s390/vmlinux.lds $(LDFLAGS)
LINKSCRIPT := arch/s390/vmlinux.lds
endif
LINKFLAGS =-T $(TOPDIR)/$(LINKSCRIPT) $(LDFLAGS)
CFLAGS_PIPE := -pipe
CFLAGS_NSR := -fno-strength-reduce
......@@ -29,14 +29,15 @@ CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
HEAD := arch/s390/kernel/head.o arch/s390/kernel/init_task.o
SUBDIRS := $(SUBDIRS) arch/s390/mm arch/s390/kernel arch/s390/lib \
drivers/s390 arch/s390/math-emu
SUBDIRS += arch/s390/mm arch/s390/kernel arch/s390/lib drivers/s390
CORE_FILES := arch/s390/mm/mm.o arch/s390/kernel/kernel.o $(CORE_FILES)
DRIVERS := $(DRIVERS) drivers/s390/built-in.o
LIBS := $(TOPDIR)/arch/s390/lib/lib.a $(LIBS) $(TOPDIR)/arch/s390/lib/lib.a
DRIVERS += drivers/s390/built-in.o
ifeq ($(CONFIG_MATHEMU),y)
CORE_FILES := $(CORE_FILES) arch/s390/math-emu/math-emu.o
SUBDIRS += arch/s390/math-emu
DRIVERS += arch/s390/math-emu/math-emu.o
endif
all: image listing
......@@ -46,13 +47,19 @@ listing: vmlinux
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: $(LINKSCRIPT)
image: vmlinux
@$(MAKEBOOT) image
archclean:
@$(MAKEBOOT) clean
$(MAKE) -C arch/$(ARCH)/kernel clean
archmrproper:
archdep:
@$(MAKEBOOT) dep
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=image install
......@@ -4,8 +4,6 @@
OBJCOPY = $(CROSS_COMPILE)objcopy
O_TARGET :=
EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
......@@ -29,3 +27,6 @@ dep:
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map $(TOPDIR)/Kerntypes "$(INSTALL_PATH)"
#!/bin/sh
#
# arch/s390x/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1995 by Linus Torvalds
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
#
# "make install" script for s390 architecture
#
# Arguments:
# $1 - kernel version
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
#
# User may have a custom install script
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
if [ -f $4/System.map ]; then
mv $4/System.map $4/System.old
fi
cat $2 > $4/vmlinuz
cp $3 $4/System.map
......@@ -7,8 +7,8 @@ define_bool CONFIG_ISA n
define_bool CONFIG_EISA n
define_bool CONFIG_MCA n
define_bool CONFIG_UID16 y
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
define_bool CONFIG_GENERIC_BUST_SPINLOCK n
mainmenu_name "Linux Kernel Configuration"
......@@ -23,8 +23,16 @@ bool 'IEEE FPU emulation' CONFIG_MATHEMU
endmenu
mainmenu_option next_comment
comment 'General setup'
comment 'Base setup'
bool 'Fast IRQ handling' CONFIG_FAST_IRQ
bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING
bool 'Use chscs for Common I/O' CONFIG_CHSC
tristate 'QDIO support' CONFIG_QDIO
if [ "$CONFIG_QDIO" != "n" ]; then
bool ' Performance statistics in /proc' CONFIG_QDIO_PERF_STATS
fi
bool 'Builtin IPL record support' CONFIG_IPL
if [ "$CONFIG_IPL" = "y" ]; then
choice 'IPL method generated into head.S' \
......@@ -39,6 +47,16 @@ bool 'Pseudo page fault support' CONFIG_PFAULT
bool 'VM shared kernel support' CONFIG_SHARED_KERNEL
endmenu
mainmenu_option next_comment
comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
fi
endmenu
source drivers/s390/Config.in
if [ "$CONFIG_NET" = "y" ]; then
......@@ -51,9 +69,9 @@ mainmenu_option next_comment
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
if [ "$CONFIG_CTC" = "y" ]; then
bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
fi
#if [ "$CONFIG_CTC" = "y" ]; then
# bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
#fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
endmenu
......
......@@ -5,9 +5,9 @@
# CONFIG_EISA is not set
# CONFIG_MCA is not set
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_GENERIC_BUST_SPINLOCK=n
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_GENERIC_BUST_SPINLOCK is not set
CONFIG_ARCH_S390=y
#
......@@ -15,6 +15,14 @@ CONFIG_ARCH_S390=y
#
CONFIG_EXPERIMENTAL=y
#
# General setup
#
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
#
# Loadable module support
#
......@@ -29,16 +37,16 @@ CONFIG_SMP=y
CONFIG_MATHEMU=y
#
# General setup
# Base setup
#
CONFIG_FAST_IRQ=y
CONFIG_MACHCHK_WARNING=y
CONFIG_CHSC=y
CONFIG_QDIO=m
# CONFIG_QDIO_PERF_STATS is not set
CONFIG_IPL=y
# CONFIG_IPL_TAPE is not set
CONFIG_IPL_VM=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
......@@ -46,6 +54,77 @@ CONFIG_BINFMT_ELF=y
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
#
# SCSI support
#
CONFIG_SCSI=m
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=m
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_SR_EXTRA_DEVS=10
CONFIG_CHR_DEV_SG=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
#
# SCSI low-level drivers
#
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
#
# PCMCIA SCSI adapter support
#
# CONFIG_SCSI_PCMCIA is not set
#
# Block device drivers
#
......@@ -103,8 +182,8 @@ CONFIG_S390_TAPE_BLOCK=y
#
# S/390 tape hardware support
#
CONFIG_S390_TAPE_3490=y
CONFIG_S390_TAPE_3480=y
CONFIG_S390_TAPE_3490=m
CONFIG_S390_TAPE_3480=m
#
# Network device drivers
......@@ -123,6 +202,7 @@ CONFIG_TR=y
#
CONFIG_CHANDEV=y
CONFIG_HOTPLUG=y
CONFIG_LCS=m
CONFIG_CTC=m
CONFIG_IUCV=m
......@@ -131,8 +211,6 @@ CONFIG_IUCV=m
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK=y
# CONFIG_RTNETLINK is not set
# CONFIG_NETLINK_DEV is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
......@@ -144,18 +222,24 @@ CONFIG_IP_MULTICAST=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
CONFIG_IPV6=m
# CONFIG_IPV6_NETLINK is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
#
# Appletalk devices
#
# CONFIG_DEV_APPLETALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
......@@ -164,7 +248,7 @@ CONFIG_IPV6=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
CONFIG_NET_FASTROUTE=y
# CONFIG_NET_HW_FLOWCONTROL is not set
#
......@@ -176,18 +260,20 @@ CONFIG_IPV6=m
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_CMS_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
......@@ -198,12 +284,15 @@ CONFIG_IPV6=m
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_TMPFS is not set
# CONFIG_RAMFS is not set
CONFIG_RAMFS=y
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_FREEVXFS_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_DEBUG is not set
# CONFIG_HPFS_FS is not set
......@@ -232,8 +321,10 @@ CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
CONFIG_NFSD=y
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
......@@ -245,7 +336,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
# CONFIG_ZISOFS_FS is not set
# CONFIG_ZLIB_FS_INFLATE is not set
#
# Partition Types
......@@ -262,6 +352,7 @@ CONFIG_IBM_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
......@@ -269,3 +360,10 @@ CONFIG_IBM_PARTITION=y
# Kernel hacking
#
CONFIG_MAGIC_SYSRQ=y
#
# Library routines
#
# CONFIG_CRC32 is not set
# CONFIG_ZLIB_INFLATE is not set
# CONFIG_ZLIB_DEFLATE is not set
......@@ -2,8 +2,10 @@
# Makefile for the linux kernel.
#
O_TARGET := kernel.o
EXTRA_TARGETS := head.o init_task.o
EXTRA_AFLAGS := -traditional
O_TARGET := kernel.o
export-objs := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o
obj-y := entry.o bitmap.o traps.o time.o process.o irq.o \
......@@ -18,7 +20,27 @@ obj-$(CONFIG_SMP) += smp.o
#
obj-$(CONFIG_REMOTE_DEBUG) += gdb-stub.o #gdb-low.o
EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
.PHONY: asm-offsets.h
entry.S: asm-offsets.h
asm-offsets.h: asm-offsets.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o - | grep -- "->" | \
(echo "#ifndef __ASM_OFFSETS_H__"; \
echo "#define __ASM_OFFSETS_H__"; \
echo "/*"; \
echo " * DO NOT MODIFY"; \
echo " *"; \
echo " * This file was generated by arch/s390/kernel/Makefile"; \
echo " */"; \
sed -e "s:^->\([^ ]*\) \([^ ]*\) \(.*\):#define \\1 \\2 /* \\3*/:" \
-e "s:->::"; \
echo "#endif" \
) > asm-offsets.h
clean:
rm -f asm-offsets.h
/*
* Generate definitions needed by assembly language modules.
* This code generates raw asm output which is post-processed to extract
* and format the required data.
*/
#include <linux/config.h>
#include <linux/sched.h>
/* Use marker if you need to separate the values later */
#define DEFINE(sym, val, marker) \
asm volatile("\n->" #sym " %0 " #val " " #marker : : "i" (val))
#define BLANK() asm volatile("\n->" : : )
int main(void)
{
DEFINE(__THREAD_info, offsetof(struct task_struct, thread_info),);
DEFINE(__THREAD_ar2, offsetof(struct task_struct, thread.ar2),);
DEFINE(__THREAD_ar4, offsetof(struct task_struct, thread.ar4),);
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),);
DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),);
BLANK();
DEFINE(__TI_task, offsetof(struct thread_info, task),);
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain),);
DEFINE(__TI_flags, offsetof(struct thread_info, flags),);
DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),);
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),);
return 0;
}
......@@ -35,3 +35,22 @@ _zb_findmap:
.byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
.byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
.globl _sb_findmap
_sb_findmap:
.byte 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
.byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
......@@ -68,12 +68,6 @@ static ssize_t debug_input(struct file *file, const char *user_buf,
size_t user_len, loff_t * offset);
static int debug_open(struct inode *inode, struct file *file);
static int debug_close(struct inode *inode, struct file *file);
static struct proc_dir_entry
*debug_create_proc_dir_entry(struct proc_dir_entry *root,
const char *name, mode_t mode,
struct file_operations *fops);
static void debug_delete_proc_dir_entry(struct proc_dir_entry *root,
struct proc_dir_entry *entry);
static debug_info_t* debug_info_create(char *name, int page_order, int nr_areas, int buf_size);
static void debug_info_get(debug_info_t *);
static void debug_info_put(debug_info_t *);
......@@ -155,7 +149,6 @@ DECLARE_MUTEX(debug_lock);
static int initialized = 0;
static struct file_operations debug_file_ops = {
owner: THIS_MODULE,
read: debug_output,
write: debug_input,
open: debug_open,
......@@ -217,8 +210,10 @@ static debug_info_t* debug_info_alloc(char *name, int page_order,
strncpy(rc->name, name, MIN(strlen(name), (DEBUG_MAX_PROCF_LEN - 1)));
rc->name[MIN(strlen(name), (DEBUG_MAX_PROCF_LEN - 1))] = 0;
memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
#ifdef CONFIG_PROC_FS
memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS *
sizeof(struct proc_dir_entry*));
#endif /* CONFIG_PROC_FS */
atomic_set(&(rc->ref_count), 0);
return rc;
......@@ -265,11 +260,9 @@ static debug_info_t* debug_info_create(char *name, int page_order,
/* create proc rood directory */
rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry);
/* append new element to linked list */
if (debug_area_first == NULL) {
/* first element in list */
debug_area_first = rc;
......@@ -331,16 +324,22 @@ static void debug_info_put(debug_info_t *db_info)
if (!db_info)
return;
if (atomic_dec_and_test(&db_info->ref_count)) {
#ifdef DEBUG
printk(KERN_INFO "debug: freeing debug area %p (%s)\n",
db_info, db_info->name);
#endif
for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
if (db_info->views[i] != NULL)
debug_delete_proc_dir_entry
(db_info->proc_root_entry,
db_info->proc_entries[i]);
if (db_info->views[i] == NULL)
continue;
#ifdef CONFIG_PROC_FS
remove_proc_entry(db_info->proc_entries[i]->name,
db_info->proc_root_entry);
#endif
}
debug_delete_proc_dir_entry(debug_proc_root_entry,
db_info->proc_root_entry);
#ifdef CONFIG_PROC_FS
remove_proc_entry(db_info->proc_root_entry->name,
debug_proc_root_entry);
#endif
if(db_info == debug_area_first)
debug_area_first = db_info->next;
if(db_info == debug_area_last)
......@@ -497,6 +496,7 @@ static int debug_open(struct inode *inode, struct file *file)
#ifdef DEBUG
printk("debug_open\n");
#endif
MOD_INC_USE_COUNT;
down(&debug_lock);
/* find debug log and view */
......@@ -524,14 +524,18 @@ static int debug_open(struct inode *inode, struct file *file)
debug_info_snapshot = debug_info_copy(debug_info);
if(!debug_info_snapshot){
#ifdef DEBUG
printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n");
#endif
rc = -ENOMEM;
goto out;
}
if ((file->private_data =
kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) {
#ifdef DEBUG
printk(KERN_ERR "debug_open: kmalloc failed\n");
#endif
debug_info_free(debug_info_snapshot);
rc = -ENOMEM;
goto out;
......@@ -549,6 +553,8 @@ static int debug_open(struct inode *inode, struct file *file)
out:
up(&debug_lock);
if (rc != 0)
MOD_DEC_USE_COUNT;
return rc;
}
......@@ -568,35 +574,10 @@ static int debug_close(struct inode *inode, struct file *file)
debug_info_free(p_info->debug_info_snap);
debug_info_put(p_info->debug_info_org);
kfree(file->private_data);
MOD_DEC_USE_COUNT;
return 0; /* success */
}
/*
* debug_create_proc_dir_entry:
* - initializes proc-dir-entry and registers it
*/
static struct proc_dir_entry *debug_create_proc_dir_entry
(struct proc_dir_entry *root, const char *name, mode_t mode,
struct file_operations *fops)
{
struct proc_dir_entry *rc = create_proc_entry(name, mode, root);
if (rc && fops)
rc->proc_fops = fops;
return rc;
}
/*
* delete_proc_dir_entry:
*/
static void debug_delete_proc_dir_entry
(struct proc_dir_entry *root, struct proc_dir_entry *proc_entry)
{
remove_proc_entry(proc_entry->name, root);
}
/*
* debug_register:
* - creates and initializes debug area for the caller
......@@ -620,9 +601,11 @@ debug_info_t *debug_register
goto out;
debug_register_view(rc, &debug_level_view);
debug_register_view(rc, &debug_flush_view);
#ifdef DEBUG
printk(KERN_INFO
"debug: reserved %d areas of %d pages for debugging %s\n",
nr_areas, 1 << page_order, rc->name);
#endif
out:
if (rc == NULL){
printk(KERN_ERR "debug: debug_register failed for %s\n",name);
......@@ -642,7 +625,9 @@ void debug_unregister(debug_info_t * id)
if (!id)
goto out;
down(&debug_lock);
#ifdef DEBUG
printk(KERN_INFO "debug: unregistering %s\n", id->name);
#endif
debug_info_put(id);
up(&debug_lock);
......@@ -849,7 +834,9 @@ int debug_init(void)
down(&debug_lock);
if (!initialized) {
#ifdef CONFIG_PROC_FS
debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
#endif /* CONFIG_PROC_FS */
printk(KERN_INFO "debug: Initialization complete\n");
initialized = 1;
}
......@@ -889,10 +876,10 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
mode |= S_IRUSR;
if (view->input_proc)
mode |= S_IWUSR;
id->proc_entries[i] =
debug_create_proc_dir_entry(id->proc_root_entry,
view->name, mode,
&debug_file_ops);
id->proc_entries[i] = create_proc_entry(view->name, mode,
id->proc_root_entry);
if (id->proc_entries[i] != NULL)
id->proc_entries[i]->proc_fops = &debug_file_ops;
rc = 0;
}
spin_unlock_irqrestore(&id->lock, flags);
......@@ -920,8 +907,10 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view)
if (i == DEBUG_MAX_VIEWS)
rc = -1;
else {
debug_delete_proc_dir_entry(id->proc_root_entry,
id->proc_entries[i]);
#ifdef CONFIG_PROC_FS
remove_proc_entry(id->proc_entries[i]->name,
id->proc_root_entry);
#endif
id->views[i] = NULL;
rc = 0;
}
......@@ -1209,7 +1198,9 @@ void cleanup_module(void)
#ifdef DEBUG
printk("debug_cleanup_module: \n");
#endif
debug_delete_proc_dir_entry(NULL, debug_proc_root_entry);
#ifdef CONFIG_PROC_FS
remove_proc_entry(debug_proc_root_entry->name, NULL);
#endif /* CONFIG_PROC_FS */
return;
}
......
This diff is collapsed.
......@@ -649,7 +649,7 @@ _stext: basr %r13,0 # get base
#
.align 8
.Ldw: .long 0x000a0000,0x00000000
.Linittu: .long init_task_union
.Linittu: .long init_thread_union
.Lstart: .long start_kernel
.Lbss_bgn: .long __bss_start
.Lbss_end: .long _end
......
/*
* arch/s390/kernel/ieee.h
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
*/
#include <linux/sched.h>
static inline void _adddf(int R1,int R2)
{
current->tss.fprs[R1].fd = current->tss.fprs[R1].fd +
current->tss.fprs[R2].fd;
}
static inline void _subdf(int R1,int R2)
{
current->tss.fprs[R1].fd = current->tss.fprs[R1].fd -
current->tss.fprs[R2].fd;
}
static inline void _muldf(int R1,int R2)
{
current->tss.fprs[R1].fd = current->tss.fprs[R1].fd *
current->tss.fprs[R2].fd;
}
static inline void _divdf(int R1,int R2)
{
current->tss.fprs[R1].fd = current->tss.fprs[R1].fd /
current->tss.fprs[R2].fd;
}
static inline void _negdf(int R1,int R2)
{
current->tss.fprs[R1].fd = -current->tss.fprs[R1].fd;
}
static inline void _fixdfsi(int R1,int R2)
{
current->tss.regs->gprs[R1] = (__u32) current->tss.fprs[R2].fd;
}
static inline void _extendsidf(int R1,int R2)
{
current->tss.fprs[R1].fd = (double) current->tss.regs->gprs[R2];
}
static inline void _addsf(int R1,int R2)
{
current->tss.fprs[R1].ff = current->tss.fprs[R1].ff +
current->tss.fprs[R2].ff;
}
static inline void _subsf(int R1,int R2)
{
current->tss.fprs[R1].ff = current->tss.fprs[R1].ff -
current->tss.fprs[R2].ff;
}
static inline void _mulsf(int R1,int R2)
{
current->tss.fprs[R1].ff = current->tss.fprs[R1].ff *
current->tss.fprs[R2].ff;
}
static inline void _divsf(int R1,int R2)
{
current->tss.fprs[R1].ff = current->tss.fprs[R1].ff /
current->tss.fprs[R2].ff;
}
static inline void _negsf(int R1,int R2)
{
current->tss.fprs[R1].ff = -current->tss.fprs[R1].ff;
}
static inline void _fixsfsi(int R1,int R2)
{
current->tss.regs->gprs[R1] = (__u32) current->tss.fprs[R2].ff;
}
static inline void _extendsisf(int R1,int R2)
{
current->tss.fprs[R1].ff = (double) current->tss.regs->gprs[R2];
}
......@@ -13,21 +13,26 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
struct mm_struct init_mm = INIT_MM(init_mm);
/*
* Initial task structure.
* Initial thread structure.
*
* We need to make sure that this is 8192-byte aligned due to the
* way process stacks are handled. This is done by making sure
* the linker maps this in the .text segment right after head.S,
* and making head.S ensure the proper alignment.
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
/*
* Initial task structure.
*
* The things we do for performance..
* All other task structs will be allocated on slabs in fork.c
*/
union task_union init_task_union __attribute__((aligned(8192))) =
{ INIT_TASK(init_task_union.task) };
struct task_struct init_task = INIT_TASK(init_task);
......@@ -63,7 +63,6 @@ BUILD_SMP_INTERRUPT(spurious_interrupt)
int show_interrupts(struct seq_file *p, void *v)
{
int i, j;
struct irqaction * action;
seq_puts(p, " ");
......@@ -76,36 +75,13 @@ int show_interrupts(struct seq_file *p, void *v)
if (ioinfo[i] == INVALID_STORAGE_AREA)
continue;
action = ioinfo[i]->irq_desc.action;
if (!action)
continue;
seq_printf(p, "%3d: ",i);
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for (j=0; j<smp_num_cpus; j++)
seq_printf( p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
seq_printf(p, " %14s", ioinfo[i]->irq_desc.handler->typename);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
{
seq_printf(p, ", %s", action->name);
} /* endfor */
seq_printf(p, " %s", ioinfo[i]->irq_desc.name);
seq_putc(p, '\n');
} /* endfor */
seq_printf(p, "NMI: %10u\n", nmi_counter);
#ifdef CONFIG_SMP
seq_printf(p, "IPI: %10u\n", atomic_read(&ipi_count));
#endif
return 0;
}
......@@ -132,10 +108,10 @@ atomic_t global_bh_count;
*/
#define check_smp_invalidate(cpu)
extern void show_stack(unsigned long* esp);
static void show(char * str)
{
int i;
unsigned long *stack;
int cpu = smp_processor_id();
printk("\n%s, CPU %d:\n", str, cpu);
......@@ -143,13 +119,7 @@ static void show(char * str)
atomic_read(&global_irq_count),local_irq_count(smp_processor_id()));
printk("bh: %d [%d]\n",
atomic_read(&global_bh_count),local_bh_count(smp_processor_id()));
stack = (unsigned long *) &str;
for (i = 40; i ; i--) {
unsigned long x = *++stack;
if (x > (unsigned long) &init_task_union && x < (unsigned long) &vsprintf) {
printk("<[%08lx]> ", x);
}
}
show_stack(NULL);
}
#define MAXCOUNT 100000000
......
......@@ -47,200 +47,80 @@
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
/*
* The idle loop on a S390...
* Return saved PC of a blocked thread. used in kernel/sched.
* resume in entry.S does not create a new stack frame, it
* just stores the registers %r6-%r15 to the frame given by
* schedule. We want to return the address of the caller of
* schedule, so we have to walk the backchain one time to
* find the frame schedule() store its return address.
*/
static psw_t wait_psw;
int cpu_idle(void *unused)
unsigned long thread_saved_pc(struct task_struct *tsk)
{
/* endless idle loop with no priority at all */
init_idle();
current->nice = 20;
wait_psw.mask = _WAIT_PSW_MASK;
wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L;
while(1) {
if (need_resched()) {
schedule();
check_pgt_cache();
continue;
}
/* load wait psw */
asm volatile (
"lpsw %0"
: : "m" (wait_psw) );
idle_wakeup:
}
unsigned long bc;
bc = *((unsigned long *) tsk->thread.ksp);
return *((unsigned long *) (bc+56));
}
/*
As all the register will only be made displayable to the root
user ( via printk ) or checking if the uid of the user is 0 from
the /proc filesystem please god this will be secure enough DJB.
The lines are given one at a time so as not to chew stack space in
printk on a crash & also for the proc filesystem when you get
0 returned you know you've got all the lines
* The idle loop on a S390...
*/
static int sprintf_regs(int line, char *buff, struct task_struct *task, struct pt_regs *regs)
void default_idle(void)
{
int linelen=0;
int regno,chaincnt;
u32 backchain,prev_backchain,endchain;
u32 ksp = 0;
char *mode = "???";
psw_t wait_psw;
unsigned long reg;
if (need_resched()) {
schedule();
return;
}
/*
* Wait for external, I/O or machine check interrupt and
* switch of machine check bit after the wait has ended.
*/
wait_psw.mask = _WAIT_PSW_MASK;
asm volatile (
" basr %0,0\n"
"0: la %0,1f-0b(%0)\n"
" st %0,4(%1)\n"
" oi 4(%1),0x80\n"
" lpsw 0(%1)\n"
"1: la %0,2f-1b(%0)\n"
" st %0,4(%1)\n"
" oi 4(%1),0x80\n"
" ni 1(%1),0xf9\n"
" lpsw 0(%1)\n"
"2:"
: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
}
enum
{
sp_linefeed,
sp_psw,
sp_ksp,
sp_gprs,
sp_gprs1,
sp_gprs2,
sp_gprs3,
sp_gprs4,
sp_acrs,
sp_acrs1,
sp_acrs2,
sp_acrs3,
sp_acrs4,
sp_kern_backchain,
sp_kern_backchain1
};
if (task)
ksp = task->thread.ksp;
if (regs && !(regs->psw.mask & PSW_PROBLEM_STATE))
ksp = regs->gprs[15];
if (regs)
mode = (regs->psw.mask & PSW_PROBLEM_STATE)?
"User" : "Kernel";
switch(line)
{
case sp_linefeed:
linelen=sprintf(buff,"\n");
break;
case sp_psw:
if(regs)
linelen=sprintf(buff, "%s PSW: %08lx %08lx %s\n", mode,
(unsigned long) regs->psw.mask,
(unsigned long) regs->psw.addr,
print_tainted());
else
linelen=sprintf(buff,"pt_regs=NULL some info unavailable\n");
break;
case sp_ksp:
linelen=sprintf(&buff[linelen],
"task: %08x ksp: %08x pt_regs: %08x\n",
(addr_t)task, (addr_t)ksp, (addr_t)regs);
break;
case sp_gprs:
if(regs)
linelen=sprintf(buff, "%s GPRS:\n", mode);
break;
case sp_gprs1 ... sp_gprs4:
if(regs)
{
regno=(line-sp_gprs1)*4;
linelen=sprintf(buff,"%08x %08x %08x %08x\n",
regs->gprs[regno],
regs->gprs[regno+1],
regs->gprs[regno+2],
regs->gprs[regno+3]);
}
break;
case sp_acrs:
if(regs)
linelen=sprintf(buff, "%s ACRS:\n", mode);
break;
case sp_acrs1 ... sp_acrs4:
if(regs)
{
regno=(line-sp_acrs1)*4;
linelen=sprintf(buff,"%08x %08x %08x %08x\n",
regs->acrs[regno],
regs->acrs[regno+1],
regs->acrs[regno+2],
regs->acrs[regno+3]);
}
break;
case sp_kern_backchain:
if (regs && (regs->psw.mask & PSW_PROBLEM_STATE))
break;
if (ksp)
linelen=sprintf(buff, "Kernel BackChain CallChain\n");
break;
default:
if (ksp)
{
backchain=ksp&PSW_ADDR_MASK;
endchain=((backchain&(-8192))+8192);
prev_backchain=backchain-1;
line-=sp_kern_backchain1;
for(chaincnt=0;;chaincnt++)
{
if((backchain==0)||(backchain>=endchain)
||(chaincnt>=8)||(prev_backchain>=backchain))
break;
if(chaincnt==line)
{
linelen+=sprintf(&buff[linelen]," %08x [<%08lx>]\n",
backchain,
*(u32 *)(backchain+56)&PSW_ADDR_MASK);
break;
}
prev_backchain=backchain;
backchain=(*((u32 *)backchain))&PSW_ADDR_MASK;
}
}
}
return(linelen);
int cpu_idle(void)
{
for (;;)
default_idle();
return 0;
}
extern void show_registers(struct pt_regs *regs);
extern void show_trace(unsigned long *sp);
void show_regs(struct pt_regs *regs)
{
char buff[80];
int i, line;
printk("CPU: %d\n",smp_processor_id());
printk("Process %s (pid: %d, stackpage=%08X)\n",
current->comm, current->pid, 4096+(addr_t)current);
for (line = 0; sprintf_regs(line, buff, current, regs); line++)
printk(buff);
if (regs->psw.mask & PSW_PROBLEM_STATE)
{
printk("User Code:\n");
memset(buff, 0, 20);
copy_from_user(buff,
(char *) (regs->psw.addr & PSW_ADDR_MASK), 20);
for (i = 0; i < 20; i++)
printk("%02x ", buff[i]);
printk("\n");
}
}
struct task_struct *tsk = current;
char *task_show_regs(struct task_struct *task, char *buffer)
{
int line, len;
printk("CPU: %d %s\n", tsk->thread_info->cpu, print_tainted());
printk("Process %s (pid: %d, task: %08lx, ksp: %08x)\n",
current->comm, current->pid, (unsigned long) tsk,
tsk->thread.ksp);
for (line = 0; ; line++)
{
len = sprintf_regs(line, buffer, task, task->thread.regs);
if (!len) break;
buffer += len;
}
return buffer;
show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */
if (!(regs->psw.mask & PSW_PROBLEM_STATE))
show_trace((unsigned long *) regs->gprs[15]);
}
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
int clone_arg = flags | CLONE_VM;
......@@ -279,7 +159,7 @@ void flush_thread(void)
{
current->used_math = 0;
current->flags &= ~PF_USEDFPU;
clear_tsk_thread_flag(current, TIF_USEDFPU);
}
void release_thread(struct task_struct *dead_task)
......@@ -300,16 +180,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
unsigned long gprs[10]; /* gprs 6 -15 */
unsigned long fprs[4]; /* fpr 4 and 6 */
unsigned long empty[4];
#if CONFIG_REMOTE_DEBUG
struct gdb_pt_regs childregs;
#else
struct pt_regs childregs;
#endif
} *frame;
frame = (struct stack_frame *) (2*PAGE_SIZE + (unsigned long) p) -1;
frame = (struct stack_frame *) (((unsigned long) frame)&-8L);
p->thread.regs = (struct pt_regs *)&frame->childregs;
frame = ((struct stack_frame *)
(THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
p->thread.ksp = (unsigned long) frame;
memcpy(&frame->childregs,regs,sizeof(struct pt_regs));
frame->childregs.gprs[15] = new_stackp;
......@@ -317,14 +192,14 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
/* new return point is ret_from_sys_call */
frame->gprs[8] = ((unsigned long) &ret_from_fork) | 0x80000000;
/* start disabled because of schedule_tick and rq->lock being held */
frame->childregs.psw.mask &= ~0x03000000;
/* fake return stack for resume(), don't go back to schedule */
frame->gprs[9] = (unsigned long) frame;
frame->childregs.old_ilc = -1; /* We are not single stepping an svc */
/* save fprs, if used in last task */
save_fp_regs(&p->thread.fp_regs);
p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
p->thread.fs = USER_DS;
/* Don't copy debug registers */
memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
return 0;
......
......@@ -41,7 +41,7 @@
void FixPerRegisters(struct task_struct *task)
{
struct pt_regs *regs = task->thread.regs;
struct pt_regs *regs = __KSTK_PTREGS(task);
per_struct *per_info=
(per_struct *)&task->thread.per_info;
......@@ -155,7 +155,7 @@ int copy_user(struct task_struct *task,saddr_t useraddr,addr_t copyaddr,int len,
mask=0xffffffff;
if(useraddr<PT_FPC)
{
realuseraddr=(addr_t)&(((u8 *)task->thread.regs)[useraddr]);
realuseraddr=((addr_t) __KSTK_PTREGS(task)) + useraddr;
if(useraddr<PT_PSWMASK)
{
copymax=PT_PSWMASK;
......@@ -217,7 +217,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
int ret = -EPERM;
unsigned long flags;
unsigned long tmp;
int copied;
ptrace_area parea;
......@@ -236,16 +235,18 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -ESRCH;
read_lock(&tasklist_lock);
child = find_task_by_pid(pid);
if (child)
get_task_struct(child);
read_unlock(&tasklist_lock);
if (!child)
goto out;
ret = -EPERM;
if (pid == 1) /* you may not mess with init */
goto out;
goto out_tsk;
if (request == PTRACE_ATTACH)
{
ret = ptrace_attach(child);
goto out;
goto out_tsk;
}
ret = -ESRCH;
// printk("child=%lX child->flags=%lX",child,child->flags);
......@@ -254,14 +255,14 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if(child!=current)
{
if (!(child->ptrace & PT_PTRACED))
goto out;
goto out_tsk;
if (child->state != TASK_STOPPED)
{
if (request != PTRACE_KILL)
goto out;
goto out_tsk;
}
if (child->p_pptr != current)
goto out;
if (child->parent != current)
goto out_tsk;
}
switch (request)
{
......@@ -271,9 +272,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
copied = access_process_vm(child,ADDR_BITS_REMOVE(addr), &tmp, sizeof(tmp), 0);
ret = -EIO;
if (copied != sizeof(tmp))
goto out;
break;
ret = put_user(tmp,(unsigned long *) data);
goto out;
break;
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
......@@ -285,9 +286,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_POKEDATA:
ret = 0;
if (access_process_vm(child,ADDR_BITS_REMOVE(addr), &data, sizeof(data), 1) == sizeof(data))
goto out;
break;
ret = -EIO;
goto out;
break;
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
......@@ -300,9 +300,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if ((unsigned long) data >= _NSIG)
break;
if (request == PTRACE_SYSCALL)
child->ptrace |= PT_TRACESYS;
set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
else
child->ptrace &= ~PT_TRACESYS;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* make sure the single step bit is not set. */
clear_single_step(child);
......@@ -329,7 +329,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret = -EIO;
if ((unsigned long) data >= _NSIG)
break;
child->ptrace &= ~PT_TRACESYS;
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
set_single_step(child);
/* give it a chance to run. */
......@@ -346,10 +346,20 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
ret=copy_user(child,parea.kernel_addr,parea.process_addr,
parea.len,1,(request==PTRACE_POKEUSR_AREA));
break;
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break;
}
default:
ret = -EIO;
break;
}
out_tsk:
put_task_struct(child);
out:
unlock_kernel();
return ret;
......@@ -357,12 +367,13 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
asmlinkage void syscall_trace(void)
{
lock_kernel();
if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
!= (PT_PTRACED|PT_TRACESYS))
goto out;
current->exit_code = SIGTRAP;
set_current_state(TASK_STOPPED);
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
if (!(current->ptrace & PT_PTRACED))
return;
current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0);
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
/*
......@@ -374,6 +385,4 @@ asmlinkage void syscall_trace(void)
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
out:
unlock_kernel();
}
......@@ -21,8 +21,10 @@ do_reipl: basr %r13,0
oi .Lschib+5-.Lpg0(%r13),0x84
.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01
msch .Lschib-.Lpg0(%r13)
ssch .Liplorb-.Lpg0(%r13)
jz .L001
lhi %r0,5
.Lssch: ssch .Liplorb-.Lpg0(%r13)
jz .L001
brct %r0,.Lssch
bas %r14,.Ldisab-.Lpg0(%r13)
.L001: mvc __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13)
.Ltpi: lpsw .Lwaitpsw-.Lpg0(%r13)
......
......@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <asm/lowcore.h>
#include <asm/s390_ext.h>
......@@ -21,34 +22,31 @@
* iucv and 0x2603 pfault) this is always the first element.
*/
ext_int_info_t *ext_int_hash[256] = { 0, };
ext_int_info_t ext_int_info_timer;
ext_int_info_t ext_int_info_hwc;
ext_int_info_t ext_int_pfault;
int register_external_interrupt(__u16 code, ext_int_handler_t handler) {
ext_int_info_t *p;
int index;
index = code & 0xff;
p = ext_int_hash[index];
while (p != NULL) {
if (p->code == code)
return -EBUSY;
p = p->next;
}
if (code == 0x1004) /* time_init is done before kmalloc works :-/ */
p = &ext_int_info_timer;
else if (code == 0x2401) /* hwc_init is done too early too */
p = &ext_int_info_hwc;
else if (code == 0x2603) /* pfault_init is done too early too */
p = &ext_int_pfault;
else
p = (ext_int_info_t *)
kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
if (p == NULL)
return -ENOMEM;
p->code = code;
p->handler = handler;
index = code & 0xff;
p->next = ext_int_hash[index];
ext_int_hash[index] = p;
return 0;
}
int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
ext_int_info_t *p) {
int index;
if (p == NULL)
return -EINVAL;
p->code = code;
p->handler = handler;
index = code & 0xff;
p->next = ext_int_hash[index];
ext_int_hash[index] = p;
return 0;
......@@ -73,11 +71,33 @@ int unregister_external_interrupt(__u16 code, ext_int_handler_t handler) {
q->next = p->next;
else
ext_int_hash[index] = p->next;
if (code != 0x1004 && code != 0x2401 && code != 0x2603)
kfree(p);
kfree(p);
return 0;
}
int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
ext_int_info_t *p) {
ext_int_info_t *q;
int index;
if (p == NULL || p->code != code || p->handler != handler)
return -EINVAL;
index = code & 0xff;
q = ext_int_hash[index];
if (p != q) {
while (q != NULL) {
if (q->next == p)
break;
q = q->next;
}
if (q == NULL)
return -ENOENT;
q->next = p->next;
} else
ext_int_hash[index] = p->next;
return 0;
}
EXPORT_SYMBOL(register_external_interrupt);
EXPORT_SYMBOL(unregister_external_interrupt);
......@@ -5,9 +5,11 @@
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/smp.h>
#include <asm/checksum.h>
#include <asm/delay.h>
#include <asm/setup.h>
#include <asm/softirq.h>
#if CONFIG_IP_MULTICAST
#include <net/arp.h>
#endif
......@@ -18,8 +20,9 @@
EXPORT_SYMBOL_NOVERS(_oi_bitmap);
EXPORT_SYMBOL_NOVERS(_ni_bitmap);
EXPORT_SYMBOL_NOVERS(_zb_findmap);
EXPORT_SYMBOL_NOVERS(__copy_from_user_fixup);
EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
EXPORT_SYMBOL_NOVERS(__copy_from_user_asm);
EXPORT_SYMBOL_NOVERS(__copy_to_user_asm);
EXPORT_SYMBOL_NOVERS(__clear_user_asm);
/*
* semaphore ops
......@@ -27,7 +30,6 @@ EXPORT_SYMBOL_NOVERS(__copy_to_user_fixup);
EXPORT_SYMBOL(__up);
EXPORT_SYMBOL(__down);
EXPORT_SYMBOL(__down_interruptible);
EXPORT_SYMBOL(__down_trylock);
/*
* string functions
......@@ -35,6 +37,7 @@ EXPORT_SYMBOL(__down_trylock);
EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memmove);
EXPORT_SYMBOL_NOVERS(memscan);
EXPORT_SYMBOL_NOVERS(strlen);
EXPORT_SYMBOL_NOVERS(strchr);
EXPORT_SYMBOL_NOVERS(strcmp);
......@@ -44,7 +47,6 @@ EXPORT_SYMBOL_NOVERS(strncpy);
EXPORT_SYMBOL_NOVERS(strnlen);
EXPORT_SYMBOL_NOVERS(strrchr);
EXPORT_SYMBOL_NOVERS(strstr);
EXPORT_SYMBOL_NOVERS(strsep);
EXPORT_SYMBOL_NOVERS(strpbrk);
/*
......@@ -57,5 +59,3 @@ EXPORT_SYMBOL(csum_fold);
EXPORT_SYMBOL(console_mode);
EXPORT_SYMBOL(console_device);
EXPORT_SYMBOL_NOVERS(do_call_softirq);
/*
* linux/arch/S390/kernel/semaphore.c
* linux/arch/s390/kernel/semaphore.c
*
* S390 version
* Copyright (C) 1998-2000 IBM Corporation
......@@ -10,151 +10,97 @@
*
*/
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/semaphore.h>
/*
* Semaphores are implemented using a two-way counter:
* The "count" variable is decremented for each process
* that tries to acquire the semaphore, while the "sleeping"
* variable is a count of such acquires.
*
* Notably, the inline "up()" and "down()" functions can
* efficiently test if they need to do any extra work (up
* needs to do something only if count was negative before
* the increment operation.
*
* "sleeping" and the contention routine ordering is
* protected by the semaphore spinlock.
*
* Note that these functions are only called when there is
* contention on the lock, and as such all this is the
* "non-critical" part of the whole semaphore business. The
* critical part is the inline stuff in <asm/semaphore.h>
* where we want to avoid any extra jumps and calls.
* Atomically update sem->count. Equivalent to:
* old_val = sem->count.counter;
* new_val = ((old_val >= 0) ? old_val : 0) + incr;
* sem->count.counter = new_val;
* return old_val;
*/
static inline int __sem_update_count(struct semaphore *sem, int incr)
{
int old_val, new_val;
__asm__ __volatile__(" l %0,0(%3)\n"
"0: ltr %1,%0\n"
" jhe 1f\n"
" lhi %1,0\n"
"1: ar %1,%4\n"
" cs %0,%1,0(%3)\n"
" jl 0b\n"
: "=&d" (old_val), "=&d" (new_val),
"+m" (sem->count)
: "a" (&sem->count), "d" (incr) : "cc" );
return old_val;
}
/*
* Logic:
* - only on a boundary condition do we need to care. When we go
* from a negative count to a non-negative, we wake people up.
* - when we go from a non-negative count to a negative do we
* (a) synchronize with the "sleeper" count and (b) make sure
* that we're on the wakeup list before we synchronize so that
* we cannot lose wakeup events.
* The inline function up() incremented count but the result
* was <= 0. This indicates that some process is waiting on
* the semaphore. The semaphore is free and we'll wake the
* first sleeping process, so we set count to 1 unless some
* other cpu has called up in the meantime in which case
* we just increment count by 1.
*/
void __up(struct semaphore *sem)
{
__sem_update_count(sem, 1);
wake_up(&sem->wait);
}
static spinlock_t semaphore_lock = SPIN_LOCK_UNLOCKED;
/*
* The inline function down() decremented count and the result
* was < 0. The wait loop will atomically test and update the
* semaphore counter following the rules:
* count > 0: decrement count, wake up queue and exit.
* count <= 0: set count to -1, go to sleep.
*/
void __down(struct semaphore * sem)
{
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
tsk->state = TASK_UNINTERRUPTIBLE;
add_wait_queue_exclusive(&sem->wait, &wait);
spin_lock_irq(&semaphore_lock);
sem->sleepers++;
for (;;) {
int sleepers = sem->sleepers;
/*
* Add "everybody else" into it. They aren't
* playing, because we own the spinlock.
*/
if (!atomic_add_negative(sleepers - 1, &sem->count)) {
sem->sleepers = 0;
break;
}
sem->sleepers = 1; /* us - see -1 above */
spin_unlock_irq(&semaphore_lock);
while (__sem_update_count(sem, -1) <= 0) {
schedule();
tsk->state = TASK_UNINTERRUPTIBLE;
spin_lock_irq(&semaphore_lock);
}
spin_unlock_irq(&semaphore_lock);
remove_wait_queue(&sem->wait, &wait);
tsk->state = TASK_RUNNING;
wake_up(&sem->wait);
}
/*
* Same as __down() with an additional test for signals.
* If a signal is pending the count is updated as follows:
* count > 0: wake up queue and exit.
* count <= 0: set count to 0, wake up queue and exit.
*/
int __down_interruptible(struct semaphore * sem)
{
int retval = 0;
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
tsk->state = TASK_INTERRUPTIBLE;
add_wait_queue_exclusive(&sem->wait, &wait);
spin_lock_irq(&semaphore_lock);
sem->sleepers ++;
for (;;) {
int sleepers = sem->sleepers;
/*
* With signals pending, this turns into
* the trylock failure case - we won't be
* sleeping, and we* can't get the lock as
* it has contention. Just correct the count
* and exit.
*/
while (__sem_update_count(sem, -1) <= 0) {
if (signal_pending(current)) {
__sem_update_count(sem, 0);
retval = -EINTR;
sem->sleepers = 0;
atomic_add(sleepers, &sem->count);
break;
}
/*
* Add "everybody else" into it. They aren't
* playing, because we own the spinlock. The
* "-1" is because we're still hoping to get
* the lock.
*/
if (!atomic_add_negative(sleepers - 1, &sem->count)) {
sem->sleepers = 0;
break;
}
sem->sleepers = 1; /* us - see -1 above */
spin_unlock_irq(&semaphore_lock);
schedule();
tsk->state = TASK_INTERRUPTIBLE;
spin_lock_irq(&semaphore_lock);
}
spin_unlock_irq(&semaphore_lock);
tsk->state = TASK_RUNNING;
remove_wait_queue(&sem->wait, &wait);
tsk->state = TASK_RUNNING;
wake_up(&sem->wait);
return retval;
}
/*
* Trylock failed - make sure we correct for
* having decremented the count.
*/
int __down_trylock(struct semaphore * sem)
{
unsigned long flags;
int sleepers;
spin_lock_irqsave(&semaphore_lock, flags);
sleepers = sem->sleepers + 1;
sem->sleepers = 0;
/*
* Add "everybody else" and us into it. They aren't
* playing, because we own the spinlock.
*/
if (!atomic_add_negative(sleepers, &sem->count))
wake_up(&sem->wait);
spin_unlock_irqrestore(&semaphore_lock, flags);
return 1;
}
......@@ -48,7 +48,7 @@ unsigned int console_mode = 0;
unsigned int console_device = -1;
unsigned long memory_size = 0;
unsigned long machine_flags = 0;
struct { unsigned long addr, size, type; } memory_chunk[16];
struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } };
#define CHUNK_READ_WRITE 0
#define CHUNK_READ_ONLY 1
__u16 boot_cpu_addr;
......@@ -99,7 +99,7 @@ void __init cpu_init (void)
/*
* Force FPU initialization:
*/
current->flags &= ~PF_USEDFPU;
clear_thread_flag(TIF_USEDFPU);
current->used_math = 0;
/* Setup active_mm for idle_task */
......@@ -165,15 +165,15 @@ __setup("condev=", condev_setup);
static int __init conmode_setup(char *str)
{
#if defined(CONFIG_HWC_CONSOLE)
if (strncmp(str, "hwc", 4) == 0 && !MACHINE_IS_P390)
if (strncmp(str, "hwc", 4) == 0)
SET_CONSOLE_HWC;
#endif
#if defined(CONFIG_TN3215_CONSOLE)
if (strncmp(str, "3215", 5) == 0 && (MACHINE_IS_VM || MACHINE_IS_P390))
if (strncmp(str, "3215", 5) == 0)
SET_CONSOLE_3215;
#endif
#if defined(CONFIG_TN3270_CONSOLE)
if (strncmp(str, "3270", 5) == 0 && (MACHINE_IS_VM || MACHINE_IS_P390))
if (strncmp(str, "3270", 5) == 0)
SET_CONSOLE_3270;
#endif
return 1;
......@@ -233,31 +233,62 @@ static void __init conmode_default(void)
}
}
#ifdef CONFIG_SMP
extern void machine_restart_smp(char *);
extern void machine_halt_smp(void);
extern void machine_power_off_smp(void);
void (*_machine_restart)(char *command) = machine_restart_smp;
void (*_machine_halt)(void) = machine_halt_smp;
void (*_machine_power_off)(void) = machine_power_off_smp;
#else
/*
* Reboot, halt and power_off routines for non SMP.
*/
#ifndef CONFIG_SMP
void machine_restart(char * __unused)
static void do_machine_restart_nonsmp(char * __unused)
{
reipl(S390_lowcore.ipl_device);
}
void machine_halt(void)
static void do_machine_halt_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
cpcmd(vmhalt_cmd, NULL, 0);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
void machine_power_off(void)
static void do_machine_power_off_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
cpcmd(vmpoff_cmd, NULL, 0);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
void (*_machine_restart)(char *command) = do_machine_restart_nonsmp;
void (*_machine_halt)(void) = do_machine_halt_nonsmp;
void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
#endif
/*
* Reboot, halt and power_off stubs. They just call _machine_restart,
* _machine_halt or _machine_power_off.
*/
void machine_restart(char *command)
{
_machine_restart(command);
}
void machine_halt(void)
{
_machine_halt();
}
void machine_power_off(void)
{
_machine_power_off();
}
/*
* Setup function called from init/main.c just after the banner
* was printed.
......@@ -284,8 +315,8 @@ void __init setup_arch(char **cmdline_p)
* print what head.S has found out about the machine
*/
printk((MACHINE_IS_VM) ?
"We are running under VM\n" :
"We are running native\n");
"We are running under VM (31 bit mode)\n" :
"We are running native (31 bit mode)\n");
printk((MACHINE_HAS_IEEE) ?
"This machine has an IEEE fpu\n" :
"This machine has no IEEE fpu\n");
......@@ -436,9 +467,10 @@ void __init setup_arch(char **cmdline_p)
lowcore->io_new_psw.mask = _IO_PSW_MASK;
lowcore->io_new_psw.addr = _ADDR_31 + (addr_t) &io_int_handler;
lowcore->ipl_device = S390_lowcore.ipl_device;
lowcore->kernel_stack = ((__u32) &init_task_union) + 8192;
lowcore->kernel_stack = ((__u32) &init_thread_union) + 8192;
lowcore->async_stack = (__u32)
__alloc_bootmem(2*PAGE_SIZE, 2*PAGE_SIZE, 0) + 8192;
lowcore->jiffy_timer = -1LL;
set_prefix((__u32) lowcore);
cpu_init();
boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
......@@ -485,17 +517,18 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
static int show_cpuinfo(struct seq_file *m, void *v)
{
struct cpuinfo_S390 *cpuinfo;
unsigned n = v;
unsigned long n = (unsigned long) v - 1;
if (!n--) {
if (!n) {
seq_printf(m, "vendor_id : IBM/S390\n"
"# processors : %i\n"
"bogomips per cpu: %lu.%02lu\n",
smp_num_cpus, loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ))%100);
} else if (cpu_online_map & (1 << n)) {
cpuinfo = &safe_get_cpu_lowcore(n).cpu_data;
seq_printf(m, "processor %i: "
}
if (cpu_online_map & (1 << n)) {
cpuinfo = &safe_get_cpu_lowcore(n)->cpu_data;
seq_printf(m, "processor %li: "
"version = %02X, "
"identification = %06X, "
"machine = %04X\n",
......@@ -508,7 +541,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
return *pos <= NR_CPUS ? (void)(*pos+1) : NULL;
return *pos <= NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
......
......@@ -24,7 +24,9 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
......@@ -267,10 +269,10 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
static inline int map_signal(int sig)
{
if (current->exec_domain
&& current->exec_domain->signal_invmap
if (current_thread_info()->exec_domain
&& current_thread_info()->exec_domain->signal_invmap
&& sig < 32)
return current->exec_domain->signal_invmap[sig];
return current_thread_info()->exec_domain->signal_invmap[sig];
else
return sig;
}
......@@ -301,6 +303,10 @@ static void setup_frame(int sig, struct k_sigaction *ka,
goto give_sigsegv;
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
......@@ -335,7 +341,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->gprs[15]),
&frame->uc.uc_stack.ss_flags);
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
......@@ -354,6 +360,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
(u16 *)(frame->retcode));
}
/* Set up backchain. */
if (__put_user(regs->gprs[15], (addr_t *) frame))
goto give_sigsegv;
/* Set up registers for signal handler */
regs->gprs[15] = (addr_t)frame;
regs->psw.addr = FIX_PSW(ka->sa.sa_handler);
......
This diff is collapsed.
......@@ -33,19 +33,19 @@
#include <asm/irq.h>
/* change this if you have some constant time drift */
#define USECS_PER_JIFFY ((signed long)1000000/HZ)
#define CLK_TICKS_PER_JIFFY ((signed long)USECS_PER_JIFFY<<12)
#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
#define TICK_SIZE tick
static uint64_t init_timer_cc, last_timer_cc;
static ext_int_info_t ext_int_info_timer;
static uint64_t init_timer_cc;
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
void tod_to_timeval(uint64_t todval, struct timeval *xtime)
void tod_to_timeval(__u64 todval, struct timeval *xtime)
{
const int high_bit = 0x80000000L;
const int c_f4240 = 0xf4240L;
......@@ -79,13 +79,15 @@ void tod_to_timeval(uint64_t todval, struct timeval *xtime)
: "cc", "memory", "2", "3", "4" );
}
unsigned long do_gettimeoffset(void)
static inline unsigned long do_gettimeoffset(void)
{
__u64 timer_cc;
__u64 now;
asm volatile ("STCK %0" : "=m" (timer_cc));
/* We require the offset from the previous interrupt */
return ((unsigned long)((timer_cc - last_timer_cc)>>12));
asm ("STCK 0(%0)" : : "a" (&now) : "memory", "cc");
now = (now - init_timer_cc) >> 12;
/* We require the offset from the latest update of xtime */
now -= (__u64) wall_jiffies*USECS_PER_JIFFY;
return (unsigned long) now;
}
/*
......@@ -95,15 +97,10 @@ void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long usec, sec;
unsigned long lost_ticks;
read_lock_irqsave(&xtime_lock, flags);
lost_ticks = jiffies - wall_jiffies;
usec = do_gettimeoffset();
if (lost_ticks)
usec +=(USECS_PER_JIFFY*lost_ticks);
sec = xtime.tv_sec;
usec += xtime.tv_usec;
usec = xtime.tv_usec + do_gettimeoffset();
read_unlock_irqrestore(&xtime_lock, flags);
while (usec >= 1000000) {
......@@ -149,51 +146,31 @@ void do_settimeofday(struct timeval *tv)
extern __u16 boot_cpu_addr;
#endif
void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
static void do_comparator_interrupt(struct pt_regs *regs, __u16 error_code)
{
int cpu = smp_processor_id();
irq_enter(cpu, 0);
/*
* reset timer to 10ms minus time already elapsed
* since timer-interrupt pending
*/
/*
* set clock comparator for next tick
*/
S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY;
asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer));
#ifdef CONFIG_SMP
if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
if (S390_lowcore.cpu_data.cpu_addr == boot_cpu_addr)
write_lock(&xtime_lock);
last_timer_cc = S390_lowcore.jiffy_timer_cc;
}
#else
last_timer_cc = S390_lowcore.jiffy_timer_cc;
#endif
/* set clock comparator */
S390_lowcore.jiffy_timer_cc += CLK_TICKS_PER_JIFFY;
asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer_cc));
/*
* In the SMP case we use the local timer interrupt to do the
* profiling, except when we simulate SMP mode on a uniprocessor
* system, in that case we have to call the local interrupt handler.
*/
#ifdef CONFIG_SMP
/* when SMP, do smp_local_timer_interrupt for *all* CPUs,
but only do the rest for the boot CPU */
smp_local_timer_interrupt(regs);
#else
if (!user_mode(regs))
s390_do_profile(regs->psw.addr);
#endif
update_process_times(user_mode(regs));
#ifdef CONFIG_SMP
if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr)
#endif
{
if (S390_lowcore.cpu_data.cpu_addr == boot_cpu_addr) {
do_timer(regs);
#ifdef CONFIG_SMP
write_unlock(&xtime_lock);
#endif
}
#else
do_timer(regs);
#endif
irq_exit(cpu, 0);
}
......@@ -201,19 +178,17 @@ void do_timer_interrupt(struct pt_regs *regs, __u16 error_code)
/*
* Start the clock comparator on the current CPU
*/
static long cr0 __attribute__ ((aligned (8)));
void init_100hz_timer(void)
void init_cpu_timer(void)
{
unsigned long cr0;
/* allow clock comparator timer interrupt */
asm volatile ("STCTL 0,0,%0" : "=m" (cr0) : : "memory");
cr0 |= 0x800;
asm volatile ("LCTL 0,0,%0" : : "m" (cr0) : "memory");
/* set clock comparator */
/* read the TOD clock */
asm volatile ("STCK %0" : "=m" (S390_lowcore.jiffy_timer_cc));
S390_lowcore.jiffy_timer_cc += CLK_TICKS_PER_JIFFY;
asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer_cc));
S390_lowcore.jiffy_timer = (__u64) jiffies * CLK_TICKS_PER_JIFFY;
S390_lowcore.jiffy_timer += init_timer_cc + CLK_TICKS_PER_JIFFY;
asm volatile ("SCKC %0" : : "m" (S390_lowcore.jiffy_timer));
}
/*
......@@ -222,12 +197,14 @@ void init_100hz_timer(void)
*/
void __init time_init(void)
{
__u64 set_time_cc;
int cc;
/* kick the TOD clock */
asm volatile ("STCK %1\n\t"
asm volatile ("STCK 0(%1)\n\t"
"IPM %0\n\t"
"SRL %0,28" : "=r" (cc), "=m" (init_timer_cc));
"SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc)
: "memory", "cc");
switch (cc) {
case 0: /* clock in set state: all is fine */
break;
......@@ -241,12 +218,17 @@ void __init time_init(void)
printk("time_init: TOD clock stopped/non-operational\n");
break;
}
/* set xtime */
set_time_cc = init_timer_cc - 0x8126d60e46000000LL +
(0x3c26700LL*1000000*4096);
tod_to_timeval(set_time_cc, &xtime);
/* request the 0x1004 external interrupt */
if (register_external_interrupt(0x1004, do_timer_interrupt) != 0)
panic("Couldn't request external interrupts 0x1004");
init_100hz_timer();
init_timer_cc = S390_lowcore.jiffy_timer_cc;
init_timer_cc -= 0x8126d60e46000000LL -
(0x3c26700LL*1000000*4096);
tod_to_timeval(init_timer_cc, &xtime);
if (register_early_external_interrupt(0x1004, do_comparator_interrupt,
&ext_int_info_timer) != 0)
panic("Couldn't request external interrupt 0x1004");
/* init CPU timer */
init_cpu_timer();
}
This diff is collapsed.
......@@ -6,46 +6,83 @@
* Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*
* These functions have a non-standard call interface
* These functions have standard call interface
*/
#include <asm/lowcore.h>
.text
.align 4
.globl __copy_from_user_fixup
__copy_from_user_fixup:
l 1,__LC_PGM_OLD_PSW+4
sll 4,1
srl 4,1
0: lhi 3,-4096
sll 3,1
srl 3,1
n 3,__LC_TRANS_EXC_ADDR
sr 3,4
bm 4(1)
1: mvcle 2,4,0
b 4(1)
.globl __copy_from_user_asm
__copy_from_user_asm:
lr %r5,%r3
sacf 512
0: mvcle %r2,%r4,0
jo 0b
1: sacf 0
lr %r2,%r5
br %r14
2: sll %r4,1
srl %r4,1
lhi %r3,-4096
sll %r3,1
srl %r3,1
n %r3,__LC_TRANS_EXC_ADDR
sr %r3,%r4
jm 1b
j 0b
.section __ex_table,"a"
.long 1b,0b
.long 0b,2b
.previous
.align 4
.text
.globl __copy_to_user_fixup
__copy_to_user_fixup:
l 1,__LC_PGM_OLD_PSW+4
sll 4,1
srl 4,1
0: lhi 5,-4096
sll 5,1
srl 5,1
n 5,__LC_TRANS_EXC_ADDR
sr 5,4
bm 4(1)
1: mvcle 4,2,0
b 4(1)
.globl __copy_to_user_asm
__copy_to_user_asm:
lr %r5,%r3
sacf 512
0: mvcle %r4,%r2,0
jo 0b
1: sacf 0
lr %r2,%r3
br %r14
2: sll %r4,1
srl %r4,1
lhi %r5,-4096
sll %r5,1
srl %r5,1
n %r5,__LC_TRANS_EXC_ADDR
sr %r5,%r4
jm 1b
j 0b
.section __ex_table,"a"
.long 1b,0b
.long 0b,2b
.previous
.align 4
.text
.globl __clear_user_asm
__clear_user_asm:
lr %r4,%r2
lr %r5,%r3
sr %r2,%r2
sr %r3,%r3
sacf 512
0: mvcle %r4,%r2,0
jo 0b
1: sacf 0
lr %r2,%r3
br %r14
2: sll %r4,1
srl %r4,1
lhi %r5,-4096
sll %r5,1
srl %r5,1
n %r5,__LC_TRANS_EXC_ADDR
sr %r5,%r4
jm 1b
j 0b
.section __ex_table,"a"
.long 0b,2b
.previous
This diff is collapsed.
......@@ -43,7 +43,6 @@ unsigned long
search_exception_table(unsigned long addr)
{
unsigned long ret = 0;
unsigned long flags;
#ifndef CONFIG_MODULES
addr &= 0x7fffffff; /* remove amode bit from address */
......@@ -52,6 +51,7 @@ search_exception_table(unsigned long addr)
if (ret) ret = FIX_PSW(ret);
return ret;
#else
unsigned long flags;
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
addr &= 0x7fffffff; /* remove amode bit from address */
......
This diff is collapsed.
......@@ -36,34 +36,13 @@
#include <asm/dma.h>
#include <asm/lowcore.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
mmu_gather_t mmu_gathers[NR_CPUS];
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
if(pgtable_cache_size > high) {
do {
if(pgd_quicklist) {
free_pgd_slow(get_pgd_fast());
freed += 2;
}
if(pmd_quicklist) {
pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
freed++;
}
if(pte_quicklist) {
pte_free_slow(pte_alloc_one_fast(NULL, 0));
freed++;
}
} while(pgtable_cache_size > low);
}
return freed;
}
void show_mem(void)
{
int i, total = 0, reserved = 0;
......@@ -86,7 +65,6 @@ void show_mem(void)
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
}
/* References to section boundaries */
......
......@@ -16,6 +16,8 @@
#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
......@@ -55,7 +57,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
if (address >= end)
BUG();
do {
pte_t * pte = pte_alloc(&init_mm, pmd, address);
pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr, flags);
......
......@@ -14,6 +14,9 @@ SECTIONS
*(.fixup)
*(.gnu.warning)
} = 0x0700
_etext = .; /* End of text section */
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
......@@ -26,13 +29,9 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
__start___kallsyms = .; /* All kernel symbols */
__kallsyms : { *(__kallsyms) }
__stop___kallsyms = .;
. = ALIGN(1048576); /* VM shared segments are 1MB aligned */
_etext = .; /* End of text section */
_eshared = .; /* End of shareable data */
.data : { /* Data */
*(.data)
......@@ -48,9 +47,7 @@ SECTIONS
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
. = ALIGN(256);
__setup_start = .;
.setup.init : { *(.setup.init) }
__setup_end = .;
......@@ -65,6 +62,10 @@ SECTIONS
*(.initcall7.init)
}
__initcall_end = .;
. = ALIGN(256);
__per_cpu_start = .;
.date.percpu : { *(.data.percpu) }
__per_cpu_end = .;
. = ALIGN(4096);
__init_end = .;
......
......@@ -14,6 +14,9 @@ SECTIONS
*(.fixup)
*(.gnu.warning)
} = 0x0700
_etext = .; /* End of text section */
.rodata : { *(.rodata) *(.rodata.*) }
.kstrtab : { *(.kstrtab) }
......@@ -26,12 +29,6 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
__start___kallsyms = .; /* All kernel symbols */
__kallsyms : { *(__kallsyms) }
__stop___kallsyms = .;
_etext = .; /* End of text section */
.data : { /* Data */
*(.data)
CONSTRUCTORS
......@@ -46,9 +43,7 @@ SECTIONS
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(4096);
__init_end = .;
. = ALIGN(256);
__setup_start = .;
.setup.init : { *(.setup.init) }
__setup_end = .;
......@@ -63,6 +58,10 @@ SECTIONS
*(.initcall7.init)
}
__initcall_end = .;
. = ALIGN(256);
__per_cpu_start = .;
.date.percpu : { *(.data.percpu) }
__per_cpu_end = .;
. = ALIGN(4096);
__init_end = .;
......@@ -72,7 +71,6 @@ SECTIONS
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
__bss_start = .; /* BSS */
.bss : {
*(.bss)
......
......@@ -154,7 +154,10 @@ CONFIG_IPL
IPL device.
CONFIG_IPL_TAPE
Select this option if you want to IPL the image from a Tape.
Select "tape" if you want to IPL the image from a Tape.
Select "vm_reader" if you are running under VM/ESA and want
to IPL the image from the emulated card reader.
CONFIG_FAST_IRQ
Select this option in order to get the interrupts processed faster
......@@ -163,6 +166,18 @@ CONFIG_FAST_IRQ
interrupts which will also be processed before leaving the interrupt
context. This speeds up the I/O a lot. Say "Y".
CONFIG_MACHCHK_WARNING
Select this option if you want the machine check handler on IBM S/390 or
zSeries to process warning machine checks (e.g. on power failures).
If unsure, say "Y".
CONFIG_CHSC
Select this option if you want the s390 common I/O layer to use information
obtained by channel subsystem calls. This will enable Linux to process link
failures and resource accessibility events. Moreover, if you have procfs
enabled, you'll be able to toggle chpids logically offline and online. Even
if you don't understand what this means, you should say "Y".
CONFIG_S390_SUPPORT
Select this option if you want to enable your system kernel to
handle system-calls from ELF binaries for 31 bit ESA. This option
......@@ -174,3 +189,39 @@ CONFIG_PROCESS_DEBUG
a debugging option; you probably do not want to set it unless you
are an S390 port maintainer.
CONFIG_PFAULT
Select this option, if you want to use PFAULT pseudo page fault
handling under VM. If running native or in LPAR, this option
has no effect. If your VM does not support PFAULT, PAGEEX
pseudo page fault handling will be used.
Note that VM 4.2 supports PFAULT but has a bug in its
implementation that causes some problems.
Everybody who wants to run Linux under VM != VM4.2 should select
this option.
CONFIG_SHARED_KERNEL
Select this option, if you want to share the text segment of the
Linux kernel between different VM guests. This reduces memory
usage with lots of guests but greatly increases kernel size.
You should only select this option if you know what you are
doing and want to exploit this feature.
CONFIG_QDIO
This driver provides the Queued Direct I/O base support for the
IBM S/390 (G5 and G6) and eServer zSeries (z800 and z900).
For details please refer to the documentation provided by IBM at
<http://www10.software.ibm.com/developerworks/opensource/linux390>
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called qdio.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
If unsure, say Y.
Performance statistics for QDIO base support
CONFIG_QDIO_PERF_STATS
Say Y here to get performance statistics in /proc/qdio_perf
If unsure, say N.
......@@ -18,10 +18,11 @@ CPP=$(CC) -E
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e start
ifeq ($(CONFIG_SHARED_KERNEL),y)
LINKFLAGS =-T $(TOPDIR)/arch/s390x/vmlinux-shared.lds $(LDFLAGS)
LINKSCRIPT := arch/s390x/vmlinux-shared.lds
else
LINKFLAGS =-T $(TOPDIR)/arch/s390x/vmlinux.lds $(LDFLAGS)
LINKSCRIPT := arch/s390x/vmlinux.lds
endif
LINKFLAGS =-T $(TOPDIR)/$(LINKSCRIPT) $(LDFLAGS)
MODFLAGS += -fpic
CFLAGS_PIPE := -pipe
......@@ -30,8 +31,7 @@ CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
HEAD := arch/s390x/kernel/head.o arch/s390x/kernel/init_task.o
SUBDIRS := $(SUBDIRS) arch/s390x/mm arch/s390x/kernel arch/s390x/lib \
drivers/s390
SUBDIRS += arch/s390x/mm arch/s390x/kernel arch/s390x/lib drivers/s390
CORE_FILES := arch/s390x/mm/mm.o arch/s390x/kernel/kernel.o $(CORE_FILES)
DRIVERS := $(DRIVERS) drivers/s390/built-in.o
LIBS := $(TOPDIR)/arch/s390x/lib/lib.a $(LIBS) $(TOPDIR)/arch/s390x/lib/lib.a
......@@ -43,11 +43,17 @@ listing: vmlinux
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: $(LINKSCRIPT)
image: vmlinux
@$(MAKEBOOT) image
install: vmlinux
@$(MAKEBOOT) BOOTIMAGE=image install
archclean:
@$(MAKEBOOT) clean
$(MAKE) -C arch/$(ARCH)/kernel clean
archmrproper:
......
......@@ -6,10 +6,10 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
O_TARGET :=
include $(TOPDIR)/Rules.make
EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
%.lnk: %.o
$(LD) -Ttext 0x0 -o $@ $<
......@@ -29,3 +29,5 @@ dep:
clean:
rm -f image listing iplfba.boot ipleckd.boot ipldump.boot
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map $(TOPDIR)/Kerntypes "$(INSTALL_PATH)"
#!/bin/sh
#
# arch/s390x/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1995 by Linus Torvalds
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
#
# "make install" script for s390 architecture
#
# Arguments:
# $1 - kernel version
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
#
# User may have a custom install script
if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old
fi
if [ -f $4/System.map ]; then
mv $4/System.map $4/System.old
fi
cat $2 > $4/vmlinuz
cp $3 $4/System.map
......@@ -6,8 +6,8 @@
define_bool CONFIG_ISA n
define_bool CONFIG_EISA n
define_bool CONFIG_MCA n
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
define_bool CONFIG_GENERIC_BUST_SPINLOCK n
mainmenu_name "Linux Kernel Configuration"
......@@ -15,6 +15,7 @@ define_bool CONFIG_ARCH_S390 y
define_bool CONFIG_ARCH_S390X y
source init/Config.in
mainmenu_option next_comment
comment 'Processor type and features'
bool 'Symmetric multi-processing support' CONFIG_SMP
......@@ -25,8 +26,16 @@ fi
endmenu
mainmenu_option next_comment
comment 'General setup'
comment 'Base setup'
bool 'Fast IRQ handling' CONFIG_FAST_IRQ
bool 'Process warning machine checks' CONFIG_MACHCHK_WARNING
bool 'Use chscs for Common I/O' CONFIG_CHSC
tristate 'QDIO support' CONFIG_QDIO
if [ "$CONFIG_QDIO" != "n" ]; then
bool ' Performance statistics in /proc' CONFIG_QDIO_PERF_STATS
fi
bool 'Builtin IPL record support' CONFIG_IPL
if [ "$CONFIG_IPL" = "y" ]; then
choice 'IPL method generated into head.S' \
......@@ -41,6 +50,15 @@ bool 'Pseudo page fault support' CONFIG_PFAULT
bool 'VM shared kernel support' CONFIG_SHARED_KERNEL
endmenu
mainmenu_option next_comment
comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
fi
endmenu
source drivers/s390/Config.in
......@@ -54,9 +72,9 @@ mainmenu_option next_comment
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
if [ "$CONFIG_CTC" = "y" ]; then
bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
fi
#if [ "$CONFIG_CTC" = "y" ]; then
# bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
#fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
endmenu
......
......@@ -4,9 +4,9 @@
# CONFIG_ISA is not set
# CONFIG_EISA is not set
# CONFIG_MCA is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
CONFIG_GENERIC_BUST_SPINLOCK=n
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_GENERIC_BUST_SPINLOCK is not set
CONFIG_ARCH_S390=y
CONFIG_ARCH_S390X=y
......@@ -16,11 +16,12 @@ CONFIG_ARCH_S390X=y
CONFIG_EXPERIMENTAL=y
#
# Processor type and features
# General setup
#
CONFIG_SMP=y
CONFIG_S390_SUPPORT=y
CONFIG_BINFMT_ELF32=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
#
# Loadable module support
......@@ -30,16 +31,23 @@ CONFIG_MODULES=y
CONFIG_KMOD=y
#
# General setup
# Processor type and features
#
CONFIG_SMP=y
CONFIG_S390_SUPPORT=y
CONFIG_BINFMT_ELF32=y
#
# Base setup
#
CONFIG_FAST_IRQ=y
CONFIG_MACHCHK_WARNING=y
CONFIG_CHSC=y
CONFIG_QDIO=m
# CONFIG_QDIO_PERF_STATS is not set
CONFIG_IPL=y
# CONFIG_IPL_TAPE is not set
CONFIG_IPL_VM=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
......@@ -47,6 +55,77 @@ CONFIG_BINFMT_ELF=y
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
#
# SCSI support
#
CONFIG_SCSI=m
#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=m
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=m
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_SR_EXTRA_DEVS=10
CONFIG_CHR_DEV_SG=m
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_REPORT_LUNS is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
#
# SCSI low-level drivers
#
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_DMA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
#
# PCMCIA SCSI adapter support
#
# CONFIG_SCSI_PCMCIA is not set
#
# Block device drivers
#
......@@ -103,8 +182,8 @@ CONFIG_S390_TAPE_BLOCK=y
#
# S/390 tape hardware support
#
CONFIG_S390_TAPE_3490=y
CONFIG_S390_TAPE_3480=y
CONFIG_S390_TAPE_3490=m
CONFIG_S390_TAPE_3480=m
#
# Network device drivers
......@@ -123,6 +202,7 @@ CONFIG_TR=y
#
CONFIG_CHANDEV=y
CONFIG_HOTPLUG=y
CONFIG_LCS=m
CONFIG_CTC=m
CONFIG_IUCV=m
......@@ -131,8 +211,6 @@ CONFIG_IUCV=m
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK=y
# CONFIG_RTNETLINK is not set
# CONFIG_NETLINK_DEV is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
......@@ -144,18 +222,24 @@ CONFIG_IP_MULTICAST=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
CONFIG_IPV6=m
# CONFIG_IPV6_NETLINK is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
#
# Appletalk devices
#
# CONFIG_DEV_APPLETALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
......@@ -164,7 +248,7 @@ CONFIG_IPV6=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
CONFIG_NET_FASTROUTE=y
# CONFIG_NET_HW_FLOWCONTROL is not set
#
......@@ -176,18 +260,20 @@ CONFIG_IPV6=m
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_QFMT_V1 is not set
# CONFIG_QFMT_V2 is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_CMS_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
CONFIG_EXT3_FS=y
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
......@@ -198,12 +284,15 @@ CONFIG_IPV6=m
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_TMPFS is not set
# CONFIG_RAMFS is not set
CONFIG_RAMFS=y
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_ZISOFS is not set
# CONFIG_JFS_FS is not set
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_FREEVXFS_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_DEBUG is not set
# CONFIG_HPFS_FS is not set
......@@ -232,8 +321,10 @@ CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_EXPORTFS is not set
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
......@@ -245,7 +336,6 @@ CONFIG_LOCKD=y
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
# CONFIG_ZISOFS_FS is not set
# CONFIG_ZLIB_FS_INFLATE is not set
#
# Partition Types
......@@ -262,6 +352,7 @@ CONFIG_IBM_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SMB_NLS is not set
# CONFIG_NLS is not set
......@@ -269,3 +360,10 @@ CONFIG_IBM_PARTITION=y
# Kernel hacking
#
CONFIG_MAGIC_SYSRQ=y
#
# Library routines
#
# CONFIG_CRC32 is not set
# CONFIG_ZLIB_INFLATE is not set
# CONFIG_ZLIB_DEFLATE is not set
......@@ -2,8 +2,10 @@
# Makefile for the linux kernel.
#
O_TARGET := kernel.o
EXTRA_TARGETS := head.o init_task.o
EXTRA_AFLAGS := -traditional
O_TARGET := kernel.o
export-objs := debug.o ebcdic.o irq.o s390_ext.o smp.o s390_ksyms.o \
exec32.o
......@@ -20,11 +22,10 @@ obj-$(CONFIG_SMP) += smp.o
#
obj-$(CONFIG_REMOTE_DEBUG) += gdb-stub.o #gdb-low.o
obj-$(CONFIG_S390_SUPPORT) += linux32.o signal32.o ioctl32.o wrapper32.o exec32.o
obj-$(CONFIG_S390_SUPPORT) += linux32.o signal32.o ioctl32.o wrapper32.o \
exec32.o exec_domain32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
EXTRA_AFLAGS := -traditional
include $(TOPDIR)/Rules.make
#
......@@ -32,3 +33,27 @@ include $(TOPDIR)/Rules.make
#
binfmt_elf32.o: $(TOPDIR)/fs/binfmt_elf.c
.PHONY: asm-offsets.h
entry.S: asm-offsets.h
#
# Automatic offset generation for assembler files.
#
asm-offsets.h: asm-offsets.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -S $< -o - | grep -- "->" | \
(echo "#ifndef __ASM_OFFSETS_H__"; \
echo "#define __ASM_OFFSETS_H__"; \
echo "/*"; \
echo " * DO NOT MODIFY"; \
echo " *"; \
echo " * This file was generated by arch/s390/kernel/Makefile"; \
echo " */"; \
sed -e "s:^->\([^ ]*\) \([^ ]*\) \(.*\):#define \\1 \\2 /* \\3*/:" \
-e "s:->::"; \
echo "#endif" \
) > asm-offsets.h
clean:
rm -f asm-offsets.h
/*
* Generate definitions needed by assembly language modules.
* This code generates raw asm output which is post-processed to extract
* and format the required data.
*/
#include <linux/config.h>
#include <linux/sched.h>
/* Use marker if you need to separate the values later */
#define DEFINE(sym, val, marker) \
asm volatile("\n->" #sym " %0 " #val " " #marker : : "i" (val))
#define BLANK() asm volatile("\n->" : : )
int main(void)
{
DEFINE(__THREAD_info, offsetof(struct task_struct, thread_info),);
DEFINE(__THREAD_ar2, offsetof(struct task_struct, thread.ar2),);
DEFINE(__THREAD_ar4, offsetof(struct task_struct, thread.ar4),);
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp),);
DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info),);
BLANK();
DEFINE(__TI_task, offsetof(struct thread_info, task),);
DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain),);
DEFINE(__TI_flags, offsetof(struct thread_info, flags),);
DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),);
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),);
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment