Merge commit 'v2.6.35' into kbuild/kbuild

Conflicts:
	arch/powerpc/Makefile
This commit is contained in:
Michal Marek 2010-08-04 13:59:13 +02:00
commit 772320e845
15241 changed files with 1249805 additions and 691683 deletions

View file

@ -54,6 +54,9 @@ config GENERIC_BUG
depends on BUG
default y
config GENERIC_BUG_RELATIVE_POINTERS
def_bool y
config NO_IOMEM
def_bool y
@ -87,6 +90,7 @@ config S390
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_DEFAULT_NO_SPIN_MUTEXES
select HAVE_OPROFILE
select HAVE_KPROBES
@ -95,6 +99,10 @@ config S390
select HAVE_ARCH_TRACEHOOK
select INIT_ALL_POSSIBLE
select HAVE_PERF_EVENTS
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select ARCH_INLINE_SPIN_TRYLOCK
select ARCH_INLINE_SPIN_TRYLOCK_BH
select ARCH_INLINE_SPIN_LOCK
@ -437,13 +445,6 @@ config FORCE_MAX_ZONEORDER
int
default "9"
config PROCESS_DEBUG
bool "Show crashed user process info"
help
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
bool "Pseudo page fault support"
help
@ -479,13 +480,6 @@ config CMM
Everybody who wants to run Linux under VM should select this
option.
config CMM_PROC
bool "/proc interface to cooperative memory management"
depends on CMM
help
Select this option to enable the /proc interface to the
cooperative memory management.
config CMM_IUCV
bool "IUCV special message interface to cooperative memory management"
depends on CMM && (SMSGIUCV=y || CMM=SMSGIUCV)

View file

@ -6,4 +6,17 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug"
config DEBUG_STRICT_USER_COPY_CHECKS
bool "Strict user copy size checks"
---help---
Enabling this option turns a certain set of sanity checks for user
copy operations into compile time warnings.
The copy_from_user() etc checks are there to help test if there
are sufficient security checks on the length argument of
the copy operation, by having gcc prove that the argument is
within bounds.
If unsure, or if you run an older (pre 4.4) gcc, say N.
endmenu

View file

@ -14,6 +14,7 @@
#
ifndef CONFIG_64BIT
LD_BFD := elf32-s390
LDFLAGS := -m elf_s390
KBUILD_CFLAGS += -m31
KBUILD_AFLAGS += -m31
@ -21,6 +22,7 @@ UTS_MACHINE := s390
STACK_SIZE := 8192
CHECKFLAGS += -D__s390__ -msize-long
else
LD_BFD := elf64-s390
LDFLAGS := -m elf64_s390
KBUILD_AFLAGS_MODULE += -fpic -D__PIC__
KBUILD_CFLAGS_MODULE += -fpic -D__PIC__
@ -31,6 +33,8 @@ STACK_SIZE := 16384
CHECKFLAGS += -D__s390__ -D__s390x__
endif
export LD_BFD
cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5)
cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
@ -86,7 +90,9 @@ KBUILD_AFLAGS += $(aflags-y)
OBJCOPYFLAGS := -O binary
LDFLAGS_vmlinux := -e start
head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o
head-y := arch/s390/kernel/head.o
head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o)
head-y += arch/s390/kernel/init_task.o
core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/
@ -100,21 +106,28 @@ drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
boot := arch/s390/boot
all: image
all: image bzImage
install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $@
image: vmlinux
image bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
zfcpdump:
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
vdso_install:
ifeq ($(CONFIG_64BIT),y)
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@
endif
$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
# Don't use tabs in echo arguments
define archhelp
echo '* image - Kernel image for IPL ($(boot)/image)'
echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)'
endef

View file

@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/pagemap.h>

View file

@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <linux/netdevice.h>

View file

@ -181,7 +181,7 @@ static int __init appldata_os_init(void)
goto out;
}
appldata_os_data = kzalloc(max_size, GFP_DMA);
appldata_os_data = kzalloc(max_size, GFP_KERNEL | GFP_DMA);
if (appldata_os_data == NULL) {
rc = -ENOMEM;
goto out;

View file

@ -9,10 +9,18 @@ COMPILE_VERSION := __linux_compile_version_id__`hostname | \
EXTRA_CFLAGS := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
targets := image
targets += bzImage
subdir- := compressed
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
install: $(CONFIGURE) $(obj)/image
sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
System.map Kerntypes "$(INSTALL_PATH)"

View file

@ -0,0 +1,63 @@
#
# linux/arch/s390/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
BITS := $(if $(CONFIG_64BIT),64,31)
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \
vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o sizes.h head$(BITS).o
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(call cc-option,-mpacked-stack)
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
GCOV_PROFILE := n
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o)
OBJECTS += $(obj)/head$(BITS).o $(obj)/misc.o $(obj)/piggy.o
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
$(call if_changed,ld)
@:
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
quiet_cmd_sizes = GEN $@
cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
$(obj)/sizes.h: vmlinux
$(call if_changed,sizes)
AFLAGS_head$(BITS).o += -I$(obj)
$(obj)/head$(BITS).o: $(obj)/sizes.h
CFLAGS_misc.o += -I$(obj)
$(obj)/misc.o: $(obj)/sizes.h
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
$(obj)/vmlinux.bin: vmlinux
$(call if_changed,objcopy)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZMA) := lzma
suffix-$(CONFIG_KERNEL_LZO) := lzo
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
$(call if_changed,lzma)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
$(call if_changed,lzo)
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
$(call if_changed,ld)

View file

@ -0,0 +1,51 @@
/*
* Startup glue code to uncompress the kernel
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include "sizes.h"
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1:
# setup stack
l %r15,.Lstack-.LPG1(%r13)
ahi %r15,-96
l %r1,.Ldecompress-.LPG1(%r13)
basr %r14,%r1
# setup registers for memory mover & branch to target
lr %r4,%r2
l %r2,.Loffset-.LPG1(%r13)
la %r4,0(%r2,%r4)
l %r3,.Lmvsize-.LPG1(%r13)
lr %r5,%r3
# move the memory mover someplace safe
la %r1,0x200
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
# decompress image is started at 0x11000
lr %r6,%r2
br %r1
mover:
mvcle %r2,%r4,0
jo mover
br %r6
mover_end:
.align 8
.Lstack:
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.Ldecompress:
.long decompress_kernel
.Loffset:
.long 0x11000
.Lmvsize:
.long SZ__bss_start

View file

@ -0,0 +1,48 @@
/*
* Startup glue code to uncompress the kernel
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include "sizes.h"
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1:
# setup stack
lg %r15,.Lstack-.LPG1(%r13)
aghi %r15,-160
brasl %r14,decompress_kernel
# setup registers for memory mover & branch to target
lgr %r4,%r2
lg %r2,.Loffset-.LPG1(%r13)
la %r4,0(%r2,%r4)
lg %r3,.Lmvsize-.LPG1(%r13)
lgr %r5,%r3
# move the memory mover someplace safe
la %r1,0x200
mvc 0(mover_end-mover,%r1),mover-.LPG1(%r13)
# decompress image is started at 0x11000
lgr %r6,%r2
br %r1
mover:
mvcle %r2,%r4,0
jo mover
br %r6
mover_end:
.align 8
.Lstack:
.quad 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.Loffset:
.quad 0x11000
.Lmvsize:
.quad SZ__bss_start

View file

@ -0,0 +1,162 @@
/*
* Definitions and wrapper functions for kernel decompressor
*
* Copyright IBM Corp. 2010
*
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/ipl.h>
#include "sizes.h"
/*
* gzip declarations
*/
#define STATIC static
#undef memset
#undef memcpy
#undef memmove
#define memzero(s, n) memset((s), 0, (n))
/* Symbols defined by linker scripts */
extern char input_data[];
extern int input_len;
extern char _text, _end;
extern char _bss, _ebss;
static void error(char *m);
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#ifdef CONFIG_HAVE_KERNEL_BZIP2
#define HEAP_SIZE 0x400000
#else
#define HEAP_SIZE 0x10000
#endif
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_BZIP2
#include "../../../../lib/decompress_bunzip2.c"
#endif
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif
extern _sclp_print_early(const char *);
int puts(const char *s)
{
_sclp_print_early(s);
return 0;
}
void *memset(void *s, int c, size_t n)
{
char *xs;
if (c == 0)
return __builtin_memset(s, 0, n);
xs = (char *) s;
if (n > 0)
do {
*xs++ = c;
} while (--n > 0);
return s;
}
void *memcpy(void *__dest, __const void *__src, size_t __n)
{
return __builtin_memcpy(__dest, __src, __n);
}
void *memmove(void *__dest, __const void *__src, size_t __n)
{
char *d;
const char *s;
if (__dest <= __src)
return __builtin_memcpy(__dest, __src, __n);
d = __dest + __n;
s = __src + __n;
while (__n--)
*--d = *--s;
return __dest;
}
static void error(char *x)
{
unsigned long long psw = 0x000a0000deadbeefULL;
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
asm volatile("lpsw %0" : : "Q" (psw));
}
/*
* Safe guard the ipl parameter block against a memory area that will be
* overwritten. The validity check for the ipl parameter block is complex
* (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
* the ipl parameter block intersects with the passed memory area we can
* safely assume that we can read from that memory. In that case just copy
* the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
* block.
*/
static void check_ipl_parmblock(void *start, unsigned long size)
{
void *src, *dst;
src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
if (src + PAGE_SIZE <= start || src >= start + size)
return;
dst = (void *) IPL_PARMBLOCK_ORIGIN;
memmove(dst, src, PAGE_SIZE);
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
}
unsigned long decompress_kernel(void)
{
unsigned long output_addr;
unsigned char *output;
check_ipl_parmblock((void *) 0, (unsigned long) output + SZ__bss_start);
memset(&_bss, 0, &_ebss - &_bss);
free_mem_ptr = (unsigned long)&_end;
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
output = (unsigned char *) ((free_mem_end_ptr + 4095UL) & -4096UL);
#ifdef CONFIG_BLK_DEV_INITRD
/*
* Move the initrd right behind the end of the decompressed
* kernel image.
*/
if (INITRD_START && INITRD_SIZE &&
INITRD_START < (unsigned long) output + SZ__bss_start) {
check_ipl_parmblock(output + SZ__bss_start,
INITRD_START + INITRD_SIZE);
memmove(output + SZ__bss_start,
(void *) INITRD_START, INITRD_SIZE);
INITRD_START = (unsigned long) output + SZ__bss_start;
}
#endif
puts("Uncompressing Linux... ");
decompress(input_data, input_len, NULL, NULL, output, NULL, error);
puts("Ok, booting the kernel.\n");
return (unsigned long) output;
}

View file

@ -0,0 +1,55 @@
#include <asm-generic/vmlinux.lds.h>
#ifdef CONFIG_64BIT
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
#else
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390)
#endif
ENTRY(startup)
SECTIONS
{
/* Be careful parts of head_64.S assume startup_32 is at
* address 0.
*/
. = 0;
.head.text : {
_head = . ;
HEAD_TEXT
_ehead = . ;
}
.rodata.compressed : {
*(.rodata.compressed)
}
.text : {
_text = .; /* Text */
*(.text)
*(.text.*)
_etext = . ;
}
.rodata : {
_rodata = . ;
*(.rodata) /* read-only data */
*(.rodata.*)
_erodata = . ;
}
.data : {
_data = . ;
*(.data)
*(.data.*)
_edata = . ;
}
. = ALIGN(256);
.bss : {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(8); /* For convenience during zeroing */
_ebss = .;
}
_end = .;
}

View file

@ -0,0 +1,10 @@
SECTIONS
{
.rodata.compressed : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
output_len = . - 4;
input_data_end = .;
}
}

View file

@ -78,14 +78,14 @@ static int setkey_fallback_cip(struct crypto_tfm *tfm, const u8 *in_key,
struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
int ret;
sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
sctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
sctx->fallback.cip->base.crt_flags |= (tfm->crt_flags &
CRYPTO_TFM_REQ_MASK);
ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
if (ret) {
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
tfm->crt_flags |= (sctx->fallback.cip->base.crt_flags &
CRYPTO_TFM_RES_MASK);
}
return ret;

View file

@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <asm/debug.h>
#include <asm/uaccess.h>

View file

@ -79,7 +79,7 @@ int s390_sha_final(struct shash_desc *desc, u8 *out)
memset(ctx->buf + index, 0x00, end - index - 8);
/*
* Append message length. Well, SHA-512 wants a 128 bit lenght value,
* Append message length. Well, SHA-512 wants a 128 bit length value,
* nevertheless we use u64, should be enough for now...
*/
bits = ctx->count * 8;

View file

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.33-rc2
# Mon Jan 4 09:03:07 2010
# Linux kernel version: 2.6.35-rc1
# Fri Jun 4 11:32:40 2010
#
CONFIG_SCHED_MC=y
CONFIG_MMU=y
@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_NO_IOMEM=y
CONFIG_NO_DMA=y
CONFIG_GENERIC_LOCKBREAK=y
@ -34,8 +35,17 @@ CONFIG_CONSTRUCTORS=y
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
@ -55,15 +65,11 @@ CONFIG_TREE_RCU=y
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=64
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
@ -72,6 +78,8 @@ CONFIG_CGROUP_NS=y
# CONFIG_CPUSETS is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_BLK_CGROUP is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@ -86,6 +94,7 @@ CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@ -119,6 +128,7 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
CONFIG_TRACEPOINTS=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_HAVE_SYSCALL_WRAPPERS=y
@ -127,6 +137,7 @@ CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
#
@ -149,7 +160,6 @@ CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
CONFIG_BLK_DEV_BSG=y
# CONFIG_BLK_DEV_INTEGRITY is not set
# CONFIG_BLK_CGROUP is not set
CONFIG_BLOCK_COMPAT=y
#
@ -158,7 +168,6 @@ CONFIG_BLOCK_COMPAT=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_CFQ_GROUP_IOSCHED is not set
CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
@ -311,7 +320,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_HAVE_AOUT is not set
CONFIG_BINFMT_MISC=m
CONFIG_FORCE_MAX_ZONEORDER=9
# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
# CONFIG_CMM is not set
@ -338,13 +346,13 @@ CONFIG_PM_SLEEP=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
# CONFIG_PM_RUNTIME is not set
CONFIG_PM_OPS=y
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@ -448,6 +456,7 @@ CONFIG_NF_CONNTRACK=m
# CONFIG_IP6_NF_IPTABLES is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_NET_SCTPPROBE is not set
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not set
@ -456,6 +465,7 @@ CONFIG_SCTP_HMAC_MD5=y
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
@ -516,12 +526,14 @@ CONFIG_NET_ACT_NAT=m
# CONFIG_NET_CLS_IND is not set
CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set
CONFIG_RPS=y
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
# CONFIG_NET_DROP_MONITOR is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
CONFIG_CAN_BCM=m
@ -536,6 +548,7 @@ CONFIG_CAN_VCAN=m
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_PCMCIA is not set
CONFIG_CCW=y
@ -598,6 +611,7 @@ CONFIG_MISC_DEVICES=y
#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
# CONFIG_SCSI_DMA is not set
@ -717,6 +731,7 @@ CONFIG_VIRTIO_NET=m
# Character devices
#
CONFIG_DEVKMEM=y
# CONFIG_N_GSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
@ -764,6 +779,7 @@ CONFIG_S390_TAPE_34XX=m
# CONFIG_MONREADER is not set
CONFIG_MONWRITER=m
CONFIG_S390_VMUR=m
# CONFIG_RAMOOPS is not set
#
# PPS support
@ -777,10 +793,6 @@ CONFIG_S390_VMUR=m
# CONFIG_NEW_LEDS is not set
CONFIG_ACCESSIBILITY=y
# CONFIG_AUXDISPLAY is not set
#
# TI VLYNQ
#
# CONFIG_STAGING is not set
#
@ -856,6 +868,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_LOGFS is not set
# CONFIG_CRAMFS is not set
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@ -884,6 +897,7 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@ -945,6 +959,7 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
@ -962,16 +977,22 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# CONFIG_LKDTM is not set
# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
@ -988,10 +1009,16 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_KPROBE_EVENT=y
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_ATOMIC64_SELFTEST is not set
CONFIG_SAMPLES=y
# CONFIG_SAMPLE_TRACEPOINTS is not set
# CONFIG_SAMPLE_TRACE_EVENTS is not set
# CONFIG_SAMPLE_KOBJECT is not set
# CONFIG_SAMPLE_KPROBES is not set
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
# Security options
@ -1025,6 +1052,7 @@ CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
CONFIG_CRYPTO_GF128MUL=m
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_PCRYPT is not set
CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=m
@ -1112,7 +1140,7 @@ CONFIG_CRYPTO_SHA512_S390=m
# CONFIG_CRYPTO_DES_S390 is not set
# CONFIG_CRYPTO_AES_S390 is not set
CONFIG_S390_PRNG=m
# CONFIG_BINARY_PRINTF is not set
CONFIG_BINARY_PRINTF=y
#
# Library routines
@ -1129,14 +1157,16 @@ CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_LZO_COMPRESS=m
CONFIG_LZO_DECOMPRESS=m
CONFIG_LZO_DECOMPRESS=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_NLATTR=y
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
# CONFIG_VHOST_NET is not set
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_BALLOON=m

View file

@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/debugfs.h>
#define REG_FILE_MODE 0440
#define UPDATE_FILE_MODE 0220
@ -34,6 +35,9 @@ extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root);
/* VM Hypervisor */
extern int hypfs_vm_init(void);
extern void hypfs_vm_exit(void);
extern int hypfs_vm_create_files(struct super_block *sb, struct dentry *root);
/* Directory for debugfs files */
extern struct dentry *hypfs_dbfs_dir;
#endif /* _HYPFS_H_ */

View file

@ -12,10 +12,10 @@
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <asm/ebcdic.h>
#include "hypfs.h"
@ -23,6 +23,8 @@
#define CPU_NAME_LEN 16 /* type name len of cpus in diag224 name table */
#define TMP_SIZE 64 /* size of temporary buffers */
#define DBFS_D204_HDR_VERSION 0
/* diag 204 subcodes */
enum diag204_sc {
SUBC_STIB4 = 4,
@ -48,6 +50,8 @@ static void *diag204_buf; /* 4K aligned buffer for diag204 data */
static void *diag204_buf_vmalloc; /* vmalloc pointer for diag204 data */
static int diag204_buf_pages; /* number of pages for diag204 data */
static struct dentry *dbfs_d204_file;
/*
* DIAG 204 data structures and member access functions.
*
@ -365,18 +369,21 @@ static void diag204_free_buffer(void)
} else {
free_pages((unsigned long) diag204_buf, 0);
}
diag204_buf_pages = 0;
diag204_buf = NULL;
}
static void *page_align_ptr(void *ptr)
{
return (void *) PAGE_ALIGN((unsigned long) ptr);
}
static void *diag204_alloc_vbuf(int pages)
{
/* The buffer has to be page aligned! */
diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1));
if (!diag204_buf_vmalloc)
return ERR_PTR(-ENOMEM);
diag204_buf = (void*)((unsigned long)diag204_buf_vmalloc
& ~0xfffUL) + 0x1000;
diag204_buf = page_align_ptr(diag204_buf_vmalloc);
diag204_buf_pages = pages;
return diag204_buf;
}
@ -469,17 +476,26 @@ fail_alloc:
return rc;
}
static int diag204_do_store(void *buf, int pages)
{
int rc;
rc = diag204((unsigned long) diag204_store_sc |
(unsigned long) diag204_info_type, pages, buf);
return rc < 0 ? -ENOSYS : 0;
}
static void *diag204_store(void)
{
void *buf;
int pages;
int pages, rc;
buf = diag204_get_buffer(diag204_info_type, &pages);
if (IS_ERR(buf))
goto out;
if (diag204((unsigned long)diag204_store_sc |
(unsigned long)diag204_info_type, pages, buf) < 0)
return ERR_PTR(-ENOSYS);
rc = diag204_do_store(buf, pages);
if (rc)
return ERR_PTR(rc);
out:
return buf;
}
@ -488,7 +504,7 @@ out:
static int diag224(void *ptr)
{
int rc = -ENOTSUPP;
int rc = -EOPNOTSUPP;
asm volatile(
" diag %1,%2,0x224\n"
@ -507,7 +523,7 @@ static int diag224_get_name_table(void)
return -ENOMEM;
if (diag224(diag224_cpu_names)) {
kfree(diag224_cpu_names);
return -ENOTSUPP;
return -EOPNOTSUPP;
}
EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
return 0;
@ -527,6 +543,92 @@ static int diag224_idx2name(int index, char *name)
return 0;
}
struct dbfs_d204_hdr {
u64 len; /* Length of d204 buffer without header */
u16 version; /* Version of header */
u8 sc; /* Used subcode */
char reserved[53];
} __attribute__ ((packed));
struct dbfs_d204 {
struct dbfs_d204_hdr hdr; /* 64 byte header */
char buf[]; /* d204 buffer */
} __attribute__ ((packed));
struct dbfs_d204_private {
struct dbfs_d204 *d204; /* Aligned d204 data with header */
void *base; /* Base pointer (needed for vfree) */
};
static int dbfs_d204_open(struct inode *inode, struct file *file)
{
struct dbfs_d204_private *data;
struct dbfs_d204 *d204;
int rc, buf_size;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr);
data->base = vmalloc(buf_size);
if (!data->base) {
rc = -ENOMEM;
goto fail_kfree_data;
}
memset(data->base, 0, buf_size);
d204 = page_align_ptr(data->base + sizeof(d204->hdr))
- sizeof(d204->hdr);
rc = diag204_do_store(&d204->buf, diag204_buf_pages);
if (rc)
goto fail_vfree_base;
d204->hdr.version = DBFS_D204_HDR_VERSION;
d204->hdr.len = PAGE_SIZE * diag204_buf_pages;
d204->hdr.sc = diag204_store_sc;
data->d204 = d204;
file->private_data = data;
return nonseekable_open(inode, file);
fail_vfree_base:
vfree(data->base);
fail_kfree_data:
kfree(data);
return rc;
}
static int dbfs_d204_release(struct inode *inode, struct file *file)
{
struct dbfs_d204_private *data = file->private_data;
vfree(data->base);
kfree(data);
return 0;
}
static ssize_t dbfs_d204_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
{
struct dbfs_d204_private *data = file->private_data;
return simple_read_from_buffer(buf, size, ppos, data->d204,
data->d204->hdr.len +
sizeof(data->d204->hdr));
}
static const struct file_operations dbfs_d204_ops = {
.open = dbfs_d204_open,
.read = dbfs_d204_read,
.release = dbfs_d204_release,
};
static int hypfs_dbfs_init(void)
{
dbfs_d204_file = debugfs_create_file("diag_204", 0400, hypfs_dbfs_dir,
NULL, &dbfs_d204_ops);
if (IS_ERR(dbfs_d204_file))
return PTR_ERR(dbfs_d204_file);
return 0;
}
__init int hypfs_diag_init(void)
{
int rc;
@ -541,11 +643,17 @@ __init int hypfs_diag_init(void)
pr_err("The hardware system does not provide all "
"functions required by hypfs\n");
}
if (diag204_info_type == INFO_EXT) {
rc = hypfs_dbfs_init();
if (rc)
diag204_free_buffer();
}
return rc;
}
void hypfs_diag_exit(void)
{
debugfs_remove(dbfs_d204_file);
diag224_delete_name_table();
diag204_free_buffer();
}

View file

@ -10,14 +10,18 @@
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/ebcdic.h>
#include <asm/timex.h>
#include "hypfs.h"
#define NAME_LEN 8
#define DBFS_D2FC_HDR_VERSION 0
static char local_guest[] = " ";
static char all_guests[] = "* ";
static char *guest_query;
static struct dentry *dbfs_d2fc_file;
struct diag2fc_data {
__u32 version;
__u32 flags;
@ -76,23 +80,26 @@ static int diag2fc(int size, char* query, void *addr)
return -residual_cnt;
}
static struct diag2fc_data *diag2fc_store(char *query, int *count)
/*
* Allocate buffer for "query" and store diag 2fc at "offset"
*/
static void *diag2fc_store(char *query, unsigned int *count, int offset)
{
void *data;
int size;
struct diag2fc_data *data;
do {
size = diag2fc(0, query, NULL);
if (size < 0)
return ERR_PTR(-EACCES);
data = vmalloc(size);
data = vmalloc(size + offset);
if (!data)
return ERR_PTR(-ENOMEM);
if (diag2fc(size, query, data) == 0)
if (diag2fc(size, query, data + offset) == 0)
break;
vfree(data);
} while (1);
*count = (size / sizeof(*data));
*count = (size / sizeof(struct diag2fc_data));
return data;
}
@ -168,9 +175,10 @@ int hypfs_vm_create_files(struct super_block *sb, struct dentry *root)
{
struct dentry *dir, *file;
struct diag2fc_data *data;
int rc, i, count = 0;
unsigned int count = 0;
int rc, i;
data = diag2fc_store(guest_query, &count);
data = diag2fc_store(guest_query, &count, 0);
if (IS_ERR(data))
return PTR_ERR(data);
@ -218,8 +226,61 @@ failed:
return rc;
}
struct dbfs_d2fc_hdr {
u64 len; /* Length of d2fc buffer without header */
u16 version; /* Version of header */
char tod_ext[16]; /* TOD clock for d2fc */
u64 count; /* Number of VM guests in d2fc buffer */
char reserved[30];
} __attribute__ ((packed));
struct dbfs_d2fc {
struct dbfs_d2fc_hdr hdr; /* 64 byte header */
char buf[]; /* d2fc buffer */
} __attribute__ ((packed));
static int dbfs_d2fc_open(struct inode *inode, struct file *file)
{
struct dbfs_d2fc *data;
unsigned int count;
data = diag2fc_store(guest_query, &count, sizeof(data->hdr));
if (IS_ERR(data))
return PTR_ERR(data);
get_clock_ext(data->hdr.tod_ext);
data->hdr.len = count * sizeof(struct diag2fc_data);
data->hdr.version = DBFS_D2FC_HDR_VERSION;
data->hdr.count = count;
memset(&data->hdr.reserved, 0, sizeof(data->hdr.reserved));
file->private_data = data;
return nonseekable_open(inode, file);
}
static int dbfs_d2fc_release(struct inode *inode, struct file *file)
{
diag2fc_free(file->private_data);
return 0;
}
static ssize_t dbfs_d2fc_read(struct file *file, char __user *buf,
size_t size, loff_t *ppos)
{
struct dbfs_d2fc *data = file->private_data;
return simple_read_from_buffer(buf, size, ppos, data, data->hdr.len +
sizeof(struct dbfs_d2fc_hdr));
}
static const struct file_operations dbfs_d2fc_ops = {
.open = dbfs_d2fc_open,
.read = dbfs_d2fc_read,
.release = dbfs_d2fc_release,
};
int hypfs_vm_init(void)
{
if (!MACHINE_IS_VM)
return 0;
if (diag2fc(0, all_guests, NULL) > 0)
guest_query = all_guests;
else if (diag2fc(0, local_guest, NULL) > 0)
@ -227,5 +288,17 @@ int hypfs_vm_init(void)
else
return -EACCES;
dbfs_d2fc_file = debugfs_create_file("diag_2fc", 0400, hypfs_dbfs_dir,
NULL, &dbfs_d2fc_ops);
if (IS_ERR(dbfs_d2fc_file))
return PTR_ERR(dbfs_d2fc_file);
return 0;
}
void hypfs_vm_exit(void)
{
if (!MACHINE_IS_VM)
return;
debugfs_remove(dbfs_d2fc_file);
}

View file

@ -14,8 +14,8 @@
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/vfs.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/gfp.h>
#include <linux/time.h>
#include <linux/parser.h>
#include <linux/sysfs.h>
@ -46,6 +46,8 @@ static const struct super_operations hypfs_s_ops;
/* start of list of all dentries, which have to be deleted on update */
static struct dentry *hypfs_last_dentry;
struct dentry *hypfs_dbfs_dir;
static void hypfs_update_update(struct super_block *sb)
{
struct hypfs_sb_info *sb_info = sb->s_fs_info;
@ -145,7 +147,7 @@ static int hypfs_open(struct inode *inode, struct file *filp)
}
mutex_unlock(&fs_info->lock);
}
return 0;
return nonseekable_open(inode, filp);
}
static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
@ -288,46 +290,30 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
sb->s_magic = HYPFS_MAGIC;
sb->s_op = &hypfs_s_ops;
if (hypfs_parse_options(data, sb)) {
rc = -EINVAL;
goto err_alloc;
}
if (hypfs_parse_options(data, sb))
return -EINVAL;
root_inode = hypfs_make_inode(sb, S_IFDIR | 0755);
if (!root_inode) {
rc = -ENOMEM;
goto err_alloc;
}
if (!root_inode)
return -ENOMEM;
root_inode->i_op = &simple_dir_inode_operations;
root_inode->i_fop = &simple_dir_operations;
root_dentry = d_alloc_root(root_inode);
sb->s_root = root_dentry = d_alloc_root(root_inode);
if (!root_dentry) {
iput(root_inode);
rc = -ENOMEM;
goto err_alloc;
return -ENOMEM;
}
if (MACHINE_IS_VM)
rc = hypfs_vm_create_files(sb, root_dentry);
else
rc = hypfs_diag_create_files(sb, root_dentry);
if (rc)
goto err_tree;
return rc;
sbi->update_file = hypfs_create_update_file(sb, root_dentry);
if (IS_ERR(sbi->update_file)) {
rc = PTR_ERR(sbi->update_file);
goto err_tree;
}
if (IS_ERR(sbi->update_file))
return PTR_ERR(sbi->update_file);
hypfs_update_update(sb);
sb->s_root = root_dentry;
pr_info("Hypervisor filesystem mounted\n");
return 0;
err_tree:
hypfs_delete_tree(root_dentry);
d_genocide(root_dentry);
dput(root_dentry);
err_alloc:
kfree(sbi);
return rc;
}
static int hypfs_get_super(struct file_system_type *fst, int flags,
@ -340,12 +326,12 @@ static void hypfs_kill_super(struct super_block *sb)
{
struct hypfs_sb_info *sb_info = sb->s_fs_info;
if (sb->s_root) {
if (sb->s_root)
hypfs_delete_tree(sb->s_root);
if (sb_info->update_file)
hypfs_remove(sb_info->update_file);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
}
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
kill_litter_super(sb);
}
@ -484,20 +470,22 @@ static int __init hypfs_init(void)
{
int rc;
if (MACHINE_IS_VM) {
if (hypfs_vm_init())
/* no diag 2fc, just exit */
return -ENODATA;
} else {
if (hypfs_diag_init()) {
rc = -ENODATA;
goto fail_diag;
}
hypfs_dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
if (IS_ERR(hypfs_dbfs_dir))
return PTR_ERR(hypfs_dbfs_dir);
if (hypfs_diag_init()) {
rc = -ENODATA;
goto fail_debugfs_remove;
}
if (hypfs_vm_init()) {
rc = -ENODATA;
goto fail_hypfs_diag_exit;
}
s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
if (!s390_kobj) {
rc = -ENOMEM;
goto fail_sysfs;
goto fail_hypfs_vm_exit;
}
rc = register_filesystem(&hypfs_type);
if (rc)
@ -506,18 +494,22 @@ static int __init hypfs_init(void)
fail_filesystem:
kobject_put(s390_kobj);
fail_sysfs:
if (!MACHINE_IS_VM)
hypfs_diag_exit();
fail_diag:
fail_hypfs_vm_exit:
hypfs_vm_exit();
fail_hypfs_diag_exit:
hypfs_diag_exit();
fail_debugfs_remove:
debugfs_remove(hypfs_dbfs_dir);
pr_err("Initialization of hypfs failed with rc=%i\n", rc);
return rc;
}
static void __exit hypfs_exit(void)
{
if (!MACHINE_IS_VM)
hypfs_diag_exit();
hypfs_diag_exit();
hypfs_vm_exit();
debugfs_remove(hypfs_dbfs_dir);
unregister_filesystem(&hypfs_type);
kobject_put(s390_kobj);
}

View file

@ -15,11 +15,10 @@
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/system.h>
#define ATOMIC_INIT(i) { (i) }
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __CS_LOOP(ptr, op_val, op_string) ({ \
int old_val, new_val; \
asm volatile( \
@ -35,26 +34,6 @@
new_val; \
})
#else /* __GNUC__ */
#define __CS_LOOP(ptr, op_val, op_string) ({ \
int old_val, new_val; \
asm volatile( \
" l %0,0(%3)\n" \
"0: lr %1,%0\n" \
op_string " %1,%4\n" \
" cs %0,%1,0(%3)\n" \
" jl 0b" \
: "=&d" (old_val), "=&d" (new_val), \
"=m" (((atomic_t *)(ptr))->counter) \
: "a" (ptr), "d" (op_val), \
"m" (((atomic_t *)(ptr))->counter) \
: "cc", "memory"); \
new_val; \
})
#endif /* __GNUC__ */
static inline int atomic_read(const atomic_t *v)
{
barrier();
@ -101,19 +80,11 @@ static inline void atomic_set_mask(unsigned long mask, atomic_t *v)
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile(
" cs %0,%2,%1"
: "+d" (old), "=Q" (v->counter)
: "d" (new), "Q" (v->counter)
: "cc", "memory");
#else /* __GNUC__ */
asm volatile(
" cs %0,%3,0(%2)"
: "+d" (old), "=m" (v->counter)
: "a" (v), "d" (new), "m" (v->counter)
: "cc", "memory");
#endif /* __GNUC__ */
return old;
}
@ -140,8 +111,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
#ifdef CONFIG_64BIT
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
long long old_val, new_val; \
asm volatile( \
@ -157,26 +126,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
new_val; \
})
#else /* __GNUC__ */
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
long long old_val, new_val; \
asm volatile( \
" lg %0,0(%3)\n" \
"0: lgr %1,%0\n" \
op_string " %1,%4\n" \
" csg %0,%1,0(%3)\n" \
" jl 0b" \
: "=&d" (old_val), "=&d" (new_val), \
"=m" (((atomic_t *)(ptr))->counter) \
: "a" (ptr), "d" (op_val), \
"m" (((atomic_t *)(ptr))->counter) \
: "cc", "memory"); \
new_val; \
})
#endif /* __GNUC__ */
static inline long long atomic64_read(const atomic64_t *v)
{
barrier();
@ -214,19 +163,11 @@ static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v)
static inline long long atomic64_cmpxchg(atomic64_t *v,
long long old, long long new)
{
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile(
" csg %0,%2,%1"
: "+d" (old), "=Q" (v->counter)
: "d" (new), "Q" (v->counter)
: "cc", "memory");
#else /* __GNUC__ */
asm volatile(
" csg %0,%3,0(%2)"
: "+d" (old), "=m" (v->counter)
: "a" (v), "d" (new), "m" (v->counter)
: "cc", "memory");
#endif /* __GNUC__ */
return old;
}
@ -243,10 +184,8 @@ static inline long long atomic64_read(const atomic64_t *v)
register_pair rp;
asm volatile(
" lm %0,%N0,0(%1)"
: "=&d" (rp)
: "a" (&v->counter), "m" (v->counter)
);
" lm %0,%N0,%1"
: "=&d" (rp) : "Q" (v->counter) );
return rp.pair;
}
@ -255,10 +194,8 @@ static inline void atomic64_set(atomic64_t *v, long long i)
register_pair rp = {.pair = i};
asm volatile(
" stm %1,%N1,0(%2)"
: "=m" (v->counter)
: "d" (rp), "a" (&v->counter)
);
" stm %1,%N1,%0"
: "=Q" (v->counter) : "d" (rp) );
}
static inline long long atomic64_xchg(atomic64_t *v, long long new)
@ -267,11 +204,11 @@ static inline long long atomic64_xchg(atomic64_t *v, long long new)
register_pair rp_old;
asm volatile(
" lm %0,%N0,0(%2)\n"
"0: cds %0,%3,0(%2)\n"
" lm %0,%N0,%1\n"
"0: cds %0,%2,%1\n"
" jl 0b\n"
: "=&d" (rp_old), "+m" (v->counter)
: "a" (&v->counter), "d" (rp_new)
: "=&d" (rp_old), "=Q" (v->counter)
: "d" (rp_new), "Q" (v->counter)
: "cc");
return rp_old.pair;
}
@ -283,9 +220,9 @@ static inline long long atomic64_cmpxchg(atomic64_t *v,
register_pair rp_new = {.pair = new};
asm volatile(
" cds %0,%3,0(%2)"
: "+&d" (rp_old), "+m" (v->counter)
: "a" (&v->counter), "d" (rp_new)
" cds %0,%2,%1"
: "+&d" (rp_old), "=Q" (v->counter)
: "d" (rp_new), "Q" (v->counter)
: "cc");
return rp_old.pair;
}
@ -338,6 +275,7 @@ static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v)
static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
{
long long c, old;
c = atomic64_read(v);
for (;;) {
if (unlikely(c == u))
@ -350,6 +288,23 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
return c != u;
}
static inline long long atomic64_dec_if_positive(atomic64_t *v)
{
long long c, old, dec;
c = atomic64_read(v);
for (;;) {
dec = c - 1;
if (unlikely(dec < 0))
break;
old = atomic64_cmpxchg((v), c, dec);
if (likely(old == c))
break;
c = old;
}
return dec;
}
#define atomic64_add(_i, _v) atomic64_add_return(_i, _v)
#define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0)
#define atomic64_inc(_v) atomic64_add_return(1, _v)

View file

@ -71,8 +71,6 @@ extern const char _sb_findmap[];
#define __BITOPS_AND "nr"
#define __BITOPS_XOR "xr"
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" l %0,%2\n" \
@ -85,22 +83,6 @@ extern const char _sb_findmap[];
: "d" (__val), "Q" (*(unsigned long *) __addr) \
: "cc");
#else /* __GNUC__ */
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" l %0,0(%4)\n" \
"0: lr %1,%0\n" \
__op_string " %1,%3\n" \
" cs %0,%1,0(%4)\n" \
" jl 0b" \
: "=&d" (__old), "=&d" (__new), \
"=m" (*(unsigned long *) __addr) \
: "d" (__val), "a" (__addr), \
"m" (*(unsigned long *) __addr) : "cc");
#endif /* __GNUC__ */
#else /* __s390x__ */
#define __BITOPS_ALIGN 7
@ -109,8 +91,6 @@ extern const char _sb_findmap[];
#define __BITOPS_AND "ngr"
#define __BITOPS_XOR "xgr"
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" lg %0,%2\n" \
@ -123,23 +103,6 @@ extern const char _sb_findmap[];
: "d" (__val), "Q" (*(unsigned long *) __addr) \
: "cc");
#else /* __GNUC__ */
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" lg %0,0(%4)\n" \
"0: lgr %1,%0\n" \
__op_string " %1,%3\n" \
" csg %0,%1,0(%4)\n" \
" jl 0b" \
: "=&d" (__old), "=&d" (__new), \
"=m" (*(unsigned long *) __addr) \
: "d" (__val), "a" (__addr), \
"m" (*(unsigned long *) __addr) : "cc");
#endif /* __GNUC__ */
#endif /* __s390x__ */
#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
@ -261,9 +224,8 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" oc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
" oc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
}
static inline void
@ -290,9 +252,8 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" nc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc");
" nc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" );
}
static inline void
@ -318,9 +279,8 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" xc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
" xc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
}
static inline void
@ -349,10 +309,9 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" oc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" oc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
@ -369,10 +328,9 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" nc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" nc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
@ -389,10 +347,9 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" xc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" xc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
@ -591,11 +548,11 @@ static inline unsigned long __load_ulong_le(const unsigned long *p,
p = (unsigned long *)((unsigned long) p + offset);
#ifndef __s390x__
asm volatile(
" ic %0,0(%1)\n"
" icm %0,2,1(%1)\n"
" icm %0,4,2(%1)\n"
" icm %0,8,3(%1)"
: "=&d" (word) : "a" (p), "m" (*p) : "cc");
" ic %0,%O1(%R1)\n"
" icm %0,2,%O1+1(%R1)\n"
" icm %0,4,%O1+2(%R1)\n"
" icm %0,8,%O1+3(%R1)"
: "=&d" (word) : "Q" (*p) : "cc");
#else
asm volatile(
" lrvg %0,%1"

View file

@ -5,12 +5,6 @@
#ifdef CONFIG_BUG
#ifdef CONFIG_64BIT
#define S390_LONG ".quad"
#else
#define S390_LONG ".long"
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define __EMIT_BUG(x) do { \
@ -21,7 +15,7 @@
"2: .asciz \""__FILE__"\"\n" \
".previous\n" \
".section __bug_table,\"a\"\n" \
"3:\t" S390_LONG "\t1b,2b\n" \
"3: .long 1b-3b,2b-3b\n" \
" .short %0,%1\n" \
" .org 3b+%2\n" \
".previous\n" \
@ -37,7 +31,7 @@
"0: j 0b+2\n" \
"1:\n" \
".section __bug_table,\"a\"\n" \
"2:\t" S390_LONG "\t1b\n" \
"2: .long 1b-2b\n" \
" .short %0\n" \
" .org 2b+%1\n" \
".previous\n" \
@ -52,18 +46,18 @@
unreachable(); \
} while (0)
#define __WARN() do { \
__EMIT_BUG(BUGFLAG_WARNING); \
#define __WARN_TAINT(taint) do { \
__EMIT_BUG(BUGFLAG_TAINT(taint)); \
} while (0)
#define WARN_ON(x) ({ \
int __ret_warn_on = !!(x); \
if (__builtin_constant_p(__ret_warn_on)) { \
if (__ret_warn_on) \
__EMIT_BUG(BUGFLAG_WARNING); \
__WARN(); \
} else { \
if (unlikely(__ret_warn_on)) \
__EMIT_BUG(BUGFLAG_WARNING); \
__WARN(); \
} \
unlikely(__ret_warn_on); \
})

View file

@ -91,6 +91,14 @@ struct ccw_device {
void (*handler) (struct ccw_device *, unsigned long, struct irb *);
};
/*
* Possible CIO actions triggered by the unit check handler.
*/
enum uc_todo {
UC_TODO_RETRY,
UC_TODO_RETRY_ON_NEW_PATH,
UC_TODO_STOP
};
/**
* struct ccw driver - device driver for channel attached devices
@ -107,6 +115,7 @@ struct ccw_device {
* @freeze: callback for freezing during hibernation snapshotting
* @thaw: undo work done in @freeze
* @restore: callback for restoring after hibernation
* @uc_handler: callback for unit check handler
* @driver: embedded device driver structure
* @name: device driver name
*/
@ -124,6 +133,7 @@ struct ccw_driver {
int (*freeze)(struct ccw_device *);
int (*thaw) (struct ccw_device *);
int (*restore)(struct ccw_device *);
enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
struct device_driver driver;
char *name;
};

View file

@ -20,7 +20,7 @@
/**
* struct ccw1 - channel command word
* @cmd_code: command code
* @flags: flags, like IDA adressing, etc.
* @flags: flags, like IDA addressing, etc.
* @count: byte count
* @cda: data address
*

View file

@ -35,7 +35,8 @@
extern long psw32_user_bits;
#define COMPAT_USER_HZ 100
#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
typedef u32 compat_size_t;
typedef s32 compat_ssize_t;

View file

@ -188,15 +188,16 @@ struct s390_idle_data {
DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
void vtime_start_cpu(void);
void vtime_start_cpu(__u64 int_clock, __u64 enter_timer);
cputime64_t s390_get_idle_time(int cpu);
#define arch_idle_time(cpu) s390_get_idle_time(cpu)
static inline void s390_idle_check(void)
static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock,
__u64 enter_timer)
{
if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL)
vtime_start_cpu();
if (regs->psw.mask & PSW_MASK_WAIT)
vtime_start_cpu(int_clock, enter_timer);
}
static inline int s390_nohz_delay(int cpu)

View file

@ -32,6 +32,7 @@ typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
extern int crw_register_handler(int rsc, crw_handler_t handler);
extern void crw_unregister_handler(int rsc);
extern void crw_handle_channel_report(void);
void crw_wait_for_channel_report(void);
#define NR_RSCS 16

View file

@ -145,11 +145,11 @@ static inline int etr_setr(struct etr_eacr *ctrl)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2160000,0(%2)\n"
" .insn s,0xb2160000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*ctrl), "a" (ctrl));
: "+d" (rc) : "Q" (*ctrl));
return rc;
}
@ -159,11 +159,11 @@ static inline int etr_stetr(struct etr_aib *aib)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2170000,0(%2)\n"
" .insn s,0xb2170000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*aib), "a" (aib));
: "+d" (rc) : "Q" (*aib));
return rc;
}
@ -174,11 +174,11 @@ static inline int etr_steai(struct etr_aib *aib, unsigned int func)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2b30000,0(%2)\n"
" .insn s,0xb2b30000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*aib), "a" (aib), "d" (reg0));
: "+d" (rc) : "Q" (*aib), "d" (reg0));
return rc;
}

View file

@ -8,8 +8,6 @@
#include <linux/types.h>
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
/* store then or system mask. */
#define __raw_local_irq_stosm(__or) \
({ \
@ -36,40 +34,6 @@
asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \
})
#else /* __GNUC__ */
/* store then or system mask. */
#define __raw_local_irq_stosm(__or) \
({ \
unsigned long __mask; \
asm volatile( \
" stosm 0(%1),%2" \
: "=m" (__mask) \
: "a" (&__mask), "i" (__or) : "memory"); \
__mask; \
})
/* store then and system mask. */
#define __raw_local_irq_stnsm(__and) \
({ \
unsigned long __mask; \
asm volatile( \
" stnsm 0(%1),%2" \
: "=m" (__mask) \
: "a" (&__mask), "i" (__and) : "memory"); \
__mask; \
})
/* set system mask. */
#define __raw_local_irq_ssm(__mask) \
({ \
asm volatile( \
" ssm 0(%0)" \
: : "a" (&__mask), "m" (__mask) : "memory"); \
})
#endif /* __GNUC__ */
/* interrupt control.. */
static inline unsigned long raw_local_irq_enable(void)
{

View file

@ -1,141 +1,16 @@
/*
* include/asm-s390/lowcore.h
*
* S390 version
* Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Hartmut Penner (hp@de.ibm.com),
* Martin Schwidefsky (schwidefsky@de.ibm.com),
* Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
* Copyright IBM Corp. 1999,2010
* Author(s): Hartmut Penner <hp@de.ibm.com>,
* Martin Schwidefsky <schwidefsky@de.ibm.com>,
* Denis Joseph Barrow,
*/
#ifndef _ASM_S390_LOWCORE_H
#define _ASM_S390_LOWCORE_H
#define __LC_IPL_PARMBLOCK_PTR 0x0014
#define __LC_EXT_PARAMS 0x0080
#define __LC_CPU_ADDRESS 0x0084
#define __LC_EXT_INT_CODE 0x0086
#define __LC_SVC_ILC 0x0088
#define __LC_SVC_INT_CODE 0x008a
#define __LC_PGM_ILC 0x008c
#define __LC_PGM_INT_CODE 0x008e
#define __LC_PER_ATMID 0x0096
#define __LC_PER_ADDRESS 0x0098
#define __LC_PER_ACCESS_ID 0x00a1
#define __LC_AR_MODE_ID 0x00a3
#define __LC_SUBCHANNEL_ID 0x00b8
#define __LC_SUBCHANNEL_NR 0x00ba
#define __LC_IO_INT_PARM 0x00bc
#define __LC_IO_INT_WORD 0x00c0
#define __LC_STFL_FAC_LIST 0x00c8
#define __LC_MCCK_CODE 0x00e8
#define __LC_DUMP_REIPL 0x0e00
#ifndef __s390x__
#define __LC_EXT_OLD_PSW 0x0018
#define __LC_SVC_OLD_PSW 0x0020
#define __LC_PGM_OLD_PSW 0x0028
#define __LC_MCK_OLD_PSW 0x0030
#define __LC_IO_OLD_PSW 0x0038
#define __LC_EXT_NEW_PSW 0x0058
#define __LC_SVC_NEW_PSW 0x0060
#define __LC_PGM_NEW_PSW 0x0068
#define __LC_MCK_NEW_PSW 0x0070
#define __LC_IO_NEW_PSW 0x0078
#define __LC_SAVE_AREA 0x0200
#define __LC_RETURN_PSW 0x0240
#define __LC_RETURN_MCCK_PSW 0x0248
#define __LC_SYNC_ENTER_TIMER 0x0250
#define __LC_ASYNC_ENTER_TIMER 0x0258
#define __LC_EXIT_TIMER 0x0260
#define __LC_USER_TIMER 0x0268
#define __LC_SYSTEM_TIMER 0x0270
#define __LC_STEAL_TIMER 0x0278
#define __LC_LAST_UPDATE_TIMER 0x0280
#define __LC_LAST_UPDATE_CLOCK 0x0288
#define __LC_CURRENT 0x0290
#define __LC_THREAD_INFO 0x0294
#define __LC_KERNEL_STACK 0x0298
#define __LC_ASYNC_STACK 0x029c
#define __LC_PANIC_STACK 0x02a0
#define __LC_KERNEL_ASCE 0x02a4
#define __LC_USER_ASCE 0x02a8
#define __LC_USER_EXEC_ASCE 0x02ac
#define __LC_CPUID 0x02b0
#define __LC_INT_CLOCK 0x02c8
#define __LC_MACHINE_FLAGS 0x02d8
#define __LC_FTRACE_FUNC 0x02dc
#define __LC_IRB 0x0300
#define __LC_PFAULT_INTPARM 0x0080
#define __LC_CPU_TIMER_SAVE_AREA 0x00d8
#define __LC_CLOCK_COMP_SAVE_AREA 0x00e0
#define __LC_PSW_SAVE_AREA 0x0100
#define __LC_PREFIX_SAVE_AREA 0x0108
#define __LC_AREGS_SAVE_AREA 0x0120
#define __LC_FPREGS_SAVE_AREA 0x0160
#define __LC_GPREGS_SAVE_AREA 0x0180
#define __LC_CREGS_SAVE_AREA 0x01c0
#else /* __s390x__ */
#define __LC_LAST_BREAK 0x0110
#define __LC_EXT_OLD_PSW 0x0130
#define __LC_SVC_OLD_PSW 0x0140
#define __LC_PGM_OLD_PSW 0x0150
#define __LC_MCK_OLD_PSW 0x0160
#define __LC_IO_OLD_PSW 0x0170
#define __LC_RESTART_PSW 0x01a0
#define __LC_EXT_NEW_PSW 0x01b0
#define __LC_SVC_NEW_PSW 0x01c0
#define __LC_PGM_NEW_PSW 0x01d0
#define __LC_MCK_NEW_PSW 0x01e0
#define __LC_IO_NEW_PSW 0x01f0
#define __LC_SAVE_AREA 0x0200
#define __LC_RETURN_PSW 0x0280
#define __LC_RETURN_MCCK_PSW 0x0290
#define __LC_SYNC_ENTER_TIMER 0x02a0
#define __LC_ASYNC_ENTER_TIMER 0x02a8
#define __LC_EXIT_TIMER 0x02b0
#define __LC_USER_TIMER 0x02b8
#define __LC_SYSTEM_TIMER 0x02c0
#define __LC_STEAL_TIMER 0x02c8
#define __LC_LAST_UPDATE_TIMER 0x02d0
#define __LC_LAST_UPDATE_CLOCK 0x02d8
#define __LC_CURRENT 0x02e0
#define __LC_THREAD_INFO 0x02e8
#define __LC_KERNEL_STACK 0x02f0
#define __LC_ASYNC_STACK 0x02f8
#define __LC_PANIC_STACK 0x0300
#define __LC_KERNEL_ASCE 0x0308
#define __LC_USER_ASCE 0x0310
#define __LC_USER_EXEC_ASCE 0x0318
#define __LC_CPUID 0x0320
#define __LC_INT_CLOCK 0x0340
#define __LC_VDSO_PER_CPU 0x0350
#define __LC_MACHINE_FLAGS 0x0358
#define __LC_FTRACE_FUNC 0x0360
#define __LC_IRB 0x0380
#define __LC_PASTE 0x03c0
#define __LC_PFAULT_INTPARM 0x11b8
#define __LC_FPREGS_SAVE_AREA 0x1200
#define __LC_GPREGS_SAVE_AREA 0x1280
#define __LC_PSW_SAVE_AREA 0x1300
#define __LC_PREFIX_SAVE_AREA 0x1318
#define __LC_FP_CREG_SAVE_AREA 0x131c
#define __LC_TODREG_SAVE_AREA 0x1324
#define __LC_CPU_TIMER_SAVE_AREA 0x1328
#define __LC_CLOCK_COMP_SAVE_AREA 0x1331
#define __LC_AREGS_SAVE_AREA 0x1340
#define __LC_CREGS_SAVE_AREA 0x1380
#endif /* __s390x__ */
#ifndef __ASSEMBLY__
#include <asm/cpu.h>
#include <asm/ptrace.h>
#include <linux/types.h>
#include <asm/ptrace.h>
#include <asm/cpu.h>
void restart_int_handler(void);
void ext_int_handler(void);
@ -144,7 +19,12 @@ void pgm_check_handler(void);
void mcck_int_handler(void);
void io_int_handler(void);
struct save_area_s390 {
#ifdef CONFIG_32BIT
#define LC_ORDER 0
#define LC_PAGES 1
struct save_area {
u32 ext_save;
u64 timer;
u64 clk_cmp;
@ -156,54 +36,13 @@ struct save_area_s390 {
u64 fp_regs[4];
u32 gp_regs[16];
u32 ctrl_regs[16];
} __attribute__((packed));
} __packed;
struct save_area_s390x {
u64 fp_regs[16];
u64 gp_regs[16];
u8 psw[16];
u8 pad1[8];
u32 pref_reg;
u32 fp_ctrl_reg;
u8 pad2[4];
u32 tod_reg;
u64 timer;
u64 clk_cmp;
u8 pad3[8];
u32 acc_regs[16];
u64 ctrl_regs[16];
} __attribute__((packed));
union save_area {
struct save_area_s390 s390;
struct save_area_s390x s390x;
};
#define SAVE_AREA_BASE_S390 0xd4
#define SAVE_AREA_BASE_S390X 0x1200
#ifndef __s390x__
#define SAVE_AREA_SIZE sizeof(struct save_area_s390)
#define SAVE_AREA_BASE SAVE_AREA_BASE_S390
#else
#define SAVE_AREA_SIZE sizeof(struct save_area_s390x)
#define SAVE_AREA_BASE SAVE_AREA_BASE_S390X
#endif
#ifndef __s390x__
#define LC_ORDER 0
#else
#define LC_ORDER 1
#endif
#define LC_PAGES (1UL << LC_ORDER)
struct _lowcore
{
#ifndef __s390x__
/* 0x0000 - 0x01ff: defined by architecture */
struct _lowcore {
psw_t restart_psw; /* 0x0000 */
__u32 ccw2[4]; /* 0x0008 */
psw_t restart_old_psw; /* 0x0008 */
__u8 pad_0x0010[0x0014-0x0010]; /* 0x0010 */
__u32 ipl_parmblock_ptr; /* 0x0014 */
psw_t external_old_psw; /* 0x0018 */
psw_t svc_old_psw; /* 0x0020 */
psw_t program_old_psw; /* 0x0028 */
@ -229,7 +68,9 @@ struct _lowcore
__u32 monitor_code; /* 0x009c */
__u8 exc_access_id; /* 0x00a0 */
__u8 per_access_id; /* 0x00a1 */
__u8 pad_0x00a2[0x00b8-0x00a2]; /* 0x00a2 */
__u8 op_access_id; /* 0x00a2 */
__u8 ar_access_id; /* 0x00a3 */
__u8 pad_0x00a4[0x00b8-0x00a4]; /* 0x00a4 */
__u16 subchannel_id; /* 0x00b8 */
__u16 subchannel_nr; /* 0x00ba */
__u32 io_int_parm; /* 0x00bc */
@ -245,8 +86,9 @@ struct _lowcore
__u32 external_damage_code; /* 0x00f4 */
__u32 failing_storage_address; /* 0x00f8 */
__u8 pad_0x00fc[0x0100-0x00fc]; /* 0x00fc */
__u32 st_status_fixed_logout[4]; /* 0x0100 */
__u8 pad_0x0110[0x0120-0x0110]; /* 0x0110 */
psw_t psw_save_area; /* 0x0100 */
__u32 prefixreg_save_area; /* 0x0108 */
__u8 pad_0x010c[0x0120-0x010c]; /* 0x010c */
/* CPU register save area: defined by architecture */
__u32 access_regs_save_area[16]; /* 0x0120 */
@ -262,43 +104,44 @@ struct _lowcore
/* CPU time accounting values */
__u64 sync_enter_timer; /* 0x0250 */
__u64 async_enter_timer; /* 0x0258 */
__u64 exit_timer; /* 0x0260 */
__u64 user_timer; /* 0x0268 */
__u64 system_timer; /* 0x0270 */
__u64 steal_timer; /* 0x0278 */
__u64 last_update_timer; /* 0x0280 */
__u64 last_update_clock; /* 0x0288 */
__u64 mcck_enter_timer; /* 0x0260 */
__u64 exit_timer; /* 0x0268 */
__u64 user_timer; /* 0x0270 */
__u64 system_timer; /* 0x0278 */
__u64 steal_timer; /* 0x0280 */
__u64 last_update_timer; /* 0x0288 */
__u64 last_update_clock; /* 0x0290 */
/* Current process. */
__u32 current_task; /* 0x0290 */
__u32 thread_info; /* 0x0294 */
__u32 kernel_stack; /* 0x0298 */
__u32 current_task; /* 0x0298 */
__u32 thread_info; /* 0x029c */
__u32 kernel_stack; /* 0x02a0 */
/* Interrupt and panic stack. */
__u32 async_stack; /* 0x029c */
__u32 panic_stack; /* 0x02a0 */
__u32 async_stack; /* 0x02a4 */
__u32 panic_stack; /* 0x02a8 */
/* Address space pointer. */
__u32 kernel_asce; /* 0x02a4 */
__u32 user_asce; /* 0x02a8 */
__u32 user_exec_asce; /* 0x02ac */
__u32 kernel_asce; /* 0x02ac */
__u32 user_asce; /* 0x02b0 */
__u32 user_exec_asce; /* 0x02b4 */
/* SMP info area */
struct cpuid cpu_id; /* 0x02b0 */
__u32 cpu_nr; /* 0x02b8 */
__u32 softirq_pending; /* 0x02bc */
__u32 percpu_offset; /* 0x02c0 */
__u32 ext_call_fast; /* 0x02c4 */
__u64 int_clock; /* 0x02c8 */
__u64 clock_comparator; /* 0x02d0 */
__u32 machine_flags; /* 0x02d8 */
__u32 ftrace_func; /* 0x02dc */
__u8 pad_0x02f0[0x0300-0x02f0]; /* 0x02f0 */
__u64 mcck_clock; /* 0x02d0 */
__u64 clock_comparator; /* 0x02d8 */
__u32 machine_flags; /* 0x02e0 */
__u32 ftrace_func; /* 0x02e4 */
__u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */
/* Interrupt response block */
__u8 irb[64]; /* 0x0300 */
__u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */
__u8 pad_0x0340[0x0e00-0x0340]; /* 0x0340 */
/*
* 0xe00 contains the address of the IPL Parameter Information
@ -310,10 +153,32 @@ struct _lowcore
/* Align to the top 1k of prefix area */
__u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */
#else /* !__s390x__ */
/* 0x0000 - 0x01ff: defined by architecture */
__u32 ccw1[2]; /* 0x0000 */
__u32 ccw2[4]; /* 0x0008 */
} __packed;
#else /* CONFIG_32BIT */
#define LC_ORDER 1
#define LC_PAGES 2
struct save_area {
u64 fp_regs[16];
u64 gp_regs[16];
u8 psw[16];
u8 pad1[8];
u32 pref_reg;
u32 fp_ctrl_reg;
u8 pad2[4];
u32 tod_reg;
u64 timer;
u64 clk_cmp;
u8 pad3[8];
u32 acc_regs[16];
u64 ctrl_regs[16];
} __packed;
struct _lowcore {
__u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */
__u32 ipl_parmblock_ptr; /* 0x0014 */
__u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */
__u32 ext_params; /* 0x0080 */
__u16 cpu_addr; /* 0x0084 */
@ -325,14 +190,14 @@ struct _lowcore
__u32 data_exc_code; /* 0x0090 */
__u16 mon_class_num; /* 0x0094 */
__u16 per_perc_atmid; /* 0x0096 */
addr_t per_address; /* 0x0098 */
__u64 per_address; /* 0x0098 */
__u8 exc_access_id; /* 0x00a0 */
__u8 per_access_id; /* 0x00a1 */
__u8 op_access_id; /* 0x00a2 */
__u8 ar_access_id; /* 0x00a3 */
__u8 pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */
addr_t trans_exc_code; /* 0x00a8 */
addr_t monitor_code; /* 0x00b0 */
__u64 trans_exc_code; /* 0x00a8 */
__u64 monitor_code; /* 0x00b0 */
__u16 subchannel_id; /* 0x00b8 */
__u16 subchannel_nr; /* 0x00ba */
__u32 io_int_parm; /* 0x00bc */
@ -343,8 +208,10 @@ struct _lowcore
__u32 mcck_interruption_code[2]; /* 0x00e8 */
__u8 pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */
__u32 external_damage_code; /* 0x00f4 */
addr_t failing_storage_address; /* 0x00f8 */
__u8 pad_0x0100[0x0120-0x0100]; /* 0x0100 */
__u64 failing_storage_address; /* 0x00f8 */
__u8 pad_0x0100[0x0110-0x0100]; /* 0x0100 */
__u64 breaking_event_addr; /* 0x0110 */
__u8 pad_0x0118[0x0120-0x0118]; /* 0x0118 */
psw_t restart_old_psw; /* 0x0120 */
psw_t external_old_psw; /* 0x0130 */
psw_t svc_old_psw; /* 0x0140 */
@ -367,39 +234,41 @@ struct _lowcore
/* CPU accounting and timing values. */
__u64 sync_enter_timer; /* 0x02a0 */
__u64 async_enter_timer; /* 0x02a8 */
__u64 exit_timer; /* 0x02b0 */
__u64 user_timer; /* 0x02b8 */
__u64 system_timer; /* 0x02c0 */
__u64 steal_timer; /* 0x02c8 */
__u64 last_update_timer; /* 0x02d0 */
__u64 last_update_clock; /* 0x02d8 */
__u64 mcck_enter_timer; /* 0x02b0 */
__u64 exit_timer; /* 0x02b8 */
__u64 user_timer; /* 0x02c0 */
__u64 system_timer; /* 0x02c8 */
__u64 steal_timer; /* 0x02d0 */
__u64 last_update_timer; /* 0x02d8 */
__u64 last_update_clock; /* 0x02e0 */
/* Current process. */
__u64 current_task; /* 0x02e0 */
__u64 thread_info; /* 0x02e8 */
__u64 kernel_stack; /* 0x02f0 */
__u64 current_task; /* 0x02e8 */
__u64 thread_info; /* 0x02f0 */
__u64 kernel_stack; /* 0x02f8 */
/* Interrupt and panic stack. */
__u64 async_stack; /* 0x02f8 */
__u64 panic_stack; /* 0x0300 */
__u64 async_stack; /* 0x0300 */
__u64 panic_stack; /* 0x0308 */
/* Address space pointer. */
__u64 kernel_asce; /* 0x0308 */
__u64 user_asce; /* 0x0310 */
__u64 user_exec_asce; /* 0x0318 */
__u64 kernel_asce; /* 0x0310 */
__u64 user_asce; /* 0x0318 */
__u64 user_exec_asce; /* 0x0320 */
/* SMP info area */
struct cpuid cpu_id; /* 0x0320 */
__u32 cpu_nr; /* 0x0328 */
__u32 softirq_pending; /* 0x032c */
__u64 percpu_offset; /* 0x0330 */
__u64 ext_call_fast; /* 0x0338 */
__u64 int_clock; /* 0x0340 */
__u64 clock_comparator; /* 0x0348 */
__u64 vdso_per_cpu_data; /* 0x0350 */
__u64 machine_flags; /* 0x0358 */
__u64 ftrace_func; /* 0x0360 */
__u8 pad_0x0368[0x0380-0x0368]; /* 0x0368 */
__u64 mcck_clock; /* 0x0348 */
__u64 clock_comparator; /* 0x0350 */
__u64 vdso_per_cpu_data; /* 0x0358 */
__u64 machine_flags; /* 0x0360 */
__u64 ftrace_func; /* 0x0368 */
__u64 sie_hook; /* 0x0370 */
__u64 cmf_hpp; /* 0x0378 */
/* Interrupt response block. */
__u8 irb[64]; /* 0x0380 */
@ -425,7 +294,7 @@ struct _lowcore
/* CPU register save area: defined by architecture */
__u64 floating_pt_save_area[16]; /* 0x1200 */
__u64 gpregs_save_area[16]; /* 0x1280 */
__u32 st_status_fixed_logout[4]; /* 0x1300 */
psw_t psw_save_area; /* 0x1300 */
__u8 pad_0x1310[0x1318-0x1310]; /* 0x1310 */
__u32 prefixreg_save_area; /* 0x1318 */
__u32 fpt_creg_save_area; /* 0x131c */
@ -439,10 +308,12 @@ struct _lowcore
/* align to the top of the prefix area */
__u8 pad_0x1400[0x2000-0x1400]; /* 0x1400 */
#endif /* !__s390x__ */
} __attribute__((packed)); /* End structure*/
} __packed;
#endif /* CONFIG_32BIT */
#define S390_lowcore (*((struct _lowcore *) 0))
extern struct _lowcore *lowcore_ptr[];
static inline void set_prefix(__u32 address)
@ -458,6 +329,4 @@ static inline __u32 store_prefix(void)
return address;
}
#endif
#endif
#endif /* _ASM_S390_LOWCORE_H */

View file

@ -107,9 +107,6 @@ typedef pte_t *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
/* default storage key used for all pages */
extern unsigned int default_storage_key;
static inline void
page_set_storage_key(unsigned long addr, unsigned int skey)
{

View file

@ -43,7 +43,7 @@ extern void vmem_map_init(void);
* The S390 doesn't have any external MMU info: the kernel page
* tables contain all the necessary information.
*/
#define update_mmu_cache(vma, address, pte) do { } while (0)
#define update_mmu_cache(vma, address, ptep) do { } while (0)
/*
* ZERO_PAGE is a global shared page that is always zero: used
@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
#ifndef __ASSEMBLY__
/*
* The vmalloc area will always be on the topmost area of the kernel
* mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
* mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
* which should be enough for any sane case.
* By putting vmalloc at the top, we maximise the gap between physical
* memory and vmalloc to catch misplaced memory accesses. As a side
@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
#define VMALLOC_END 0x7e000000UL
#define VMEM_MAP_END 0x80000000UL
#else /* __s390x__ */
#define VMALLOC_SIZE (1UL << 30)
#define VMALLOC_END 0x3e040000000UL
#define VMALLOC_SIZE (128UL << 30)
#define VMALLOC_END 0x3e000000000UL
#define VMEM_MAP_END 0x40000000000UL
#endif /* __s390x__ */

View file

@ -28,7 +28,7 @@
static inline void get_cpu_id(struct cpuid *ptr)
{
asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
asm volatile("stidp %0" : "=Q" (*ptr));
}
extern void s390_adjust_jiffies(void);
@ -184,9 +184,9 @@ static inline void psw_set_key(unsigned int key)
static inline void __load_psw(psw_t psw)
{
#ifndef __s390x__
asm volatile("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
asm volatile("lpsw %0" : : "Q" (psw) : "cc");
#else
asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
asm volatile("lpswe %0" : : "Q" (psw) : "cc");
#endif
}
@ -206,17 +206,17 @@ static inline void __load_psw_mask (unsigned long mask)
asm volatile(
" basr %0,0\n"
"0: ahi %0,1f-0b\n"
" st %0,4(%1)\n"
" lpsw 0(%1)\n"
" st %0,%O1+4(%R1)\n"
" lpsw %1\n"
"1:"
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
#else /* __s390x__ */
asm volatile(
" larl %0,1f\n"
" stg %0,8(%1)\n"
" lpswe 0(%1)\n"
" stg %0,%O1+8(%R1)\n"
" lpswe %1\n"
"1:"
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
#endif /* __s390x__ */
}

View file

@ -328,8 +328,8 @@ struct pt_regs
psw_t psw;
unsigned long gprs[NUM_GPRS];
unsigned long orig_gpr2;
unsigned short svcnr;
unsigned short ilc;
unsigned short svcnr;
};
#endif
@ -436,6 +436,7 @@ typedef struct
#define PTRACE_PEEKDATA_AREA 0x5003
#define PTRACE_POKETEXT_AREA 0x5004
#define PTRACE_POKEDATA_AREA 0x5005
#define PTRACE_GET_LAST_BREAK 0x5006
/*
* PT_PROT definition is loosely based on hppa bsd definition in
@ -489,16 +490,24 @@ struct user_regs_struct
* These are defined as per linux/ptrace.h, which see.
*/
#define arch_has_single_step() (1)
struct task_struct;
extern void user_enable_single_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
extern void show_regs(struct pt_regs * regs);
#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
#define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
#define user_stack_pointer(regs)((regs)->gprs[15])
#define regs_return_value(regs)((regs)->gprs[2])
#define profile_pc(regs) instruction_pointer(regs)
extern void show_regs(struct pt_regs * regs);
int regs_query_register_offset(const char *name);
const char *regs_query_register_name(unsigned int offset);
unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset);
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
return regs->gprs[15] & PSW_ADDR_INSN;
}
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */

View file

@ -13,7 +13,8 @@
#include <asm/cio.h>
#include <asm/ccwdev.h>
#define QDIO_MAX_QUEUES_PER_IRQ 32
/* only use 4 queues to save some cachelines */
#define QDIO_MAX_QUEUES_PER_IRQ 4
#define QDIO_MAX_BUFFERS_PER_Q 128
#define QDIO_MAX_BUFFERS_MASK (QDIO_MAX_BUFFERS_PER_Q - 1)
#define QDIO_MAX_ELEMENTS_PER_BUFFER 16
@ -320,11 +321,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
#define QDIO_ERROR_SLSB_STATE 0x80
/* for qdio_initialize */
#define QDIO_INBOUND_0COPY_SBALS 0x01
#define QDIO_OUTBOUND_0COPY_SBALS 0x02
#define QDIO_USE_OUTBOUND_PCIS 0x04
/* for qdio_cleanup */
#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
@ -343,7 +339,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
* @input_handler: handler to be called for input queues
* @output_handler: handler to be called for output queues
* @int_parm: interruption parameter
* @flags: initialization flags
* @input_sbal_addr_array: address of no_input_qs * 128 pointers
* @output_sbal_addr_array: address of no_output_qs * 128 pointers
*/
@ -360,7 +355,6 @@ struct qdio_initialize {
qdio_handler_t *input_handler;
qdio_handler_t *output_handler;
unsigned long int_parm;
unsigned long flags;
void **input_sbal_addr_array;
void **output_sbal_addr_array;
};
@ -374,14 +368,12 @@ struct qdio_initialize {
#define QDIO_FLAG_SYNC_OUTPUT 0x02
#define QDIO_FLAG_PCI_OUT 0x10
extern int qdio_initialize(struct qdio_initialize *);
extern int qdio_allocate(struct qdio_initialize *);
extern int qdio_establish(struct qdio_initialize *);
extern int qdio_activate(struct ccw_device *);
extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
int q_nr, unsigned int bufnr, unsigned int count);
extern int qdio_cleanup(struct ccw_device*, int);
extern int qdio_shutdown(struct ccw_device*, int);
extern int qdio_free(struct ccw_device *);
extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*);

View file

@ -124,21 +124,21 @@ static inline void __down_read(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
if (old < 0)
rwsem_down_read_failed(sem);
}
@ -152,25 +152,25 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: ltr %1,%0\n"
" jm 1f\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b\n"
"1:"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: ltgr %1,%0\n"
" jm 1f\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b\n"
"1:"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
return old >= 0 ? 1 : 0;
}
@ -184,20 +184,20 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
tmp = RWSEM_ACTIVE_WRITE_BIAS;
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" a %1,%5\n"
" cs %0,%1,0(%3)\n"
" a %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" ag %1,%5\n"
" csg %0,%1,0(%3)\n"
" ag %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "m" (tmp)
: "cc", "memory");
if (old != 0)
rwsem_down_write_failed(sem);
@ -217,22 +217,22 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%2)\n"
" l %0,%1\n"
"0: ltr %0,%0\n"
" jnz 1f\n"
" cs %0,%4,0(%2)\n"
" cs %0,%3,%1\n"
" jl 0b\n"
#else /* __s390x__ */
" lg %0,0(%2)\n"
" lg %0,%1\n"
"0: ltgr %0,%0\n"
" jnz 1f\n"
" csg %0,%4,0(%2)\n"
" csg %0,%3,%1\n"
" jl 0b\n"
#endif /* __s390x__ */
"1:"
: "=&d" (old), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory");
: "=&d" (old), "=Q" (sem->count)
: "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS)
: "cc", "memory");
return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
}
@ -245,21 +245,20 @@ static inline void __up_read(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (-RWSEM_ACTIVE_READ_BIAS)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
if (new < 0)
if ((new & RWSEM_ACTIVE_MASK) == 0)
@ -276,20 +275,20 @@ static inline void __up_write(struct rw_semaphore *sem)
tmp = -RWSEM_ACTIVE_WRITE_BIAS;
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" a %1,%5\n"
" cs %0,%1,0(%3)\n"
" a %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" ag %1,%5\n"
" csg %0,%1,0(%3)\n"
" ag %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "m" (tmp)
: "cc", "memory");
if (new < 0)
if ((new & RWSEM_ACTIVE_MASK) == 0)
@ -306,20 +305,20 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
tmp = -RWSEM_WAITING_BIAS;
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" a %1,%5\n"
" cs %0,%1,0(%3)\n"
" a %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" ag %1,%5\n"
" csg %0,%1,0(%3)\n"
" ag %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "m" (tmp)
: "cc", "memory");
if (new > 1)
rwsem_downgrade_wake(sem);
@ -334,20 +333,20 @@ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ar %1,%5\n"
" cs %0,%1,0(%3)\n"
" ar %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" agr %1,%5\n"
" csg %0,%1,0(%3)\n"
" agr %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "d" (delta)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "d" (delta)
: "cc", "memory");
}
@ -360,20 +359,20 @@ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ar %1,%5\n"
" cs %0,%1,0(%3)\n"
" ar %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" agr %1,%5\n"
" csg %0,%1,0(%3)\n"
" agr %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "d" (delta)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "d" (delta)
: "cc", "memory");
return new;
}

View file

@ -1 +1,3 @@
#define ISA_DMA_THRESHOLD (~0UL)
#include <asm-generic/scatterlist.h>

View file

@ -2,7 +2,7 @@
* include/asm-s390/setup.h
*
* S390 version
* Copyright IBM Corp. 1999,2006
* Copyright IBM Corp. 1999,2010
*/
#ifndef _ASM_S390_SETUP_H
@ -14,14 +14,14 @@
#ifdef __KERNEL__
#include <asm/lowcore.h>
#include <asm/types.h>
#define PARMAREA 0x10400
#define MEMORY_CHUNKS 256
#ifndef __ASSEMBLY__
#include <asm/lowcore.h>
#include <asm/types.h>
#ifndef __s390x__
#define IPL_DEVICE (*(unsigned long *) (0x10404))
#define INITRD_START (*(unsigned long *) (0x1040C))
@ -71,9 +71,13 @@ extern unsigned int user_mode;
#define MACHINE_FLAG_KVM (1UL << 9)
#define MACHINE_FLAG_HPAGE (1UL << 10)
#define MACHINE_FLAG_PFMF (1UL << 11)
#define MACHINE_FLAG_LPAR (1UL << 12)
#define MACHINE_FLAG_SPP (1UL << 13)
#define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
#define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
#define MACHINE_IS_LPAR (S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
#define MACHINE_HAS_DIAG9C (S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
#ifndef __s390x__
@ -85,6 +89,7 @@ extern unsigned int user_mode;
#define MACHINE_HAS_MVCOS (0)
#define MACHINE_HAS_HPAGE (0)
#define MACHINE_HAS_PFMF (0)
#define MACHINE_HAS_SPP (0)
#else /* __s390x__ */
#define MACHINE_HAS_IEEE (1)
#define MACHINE_HAS_CSP (1)
@ -94,6 +99,7 @@ extern unsigned int user_mode;
#define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
#define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
#define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
#define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
#endif /* __s390x__ */
#define ZFCPDUMP_HSA_SIZE (32UL<<20)

View file

@ -1,24 +1,19 @@
/*
* include/asm-s390/sigp.h
* Routines and structures for signalling other processors.
*
* S390 version
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
* Martin Schwidefsky (schwidefsky@de.ibm.com)
* Heiko Carstens (heiko.carstens@de.ibm.com)
*
* sigp.h by D.J. Barrow (c) IBM 1999
* contains routines / structures for signalling other S/390 processors in an
* SMP configuration.
* Copyright IBM Corp. 1999,2010
* Author(s): Denis Joseph Barrow,
* Martin Schwidefsky <schwidefsky@de.ibm.com>,
* Heiko Carstens <heiko.carstens@de.ibm.com>,
*/
#ifndef __SIGP__
#define __SIGP__
#ifndef __ASM_SIGP_H
#define __ASM_SIGP_H
#include <asm/system.h>
/* get real cpu address from logical cpu number */
extern int __cpu_logical_map[];
/* Get real cpu address from logical cpu number. */
extern unsigned short __cpu_logical_map[];
static inline int cpu_logical_map(int cpu)
{
@ -29,107 +24,108 @@ static inline int cpu_logical_map(int cpu)
#endif
}
typedef enum
{
sigp_unassigned=0x0,
sigp_sense,
sigp_external_call,
sigp_emergency_signal,
sigp_start,
sigp_stop,
sigp_restart,
sigp_unassigned1,
sigp_unassigned2,
sigp_stop_and_store_status,
sigp_unassigned3,
sigp_initial_cpu_reset,
sigp_cpu_reset,
sigp_set_prefix,
sigp_store_status_at_address,
sigp_store_extended_status_at_address
} sigp_order_code;
typedef __u32 sigp_status_word;
typedef enum
{
sigp_order_code_accepted=0,
sigp_status_stored,
sigp_busy,
sigp_not_operational
} sigp_ccode;
enum {
sigp_sense = 1,
sigp_external_call = 2,
sigp_emergency_signal = 3,
sigp_start = 4,
sigp_stop = 5,
sigp_restart = 6,
sigp_stop_and_store_status = 9,
sigp_initial_cpu_reset = 11,
sigp_cpu_reset = 12,
sigp_set_prefix = 13,
sigp_store_status_at_address = 14,
sigp_store_extended_status_at_address = 15,
sigp_set_architecture = 18,
sigp_conditional_emergency_signal = 19,
sigp_sense_running = 21,
};
enum {
sigp_order_code_accepted = 0,
sigp_status_stored = 1,
sigp_busy = 2,
sigp_not_operational = 3,
};
/*
* Definitions for the external call
* Definitions for external call.
*/
/* 'Bit' signals, asynchronous */
typedef enum
{
ec_schedule=0,
enum {
ec_schedule = 0,
ec_call_function,
ec_call_function_single,
ec_bit_last
} ec_bit_sig;
};
/*
* Signal processor
* Signal processor.
*/
static inline sigp_ccode
signal_processor(__u16 cpu_addr, sigp_order_code order_code)
static inline int raw_sigp(u16 cpu, int order)
{
register unsigned long reg1 asm ("1") = 0;
sigp_ccode ccode;
int ccode;
asm volatile(
" sigp %1,%2,0(%3)\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (ccode)
: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
"a" (order_code) : "cc" , "memory");
: "d" (reg1), "d" (cpu),
"a" (order) : "cc" , "memory");
return ccode;
}
/*
* Signal processor with parameter
* Signal processor with parameter.
*/
static inline sigp_ccode
signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code)
static inline int raw_sigp_p(u32 parameter, u16 cpu, int order)
{
register unsigned int reg1 asm ("1") = parameter;
sigp_ccode ccode;
int ccode;
asm volatile(
" sigp %1,%2,0(%3)\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (ccode)
: "d" (reg1), "d" (cpu_logical_map(cpu_addr)),
"a" (order_code) : "cc" , "memory");
: "d" (reg1), "d" (cpu),
"a" (order) : "cc" , "memory");
return ccode;
}
/*
* Signal processor with parameter and return status
* Signal processor with parameter and return status.
*/
static inline sigp_ccode
signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr,
sigp_order_code order_code)
static inline int raw_sigp_ps(u32 *status, u32 parm, u16 cpu, int order)
{
register unsigned int reg1 asm ("1") = parameter;
sigp_ccode ccode;
register unsigned int reg1 asm ("1") = parm;
int ccode;
asm volatile(
" sigp %1,%2,0(%3)\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (ccode), "+d" (reg1)
: "d" (cpu_logical_map(cpu_addr)), "a" (order_code)
: "d" (cpu), "a" (order)
: "cc" , "memory");
*statusptr = reg1;
*status = reg1;
return ccode;
}
#endif /* __SIGP__ */
static inline int sigp(int cpu, int order)
{
return raw_sigp(cpu_logical_map(cpu), order);
}
static inline int sigp_p(u32 parameter, int cpu, int order)
{
return raw_sigp_p(parameter, cpu_logical_map(cpu), order);
}
static inline int sigp_ps(u32 *status, u32 parm, int cpu, int order)
{
return raw_sigp_ps(status, parm, cpu_logical_map(cpu), order);
}
#endif /* __ASM_SIGP_H */

View file

@ -29,7 +29,43 @@ extern int smp_cpu_polarization[];
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
extern void smp_switch_to_ipl_cpu(void (*func)(void *), void *);
extern void smp_switch_to_cpu(void (*)(void *), void *, unsigned long sp,
int from, int to);
extern void smp_restart_cpu(void);
/*
* returns 1 if (virtual) cpu is scheduled
* returns 0 otherwise
*/
static inline int smp_vcpu_scheduled(int cpu)
{
u32 status;
switch (sigp_ps(&status, 0, cpu, sigp_sense_running)) {
case sigp_status_stored:
/* Check for running status */
if (status & 0x400)
return 0;
break;
case sigp_not_operational:
return 0;
default:
break;
}
return 1;
}
#else /* CONFIG_SMP */
static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
{
func(data);
}
#define smp_vcpu_scheduled (1)
#endif /* CONFIG_SMP */

View file

@ -13,8 +13,6 @@
#include <linux/smp.h>
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
static inline int
_raw_compare_and_swap(volatile unsigned int *lock,
unsigned int old, unsigned int new)
@ -27,22 +25,6 @@ _raw_compare_and_swap(volatile unsigned int *lock,
return old;
}
#else /* __GNUC__ */
static inline int
_raw_compare_and_swap(volatile unsigned int *lock,
unsigned int old, unsigned int new)
{
asm volatile(
" cs %0,%3,0(%4)"
: "=d" (old), "=m" (*lock)
: "0" (old), "d" (new), "a" (lock), "m" (*lock)
: "cc", "memory" );
return old;
}
#endif /* __GNUC__ */
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
* on the local processor, one does not.

View file

@ -47,11 +47,11 @@ static inline __u32 __arch_swab32p(const __u32 *x)
asm volatile(
#ifndef __s390x__
" icm %0,8,3(%1)\n"
" icm %0,4,2(%1)\n"
" icm %0,2,1(%1)\n"
" ic %0,0(%1)"
: "=&d" (result) : "a" (x), "m" (*x) : "cc");
" icm %0,8,%O1+3(%R1)\n"
" icm %0,4,%O1+2(%R1)\n"
" icm %0,2,%O1+1(%R1)\n"
" ic %0,%1"
: "=&d" (result) : "Q" (*x) : "cc");
#else /* __s390x__ */
" lrv %0,%1"
: "=d" (result) : "m" (*x));
@ -77,9 +77,9 @@ static inline __u16 __arch_swab16p(const __u16 *x)
asm volatile(
#ifndef __s390x__
" icm %0,2,1(%1)\n"
" ic %0,0(%1)\n"
: "=&d" (result) : "a" (x), "m" (*x) : "cc");
" icm %0,2,%O+1(%R1)\n"
" ic %0,%1\n"
: "=&d" (result) : "Q" (*x) : "cc");
#else /* __s390x__ */
" lrvh %0,%1"
: "=d" (result) : "m" (*x));

View file

@ -15,6 +15,13 @@
#include <linux/sched.h>
#include <asm/ptrace.h>
/*
* The syscall table always contains 32 bit pointers since we know that the
* address of the function to be called is (way) below 4GB. So the "int"
* type here is what we want [need] for both 32 bit and 64 bit systems.
*/
extern const unsigned int sys_call_table[];
static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
{

View file

@ -87,7 +87,8 @@ struct sysinfo_2_2_2 {
struct sysinfo_3_2_2 {
char reserved_0[31];
unsigned char count;
unsigned char :4;
unsigned char count:4;
struct {
char reserved_0[4];
unsigned short cpus_total;

View file

@ -24,65 +24,65 @@ extern struct task_struct *__switch_to(void *, void *);
static inline void save_fp_regs(s390_fp_regs *fpregs)
{
asm volatile(
" std 0,8(%1)\n"
" std 2,24(%1)\n"
" std 4,40(%1)\n"
" std 6,56(%1)"
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
" std 0,%O0+8(%R0)\n"
" std 2,%O0+24(%R0)\n"
" std 4,%O0+40(%R0)\n"
" std 6,%O0+56(%R0)"
: "=Q" (*fpregs) : "Q" (*fpregs));
if (!MACHINE_HAS_IEEE)
return;
asm volatile(
" stfpc 0(%1)\n"
" std 1,16(%1)\n"
" std 3,32(%1)\n"
" std 5,48(%1)\n"
" std 7,64(%1)\n"
" std 8,72(%1)\n"
" std 9,80(%1)\n"
" std 10,88(%1)\n"
" std 11,96(%1)\n"
" std 12,104(%1)\n"
" std 13,112(%1)\n"
" std 14,120(%1)\n"
" std 15,128(%1)\n"
: "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory");
" stfpc %0\n"
" std 1,%O0+16(%R0)\n"
" std 3,%O0+32(%R0)\n"
" std 5,%O0+48(%R0)\n"
" std 7,%O0+64(%R0)\n"
" std 8,%O0+72(%R0)\n"
" std 9,%O0+80(%R0)\n"
" std 10,%O0+88(%R0)\n"
" std 11,%O0+96(%R0)\n"
" std 12,%O0+104(%R0)\n"
" std 13,%O0+112(%R0)\n"
" std 14,%O0+120(%R0)\n"
" std 15,%O0+128(%R0)\n"
: "=Q" (*fpregs) : "Q" (*fpregs));
}
static inline void restore_fp_regs(s390_fp_regs *fpregs)
{
asm volatile(
" ld 0,8(%0)\n"
" ld 2,24(%0)\n"
" ld 4,40(%0)\n"
" ld 6,56(%0)"
: : "a" (fpregs), "m" (*fpregs));
" ld 0,%O0+8(%R0)\n"
" ld 2,%O0+24(%R0)\n"
" ld 4,%O0+40(%R0)\n"
" ld 6,%O0+56(%R0)"
: : "Q" (*fpregs));
if (!MACHINE_HAS_IEEE)
return;
asm volatile(
" lfpc 0(%0)\n"
" ld 1,16(%0)\n"
" ld 3,32(%0)\n"
" ld 5,48(%0)\n"
" ld 7,64(%0)\n"
" ld 8,72(%0)\n"
" ld 9,80(%0)\n"
" ld 10,88(%0)\n"
" ld 11,96(%0)\n"
" ld 12,104(%0)\n"
" ld 13,112(%0)\n"
" ld 14,120(%0)\n"
" ld 15,128(%0)\n"
: : "a" (fpregs), "m" (*fpregs));
" lfpc %0\n"
" ld 1,%O0+16(%R0)\n"
" ld 3,%O0+32(%R0)\n"
" ld 5,%O0+48(%R0)\n"
" ld 7,%O0+64(%R0)\n"
" ld 8,%O0+72(%R0)\n"
" ld 9,%O0+80(%R0)\n"
" ld 10,%O0+88(%R0)\n"
" ld 11,%O0+96(%R0)\n"
" ld 12,%O0+104(%R0)\n"
" ld 13,%O0+112(%R0)\n"
" ld 14,%O0+120(%R0)\n"
" ld 15,%O0+128(%R0)\n"
: : "Q" (*fpregs));
}
static inline void save_access_regs(unsigned int *acrs)
{
asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory");
asm volatile("stam 0,15,%0" : "=Q" (*acrs));
}
static inline void restore_access_regs(unsigned int *acrs)
{
asm volatile("lam 0,15,0(%0)" : : "a" (acrs));
asm volatile("lam 0,15,%0" : : "Q" (*acrs));
}
#define switch_to(prev,next,last) do { \
@ -110,6 +110,7 @@ extern void pfault_fini(void);
#endif /* CONFIG_PFAULT */
extern void cmma_init(void);
extern int memcpy_real(void *, void *, size_t);
#define finish_arch_switch(prev) do { \
set_fs(current->thread.mm_segment); \
@ -139,48 +140,48 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
shift = (3 ^ (addr & 3)) << 3;
addr ^= addr & 3;
asm volatile(
" l %0,0(%4)\n"
" l %0,%4\n"
"0: lr 0,%0\n"
" nr 0,%3\n"
" or 0,%2\n"
" cs %0,0,0(%4)\n"
" cs %0,0,%4\n"
" jl 0b\n"
: "=&d" (old), "=m" (*(int *) addr)
: "d" (x << shift), "d" (~(255 << shift)), "a" (addr),
"m" (*(int *) addr) : "memory", "cc", "0");
: "=&d" (old), "=Q" (*(int *) addr)
: "d" (x << shift), "d" (~(255 << shift)),
"Q" (*(int *) addr) : "memory", "cc", "0");
return old >> shift;
case 2:
addr = (unsigned long) ptr;
shift = (2 ^ (addr & 2)) << 3;
addr ^= addr & 2;
asm volatile(
" l %0,0(%4)\n"
" l %0,%4\n"
"0: lr 0,%0\n"
" nr 0,%3\n"
" or 0,%2\n"
" cs %0,0,0(%4)\n"
" cs %0,0,%4\n"
" jl 0b\n"
: "=&d" (old), "=m" (*(int *) addr)
: "d" (x << shift), "d" (~(65535 << shift)), "a" (addr),
"m" (*(int *) addr) : "memory", "cc", "0");
: "=&d" (old), "=Q" (*(int *) addr)
: "d" (x << shift), "d" (~(65535 << shift)),
"Q" (*(int *) addr) : "memory", "cc", "0");
return old >> shift;
case 4:
asm volatile(
" l %0,0(%3)\n"
"0: cs %0,%2,0(%3)\n"
" l %0,%3\n"
"0: cs %0,%2,%3\n"
" jl 0b\n"
: "=&d" (old), "=m" (*(int *) ptr)
: "d" (x), "a" (ptr), "m" (*(int *) ptr)
: "=&d" (old), "=Q" (*(int *) ptr)
: "d" (x), "Q" (*(int *) ptr)
: "memory", "cc");
return old;
#ifdef __s390x__
case 8:
asm volatile(
" lg %0,0(%3)\n"
"0: csg %0,%2,0(%3)\n"
" lg %0,%3\n"
"0: csg %0,%2,%3\n"
" jl 0b\n"
: "=&d" (old), "=m" (*(long *) ptr)
: "d" (x), "a" (ptr), "m" (*(long *) ptr)
: "d" (x), "Q" (*(long *) ptr)
: "memory", "cc");
return old;
#endif /* __s390x__ */
@ -215,20 +216,20 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
shift = (3 ^ (addr & 3)) << 3;
addr ^= addr & 3;
asm volatile(
" l %0,0(%4)\n"
" l %0,%2\n"
"0: nr %0,%5\n"
" lr %1,%0\n"
" or %0,%2\n"
" or %1,%3\n"
" cs %0,%1,0(%4)\n"
" or %0,%3\n"
" or %1,%4\n"
" cs %0,%1,%2\n"
" jnl 1f\n"
" xr %1,%0\n"
" nr %1,%5\n"
" jnz 0b\n"
"1:"
: "=&d" (prev), "=&d" (tmp)
: "d" (old << shift), "d" (new << shift), "a" (ptr),
"d" (~(255 << shift))
: "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr)
: "d" (old << shift), "d" (new << shift),
"d" (~(255 << shift)), "Q" (*(int *) ptr)
: "memory", "cc");
return prev >> shift;
case 2:
@ -236,33 +237,35 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
shift = (2 ^ (addr & 2)) << 3;
addr ^= addr & 2;
asm volatile(
" l %0,0(%4)\n"
" l %0,%2\n"
"0: nr %0,%5\n"
" lr %1,%0\n"
" or %0,%2\n"
" or %1,%3\n"
" cs %0,%1,0(%4)\n"
" or %0,%3\n"
" or %1,%4\n"
" cs %0,%1,%2\n"
" jnl 1f\n"
" xr %1,%0\n"
" nr %1,%5\n"
" jnz 0b\n"
"1:"
: "=&d" (prev), "=&d" (tmp)
: "d" (old << shift), "d" (new << shift), "a" (ptr),
"d" (~(65535 << shift))
: "=&d" (prev), "=&d" (tmp), "=Q" (*(int *) ptr)
: "d" (old << shift), "d" (new << shift),
"d" (~(65535 << shift)), "Q" (*(int *) ptr)
: "memory", "cc");
return prev >> shift;
case 4:
asm volatile(
" cs %0,%2,0(%3)\n"
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
" cs %0,%3,%1\n"
: "=&d" (prev), "=Q" (*(int *) ptr)
: "0" (old), "d" (new), "Q" (*(int *) ptr)
: "memory", "cc");
return prev;
#ifdef __s390x__
case 8:
asm volatile(
" csg %0,%2,0(%3)\n"
: "=&d" (prev) : "0" (old), "d" (new), "a" (ptr)
" csg %0,%3,%1\n"
: "=&d" (prev), "=Q" (*(long *) ptr)
: "0" (old), "d" (new), "Q" (*(long *) ptr)
: "memory", "cc");
return prev;
#endif /* __s390x__ */
@ -302,17 +305,17 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
#define __ctl_load(array, low, high) ({ \
typedef struct { char _[sizeof(array)]; } addrtype; \
asm volatile( \
" lctlg %1,%2,0(%0)\n" \
: : "a" (&array), "i" (low), "i" (high), \
"m" (*(addrtype *)(&array))); \
" lctlg %1,%2,%0\n" \
: : "Q" (*(addrtype *)(&array)), \
"i" (low), "i" (high)); \
})
#define __ctl_store(array, low, high) ({ \
typedef struct { char _[sizeof(array)]; } addrtype; \
asm volatile( \
" stctg %2,%3,0(%1)\n" \
: "=m" (*(addrtype *)(&array)) \
: "a" (&array), "i" (low), "i" (high)); \
" stctg %1,%2,%0\n" \
: "=Q" (*(addrtype *)(&array)) \
: "i" (low), "i" (high)); \
})
#else /* __s390x__ */
@ -320,17 +323,17 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
#define __ctl_load(array, low, high) ({ \
typedef struct { char _[sizeof(array)]; } addrtype; \
asm volatile( \
" lctl %1,%2,0(%0)\n" \
: : "a" (&array), "i" (low), "i" (high), \
"m" (*(addrtype *)(&array))); \
" lctl %1,%2,%0\n" \
: : "Q" (*(addrtype *)(&array)), \
"i" (low), "i" (high)); \
})
#define __ctl_store(array, low, high) ({ \
typedef struct { char _[sizeof(array)]; } addrtype; \
asm volatile( \
" stctl %2,%3,0(%1)\n" \
: "=m" (*(addrtype *)(&array)) \
: "a" (&array), "i" (low), "i" (high)); \
" stctl %1,%2,%0\n" \
: "=Q" (*(addrtype *)(&array)) \
: "i" (low), "i" (high)); \
})
#endif /* __s390x__ */
@ -456,11 +459,6 @@ extern void (*_machine_power_off)(void);
#define arch_align_stack(x) (x)
#ifdef CONFIG_TRACE_IRQFLAGS
extern psw_t sysc_restore_trace_psw;
extern psw_t io_restore_trace_psw;
#endif
static inline int tprot(unsigned long addr)
{
int rc = -EFAULT;

View file

@ -50,6 +50,7 @@ struct thread_info {
struct restart_block restart_block;
__u64 user_timer;
__u64 system_timer;
unsigned long last_break; /* last breaking-event-address. */
};
/*
@ -73,7 +74,7 @@ struct thread_info {
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE);
return (struct thread_info *)(S390_lowcore.kernel_stack - THREAD_SIZE);
}
#define THREAD_SIZE_ORDER THREAD_ORDER
@ -96,7 +97,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_31BIT 17 /* 32bit process */
#define TIF_MEMDIE 18
#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_RESTORE_SIGMASK 19 /* restore signal mask in do_signal() */
#define TIF_FREEZE 20 /* thread is freezing for suspend */

View file

@ -20,10 +20,10 @@ static inline int set_clock(__u64 time)
int cc;
asm volatile(
" sck 0(%2)\n"
" sck %1\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc) : "m" (time), "a" (&time) : "cc");
: "=d" (cc) : "Q" (time) : "cc");
return cc;
}
@ -32,21 +32,21 @@ static inline int store_clock(__u64 *time)
int cc;
asm volatile(
" stck 0(%2)\n"
" stck %1\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc), "=m" (*time) : "a" (time) : "cc");
: "=d" (cc), "=Q" (*time) : : "cc");
return cc;
}
static inline void set_clock_comparator(__u64 time)
{
asm volatile("sckc 0(%1)" : : "m" (time), "a" (&time));
asm volatile("sckc %0" : : "Q" (time));
}
static inline void store_clock_comparator(__u64 *time)
{
asm volatile("stckc 0(%1)" : "=m" (*time) : "a" (time));
asm volatile("stckc %0" : "=Q" (*time));
}
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
@ -57,25 +57,19 @@ static inline unsigned long long get_clock (void)
{
unsigned long long clk;
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile("stck %0" : "=Q" (clk) : : "cc");
#else /* __GNUC__ */
asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc");
#endif /* __GNUC__ */
return clk;
}
static inline void get_clock_ext(char *clk)
{
asm volatile("stcke %0" : "=Q" (*clk) : : "cc");
}
static inline unsigned long long get_clock_xt(void)
{
unsigned char clk[16];
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile("stcke %0" : "=Q" (clk) : : "cc");
#else /* __GNUC__ */
asm volatile("stcke 0(%1)" : "=m" (clk)
: "a" (clk) : "cc");
#endif /* __GNUC__ */
get_clock_ext(clk);
return *((unsigned long long *)&clk[1]);
}

View file

@ -7,8 +7,10 @@
const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
extern unsigned char cpu_core_id[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];
#define topology_core_id(cpu) (cpu_core_id[cpu])
#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
int topology_set_cpu_management(int fc);

View file

@ -265,6 +265,12 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
return uaccess.copy_from_user(n, from, to);
}
extern void copy_from_user_overflow(void)
#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
__compiletime_warning("copy_from_user() buffer size is not provably correct")
#endif
;
/**
* copy_from_user: - Copy a block of data from user space.
* @to: Destination address, in kernel space.
@ -284,7 +290,13 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
static inline unsigned long __must_check
copy_from_user(void *to, const void __user *from, unsigned long n)
{
unsigned int sz = __compiletime_object_size(to);
might_fault();
if (unlikely(sz != -1 && sz < n)) {
copy_from_user_overflow();
return n;
}
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
else

View file

@ -392,6 +392,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
#define __ARCH_WANT_SYS_OLD_MMAP
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK

View file

@ -7,7 +7,7 @@
#define VDSO32_LBASE 0
#define VDSO64_LBASE 0
#define VDSO_VERSION_STRING LINUX_2.6.26
#define VDSO_VERSION_STRING LINUX_2.6.29
#ifndef __ASSEMBLY__
@ -29,6 +29,7 @@ struct vdso_data {
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
__u32 tz_dsttime; /* Type of dst correction 0x34 */
__u32 ectg_available;
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
};
struct vdso_per_cpu_data {

View file

@ -29,9 +29,12 @@ obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
extra-y += head.o init_task.o vmlinux.lds
extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o topology.o
obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \
switch_cpu.o)
obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
obj-$(CONFIG_AUDIT) += audit.o
compat-obj-$(CONFIG_AUDIT) += compat_audit.o

View file

@ -4,18 +4,27 @@
* and format the required data.
*/
#include <linux/sched.h>
#define ASM_OFFSETS_C
#include <linux/kbuild.h>
#include <linux/sched.h>
#include <asm/vdso.h>
#include <asm/sigp.h>
/*
* Make sure that the compiler is new enough. We want a compiler that
* is known to work with the "Q" assembler constraint.
*/
#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
#error Your compiler is too old; please use version 3.3.3 or newer
#endif
int main(void)
{
DEFINE(__THREAD_info, offsetof(struct task_struct, stack));
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp));
DEFINE(__THREAD_per, offsetof(struct task_struct, thread.per_info));
DEFINE(__THREAD_mm_segment,
offsetof(struct task_struct, thread.mm_segment));
DEFINE(__THREAD_mm_segment, offsetof(struct task_struct, thread.mm_segment));
BLANK();
DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
BLANK();
@ -30,6 +39,7 @@ int main(void)
DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));
DEFINE(__TI_system_timer, offsetof(struct thread_info, system_timer));
DEFINE(__TI_last_break, offsetof(struct thread_info, last_break));
BLANK();
DEFINE(__PT_ARGS, offsetof(struct pt_regs, args));
DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
@ -52,18 +62,98 @@ int main(void)
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
DEFINE(__VDSO_ECTG_BASE,
offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER,
offsetof(struct vdso_per_cpu_data, ectg_user_time));
DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
/* constants used by the vdso */
DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
BLANK();
/* constants for SIGP */
DEFINE(__SIGP_STOP, sigp_stop);
DEFINE(__SIGP_RESTART, sigp_restart);
DEFINE(__SIGP_SENSE, sigp_sense);
DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset);
BLANK();
/* lowcore offsets */
DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
DEFINE(__LC_CPU_ADDRESS, offsetof(struct _lowcore, cpu_addr));
DEFINE(__LC_EXT_INT_CODE, offsetof(struct _lowcore, ext_int_code));
DEFINE(__LC_SVC_ILC, offsetof(struct _lowcore, svc_ilc));
DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
DEFINE(__LC_PGM_ILC, offsetof(struct _lowcore, pgm_ilc));
DEFINE(__LC_PGM_INT_CODE, offsetof(struct _lowcore, pgm_code));
DEFINE(__LC_PER_ATMID, offsetof(struct _lowcore, per_perc_atmid));
DEFINE(__LC_PER_ADDRESS, offsetof(struct _lowcore, per_address));
DEFINE(__LC_PER_ACCESS_ID, offsetof(struct _lowcore, per_access_id));
DEFINE(__LC_AR_MODE_ID, offsetof(struct _lowcore, ar_access_id));
DEFINE(__LC_SUBCHANNEL_ID, offsetof(struct _lowcore, subchannel_id));
DEFINE(__LC_SUBCHANNEL_NR, offsetof(struct _lowcore, subchannel_nr));
DEFINE(__LC_IO_INT_PARM, offsetof(struct _lowcore, io_int_parm));
DEFINE(__LC_IO_INT_WORD, offsetof(struct _lowcore, io_int_word));
DEFINE(__LC_STFL_FAC_LIST, offsetof(struct _lowcore, stfl_fac_list));
DEFINE(__LC_MCCK_CODE, offsetof(struct _lowcore, mcck_interruption_code));
DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
BLANK();
DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
DEFINE(__LC_RST_OLD_PSW, offsetof(struct _lowcore, restart_old_psw));
DEFINE(__LC_EXT_OLD_PSW, offsetof(struct _lowcore, external_old_psw));
DEFINE(__LC_SVC_OLD_PSW, offsetof(struct _lowcore, svc_old_psw));
DEFINE(__LC_PGM_OLD_PSW, offsetof(struct _lowcore, program_old_psw));
DEFINE(__LC_MCK_OLD_PSW, offsetof(struct _lowcore, mcck_old_psw));
DEFINE(__LC_IO_OLD_PSW, offsetof(struct _lowcore, io_old_psw));
DEFINE(__LC_EXT_NEW_PSW, offsetof(struct _lowcore, external_new_psw));
DEFINE(__LC_SVC_NEW_PSW, offsetof(struct _lowcore, svc_new_psw));
DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area));
DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer));
DEFINE(__LC_MCCK_ENTER_TIMER, offsetof(struct _lowcore, mcck_enter_timer));
DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer));
DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer));
DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer));
DEFINE(__LC_STEAL_TIMER, offsetof(struct _lowcore, steal_timer));
DEFINE(__LC_LAST_UPDATE_TIMER, offsetof(struct _lowcore, last_update_timer));
DEFINE(__LC_LAST_UPDATE_CLOCK, offsetof(struct _lowcore, last_update_clock));
DEFINE(__LC_CURRENT, offsetof(struct _lowcore, current_task));
DEFINE(__LC_THREAD_INFO, offsetof(struct _lowcore, thread_info));
DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce));
DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
DEFINE(__LC_PSW_SAVE_AREA, offsetof(struct _lowcore, psw_save_area));
DEFINE(__LC_PREFIX_SAVE_AREA, offsetof(struct _lowcore, prefixreg_save_area));
DEFINE(__LC_AREGS_SAVE_AREA, offsetof(struct _lowcore, access_regs_save_area));
DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
#ifdef CONFIG_32BIT
DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params));
DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
#else /* CONFIG_32BIT */
DEFINE(__LC_PFAULT_INTPARM, offsetof(struct _lowcore, ext_params2));
DEFINE(__LC_EXT_PARAMS2, offsetof(struct _lowcore, ext_params2));
DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, floating_pt_save_area));
DEFINE(__LC_PASTE, offsetof(struct _lowcore, paste));
DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area));
DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook));
DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp));
#endif /* CONFIG_32BIT */
return 0;
}

View file

@ -6,8 +6,8 @@
* Michael Holzheu <holzheu@de.ibm.com>
*/
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
#include <asm/lowcore.h>
#ifdef CONFIG_64BIT

View file

@ -29,7 +29,6 @@
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/quota.h>
#include <linux/module.h>
@ -52,6 +51,7 @@
#include <linux/ptrace.h>
#include <linux/fadvise.h>
#include <linux/ipc.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/uaccess.h>

View file

@ -547,7 +547,7 @@ sys32_setdomainname_wrapper:
.globl sys32_newuname_wrapper
sys32_newuname_wrapper:
llgtr %r2,%r2 # struct new_utsname *
jg sys_s390_newuname # branch to system call
jg sys_newuname # branch to system call
.globl compat_sys_adjtimex_wrapper
compat_sys_adjtimex_wrapper:

View file

@ -655,6 +655,7 @@ found:
p_info->act_entry_offset = 0;
file->private_data = p_info;
debug_info_get(debug_info);
nonseekable_open(inode, file);
out:
mutex_unlock(&debug_mutex);
return rc;

View file

@ -86,10 +86,17 @@ enum {
U4_12, /* 4 bit unsigned value starting at 12 */
U4_16, /* 4 bit unsigned value starting at 16 */
U4_20, /* 4 bit unsigned value starting at 20 */
U4_32, /* 4 bit unsigned value starting at 32 */
U8_8, /* 8 bit unsigned value starting at 8 */
U8_16, /* 8 bit unsigned value starting at 16 */
U8_24, /* 8 bit unsigned value starting at 24 */
U8_32, /* 8 bit unsigned value starting at 32 */
I8_8, /* 8 bit signed value starting at 8 */
I8_32, /* 8 bit signed value starting at 32 */
I16_16, /* 16 bit signed value starting at 16 */
I16_32, /* 32 bit signed value starting at 16 */
U16_16, /* 16 bit unsigned value starting at 16 */
U16_32, /* 32 bit unsigned value starting at 16 */
J16_16, /* PC relative jump offset at 16 */
J32_16, /* PC relative long offset at 16 */
I32_16, /* 32 bit signed value starting at 16 */
@ -104,21 +111,37 @@ enum {
*/
enum {
INSTR_INVALID,
INSTR_E, INSTR_RIE_RRP, INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU,
INSTR_RIL_UP, INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
INSTR_E,
INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU,
INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU,
INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP,
INSTR_RIS_R0RDU, INSTR_RIS_R0UU, INSTR_RIS_RURDI, INSTR_RIS_RURDU,
INSTR_RI_RI, INSTR_RI_RP, INSTR_RI_RU, INSTR_RI_UP,
INSTR_RRE_00, INSTR_RRE_0R, INSTR_RRE_AA, INSTR_RRE_AR, INSTR_RRE_F0,
INSTR_RRE_FF, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, INSTR_RRE_RR,
INSTR_RRE_RR_OPT, INSTR_RRF_F0FF, INSTR_RRF_FUFF, INSTR_RRF_M0RR,
INSTR_RRF_R0RR, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF,
INSTR_RRE_FF, INSTR_RRE_FR, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF,
INSTR_RRE_RR, INSTR_RRE_RR_OPT,
INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR,
INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR,
INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR,
INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU,
INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR,
INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, INSTR_RSI_RRP,
INSTR_RSL_R0RD, INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD,
INSTR_RSY_RURD, INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD,
INSTR_RS_RRRD, INSTR_RS_RURD, INSTR_RXE_FRRD, INSTR_RXE_RRRD,
INSTR_RXF_FRRDF, INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RX_FRRD,
INSTR_RX_RRRD, INSTR_RX_URRD, INSTR_SIY_URD, INSTR_SI_URD,
INSTR_SSE_RDRD, INSTR_SSF_RRDRD, INSTR_SS_L0RDRD, INSTR_SS_LIRDRD,
INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD,
INSTR_RSI_RRP,
INSTR_RSL_R0RD,
INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD,
INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD,
INSTR_RS_RURD,
INSTR_RXE_FRRD, INSTR_RXE_RRRD,
INSTR_RXF_FRRDF,
INSTR_RXY_FRRD, INSTR_RXY_RRRD, INSTR_RXY_URRD,
INSTR_RX_FRRD, INSTR_RX_RRRD, INSTR_RX_URRD,
INSTR_SIL_RDI, INSTR_SIL_RDU,
INSTR_SIY_IRD, INSTR_SIY_URD,
INSTR_SI_URD,
INSTR_SSE_RDRD,
INSTR_SSF_RRDRD,
INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD,
INSTR_SS_RRRDRD2, INSTR_SS_RRRDRD3,
INSTR_S_00, INSTR_S_RD,
};
@ -129,7 +152,7 @@ struct operand {
};
struct insn {
const char name[5];
const char name[6];
unsigned char opfrag;
unsigned char format;
};
@ -170,11 +193,16 @@ static const struct operand operands[] =
[U4_12] = { 4, 12, 0 },
[U4_16] = { 4, 16, 0 },
[U4_20] = { 4, 20, 0 },
[U4_32] = { 4, 32, 0 },
[U8_8] = { 8, 8, 0 },
[U8_16] = { 8, 16, 0 },
[U8_24] = { 8, 24, 0 },
[U8_32] = { 8, 32, 0 },
[I16_16] = { 16, 16, OPERAND_SIGNED },
[U16_16] = { 16, 16, 0 },
[U16_32] = { 16, 32, 0 },
[J16_16] = { 16, 16, OPERAND_PCREL },
[I16_32] = { 16, 32, OPERAND_SIGNED },
[J32_16] = { 32, 16, OPERAND_PCREL },
[I32_16] = { 32, 16, OPERAND_SIGNED },
[U32_16] = { 32, 16, 0 },
@ -183,82 +211,93 @@ static const struct operand operands[] =
};
static const unsigned char formats[][7] = {
[INSTR_E] = { 0xff, 0,0,0,0,0,0 }, /* e.g. pr */
[INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxhg */
[INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 }, /* e.g. brasl */
[INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 }, /* e.g. brcl */
[INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 }, /* e.g. afi */
[INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 }, /* e.g. alfi */
[INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 }, /* e.g. ahi */
[INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 }, /* e.g. brct */
[INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 }, /* e.g. tml */
[INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 }, /* e.g. brc */
[INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. palb */
[INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 }, /* e.g. tb */
[INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 }, /* e.g. cpya */
[INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 }, /* e.g. sar */
[INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 }, /* e.g. sqer */
[INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 }, /* e.g. debr */
[INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 }, /* e.g. ipm */
[INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 }, /* e.g. ear */
[INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 }, /* e.g. cefbr */
[INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 }, /* e.g. lura */
[INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 }, /* efpc, sfpc */
[INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 }, /* e.g. madbr */
[INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },/* e.g. didbr */
[INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },/* e.g. .insn */
[INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 }, /* e.g. idte */
[INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 }, /* e.g. fixr */
[INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 }, /* e.g. cfebr */
[INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 }, /* e.g. sske */
[INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 }, /* e.g. adr */
[INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 }, /* e.g. spm */
[INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 }, /* e.g. lr */
[INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 }, /* e.g. svc */
[INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 }, /* e.g. bcr */
[INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. lmh */
[INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lmh */
[INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icmh */
[INSTR_RSL_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. tp */
[INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, /* e.g. brxh */
[INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },/* e.g. stmy */
[INSTR_E] = { 0xff, 0,0,0,0,0,0 },
[INSTR_RIE_R0UU] = { 0xff, R_8,U16_16,U4_32,0,0,0 },
[INSTR_RIE_RRPU] = { 0xff, R_8,R_12,U4_32,J16_16,0,0 },
[INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
[INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 },
[INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 },
[INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 },
[INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 },
[INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 },
[INSTR_RIL_UP] = { 0x0f, U4_8,J32_16,0,0,0,0 },
[INSTR_RIS_R0RDU] = { 0xff, R_8,U8_32,D_20,B_16,0,0 },
[INSTR_RIS_RURDI] = { 0xff, R_8,I8_32,U4_12,D_20,B_16,0 },
[INSTR_RIS_RURDU] = { 0xff, R_8,U8_32,U4_12,D_20,B_16,0 },
[INSTR_RI_RI] = { 0x0f, R_8,I16_16,0,0,0,0 },
[INSTR_RI_RP] = { 0x0f, R_8,J16_16,0,0,0,0 },
[INSTR_RI_RU] = { 0x0f, R_8,U16_16,0,0,0,0 },
[INSTR_RI_UP] = { 0x0f, U4_8,J16_16,0,0,0,0 },
[INSTR_RRE_00] = { 0xff, 0,0,0,0,0,0 },
[INSTR_RRE_0R] = { 0xff, R_28,0,0,0,0,0 },
[INSTR_RRE_AA] = { 0xff, A_24,A_28,0,0,0,0 },
[INSTR_RRE_AR] = { 0xff, A_24,R_28,0,0,0,0 },
[INSTR_RRE_F0] = { 0xff, F_24,0,0,0,0,0 },
[INSTR_RRE_FF] = { 0xff, F_24,F_28,0,0,0,0 },
[INSTR_RRE_FR] = { 0xff, F_24,R_28,0,0,0,0 },
[INSTR_RRE_R0] = { 0xff, R_24,0,0,0,0,0 },
[INSTR_RRE_RA] = { 0xff, R_24,A_28,0,0,0,0 },
[INSTR_RRE_RF] = { 0xff, R_24,F_28,0,0,0,0 },
[INSTR_RRE_RR] = { 0xff, R_24,R_28,0,0,0,0 },
[INSTR_RRE_RR_OPT]= { 0xff, R_24,RO_28,0,0,0,0 },
[INSTR_RRF_0UFF] = { 0xff, F_24,F_28,U4_20,0,0,0 },
[INSTR_RRF_F0FF2] = { 0xff, F_24,F_16,F_28,0,0,0 },
[INSTR_RRF_F0FF] = { 0xff, F_16,F_24,F_28,0,0,0 },
[INSTR_RRF_F0FR] = { 0xff, F_24,F_16,R_28,0,0,0 },
[INSTR_RRF_FFRU] = { 0xff, F_24,F_16,R_28,U4_20,0,0 },
[INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 },
[INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 },
[INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 },
[INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 },
[INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 },
[INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 },
[INSTR_RRF_U0RR] = { 0xff, R_24,R_28,U4_16,0,0,0 },
[INSTR_RRF_UUFF] = { 0xff, F_24,U4_16,F_28,U4_20,0,0 },
[INSTR_RRR_F0FF] = { 0xff, F_24,F_28,F_16,0,0,0 },
[INSTR_RRS_RRRDU] = { 0xff, R_8,R_12,U4_32,D_20,B_16,0 },
[INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 },
[INSTR_RR_R0] = { 0xff, R_8, 0,0,0,0,0 },
[INSTR_RR_RR] = { 0xff, R_8,R_12,0,0,0,0 },
[INSTR_RR_U0] = { 0xff, U8_8, 0,0,0,0,0 },
[INSTR_RR_UR] = { 0xff, U4_8,R_12,0,0,0,0 },
[INSTR_RSE_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
[INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
[INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
[INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 },
[INSTR_RSL_R0RD] = { 0xff, D_20,L4_8,B_16,0,0,0 },
[INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },
[INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },
[INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 },
[INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 },
/* e.g. icmh */
[INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 },/* e.g. lamy */
[INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 },/* e.g. lamy */
[INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, /* e.g. lam */
[INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, /* e.g. lctl */
[INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, /* e.g. sll */
[INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, /* e.g. cs */
[INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, /* e.g. icm */
[INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. axbr */
[INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. lg */
[INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 },
[INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 },
[INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 },
[INSTR_RS_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 },
[INSTR_RS_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 },
[INSTR_RXE_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
[INSTR_RXE_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
[INSTR_RXF_FRRDF] = { 0xff, F_32,F_8,D_20,X_12,B_16,0 },
/* e.g. madb */
[INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },/* e.g. ly */
[INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },/* e.g. ley */
[INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 }, /* e.g. ae */
[INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 }, /* e.g. l */
[INSTR_RX_URRD] = { 0xff, U4_8,D_20,X_12,B_16,0,0 }, /* e.g. bc */
[INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 }, /* e.g. cli */
[INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 }, /* e.g. tmy */
[INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 }, /* e.g. mvsdk */
[INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
/* e.g. mvc */
[INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
/* e.g. srp */
[INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
/* e.g. pack */
[INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
/* e.g. mvck */
[INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
/* e.g. plo */
[INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
/* e.g. lmd */
[INSTR_S_00] = { 0xff, 0,0,0,0,0,0 }, /* e.g. hsch */
[INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 }, /* e.g. lpsw */
[INSTR_RXY_FRRD] = { 0xff, F_8,D20_20,X_12,B_16,0,0 },
[INSTR_RXY_RRRD] = { 0xff, R_8,D20_20,X_12,B_16,0,0 },
[INSTR_RXY_URRD] = { 0xff, U4_8,D20_20,X_12,B_16,0,0 },
[INSTR_RX_FRRD] = { 0xff, F_8,D_20,X_12,B_16,0,0 },
[INSTR_RX_RRRD] = { 0xff, R_8,D_20,X_12,B_16,0,0 },
[INSTR_RX_URRD] = { 0xff, U4_8,D_20,X_12,B_16,0,0 },
[INSTR_SIL_RDI] = { 0xff, D_20,B_16,I16_32,0,0,0 },
[INSTR_SIL_RDU] = { 0xff, D_20,B_16,U16_32,0,0,0 },
[INSTR_SIY_IRD] = { 0xff, D20_20,B_16,I8_8,0,0,0 },
[INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 },
[INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 },
[INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 },
[INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 },
/* e.g. mvcos */
[INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 },
[INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 },
[INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 },
[INSTR_SS_RRRDRD2]= { 0xff, R_8,D_20,B_16,R_12,D_36,B_32 },
[INSTR_SS_RRRDRD3]= { 0xff, R_8,R_12,D_20,B_16,D_36,B_32 },
[INSTR_SS_RRRDRD] = { 0xff, D_20,R_8,B_16,D_36,B_32,R_12 },
[INSTR_S_00] = { 0xff, 0,0,0,0,0,0 },
[INSTR_S_RD] = { 0xff, D_20,B_16,0,0,0,0 },
};
static struct insn opcode[] = {
@ -454,6 +493,8 @@ static struct insn opcode[] = {
static struct insn opcode_01[] = {
#ifdef CONFIG_64BIT
{ "sam64", 0x0e, INSTR_E },
{ "pfpo", 0x0a, INSTR_E },
{ "ptff", 0x04, INSTR_E },
#endif
{ "pr", 0x01, INSTR_E },
{ "upt", 0x02, INSTR_E },
@ -519,6 +560,8 @@ static struct insn opcode_b2[] = {
{ "cutfu", 0xa7, INSTR_RRF_M0RR },
{ "stfle", 0xb0, INSTR_S_RD },
{ "lpswe", 0xb2, INSTR_S_RD },
{ "srnmt", 0xb9, INSTR_S_RD },
{ "lfas", 0xbd, INSTR_S_RD },
#endif
{ "stidp", 0x02, INSTR_S_RD },
{ "sck", 0x04, INSTR_S_RD },
@ -589,7 +632,6 @@ static struct insn opcode_b2[] = {
{ "clst", 0x5d, INSTR_RRE_RR },
{ "srst", 0x5e, INSTR_RRE_RR },
{ "cmpsc", 0x63, INSTR_RRE_RR },
{ "cmpsc", 0x63, INSTR_RRE_RR },
{ "siga", 0x74, INSTR_S_RD },
{ "xsch", 0x76, INSTR_S_00 },
{ "rp", 0x77, INSTR_S_RD },
@ -630,6 +672,57 @@ static struct insn opcode_b3[] = {
{ "cger", 0xc8, INSTR_RRF_U0RF },
{ "cgdr", 0xc9, INSTR_RRF_U0RF },
{ "cgxr", 0xca, INSTR_RRF_U0RF },
{ "lpdfr", 0x70, INSTR_RRE_FF },
{ "lndfr", 0x71, INSTR_RRE_FF },
{ "cpsdr", 0x72, INSTR_RRF_F0FF2 },
{ "lcdfr", 0x73, INSTR_RRE_FF },
{ "ldgr", 0xc1, INSTR_RRE_FR },
{ "lgdr", 0xcd, INSTR_RRE_RF },
{ "adtr", 0xd2, INSTR_RRR_F0FF },
{ "axtr", 0xda, INSTR_RRR_F0FF },
{ "cdtr", 0xe4, INSTR_RRE_FF },
{ "cxtr", 0xec, INSTR_RRE_FF },
{ "kdtr", 0xe0, INSTR_RRE_FF },
{ "kxtr", 0xe8, INSTR_RRE_FF },
{ "cedtr", 0xf4, INSTR_RRE_FF },
{ "cextr", 0xfc, INSTR_RRE_FF },
{ "cdgtr", 0xf1, INSTR_RRE_FR },
{ "cxgtr", 0xf9, INSTR_RRE_FR },
{ "cdstr", 0xf3, INSTR_RRE_FR },
{ "cxstr", 0xfb, INSTR_RRE_FR },
{ "cdutr", 0xf2, INSTR_RRE_FR },
{ "cxutr", 0xfa, INSTR_RRE_FR },
{ "cgdtr", 0xe1, INSTR_RRF_U0RF },
{ "cgxtr", 0xe9, INSTR_RRF_U0RF },
{ "csdtr", 0xe3, INSTR_RRE_RF },
{ "csxtr", 0xeb, INSTR_RRE_RF },
{ "cudtr", 0xe2, INSTR_RRE_RF },
{ "cuxtr", 0xea, INSTR_RRE_RF },
{ "ddtr", 0xd1, INSTR_RRR_F0FF },
{ "dxtr", 0xd9, INSTR_RRR_F0FF },
{ "eedtr", 0xe5, INSTR_RRE_RF },
{ "eextr", 0xed, INSTR_RRE_RF },
{ "esdtr", 0xe7, INSTR_RRE_RF },
{ "esxtr", 0xef, INSTR_RRE_RF },
{ "iedtr", 0xf6, INSTR_RRF_F0FR },
{ "iextr", 0xfe, INSTR_RRF_F0FR },
{ "ltdtr", 0xd6, INSTR_RRE_FF },
{ "ltxtr", 0xde, INSTR_RRE_FF },
{ "fidtr", 0xd7, INSTR_RRF_UUFF },
{ "fixtr", 0xdf, INSTR_RRF_UUFF },
{ "ldetr", 0xd4, INSTR_RRF_0UFF },
{ "lxdtr", 0xdc, INSTR_RRF_0UFF },
{ "ledtr", 0xd5, INSTR_RRF_UUFF },
{ "ldxtr", 0xdd, INSTR_RRF_UUFF },
{ "mdtr", 0xd0, INSTR_RRR_F0FF },
{ "mxtr", 0xd8, INSTR_RRR_F0FF },
{ "qadtr", 0xf5, INSTR_RRF_FUFF },
{ "qaxtr", 0xfd, INSTR_RRF_FUFF },
{ "rrdtr", 0xf7, INSTR_RRF_FFRU },
{ "rrxtr", 0xff, INSTR_RRF_FFRU },
{ "sfasr", 0x85, INSTR_RRE_R0 },
{ "sdtr", 0xd3, INSTR_RRR_F0FF },
{ "sxtr", 0xdb, INSTR_RRR_F0FF },
#endif
{ "lpebr", 0x00, INSTR_RRE_FF },
{ "lnebr", 0x01, INSTR_RRE_FF },
@ -780,6 +873,14 @@ static struct insn opcode_b9[] = {
{ "cu24", 0xb1, INSTR_RRF_M0RR },
{ "cu41", 0xb2, INSTR_RRF_M0RR },
{ "cu42", 0xb3, INSTR_RRF_M0RR },
{ "crt", 0x72, INSTR_RRF_U0RR },
{ "cgrt", 0x60, INSTR_RRF_U0RR },
{ "clrt", 0x73, INSTR_RRF_U0RR },
{ "clgrt", 0x61, INSTR_RRF_U0RR },
{ "ptf", 0xa2, INSTR_RRE_R0 },
{ "pfmf", 0xaf, INSTR_RRE_RR },
{ "trte", 0xbf, INSTR_RRF_M0RR },
{ "trtre", 0xbd, INSTR_RRF_M0RR },
#endif
{ "kmac", 0x1e, INSTR_RRE_RR },
{ "lrvr", 0x1f, INSTR_RRE_RR },
@ -835,6 +936,43 @@ static struct insn opcode_c2[] = {
{ "cfi", 0x0d, INSTR_RIL_RI },
{ "clgfi", 0x0e, INSTR_RIL_RU },
{ "clfi", 0x0f, INSTR_RIL_RU },
{ "msfi", 0x01, INSTR_RIL_RI },
{ "msgfi", 0x00, INSTR_RIL_RI },
#endif
{ "", 0, INSTR_INVALID }
};
static struct insn opcode_c4[] = {
#ifdef CONFIG_64BIT
{ "lrl", 0x0d, INSTR_RIL_RP },
{ "lgrl", 0x08, INSTR_RIL_RP },
{ "lgfrl", 0x0c, INSTR_RIL_RP },
{ "lhrl", 0x05, INSTR_RIL_RP },
{ "lghrl", 0x04, INSTR_RIL_RP },
{ "llgfrl", 0x0e, INSTR_RIL_RP },
{ "llhrl", 0x02, INSTR_RIL_RP },
{ "llghrl", 0x06, INSTR_RIL_RP },
{ "strl", 0x0f, INSTR_RIL_RP },
{ "stgrl", 0x0b, INSTR_RIL_RP },
{ "sthrl", 0x07, INSTR_RIL_RP },
#endif
{ "", 0, INSTR_INVALID }
};
static struct insn opcode_c6[] = {
#ifdef CONFIG_64BIT
{ "crl", 0x0d, INSTR_RIL_RP },
{ "cgrl", 0x08, INSTR_RIL_RP },
{ "cgfrl", 0x0c, INSTR_RIL_RP },
{ "chrl", 0x05, INSTR_RIL_RP },
{ "cghrl", 0x04, INSTR_RIL_RP },
{ "clrl", 0x0f, INSTR_RIL_RP },
{ "clgrl", 0x0a, INSTR_RIL_RP },
{ "clgfrl", 0x0e, INSTR_RIL_RP },
{ "clhrl", 0x07, INSTR_RIL_RP },
{ "clghrl", 0x06, INSTR_RIL_RP },
{ "pfdrl", 0x02, INSTR_RIL_UP },
{ "exrl", 0x00, INSTR_RIL_RP },
#endif
{ "", 0, INSTR_INVALID }
};
@ -842,6 +980,8 @@ static struct insn opcode_c2[] = {
static struct insn opcode_c8[] = {
#ifdef CONFIG_64BIT
{ "mvcos", 0x00, INSTR_SSF_RRDRD },
{ "ectg", 0x01, INSTR_SSF_RRDRD },
{ "csst", 0x02, INSTR_SSF_RRDRD },
#endif
{ "", 0, INSTR_INVALID }
};
@ -917,6 +1057,12 @@ static struct insn opcode_e3[] = {
{ "llgh", 0x91, INSTR_RXY_RRRD },
{ "llc", 0x94, INSTR_RXY_RRRD },
{ "llh", 0x95, INSTR_RXY_RRRD },
{ "cgh", 0x34, INSTR_RXY_RRRD },
{ "laey", 0x75, INSTR_RXY_RRRD },
{ "ltgf", 0x32, INSTR_RXY_RRRD },
{ "mfy", 0x5c, INSTR_RXY_RRRD },
{ "mhy", 0x7c, INSTR_RXY_RRRD },
{ "pfd", 0x36, INSTR_RXY_URRD },
#endif
{ "lrv", 0x1e, INSTR_RXY_RRRD },
{ "lrvh", 0x1f, INSTR_RXY_RRRD },
@ -931,6 +1077,15 @@ static struct insn opcode_e3[] = {
static struct insn opcode_e5[] = {
#ifdef CONFIG_64BIT
{ "strag", 0x02, INSTR_SSE_RDRD },
{ "chhsi", 0x54, INSTR_SIL_RDI },
{ "chsi", 0x5c, INSTR_SIL_RDI },
{ "cghsi", 0x58, INSTR_SIL_RDI },
{ "clhhsi", 0x55, INSTR_SIL_RDU },
{ "clfhsi", 0x5d, INSTR_SIL_RDU },
{ "clghsi", 0x59, INSTR_SIL_RDU },
{ "mvhhi", 0x44, INSTR_SIL_RDI },
{ "mvhi", 0x4c, INSTR_SIL_RDI },
{ "mvghi", 0x48, INSTR_SIL_RDI },
#endif
{ "lasp", 0x00, INSTR_SSE_RDRD },
{ "tprot", 0x01, INSTR_SSE_RDRD },
@ -977,6 +1132,11 @@ static struct insn opcode_eb[] = {
{ "lmy", 0x98, INSTR_RSY_RRRD },
{ "lamy", 0x9a, INSTR_RSY_AARD },
{ "stamy", 0x9b, INSTR_RSY_AARD },
{ "asi", 0x6a, INSTR_SIY_IRD },
{ "agsi", 0x7a, INSTR_SIY_IRD },
{ "alsi", 0x6e, INSTR_SIY_IRD },
{ "algsi", 0x7e, INSTR_SIY_IRD },
{ "ecag", 0x4c, INSTR_RSY_RRRD },
#endif
{ "rll", 0x1d, INSTR_RSY_RRRD },
{ "mvclu", 0x8e, INSTR_RSY_RRRD },
@ -988,6 +1148,30 @@ static struct insn opcode_ec[] = {
#ifdef CONFIG_64BIT
{ "brxhg", 0x44, INSTR_RIE_RRP },
{ "brxlg", 0x45, INSTR_RIE_RRP },
{ "crb", 0xf6, INSTR_RRS_RRRDU },
{ "cgrb", 0xe4, INSTR_RRS_RRRDU },
{ "crj", 0x76, INSTR_RIE_RRPU },
{ "cgrj", 0x64, INSTR_RIE_RRPU },
{ "cib", 0xfe, INSTR_RIS_RURDI },
{ "cgib", 0xfc, INSTR_RIS_RURDI },
{ "cij", 0x7e, INSTR_RIE_RUPI },
{ "cgij", 0x7c, INSTR_RIE_RUPI },
{ "cit", 0x72, INSTR_RIE_R0IU },
{ "cgit", 0x70, INSTR_RIE_R0IU },
{ "clrb", 0xf7, INSTR_RRS_RRRDU },
{ "clgrb", 0xe5, INSTR_RRS_RRRDU },
{ "clrj", 0x77, INSTR_RIE_RRPU },
{ "clgrj", 0x65, INSTR_RIE_RRPU },
{ "clib", 0xff, INSTR_RIS_RURDU },
{ "clgib", 0xfd, INSTR_RIS_RURDU },
{ "clij", 0x7f, INSTR_RIE_RUPU },
{ "clgij", 0x7d, INSTR_RIE_RUPU },
{ "clfit", 0x73, INSTR_RIE_R0UU },
{ "clgit", 0x71, INSTR_RIE_R0UU },
{ "rnsbg", 0x54, INSTR_RIE_RRUUU },
{ "rxsbg", 0x57, INSTR_RIE_RRUUU },
{ "rosbg", 0x56, INSTR_RIE_RRUUU },
{ "risbg", 0x55, INSTR_RIE_RRUUU },
#endif
{ "", 0, INSTR_INVALID }
};
@ -1004,6 +1188,16 @@ static struct insn opcode_ed[] = {
{ "ldy", 0x65, INSTR_RXY_FRRD },
{ "stey", 0x66, INSTR_RXY_FRRD },
{ "stdy", 0x67, INSTR_RXY_FRRD },
{ "sldt", 0x40, INSTR_RXF_FRRDF },
{ "slxt", 0x48, INSTR_RXF_FRRDF },
{ "srdt", 0x41, INSTR_RXF_FRRDF },
{ "srxt", 0x49, INSTR_RXF_FRRDF },
{ "tdcet", 0x50, INSTR_RXE_FRRD },
{ "tdcdt", 0x54, INSTR_RXE_FRRD },
{ "tdcxt", 0x58, INSTR_RXE_FRRD },
{ "tdget", 0x51, INSTR_RXE_FRRD },
{ "tdgdt", 0x55, INSTR_RXE_FRRD },
{ "tdgxt", 0x59, INSTR_RXE_FRRD },
#endif
{ "ldeb", 0x04, INSTR_RXE_FRRD },
{ "lxdb", 0x05, INSTR_RXE_FRRD },
@ -1037,6 +1231,7 @@ static struct insn opcode_ed[] = {
{ "mae", 0x2e, INSTR_RXF_FRRDF },
{ "mse", 0x2f, INSTR_RXF_FRRDF },
{ "sqe", 0x34, INSTR_RXE_FRRD },
{ "sqd", 0x35, INSTR_RXE_FRRD },
{ "mee", 0x37, INSTR_RXE_FRRD },
{ "mad", 0x3e, INSTR_RXF_FRRDF },
{ "msd", 0x3f, INSTR_RXF_FRRDF },
@ -1117,6 +1312,12 @@ static struct insn *find_insn(unsigned char *code)
case 0xc2:
table = opcode_c2;
break;
case 0xc4:
table = opcode_c4;
break;
case 0xc6:
table = opcode_c6;
break;
case 0xc8:
table = opcode_c8;
break;

View file

@ -82,7 +82,8 @@ asm(
" lm 6,15,24(15)\n"
#endif
" br 14\n"
" .size savesys_ipl_nss, .-savesys_ipl_nss\n");
" .size savesys_ipl_nss, .-savesys_ipl_nss\n"
" .previous\n");
static __initdata char upper_command_line[COMMAND_LINE_SIZE];
@ -214,10 +215,13 @@ static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
static noinline __init void detect_machine_type(void)
{
/* No VM information? Looks like LPAR */
if (stsi(&vmms, 3, 2, 2) == -ENOSYS)
/* Check current-configuration-level */
if ((stsi(NULL, 0, 0, 0) >> 28) <= 2) {
S390_lowcore.machine_flags |= MACHINE_FLAG_LPAR;
return;
if (!vmms.count)
}
/* Get virtual-machine cpu information. */
if (stsi(&vmms, 3, 2, 2) == -ENOSYS || !vmms.count)
return;
/* Running under KVM? If not we assume z/VM */
@ -352,6 +356,7 @@ static __init void detect_machine_facilities(void)
{
#ifdef CONFIG_64BIT
unsigned int facilities;
unsigned long long facility_bits;
facilities = stfl();
if (facilities & (1 << 28))
@ -360,6 +365,9 @@ static __init void detect_machine_facilities(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
if (facilities & (1 << 4))
S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
if ((stfle(&facility_bits, 1) > 0) &&
(facility_bits & (1ULL << (63 - 40))))
S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
#endif
}
@ -402,8 +410,19 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
static void __init setup_boot_command_line(void)
{
int i;
/* convert arch command line to ascii */
for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++)
if (COMMAND_LINE[i] & 0x80)
break;
if (i < ARCH_COMMAND_LINE_SIZE)
EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
/* copy arch command line */
strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
strlcpy(boot_command_line, strstrip(COMMAND_LINE),
ARCH_COMMAND_LINE_SIZE);
/* append IPL PARM data to the boot command line */
if (MACHINE_IS_VM)

View file

@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/cache.h>
#include <asm/lowcore.h>
#include <asm/errno.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
@ -74,21 +73,24 @@ STACK_SIZE = 1 << STACK_SHIFT
basr %r14,%r1
.endm
.macro TRACE_IRQS_CHECK
basr %r2,%r0
.macro TRACE_IRQS_CHECK_ON
tm SP_PSW(%r15),0x03 # irqs enabled?
jz 0f
l %r1,BASED(.Ltrace_irq_on_caller)
basr %r14,%r1
j 1f
0: l %r1,BASED(.Ltrace_irq_off_caller)
basr %r14,%r1
1:
bz BASED(0f)
TRACE_IRQS_ON
0:
.endm
.macro TRACE_IRQS_CHECK_OFF
tm SP_PSW(%r15),0x03 # irqs enabled?
bz BASED(0f)
TRACE_IRQS_OFF
0:
.endm
#else
#define TRACE_IRQS_ON
#define TRACE_IRQS_OFF
#define TRACE_IRQS_CHECK
#define TRACE_IRQS_CHECK_ON
#define TRACE_IRQS_CHECK_OFF
#endif
#ifdef CONFIG_LOCKDEP
@ -178,9 +180,9 @@ STACK_SIZE = 1 << STACK_SHIFT
s %r15,BASED(.Lc_spsize) # make room for registers & psw
mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
icm %r12,3,__LC_SVC_ILC
icm %r12,12,__LC_SVC_ILC
stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
st %r12,SP_SVCNR(%r15)
st %r12,SP_ILC(%r15)
mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
la %r12,0
st %r12,__SF_BACKCHAIN(%r15) # clear back chain
@ -274,66 +276,45 @@ sysc_do_restart:
st %r2,SP_R2(%r15) # store return value (change R2 on stack)
sysc_return:
LOCKDEP_SYS_EXIT
sysc_tif:
tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.)
sysc_restore:
#ifdef CONFIG_TRACE_IRQFLAGS
la %r1,BASED(sysc_restore_trace_psw_addr)
l %r1,0(%r1)
lpsw 0(%r1)
sysc_restore_trace:
TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
#endif
sysc_leave:
RESTORE_ALL __LC_RETURN_PSW,1
sysc_done:
#ifdef CONFIG_TRACE_IRQFLAGS
sysc_restore_trace_psw_addr:
.long sysc_restore_trace_psw
.section .data,"aw",@progbits
.align 8
.globl sysc_restore_trace_psw
sysc_restore_trace_psw:
.long 0, sysc_restore_trace + 0x80000000
.previous
#endif
#
# recheck if there is more work to do
#
sysc_work_loop:
tm __TI_flags+3(%r9),_TIF_WORK_SVC
bz BASED(sysc_restore) # there is no work to do
#
# One of the work bits is on. Find out which one.
# There is work to do, but first we need to check if we return to userspace.
#
sysc_work:
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_restore)
#
# One of the work bits is on. Find out which one.
#
sysc_work_tif:
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
bo BASED(sysc_mcck_pending)
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bo BASED(sysc_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(sysc_sigpending)
bo BASED(sysc_sigpending)
tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
bnz BASED(sysc_notify_resume)
bo BASED(sysc_notify_resume)
tm __TI_flags+3(%r9),_TIF_RESTART_SVC
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
b BASED(sysc_restore)
sysc_work_done:
b BASED(sysc_return) # beware of critical section cleanup
#
# _TIF_NEED_RESCHED is set, call schedule
#
sysc_reschedule:
l %r1,BASED(.Lschedule)
la %r14,BASED(sysc_work_loop)
la %r14,BASED(sysc_return)
br %r1 # call scheduler
#
@ -341,7 +322,7 @@ sysc_reschedule:
#
sysc_mcck_pending:
l %r1,BASED(.Ls390_handle_mcck)
la %r14,BASED(sysc_work_loop)
la %r14,BASED(sysc_return)
br %r1 # TIF bit will be cleared by handler
#
@ -356,7 +337,7 @@ sysc_sigpending:
bo BASED(sysc_restart)
tm __TI_flags+3(%r9),_TIF_SINGLE_STEP
bo BASED(sysc_singlestep)
b BASED(sysc_work_loop)
b BASED(sysc_return)
#
# _TIF_NOTIFY_RESUME is set, call do_notify_resume
@ -364,7 +345,7 @@ sysc_sigpending:
sysc_notify_resume:
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_notify_resume)
la %r14,BASED(sysc_work_loop)
la %r14,BASED(sysc_return)
br %r1 # call do_notify_resume
@ -459,11 +440,13 @@ kernel_execve:
br %r14
# execve succeeded.
0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts
TRACE_IRQS_OFF
l %r15,__LC_KERNEL_STACK # load ksp
s %r15,BASED(.Lc_spsize) # make room for registers & psw
l %r9,__LC_THREAD_INFO
mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs
xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
l %r1,BASED(.Lexecve_tail)
basr %r14,%r1
@ -500,8 +483,8 @@ pgm_check_handler:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime:
TRACE_IRQS_CHECK_OFF
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
nr %r8,%r3
@ -510,8 +493,10 @@ pgm_do_call:
sll %r8,2
l %r7,0(%r8,%r7) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
la %r14,BASED(sysc_return)
br %r7 # branch to interrupt-handler
basr %r14,%r7 # branch to interrupt-handler
pgm_exit:
TRACE_IRQS_CHECK_ON
b BASED(sysc_return)
#
# handle per exception
@ -538,20 +523,28 @@ pgm_per_std:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
pgm_no_vtime2:
TRACE_IRQS_CHECK_OFF
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r1,__TI_task(%r9)
tm SP_PSW+1(%r15),0x01 # kernel per event ?
bz BASED(kernel_per)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
tm SP_PSW+1(%r15),0x01 # kernel per event ?
bz BASED(kernel_per)
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
nr %r8,%r3 # clear per-event-bit and ilc
be BASED(sysc_return) # only per or per+check ?
b BASED(pgm_do_call)
be BASED(pgm_exit2) # only per or per+check ?
l %r7,BASED(.Ljump_table)
sll %r8,2
l %r7,0(%r8,%r7) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r7 # branch to interrupt-handler
pgm_exit2:
TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_return)
#
# it was a single stepped SVC that is causing all the trouble
@ -571,8 +564,8 @@ pgm_svcper:
mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
TRACE_IRQS_ON
lm %r2,%r6,SP_R2(%r15) # load svc arguments
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
lm %r2,%r6,SP_R2(%r15) # load svc arguments
b BASED(sysc_do_svc)
#
@ -583,8 +576,8 @@ kernel_per:
mvi SP_SVCNR+1(%r15),0xff
la %r2,SP_PTREGS(%r15) # address of register-save area
l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_restore)# load adr. of system return
br %r1 # branch to do_single_step
basr %r14,%r1 # branch to do_single_step
b BASED(pgm_exit)
/*
* IO interrupt handler routine
@ -603,134 +596,126 @@ io_int_handler:
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
io_no_vtime:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
TRACE_IRQS_OFF
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
io_return:
LOCKDEP_SYS_EXIT
TRACE_IRQS_ON
io_tif:
tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.)
io_restore:
#ifdef CONFIG_TRACE_IRQFLAGS
la %r1,BASED(io_restore_trace_psw_addr)
l %r1,0(%r1)
lpsw 0(%r1)
io_restore_trace:
TRACE_IRQS_CHECK
LOCKDEP_SYS_EXIT
#endif
io_leave:
RESTORE_ALL __LC_RETURN_PSW,0
io_done:
#ifdef CONFIG_TRACE_IRQFLAGS
io_restore_trace_psw_addr:
.long io_restore_trace_psw
.section .data,"aw",@progbits
.align 8
.globl io_restore_trace_psw
io_restore_trace_psw:
.long 0, io_restore_trace + 0x80000000
.previous
#endif
#
# switch to kernel stack, then check the TIF bits
# There is work todo, find out in which context we have been interrupted:
# 1) if we return to user space we can do all _TIF_WORK_INT work
# 2) if we return to kernel code and preemptive scheduling is enabled check
# the preemption counter and if it is zero call preempt_schedule_irq
# Before any work can be done, a switch to the kernel stack is required.
#
io_work:
tm SP_PSW+1(%r15),0x01 # returning to user ?
#ifndef CONFIG_PREEMPT
bno BASED(io_restore) # no-> skip resched & signal
#else
bnz BASED(io_work_user) # no -> check for preemptive scheduling
bo BASED(io_work_user) # yes -> do resched & signal
#ifdef CONFIG_PREEMPT
# check for preemptive scheduling
icm %r0,15,__TI_precount(%r9)
bnz BASED(io_restore) # preemption disabled
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bno BASED(io_restore)
# switch to kernel stack
l %r1,SP_R15(%r15)
s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
lr %r15,%r1
io_resume_loop:
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bno BASED(io_restore)
# TRACE_IRQS_ON already done at io_return, call
# TRACE_IRQS_OFF to keep things symmetrical
TRACE_IRQS_OFF
l %r1,BASED(.Lpreempt_schedule_irq)
la %r14,BASED(io_resume_loop)
br %r1 # call schedule
basr %r14,%r1 # call preempt_schedule_irq
b BASED(io_return)
#else
b BASED(io_restore)
#endif
#
# Need to do work before returning to userspace, switch to kernel stack
#
io_work_user:
l %r1,__LC_KERNEL_STACK
s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
lr %r15,%r1
#
# One of the work bits is on. Find out which one.
# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED
# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
# and _TIF_MCCK_PENDING
#
io_work_loop:
io_work_tif:
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
bo BASED(io_mcck_pending)
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
bo BASED(io_reschedule)
tm __TI_flags+3(%r9),_TIF_SIGPENDING
bnz BASED(io_sigpending)
bo BASED(io_sigpending)
tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
bnz BASED(io_notify_resume)
b BASED(io_restore)
io_work_done:
bo BASED(io_notify_resume)
b BASED(io_return) # beware of critical section cleanup
#
# _TIF_MCCK_PENDING is set, call handler
#
io_mcck_pending:
# TRACE_IRQS_ON already done at io_return
l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # TIF bit will be cleared by handler
b BASED(io_work_loop)
TRACE_IRQS_OFF
b BASED(io_return)
#
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
TRACE_IRQS_ON
# TRACE_IRQS_ON already done at io_return
l %r1,BASED(.Lschedule)
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
basr %r14,%r1 # call scheduler
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
tm __TI_flags+3(%r9),_TIF_WORK_INT
bz BASED(io_restore) # there is no work to do
b BASED(io_work_loop)
b BASED(io_return)
#
# _TIF_SIGPENDING is set, call do_signal
#
io_sigpending:
TRACE_IRQS_ON
# TRACE_IRQS_ON already done at io_return
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_signal)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
b BASED(io_work_loop)
b BASED(io_return)
#
# _TIF_SIGPENDING is set, call do_signal
#
io_notify_resume:
TRACE_IRQS_ON
# TRACE_IRQS_ON already done at io_return
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
la %r2,SP_PTREGS(%r15) # load pt_regs
l %r1,BASED(.Ldo_notify_resume)
basr %r14,%r1 # call do_signal
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
TRACE_IRQS_OFF
b BASED(io_work_loop)
b BASED(io_return)
/*
* External interrupt handler routine
@ -765,15 +750,14 @@ __critical_end:
.globl mcck_int_handler
mcck_int_handler:
stck __LC_INT_CLOCK
stck __LC_MCCK_CLOCK
spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
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
mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
mvc __LC_MCCK_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
@ -787,7 +771,7 @@ mcck_int_handler:
bl BASED(0f)
la %r14,__LC_LAST_UPDATE_TIMER
0: spt 0(%r14)
mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
1: 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
@ -809,9 +793,9 @@ mcck_int_main:
bno BASED(mcck_no_vtime) # no -> skip cleanup critical
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_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
mcck_no_vtime:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
la %r2,SP_PTREGS(%r15) # load pt_regs
@ -834,7 +818,6 @@ mcck_no_vtime:
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
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
@ -918,18 +901,14 @@ stack_overflow:
cleanup_table_system_call:
.long system_call + 0x80000000, sysc_do_svc + 0x80000000
cleanup_table_sysc_return:
.long sysc_return + 0x80000000, sysc_leave + 0x80000000
cleanup_table_sysc_leave:
.long sysc_leave + 0x80000000, sysc_done + 0x80000000
cleanup_table_sysc_work_loop:
.long sysc_work_loop + 0x80000000, sysc_work_done + 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:
.long io_work_loop + 0x80000000, io_work_done + 0x80000000
cleanup_table_sysc_tif:
.long sysc_tif + 0x80000000, sysc_restore + 0x80000000
cleanup_table_sysc_restore:
.long sysc_restore + 0x80000000, sysc_done + 0x80000000
cleanup_table_io_tif:
.long io_tif + 0x80000000, io_restore + 0x80000000
cleanup_table_io_restore:
.long io_restore + 0x80000000, io_done + 0x80000000
cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_system_call)
@ -937,49 +916,40 @@ cleanup_critical:
clc 4(4,%r12),BASED(cleanup_table_system_call+4)
bl BASED(cleanup_system_call)
0:
clc 4(4,%r12),BASED(cleanup_table_sysc_return)
clc 4(4,%r12),BASED(cleanup_table_sysc_tif)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_sysc_return+4)
bl BASED(cleanup_sysc_return)
clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4)
bl BASED(cleanup_sysc_tif)
0:
clc 4(4,%r12),BASED(cleanup_table_sysc_leave)
clc 4(4,%r12),BASED(cleanup_table_sysc_restore)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_sysc_leave+4)
bl BASED(cleanup_sysc_leave)
clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4)
bl BASED(cleanup_sysc_restore)
0:
clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop)
clc 4(4,%r12),BASED(cleanup_table_io_tif)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
bl BASED(cleanup_sysc_return)
clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
bl BASED(cleanup_io_tif)
0:
clc 4(4,%r12),BASED(cleanup_table_io_return)
clc 4(4,%r12),BASED(cleanup_table_io_restore)
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)
bl BASED(cleanup_io_leave)
0:
clc 4(4,%r12),BASED(cleanup_table_io_work_loop)
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4)
bl BASED(cleanup_io_return)
clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
bl BASED(cleanup_io_restore)
0:
br %r14
cleanup_system_call:
mvc __LC_RETURN_PSW(8),0(%r12)
c %r12,BASED(.Lmck_old_psw)
be BASED(0f)
la %r12,__LC_SAVE_AREA+16
b BASED(1f)
0: la %r12,__LC_SAVE_AREA+32
1:
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
bh BASED(0f)
mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
c %r12,BASED(.Lmck_old_psw)
be BASED(0f)
mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
0: c %r12,BASED(.Lmck_old_psw)
la %r12,__LC_SAVE_AREA+32
be BASED(0f)
la %r12,__LC_SAVE_AREA+16
0: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8)
bhe BASED(cleanup_vtime)
clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
@ -1012,55 +982,54 @@ cleanup_system_call_insn:
.long sysc_stime + 0x80000000
.long sysc_update + 0x80000000
cleanup_sysc_return:
cleanup_sysc_tif:
mvc __LC_RETURN_PSW(4),0(%r12)
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return)
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave:
clc 4(4,%r12),BASED(cleanup_sysc_leave_insn)
cleanup_sysc_restore:
clc 4(4,%r12),BASED(cleanup_sysc_restore_insn)
be BASED(2f)
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
c %r12,BASED(.Lmck_old_psw)
be BASED(0f)
mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
0: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4)
be BASED(2f)
mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
c %r12,BASED(.Lmck_old_psw)
bne BASED(0f)
mvc __LC_SAVE_AREA+32(16),SP_R12(%r15)
b BASED(1f)
0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
1: lm %r0,%r11,SP_R0(%r15)
la %r12,__LC_SAVE_AREA+32
be BASED(1f)
la %r12,__LC_SAVE_AREA+16
1: mvc 0(16,%r12),SP_R12(%r15)
lm %r0,%r11,SP_R0(%r15)
l %r15,SP_R15(%r15)
2: la %r12,__LC_RETURN_PSW
br %r14
cleanup_sysc_leave_insn:
cleanup_sysc_restore_insn:
.long sysc_done - 4 + 0x80000000
.long sysc_done - 8 + 0x80000000
cleanup_io_return:
cleanup_io_tif:
mvc __LC_RETURN_PSW(4),0(%r12)
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave:
clc 4(4,%r12),BASED(cleanup_io_leave_insn)
be BASED(2f)
mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
clc 4(4,%r12),BASED(cleanup_io_leave_insn+4)
be BASED(2f)
cleanup_io_restore:
clc 4(4,%r12),BASED(cleanup_io_restore_insn)
be BASED(1f)
mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
clc 4(4,%r12),BASED(cleanup_io_restore_insn+4)
be BASED(1f)
mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
c %r12,BASED(.Lmck_old_psw)
bne BASED(0f)
mvc __LC_SAVE_AREA+32(16),SP_R12(%r15)
b BASED(1f)
0: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
1: lm %r0,%r11,SP_R0(%r15)
lm %r0,%r11,SP_R0(%r15)
l %r15,SP_R15(%r15)
2: la %r12,__LC_RETURN_PSW
1: la %r12,__LC_RETURN_PSW
br %r14
cleanup_io_leave_insn:
cleanup_io_restore_insn:
.long io_done - 4 + 0x80000000
.long io_done - 8 + 0x80000000

View file

@ -24,17 +24,13 @@ int __cpuinit start_secondary(void *cpuvoid);
void __init startup_init(void);
void die(const char * str, struct pt_regs * regs, long err);
struct new_utsname;
struct mmap_arg_struct;
struct s390_mmap_arg_struct;
struct fadvise64_64_args;
struct old_sigaction;
struct sel_arg_struct;
long sys_mmap2(struct mmap_arg_struct __user *arg);
long sys_s390_old_mmap(struct mmap_arg_struct __user *arg);
long sys_ipc(uint call, int first, unsigned long second,
long sys_mmap2(struct s390_mmap_arg_struct __user *arg);
long sys_s390_ipc(uint call, int first, unsigned long second,
unsigned long third, void __user *ptr);
long sys_s390_newuname(struct new_utsname __user *name);
long sys_s390_personality(unsigned long personality);
long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low,
size_t len, int advice);

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <trace/syscall.h>
#include <asm/lowcore.h>
#include <asm/asm-offsets.h>
#ifdef CONFIG_DYNAMIC_FTRACE
@ -200,13 +200,3 @@ out:
return parent;
}
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
#ifdef CONFIG_FTRACE_SYSCALLS
extern unsigned int sys_call_table[];
unsigned long __init arch_syscall_addr(int nr)
{
return (unsigned long)sys_call_table[nr];
}
#endif

View file

@ -1,5 +1,5 @@
/*
* Copyright IBM Corp. 1999,2009
* Copyright IBM Corp. 1999,2010
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -22,12 +22,9 @@
*/
#include <linux/init.h>
#include <asm/setup.h>
#include <asm/lowcore.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/cpu.h>
#ifdef CONFIG_64BIT
#define ARCH_OFFSET 4
@ -288,19 +285,7 @@ iplstart:
bz .Lagain1 # skip dateset trailer
la %r5,0(%r4,%r2)
lr %r3,%r2
.Lidebc:
tm 0(%r5),0x80 # high order bit set ?
bo .Ldocv # yes -> convert from EBCDIC
ahi %r5,-1
bct %r3,.Lidebc
b .Lnocv
.Ldocv:
l %r3,.Lcvtab
tr 0(256,%r4),0(%r3) # convert parameters to ascii
tr 256(256,%r4),0(%r3)
tr 512(256,%r4),0(%r3)
tr 768(122,%r4),0(%r3)
.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
mvc 0(256,%r3),0(%r4)
mvc 256(256,%r3),256(%r4)
mvc 512(256,%r3),512(%r4)
@ -343,8 +328,8 @@ iplstart:
#
# reset files in VM reader
#
stidp __LC_CPUID # store cpuid
tm __LC_CPUID,0xff # running VM ?
stidp __LC_SAVE_AREA # store cpuid
tm __LC_SAVE_AREA,0xff # running VM ?
bno .Lnoreset
la %r2,.Lreset
lhi %r3,26
@ -384,7 +369,6 @@ iplstart:
.Linitrd:.long _end + 0x400000 # default address of initrd
.Lparm: .long PARMAREA
.Lstartup: .long startup
.Lcvtab:.long _ebcasc # ebcdic to ascii table
.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
.byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
.byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold"
@ -417,13 +401,10 @@ start:
.sk8x8:
mvc 0(240,%r8),0(%r9) # copy iplparms into buffer
.gotr:
l %r10,.tbl # EBCDIC to ASCII table
tr 0(240,%r8),0(%r10)
slr %r0,%r0
st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
j startup # continue with startup
.tbl: .long _ebcasc # translate table
.cmd: .long COMMAND_LINE # address of command line buffer
.parm: .long PARMAREA
.lowcase:
@ -467,16 +448,15 @@ start:
# or linload or SALIPL
#
.org 0x10000
startup:basr %r13,0 # get base
.globl startup
startup:
basr %r13,0 # get base
.LPG0:
xc 0x200(256),0x200 # partially clear lowcore
xc 0x300(256),0x300
l %r1,5f-.LPG0(%r13)
stck 0(%r1)
spt 6f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_CLOCK(8),0(%r1)
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
mvc __LC_EXIT_TIMER(8),5f-.LPG0(%r13)
stck __LC_LAST_UPDATE_CLOCK
spt 5f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
#ifndef CONFIG_MARCH_G5
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10}
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST
@ -494,7 +474,6 @@ startup:basr %r13,0 # get base
cl %r0,2f+12-.LPG0(%r13)
je 3f
1: l %r15,.Lstack-.LPG0(%r13)
ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
ahi %r15,-96
la %r2,.Lals_string-.LPG0(%r13)
l %r3,.Lsclp_print-.LPG0(%r13)
@ -505,7 +484,7 @@ startup:basr %r13,0 # get base
.Lsclp_print:
.long _sclp_print_early
.Lstack:
.long init_thread_union
.long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER))
.align 16
2: .long 0x000a0000,0x8badcccc
#if defined(CONFIG_64BIT)
@ -532,13 +511,25 @@ startup:basr %r13,0 # get base
3:
#endif
#ifdef CONFIG_64BIT
mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
lhi %r1,2 # mode 2 = esame (dump)
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
larl %r13,4f
lmh %r0,%r15,0(%r13) # clear high-order half
jg startup_continue
4: .fill 16,4,0x0
#else
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
l %r13,4f-.LPG0(%r13)
b 0(%r13)
.align 4
4: .long startup_continue
5: .long sched_clock_base_cc
.align 8
6: .long 0x7fffffff,0xffffffff
4: .long startup_continue
#endif
.align 8
5: .long 0x7fffffff,0xffffffff
#
# params at 10400 (setup.h)
@ -552,8 +543,4 @@ startup:basr %r13,0 # get base
.byte "root=/dev/ram0 ro"
.byte 0
#ifdef CONFIG_64BIT
#include "head64.S"
#else
#include "head31.S"
#endif
.org 0x11000

View file

@ -1,7 +1,7 @@
/*
* arch/s390/kernel/head31.S
*
* Copyright (C) IBM Corp. 2005,2006
* Copyright (C) IBM Corp. 2005,2010
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -10,13 +10,19 @@
*
*/
.org 0x11000
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1:
mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
l %r1,.Lbase_cc-.LPG1(%r13)
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
@ -69,12 +75,14 @@ startup_continue:
.Lduald:.rept 8
.long 0x80000000,0,0,0 # invalid access-list entries
.endr
.Lbase_cc:
.long sched_clock_base_cc
.org 0x12000
.globl _ehead
_ehead:
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
.org 0x100000 - 0x11000 # head.o ends at 0x11000
#endif
#

View file

@ -1,7 +1,7 @@
/*
* arch/s390/kernel/head64.S
*
* Copyright (C) IBM Corp. 1999,2006
* Copyright (C) IBM Corp. 1999,2010
*
* Author(s): Hartmut Penner <hp@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
@ -10,81 +10,17 @@
*
*/
.org 0x11000
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
__HEAD
.globl startup_continue
startup_continue:
basr %r13,0 # get base
.LPG1: sll %r13,1 # remove high order bit
srl %r13,1
#ifdef CONFIG_ZFCPDUMP
# check if we have been ipled using zfcp dump:
tm 0xb9,0x01 # test if subchannel is enabled
jno .nodump # subchannel disabled
l %r1,0xb8
la %r5,.Lipl_schib-.LPG1(%r13)
stsch 0(%r5) # get schib of subchannel
jne .nodump # schib not available
tm 5(%r5),0x01 # devno valid?
jno .nodump
tm 4(%r5),0x80 # qdio capable device?
jno .nodump
l %r2,20(%r0) # address of ipl parameter block
lhi %r3,0
ic %r3,0x148(%r2) # get opt field
chi %r3,0x20 # load with dump?
jne .nodump
# store all prefix registers in case of load with dump:
la %r7,0 # base register for 0 page
la %r8,0 # first cpu
l %r11,.Lpref_arr_ptr-.LPG1(%r13) # address of prefix array
ahi %r11,4 # skip boot cpu
lr %r12,%r11
ahi %r12,(CONFIG_NR_CPUS*4) # end of prefix array
stap .Lcurrent_cpu+2-.LPG1(%r13) # store current cpu addr
1:
cl %r8,.Lcurrent_cpu-.LPG1(%r13) # is ipl cpu ?
je 4f # if yes get next cpu
2:
lr %r9,%r7
sigp %r9,%r8,0x9 # stop & store status of cpu
brc 8,3f # accepted
brc 4,4f # status stored: next cpu
brc 2,2b # busy: try again
brc 1,4f # not op: next cpu
3:
mvc 0(4,%r11),264(%r7) # copy prefix register to prefix array
ahi %r11,4 # next element in prefix array
clr %r11,%r12
je 5f # no more space in prefix array
4:
ahi %r8,1 # next cpu (r8 += 1)
chi %r8,MAX_CPU_ADDRESS # is last possible cpu ?
jle 1b # jump if not last cpu
5:
lhi %r1,2 # mode 2 = esame (dump)
j 6f
.align 4
.Lipl_schib:
.rept 13
.long 0
.endr
.nodump:
lhi %r1,1 # mode 1 = esame (normal ipl)
6:
#else
lhi %r1,1 # mode 1 = esame (normal ipl)
#endif /* CONFIG_ZFCPDUMP */
mvi __LC_AR_MODE_ID,1 # set esame flag
slr %r0,%r0 # set cpuid to zero
sigp %r1,%r0,0x12 # switch to esame mode
sam64 # switch to 64 bit mode
llgfr %r13,%r13 # clear high-order half of base reg
lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half
larl %r1,sched_clock_base_cc
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
larl %r13,.LPG1 # get base
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
@ -108,6 +44,7 @@ startup_continue:
lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
# virtual and never return ...
.align 16
.LPG1:
.Lentry:.quad 0x0000000180000000,_stext
.Lctl: .quad 0x04350002 # cr0: various things
.quad 0 # cr1: primary space segment table
@ -129,13 +66,6 @@ startup_continue:
.L4malign:.quad 0xffffffffffc00000
.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
.Lnop: .long 0x07000700
.Lzero64:.fill 16,4,0x0
#ifdef CONFIG_ZFCPDUMP
.Lcurrent_cpu:
.long 0x0
.Lpref_arr_ptr:
.long zfcpdump_prefix_array
#endif /* CONFIG_ZFCPDUMP */
.Lparmaddr:
.quad PARMAREA
.align 64
@ -146,11 +76,11 @@ startup_continue:
.long 0x80000000,0,0,0 # invalid access-list entries
.endr
.org 0x12000
.globl _ehead
_ehead:
#ifdef CONFIG_SHARED_KERNEL
.org 0x100000
.org 0x100000 - 0x11000 # head.o ends at 0x11000
#endif
#

View file

@ -15,6 +15,7 @@
#include <linux/reboot.h>
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/gfp.h>
#include <asm/ipl.h>
#include <asm/smp.h>
#include <asm/setup.h>
@ -402,8 +403,9 @@ static ssize_t sys_ipl_device_show(struct kobject *kobj,
static struct kobj_attribute sys_ipl_device_attr =
__ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START,
IPL_PARMBLOCK_SIZE);
@ -418,8 +420,9 @@ static struct bin_attribute ipl_parameter_attr = {
.read = &ipl_parameter_read,
};
static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
@ -553,7 +556,7 @@ out:
return rc;
}
static void ipl_run(struct shutdown_trigger *trigger)
static void __ipl_run(void *unused)
{
diag308(DIAG308_IPL, NULL);
if (MACHINE_IS_VM)
@ -562,6 +565,11 @@ static void ipl_run(struct shutdown_trigger *trigger)
reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
}
static void ipl_run(struct shutdown_trigger *trigger)
{
smp_switch_to_ipl_cpu(__ipl_run, NULL);
}
static int __init ipl_init(void)
{
int rc;
@ -688,7 +696,7 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
/* FCP reipl device attributes */
static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj,
static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
@ -698,7 +706,7 @@ static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj,
return memory_read_from_buffer(buf, count, &off, scp_data, size);
}
static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj,
static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
@ -1039,7 +1047,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
sprintf(dst + pos, " PARM %s", vmparm);
}
static void reipl_run(struct shutdown_trigger *trigger)
static void __reipl_run(void *unused)
{
struct ccw_dev_id devid;
static char buf[128];
@ -1087,6 +1095,11 @@ static void reipl_run(struct shutdown_trigger *trigger)
disabled_wait((unsigned long) __builtin_return_address(0));
}
static void reipl_run(struct shutdown_trigger *trigger)
{
smp_switch_to_ipl_cpu(__reipl_run, NULL);
}
static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
{
ipb->hdr.len = IPL_PARM_BLK_CCW_LEN;
@ -1369,20 +1382,18 @@ static struct kobj_attribute dump_type_attr =
static struct kset *dump_kset;
static void dump_run(struct shutdown_trigger *trigger)
static void __dump_run(void *unused)
{
struct ccw_dev_id devid;
static char buf[100];
switch (dump_method) {
case DUMP_METHOD_CCW_CIO:
smp_send_stop();
devid.devno = dump_block_ccw->ipl_info.ccw.devno;
devid.ssid = 0;
reipl_ccw_dev(&devid);
break;
case DUMP_METHOD_CCW_VM:
smp_send_stop();
sprintf(buf, "STORE STATUS");
__cpcmd(buf, NULL, 0, NULL);
sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
@ -1396,10 +1407,17 @@ static void dump_run(struct shutdown_trigger *trigger)
diag308(DIAG308_SET, dump_block_fcp);
diag308(DIAG308_DUMP, NULL);
break;
case DUMP_METHOD_NONE:
return;
default:
break;
}
printk(KERN_EMERG "Dump failed!\n");
}
static void dump_run(struct shutdown_trigger *trigger)
{
if (dump_method == DUMP_METHOD_NONE)
return;
smp_send_stop();
smp_switch_to_ipl_cpu(__dump_run, NULL);
}
static int __init dump_ccw_init(void)
@ -1577,7 +1595,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger)
static int vmcmd_init(void)
{
if (!MACHINE_IS_VM)
return -ENOTSUPP;
return -EOPNOTSUPP;
vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
if (!vmcmd_kset)
return -ENOMEM;
@ -1595,7 +1613,7 @@ static void stop_run(struct shutdown_trigger *trigger)
{
if (strcmp(trigger->name, ON_PANIC_STR) == 0)
disabled_wait((unsigned long) __builtin_return_address(0));
while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
cpu_relax();
for (;;);
}
@ -1902,7 +1920,6 @@ void __init ipl_update_parameters(void)
void __init ipl_save_parameters(void)
{
struct cio_iplinfo iplinfo;
unsigned int *ipl_ptr;
void *src, *dst;
if (cio_get_iplinfo(&iplinfo))
@ -1913,11 +1930,10 @@ void __init ipl_save_parameters(void)
if (!iplinfo.is_qdio)
return;
ipl_flags |= IPL_PARMBLOCK_VALID;
ipl_ptr = (unsigned int *)__LC_IPL_PARMBLOCK_PTR;
src = (void *)(unsigned long)*ipl_ptr;
src = (void *)(unsigned long)S390_lowcore.ipl_parmblock_ptr;
dst = (void *)IPL_PARMBLOCK_ORIGIN;
memmove(dst, src, PAGE_SIZE);
*ipl_ptr = IPL_PARMBLOCK_ORIGIN;
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
}
static LIST_HEAD(rcall);

View file

@ -29,6 +29,7 @@
#include <asm/cacheflush.h>
#include <asm/sections.h>
#include <linux/module.h>
#include <linux/slab.h>
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
@ -62,6 +63,8 @@ int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
case 0x0b: /* bsm */
case 0x83: /* diag */
case 0x44: /* ex */
case 0xac: /* stnsm */
case 0xad: /* stosm */
return -EINVAL;
}
switch (*(__u16 *) instruction) {
@ -71,6 +74,7 @@ int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
case 0xb258: /* bsg */
case 0xb218: /* pc */
case 0xb228: /* pt */
case 0xb98d: /* epsw */
return -EINVAL;
}
return 0;

View file

@ -54,11 +54,11 @@ void machine_shutdown(void)
{
}
void machine_kexec(struct kimage *image)
static void __machine_kexec(void *data)
{
relocate_kernel_t data_mover;
struct kimage *image = data;
smp_send_stop();
pfault_fini();
s390_reset_system();
@ -68,3 +68,9 @@ void machine_kexec(struct kimage *image)
(*data_mover)(&image->head, image->start);
for (;;);
}
void machine_kexec(struct kimage *image)
{
smp_send_stop();
smp_switch_to_ipl_cpu(__machine_kexec, image);
}

View file

@ -55,8 +55,10 @@ void *module_alloc(unsigned long size)
/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
vfree(mod->arch.syminfo);
mod->arch.syminfo = NULL;
if (mod) {
vfree(mod->arch.syminfo);
mod->arch.syminfo = NULL;
}
vfree(module_region);
}

View file

@ -255,7 +255,8 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
int umode;
nmi_enter();
s390_idle_check();
s390_idle_check(regs, S390_lowcore.mcck_clock,
S390_lowcore.mcck_enter_timer);
mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
mcck = &__get_cpu_var(cpu_mcck);

View file

@ -16,9 +16,9 @@
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/interrupt.h>

View file

@ -18,24 +18,42 @@
#include <asm/lowcore.h>
#include <asm/param.h>
static DEFINE_PER_CPU(struct cpuid, cpu_id);
/*
* cpu_init - initializes state that is per-CPU.
*/
void __cpuinit cpu_init(void)
{
struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
get_cpu_id(id);
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
BUG_ON(current->mm);
enter_lazy_tlb(&init_mm, current);
}
/*
* print_cpu_info - print basic information about a cpu
*/
void __cpuinit print_cpu_info(void)
{
struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
pr_info("Processor %d started, address %d, identification %06X\n",
S390_lowcore.cpu_nr, S390_lowcore.cpu_addr,
S390_lowcore.cpu_id.ident);
S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, id->ident);
}
/*
* show_cpuinfo - Get information on one CPU for use by procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
static const char *hwcap_str[10] = {
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
"edat", "etf3eh", "highgprs"
};
struct _lowcore *lc;
unsigned long n = (unsigned long) v - 1;
int i;
@ -55,19 +73,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
}
if (cpu_online(n)) {
#ifdef CONFIG_SMP
lc = (smp_processor_id() == n) ?
&S390_lowcore : lowcore_ptr[n];
#else
lc = &S390_lowcore;
#endif
struct cpuid *id = &per_cpu(cpu_id, n);
seq_printf(m, "processor %li: "
"version = %02X, "
"identification = %06X, "
"machine = %04X\n",
n, lc->cpu_id.version,
lc->cpu_id.ident,
lc->cpu_id.machine);
n, id->version, id->ident, id->machine);
}
preempt_enable();
return 0;

View file

@ -57,6 +57,7 @@
enum s390_regset {
REGSET_GENERAL,
REGSET_FP,
REGSET_LAST_BREAK,
REGSET_GENERAL_EXTENDED,
};
@ -381,6 +382,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
copied += sizeof(unsigned long);
}
return 0;
case PTRACE_GET_LAST_BREAK:
put_user(task_thread_info(child)->last_break,
(unsigned long __user *) data);
return 0;
default:
/* Removing high order bit from addr (only for 31 bit). */
addr &= PSW_ADDR_INSN;
@ -633,6 +638,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
copied += sizeof(unsigned int);
}
return 0;
case PTRACE_GET_LAST_BREAK:
put_user(task_thread_info(child)->last_break,
(unsigned int __user *) data);
return 0;
}
return compat_ptrace_request(child, request, addr, data);
}
@ -640,7 +649,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret;
long ret = 0;
/* Do the secure computing check first. */
secure_computing(regs->gprs[2]);
@ -649,7 +658,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
*/
ret = regs->gprs[2];
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
(tracehook_report_syscall_entry(regs) ||
regs->gprs[2] >= NR_syscalls)) {
@ -671,7 +679,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
regs->gprs[2], regs->orig_gpr2,
regs->gprs[3], regs->gprs[4],
regs->gprs[5]);
return ret;
return ret ?: regs->gprs[2];
}
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
@ -798,6 +806,28 @@ static int s390_fpregs_set(struct task_struct *target,
return rc;
}
#ifdef CONFIG_64BIT
static int s390_last_break_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
if (count > 0) {
if (kbuf) {
unsigned long *k = kbuf;
*k = task_thread_info(target)->last_break;
} else {
unsigned long __user *u = ubuf;
if (__put_user(task_thread_info(target)->last_break, u))
return -EFAULT;
}
}
return 0;
}
#endif
static const struct user_regset s390_regsets[] = {
[REGSET_GENERAL] = {
.core_note_type = NT_PRSTATUS,
@ -815,6 +845,15 @@ static const struct user_regset s390_regsets[] = {
.get = s390_fpregs_get,
.set = s390_fpregs_set,
},
#ifdef CONFIG_64BIT
[REGSET_LAST_BREAK] = {
.core_note_type = NT_S390_LAST_BREAK,
.n = 1,
.size = sizeof(long),
.align = sizeof(long),
.get = s390_last_break_get,
},
#endif
};
static const struct user_regset_view user_s390_view = {
@ -949,6 +988,27 @@ static int s390_compat_regs_high_set(struct task_struct *target,
return rc;
}
static int s390_compat_last_break_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
compat_ulong_t last_break;
if (count > 0) {
last_break = task_thread_info(target)->last_break;
if (kbuf) {
unsigned long *k = kbuf;
*k = last_break;
} else {
unsigned long __user *u = ubuf;
if (__put_user(last_break, u))
return -EFAULT;
}
}
return 0;
}
static const struct user_regset s390_compat_regsets[] = {
[REGSET_GENERAL] = {
.core_note_type = NT_PRSTATUS,
@ -966,6 +1026,13 @@ static const struct user_regset s390_compat_regsets[] = {
.get = s390_fpregs_get,
.set = s390_fpregs_set,
},
[REGSET_LAST_BREAK] = {
.core_note_type = NT_S390_LAST_BREAK,
.n = 1,
.size = sizeof(long),
.align = sizeof(long),
.get = s390_compat_last_break_get,
},
[REGSET_GENERAL_EXTENDED] = {
.core_note_type = NT_S390_HIGH_GPRS,
.n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
@ -992,3 +1059,61 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
#endif
return &user_s390_view;
}
static const char *gpr_names[NUM_GPRS] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
};
unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
{
if (offset >= NUM_GPRS)
return 0;
return regs->gprs[offset];
}
int regs_query_register_offset(const char *name)
{
unsigned long offset;
if (!name || *name != 'r')
return -EINVAL;
if (strict_strtoul(name + 1, 10, &offset))
return -EINVAL;
if (offset >= NUM_GPRS)
return -EINVAL;
return offset;
}
const char *regs_query_register_name(unsigned int offset)
{
if (offset >= NUM_GPRS)
return NULL;
return gpr_names[offset];
}
static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
{
unsigned long ksp = kernel_stack_pointer(regs);
return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1));
}
/**
* regs_get_kernel_stack_nth() - get Nth entry of the stack
* @regs:pt_regs which contains kernel stack pointer.
* @n:stack entry number.
*
* regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
* is specifined by @regs. If the @n th entry is NOT in the kernel stack,
* this returns 0.
*/
unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
{
unsigned long addr;
addr = kernel_stack_pointer(regs) + n * sizeof(long);
if (!regs_within_kernel_stack(regs, addr))
return 0;
return *(unsigned long *)addr;
}

View file

@ -6,7 +6,7 @@
* Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
*/
#include <asm/lowcore.h>
#include <asm/asm-offsets.h>
#
# do_reipl_asm

View file

@ -4,7 +4,7 @@
* Denis Joseph Barrow,
*/
#include <asm/lowcore.h>
#include <asm/asm-offsets.h>
#
# do_reipl_asm

View file

@ -120,7 +120,8 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
struct pt_regs *old_regs;
old_regs = set_irq_regs(regs);
s390_idle_check();
s390_idle_check(regs, S390_lowcore.int_clock,
S390_lowcore.async_enter_timer);
irq_enter();
if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
/* Serve timer interrupts first. */

View file

@ -9,8 +9,10 @@
*/
LC_EXT_NEW_PSW = 0x58 # addr of ext int handler
LC_EXT_NEW_PSW_64 = 0x1b0 # addr of ext int handler 64 bit
LC_EXT_INT_PARAM = 0x80 # addr of ext int parameter
LC_EXT_INT_CODE = 0x86 # addr of ext int code
LC_AR_MODE_ID = 0xa3
#
# Subroutine which waits synchronously until either an external interruption
@ -30,8 +32,16 @@ _sclp_wait_int:
.LbaseS1:
ahi %r15,-96 # create stack frame
la %r8,LC_EXT_NEW_PSW # register int handler
mvc .LoldpswS1-.LbaseS1(8,%r13),0(%r8)
mvc 0(8,%r8),.LextpswS1-.LbaseS1(%r13)
la %r9,.LextpswS1-.LbaseS1(%r13)
#ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa1
la %r8,LC_EXT_NEW_PSW_64 # register int handler 64 bit
la %r9,.LextpswS1_64-.LbaseS1(%r13)
.Lesa1:
#endif
mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8)
mvc 0(16,%r8),0(%r9)
lhi %r6,0x0200 # cr mask for ext int (cr0.54)
ltr %r2,%r2
jz .LsetctS1
@ -64,15 +74,19 @@ _sclp_wait_int:
.LtimeoutS1:
lctl %c0,%c0,.LctlS1-.LbaseS1(%r13) # restore interrupt setting
# restore old handler
mvc 0(8,%r8),.LoldpswS1-.LbaseS1(%r13)
mvc 0(16,%r8),.LoldpswS1-.LbaseS1(%r13)
lm %r6,%r15,120(%r15) # restore registers
br %r14 # return to caller
.align 8
.LoldpswS1:
.long 0, 0 # old ext int PSW
.long 0, 0, 0, 0 # old ext int PSW
.LextpswS1:
.long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int
#ifdef CONFIG_64BIT
.LextpswS1_64:
.quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit
#endif
.LwaitpswS1:
.long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int
.LtimeS1:
@ -221,7 +235,7 @@ _sclp_print:
lh %r9,0(%r8) # update sccb length
ar %r9,%r6
sth %r9,0(%r8)
ar %r7,%r6 # update current mto adress
ar %r7,%r6 # update current mto address
ltr %r0,%r0 # more characters?
jnz .LinitmtoS4
l %r2,.LwritedataS4-.LbaseS4(%r13)# write data
@ -250,6 +264,13 @@ _sclp_print:
_sclp_print_early:
stm %r6,%r15,24(%r15) # save registers
ahi %r15,-96 # create stack frame
#ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa2
ahi %r15,-80
stmh %r6,%r15,96(%r15) # store upper register halves
.Lesa2:
#endif
lr %r10,%r2 # save string pointer
lhi %r2,0
bras %r14,_sclp_setup # enable console
@ -262,6 +283,13 @@ _sclp_print_early:
lhi %r2,1
bras %r14,_sclp_setup # disable console
.LendS5:
#ifdef CONFIG_64BIT
tm LC_AR_MODE_ID,1
jno .Lesa3
lmh %r6,%r15,96(%r15) # store upper register halves
ahi %r15,80
.Lesa3:
#endif
lm %r6,%r15,120(%r15) # restore registers
br %r14

View file

@ -2,7 +2,7 @@
* arch/s390/kernel/setup.c
*
* S390 version
* Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Copyright (C) IBM Corp. 1999,2010
* Author(s): Hartmut Penner (hp@de.ibm.com),
* Martin Schwidefsky (schwidefsky@de.ibm.com)
*
@ -25,7 +25,6 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/ioport.h>
@ -113,22 +112,6 @@ static struct resource data_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM,
};
/*
* cpu_init() initializes state that is per-CPU.
*/
void __cpuinit cpu_init(void)
{
/*
* Store processor id in lowcore (used e.g. in timer_interrupt)
*/
get_cpu_id(&S390_lowcore.cpu_id);
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
BUG_ON(current->mm);
enter_lazy_tlb(&init_mm, current);
}
/*
* condev= and conmode= setup parameter.
*/
@ -386,25 +369,18 @@ static void setup_addressing_mode(void)
pr_info("Address spaces switched, "
"mvcos not available\n");
}
#ifdef CONFIG_TRACE_IRQFLAGS
sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
#endif
}
static void __init
setup_lowcore(void)
{
struct _lowcore *lc;
int lc_pages;
/*
* Setup lowcore for boot cpu
*/
lc_pages = sizeof(void *) == 8 ? 2 : 1;
lc = (struct _lowcore *)
__alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);
memset(lc, 0, lc_pages * PAGE_SIZE);
BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096);
lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
lc->restart_psw.addr =
PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
@ -436,11 +412,12 @@ setup_lowcore(void)
#ifndef CONFIG_64BIT
if (MACHINE_HAS_IEEE) {
lc->extended_save_area_addr = (__u32)
__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
__alloc_bootmem_low(PAGE_SIZE, PAGE_SIZE, 0);
/* enable extended save area */
__ctl_set_bit(14, 29);
}
#else
lc->cmf_hpp = -1ULL;
lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
#endif
lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
@ -699,6 +676,7 @@ static void __init setup_hwcaps(void)
static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
unsigned long long facility_list_extended;
unsigned int facility_list;
struct cpuid cpu_id;
int i;
facility_list = stfl();
@ -760,7 +738,8 @@ static void __init setup_hwcaps(void)
*/
elf_hwcap |= HWCAP_S390_HIGH_GPRS;
switch (S390_lowcore.cpu_id.machine) {
get_cpu_id(&cpu_id);
switch (cpu_id.machine) {
case 0x9672:
#if !defined(CONFIG_64BIT)
default: /* Use "g5" as default for 31 bit kernels. */
@ -804,7 +783,7 @@ setup_arch(char **cmdline_p)
if (MACHINE_IS_VM)
pr_info("Linux is running as a z/VM "
"guest operating system in 31-bit mode\n");
else
else if (MACHINE_IS_LPAR)
pr_info("Linux is running natively in 31-bit mode\n");
if (MACHINE_HAS_IEEE)
pr_info("The hardware system has IEEE compatible "
@ -818,7 +797,7 @@ setup_arch(char **cmdline_p)
"guest operating system in 64-bit mode\n");
else if (MACHINE_IS_KVM)
pr_info("Linux is running under KVM in 64-bit mode\n");
else
else if (MACHINE_IS_LPAR)
pr_info("Linux is running natively in 64-bit mode\n");
#endif /* CONFIG_64BIT */

View file

@ -313,6 +313,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
To avoid breaking binary compatibility, they are passed as args. */
regs->gprs[4] = current->thread.trap_no;
regs->gprs[5] = current->thread.prot_addr;
regs->gprs[6] = task_thread_info(current)->last_break;
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
@ -376,6 +377,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
regs->gprs[2] = map_signal(sig);
regs->gprs[3] = (unsigned long) &frame->info;
regs->gprs[4] = (unsigned long) &frame->uc;
regs->gprs[5] = task_thread_info(current)->last_break;
return 0;
give_sigsegv:

View file

@ -36,6 +36,8 @@
#include <linux/cpu.h>
#include <linux/timex.h>
#include <linux/bootmem.h>
#include <linux/slab.h>
#include <asm/asm-offsets.h>
#include <asm/ipl.h>
#include <asm/setup.h>
#include <asm/sigp.h>
@ -53,7 +55,7 @@
#include "entry.h"
/* logical cpu to cpu address */
int __cpu_logical_map[NR_CPUS];
unsigned short __cpu_logical_map[NR_CPUS];
static struct task_struct *current_set[NR_CPUS];
@ -72,13 +74,13 @@ static int cpu_management;
static DEFINE_PER_CPU(struct cpu, cpu_devices);
static void smp_ext_bitcall(int, ec_bit_sig);
static void smp_ext_bitcall(int, int);
static int cpu_stopped(int cpu)
static int raw_cpu_stopped(int cpu)
{
__u32 status;
u32 status;
switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) {
switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
case sigp_status_stored:
/* Check for stopped and check stop state */
if (status & 0x50)
@ -90,6 +92,44 @@ static int cpu_stopped(int cpu)
return 0;
}
static inline int cpu_stopped(int cpu)
{
return raw_cpu_stopped(cpu_logical_map(cpu));
}
void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
{
struct _lowcore *lc, *current_lc;
struct stack_frame *sf;
struct pt_regs *regs;
unsigned long sp;
if (smp_processor_id() == 0)
func(data);
__load_psw_mask(PSW_BASE_BITS | PSW_DEFAULT_KEY);
/* Disable lowcore protection */
__ctl_clear_bit(0, 28);
current_lc = lowcore_ptr[smp_processor_id()];
lc = lowcore_ptr[0];
if (!lc)
lc = current_lc;
lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
if (!cpu_online(0))
smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
cpu_relax();
sp = lc->panic_stack;
sp -= sizeof(struct pt_regs);
regs = (struct pt_regs *) sp;
memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
regs->psw = lc->psw_save_area;
sp -= STACK_FRAME_OVERHEAD;
sf = (struct stack_frame *) sp;
sf->back_chain = regs->gprs[15];
smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
}
void smp_send_stop(void)
{
int cpu, rc;
@ -103,7 +143,7 @@ void smp_send_stop(void)
if (cpu == smp_processor_id())
continue;
do {
rc = signal_processor(cpu, sigp_stop);
rc = sigp(cpu, sigp_stop);
} while (rc == sigp_busy);
while (!cpu_stopped(cpu))
@ -139,13 +179,13 @@ static void do_ext_call_interrupt(__u16 code)
* Send an external call sigp to another cpu and return without waiting
* for its completion.
*/
static void smp_ext_bitcall(int cpu, ec_bit_sig sig)
static void smp_ext_bitcall(int cpu, int sig)
{
/*
* Set signaling bit in lowcore of target cpu and kick it
*/
set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy)
while (sigp(cpu, sigp_emergency_signal) == sigp_busy)
udelay(10);
}
@ -239,24 +279,8 @@ void smp_ctl_clear_bit(int cr, int bit)
}
EXPORT_SYMBOL(smp_ctl_clear_bit);
/*
* In early ipl state a temp. logically cpu number is needed, so the sigp
* functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
* CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
*/
#define CPU_INIT_NO 1
#ifdef CONFIG_ZFCPDUMP
/*
* zfcpdump_prefix_array holds prefix registers for the following scenario:
* 64 bit zfcpdump kernel and 31 bit kernel which is to be dumped. We have to
* save its prefix registers, since they get lost, when switching from 31 bit
* to 64 bit.
*/
unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
__attribute__((__section__(".data")));
static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
{
if (ipl_info.type != IPL_TYPE_FCP_DUMP)
@ -266,21 +290,15 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
"the dump\n", cpu, NR_CPUS - 1);
return;
}
zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
__cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
sigp_busy)
zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
cpu_relax();
memcpy(zfcpdump_save_areas[cpu],
(void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
SAVE_AREA_SIZE);
#ifdef CONFIG_64BIT
/* copy original prefix register */
zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
#endif
memcpy_real(zfcpdump_save_areas[cpu],
(void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
sizeof(struct save_area));
}
union save_area *zfcpdump_save_areas[NR_CPUS + 1];
struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
#else
@ -389,8 +407,7 @@ static void __init smp_detect_cpus(void)
for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
if (cpu == boot_cpu_addr)
continue;
__cpu_logical_map[CPU_INIT_NO] = cpu;
if (!cpu_stopped(CPU_INIT_NO))
if (!raw_cpu_stopped(cpu))
continue;
smp_get_save_area(c_cpus, cpu);
c_cpus++;
@ -413,8 +430,7 @@ static void __init smp_detect_cpus(void)
cpu_addr = info->cpu[cpu].address;
if (cpu_addr == boot_cpu_addr)
continue;
__cpu_logical_map[CPU_INIT_NO] = cpu_addr;
if (!cpu_stopped(CPU_INIT_NO)) {
if (!raw_cpu_stopped(cpu_addr)) {
s_cpus++;
continue;
}
@ -533,18 +549,18 @@ static void smp_free_lowcore(int cpu)
/* Upping and downing of CPUs */
int __cpuinit __cpu_up(unsigned int cpu)
{
struct task_struct *idle;
struct _lowcore *cpu_lowcore;
struct task_struct *idle;
struct stack_frame *sf;
sigp_ccode ccode;
u32 lowcore;
int ccode;
if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
return -EIO;
if (smp_alloc_lowcore(cpu))
return -ENOMEM;
do {
ccode = signal_processor(cpu, sigp_initial_cpu_reset);
ccode = sigp(cpu, sigp_initial_cpu_reset);
if (ccode == sigp_busy)
udelay(10);
if (ccode == sigp_not_operational)
@ -552,7 +568,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
} while (ccode == sigp_busy);
lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
udelay(10);
idle = current_set[cpu];
@ -578,7 +594,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
eieio();
while (signal_processor(cpu, sigp_restart) == sigp_busy)
while (sigp(cpu, sigp_restart) == sigp_busy)
udelay(10);
while (!cpu_online(cpu))
@ -640,7 +656,7 @@ void __cpu_die(unsigned int cpu)
/* Wait until target cpu is down */
while (!cpu_stopped(cpu))
cpu_relax();
while (signal_processor_p(0, cpu, sigp_set_prefix) == sigp_busy)
while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
udelay(10);
smp_free_lowcore(cpu);
pr_info("Processor %d stopped\n", cpu);
@ -649,7 +665,7 @@ void __cpu_die(unsigned int cpu)
void cpu_die(void)
{
idle_task_exit();
while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
cpu_relax();
for (;;);
}
@ -765,7 +781,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
get_online_cpus();
mutex_lock(&smp_cpu_state_mutex);
rc = -EBUSY;
if (cpu_online(cpu))
/* disallow configuration changes of online cpus and cpu 0 */
if (cpu_online(cpu) || cpu == 0)
goto out;
rc = 0;
switch (val) {
@ -927,21 +944,21 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
struct cpu *c = &per_cpu(cpu_devices, cpu);
struct sys_device *s = &c->sysdev;
struct s390_idle_data *idle;
int err = 0;
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
idle = &per_cpu(s390_idle, cpu);
memset(idle, 0, sizeof(struct s390_idle_data));
if (sysfs_create_group(&s->kobj, &cpu_online_attr_group))
return NOTIFY_BAD;
err = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
break;
}
return NOTIFY_OK;
return notifier_from_errno(err);
}
static struct notifier_block __cpuinitdata smp_cpu_nb = {
@ -1004,7 +1021,9 @@ out:
return rc;
}
static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
static ssize_t __ref rescan_store(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
const char *buf,
size_t count)
{
int rc;
@ -1015,7 +1034,9 @@ static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf,
static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store);
#endif /* CONFIG_HOTPLUG_CPU */
static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
static ssize_t dispatching_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
ssize_t count;
@ -1025,7 +1046,9 @@ static ssize_t dispatching_show(struct sysdev_class *class, char *buf)
return count;
}
static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf,
static ssize_t dispatching_store(struct sysdev_class *dev,
struct sysdev_class_attribute *attr,
const char *buf,
size_t count)
{
int val, rc;

View file

@ -0,0 +1,58 @@
/*
* 31-bit switch cpu code
*
* Copyright IBM Corp. 2009
*
*/
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
# smp_switch_to_cpu switches to destination cpu and executes the passed function
# Parameter: %r2 - function to call
# %r3 - function parameter
# %r4 - stack poiner
# %r5 - current cpu
# %r6 - destination cpu
.section .text
.align 4
.globl smp_switch_to_cpu
smp_switch_to_cpu:
stm %r6,%r15,__SF_GPRS(%r15)
lr %r1,%r15
ahi %r15,-STACK_FRAME_OVERHEAD
st %r1,__SF_BACKCHAIN(%r15)
basr %r13,0
0: la %r1,.gprregs_addr-0b(%r13)
l %r1,0(%r1)
stm %r0,%r15,0(%r1)
1: sigp %r0,%r6,__SIGP_RESTART /* start destination CPU */
brc 2,1b /* busy, try again */
2: sigp %r0,%r5,__SIGP_STOP /* stop current CPU */
brc 2,2b /* busy, try again */
3: j 3b
.globl smp_restart_cpu
smp_restart_cpu:
basr %r13,0
0: la %r1,.gprregs_addr-0b(%r13)
l %r1,0(%r1)
lm %r0,%r15,0(%r1)
1: sigp %r0,%r5,__SIGP_SENSE /* Wait for calling CPU */
brc 10,1b /* busy, accepted (status 0), running */
tmll %r0,0x40 /* Test if calling CPU is stopped */
jz 1b
ltr %r4,%r4 /* New stack ? */
jz 1f
lr %r15,%r4
1: basr %r14,%r2
.gprregs_addr:
.long .gprregs
.section .data,"aw",@progbits
.gprregs:
.rept 16
.long 0
.endr

View file

@ -0,0 +1,51 @@
/*
* 64-bit switch cpu code
*
* Copyright IBM Corp. 2009
*
*/
#include <asm/asm-offsets.h>
#include <asm/ptrace.h>
# smp_switch_to_cpu switches to destination cpu and executes the passed function
# Parameter: %r2 - function to call
# %r3 - function parameter
# %r4 - stack poiner
# %r5 - current cpu
# %r6 - destination cpu
.section .text
.align 4
.globl smp_switch_to_cpu
smp_switch_to_cpu:
stmg %r6,%r15,__SF_GPRS(%r15)
lgr %r1,%r15
aghi %r15,-STACK_FRAME_OVERHEAD
stg %r1,__SF_BACKCHAIN(%r15)
larl %r1,.gprregs
stmg %r0,%r15,0(%r1)
1: sigp %r0,%r6,__SIGP_RESTART /* start destination CPU */
brc 2,1b /* busy, try again */
2: sigp %r0,%r5,__SIGP_STOP /* stop current CPU */
brc 2,2b /* busy, try again */
3: j 3b
.globl smp_restart_cpu
smp_restart_cpu:
larl %r1,.gprregs
lmg %r0,%r15,0(%r1)
1: sigp %r0,%r5,__SIGP_SENSE /* Wait for calling CPU */
brc 10,1b /* busy, accepted (status 0), running */
tmll %r0,0x40 /* Test if calling CPU is stopped */
jz 1b
ltgr %r4,%r4 /* New stack ? */
jz 1f
lgr %r15,%r4
1: basr %r14,%r2
.section .data,"aw",@progbits
.gprregs:
.rept 16
.quad 0
.endr

View file

@ -176,7 +176,7 @@ pgm_check_entry:
cgr %r1,%r2
je restore_registers /* r1 = r2 -> nothing to do */
larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */
mvc __LC_RESTART_PSW(16,%r0),0(%r4)
mvc __LC_RST_NEW_PSW(16,%r0),0(%r4)
3:
sigp %r9,%r1,__SIGP_INITIAL_CPU_RESET
brc 8,4f /* accepted */
@ -256,6 +256,9 @@ restore_registers:
lghi %r2,0
brasl %r14,arch_set_page_states
/* Reinitialize the channel subsystem */
brasl %r14,channel_subsystem_reinit
/* Return 0 */
lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
lghi %r2,0

View file

@ -33,13 +33,12 @@
#include "entry.h"
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux for S/390 isn't able to handle more than 5
* system call parameters, so these system calls used a memory
* block for parameter passing..
* Perform the mmap() system call. Linux for S/390 isn't able to handle more
* than 5 system call parameters, so this system call uses a memory block
* for parameter passing.
*/
struct mmap_arg_struct {
struct s390_mmap_arg_struct {
unsigned long addr;
unsigned long len;
unsigned long prot;
@ -48,9 +47,9 @@ struct mmap_arg_struct {
unsigned long offset;
};
SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg)
SYSCALL_DEFINE1(mmap2, struct s390_mmap_arg_struct __user *, arg)
{
struct mmap_arg_struct a;
struct s390_mmap_arg_struct a;
int error = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
@ -60,29 +59,12 @@ out:
return error;
}
SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg)
{
struct mmap_arg_struct a;
long error = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
goto out;
error = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;
error = sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
return error;
}
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr)
{
struct ipc_kludge tmp;
@ -149,17 +131,6 @@ SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
}
#ifdef CONFIG_64BIT
SYSCALL_DEFINE1(s390_newuname, struct new_utsname __user *, name)
{
int ret = sys_newuname(name);
if (personality(current->personality) == PER_LINUX32 && !ret) {
ret = copy_to_user(name->machine, "s390\0\0\0\0", 8);
if (ret) ret = -EFAULT;
}
return ret;
}
SYSCALL_DEFINE1(s390_personality, unsigned long, personality)
{
int ret;

View file

@ -98,7 +98,7 @@ SYSCALL(sys_uselib,sys_uselib,sys32_uselib_wrapper)
SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper)
SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper)
SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */
SYSCALL(sys_s390_old_mmap,sys_s390_old_mmap,old32_mmap_wrapper) /* 90 */
SYSCALL(sys_old_mmap,sys_old_mmap,old32_mmap_wrapper) /* 90 */
SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper)
SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper)
SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper)
@ -125,12 +125,12 @@ NI_SYSCALL /* vm86old for i386 */
SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper) /* 115 */
SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */
SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper)
SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper)
SYSCALL(sys_newuname,sys_newuname,sys32_newuname_wrapper)
NI_SYSCALL /* modify_ldt for i386 */
SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper)
SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */

View file

@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <asm/ebcdic.h>
#include <asm/sysinfo.h>
#include <asm/cpcmd.h>

View file

@ -36,6 +36,7 @@
#include <linux/notifier.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
#include <asm/s390_ext.h>
@ -51,14 +52,6 @@
#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
/*
* Create a small time difference between the timer interrupts
* on the different cpus to avoid lock contention.
*/
#define CPU_DEVIATION (smp_processor_id() << 12)
#define TICK_SIZE tick
u64 sched_clock_base_cc = -1; /* Force to data section. */
EXPORT_SYMBOL_GPL(sched_clock_base_cc);
@ -81,15 +74,15 @@ unsigned long long monotonic_clock(void)
}
EXPORT_SYMBOL(monotonic_clock);
void tod_to_timeval(__u64 todval, struct timespec *xtime)
void tod_to_timeval(__u64 todval, struct timespec *xt)
{
unsigned long long sec;
sec = todval >> 12;
do_div(sec, 1000000);
xtime->tv_sec = sec;
xt->tv_sec = sec;
todval -= (sec * 1000000) << 12;
xtime->tv_nsec = ((todval * 1000) >> 12);
xt->tv_nsec = ((todval * 1000) >> 12);
}
EXPORT_SYMBOL(tod_to_timeval);
@ -224,10 +217,11 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
++vdso_data->tb_update_count;
smp_wmb();
vdso_data->xtime_tod_stamp = clock->cycle_last;
vdso_data->xtime_clock_sec = xtime.tv_sec;
vdso_data->xtime_clock_nsec = xtime.tv_nsec;
vdso_data->xtime_clock_sec = wall_time->tv_sec;
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
vdso_data->ntp_mult = mult;
smp_wmb();
++vdso_data->tb_update_count;
}
@ -397,7 +391,6 @@ static void __init time_init_wq(void)
if (time_sync_wq)
return;
time_sync_wq = create_singlethread_workqueue("timesync");
stop_machine_create();
}
/*
@ -531,8 +524,11 @@ void etr_switch_to_local(void)
if (!etr_eacr.sl)
return;
disable_sync_clock(NULL);
set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
queue_work(time_sync_wq, &etr_work);
if (!test_and_set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events)) {
etr_eacr.es = etr_eacr.sl = 0;
etr_setr(&etr_eacr);
queue_work(time_sync_wq, &etr_work);
}
}
/*
@ -546,8 +542,11 @@ void etr_sync_check(void)
if (!etr_eacr.es)
return;
disable_sync_clock(NULL);
set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
queue_work(time_sync_wq, &etr_work);
if (!test_and_set_bit(ETR_EVENT_SYNC_CHECK, &etr_events)) {
etr_eacr.es = 0;
etr_setr(&etr_eacr);
queue_work(time_sync_wq, &etr_work);
}
}
/*
@ -909,7 +908,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib,
* Do not try to get the alternate port aib if the clock
* is not in sync yet.
*/
if (!check_sync_clock())
if (!eacr.es || !check_sync_clock())
return eacr;
/*
@ -1071,7 +1070,7 @@ static void etr_work_fn(struct work_struct *work)
* If the clock is in sync just update the eacr and return.
* If there is no valid sync port wait for a port update.
*/
if (check_sync_clock() || sync_port < 0) {
if ((eacr.es && check_sync_clock()) || sync_port < 0) {
etr_update_eacr(eacr);
etr_set_tolec_timeout(now);
goto out_unlock;
@ -1124,14 +1123,18 @@ static struct sys_device etr_port1_dev = {
/*
* ETR class attributes
*/
static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf)
static ssize_t etr_stepping_port_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
return sprintf(buf, "%i\n", etr_port0.esw.p);
}
static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf)
static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
char *mode_str;
@ -1592,7 +1595,9 @@ static struct sysdev_class stp_sysclass = {
.name = "stp",
};
static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
static ssize_t stp_ctn_id_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online)
return -ENODATA;
@ -1602,7 +1607,9 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
static ssize_t stp_ctn_type_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online)
return -ENODATA;
@ -1611,7 +1618,9 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
static ssize_t stp_dst_offset_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x2000))
return -ENODATA;
@ -1620,7 +1629,9 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x8000))
return -ENODATA;
@ -1629,7 +1640,9 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
static ssize_t stp_stratum_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online)
return -ENODATA;
@ -1638,7 +1651,9 @@ static ssize_t stp_stratum_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL);
static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
static ssize_t stp_time_offset_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x0800))
return -ENODATA;
@ -1647,7 +1662,9 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online || !(stp_info.vbits & 0x4000))
return -ENODATA;
@ -1657,7 +1674,9 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(time_zone_offset, 0400,
stp_time_zone_offset_show, NULL);
static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
static ssize_t stp_timing_mode_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online)
return -ENODATA;
@ -1666,7 +1685,9 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
static ssize_t stp_timing_state_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
if (!stp_online)
return -ENODATA;
@ -1675,12 +1696,15 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class, char *buf)
static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
static ssize_t stp_online_show(struct sysdev_class *class, char *buf)
static ssize_t stp_online_show(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
char *buf)
{
return sprintf(buf, "%i\n", stp_online);
}
static ssize_t stp_online_store(struct sysdev_class *class,
struct sysdev_class_attribute *attr,
const char *buf, size_t count)
{
unsigned int value;

View file

@ -37,7 +37,8 @@ struct tl_cpu {
};
struct tl_container {
unsigned char reserved[8];
unsigned char reserved[7];
unsigned char id;
};
union tl_entry {
@ -58,6 +59,7 @@ struct tl_info {
struct core_info {
struct core_info *next;
unsigned char id;
cpumask_t mask;
};
@ -73,6 +75,7 @@ static DECLARE_WORK(topology_work, topology_work_fn);
static DEFINE_SPINLOCK(topology_lock);
cpumask_t cpu_core_map[NR_CPUS];
unsigned char cpu_core_id[NR_CPUS];
static cpumask_t cpu_coregroup_map(unsigned int cpu)
{
@ -116,6 +119,7 @@ static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core)
for_each_present_cpu(lcpu) {
if (cpu_logical_map(lcpu) == rcpu) {
cpu_set(lcpu, core->mask);
cpu_core_id[lcpu] = core->id;
smp_cpu_polarization[lcpu] = tl_cpu->pp;
}
}
@ -158,6 +162,7 @@ static void tl_to_cores(struct tl_info *info)
break;
case 1:
core = core->next;
core->id = tle->container.id;
break;
case 0:
add_cpus_to_core(&tle->cpu, core);
@ -165,10 +170,11 @@ static void tl_to_cores(struct tl_info *info)
default:
clear_cores();
machine_has_topology = 0;
return;
goto out;
}
tle = next_tle(tle);
}
out:
spin_unlock_irq(&topology_lock);
}

View file

@ -46,13 +46,7 @@
pgm_check_handler_t *pgm_check_table[128];
#ifdef CONFIG_SYSCTL
#ifdef CONFIG_PROCESS_DEBUG
int sysctl_userprocess_debug = 1;
#else
int sysctl_userprocess_debug = 0;
#endif
#endif
int show_unhandled_signals;
extern pgm_check_handler_t do_protection_exception;
extern pgm_check_handler_t do_dat_exception;
@ -315,18 +309,19 @@ void die(const char * str, struct pt_regs * regs, long err)
do_exit(SIGSEGV);
}
static void inline
report_user_fault(long interruption_code, struct pt_regs *regs)
static void inline report_user_fault(struct pt_regs *regs, long int_code,
int signr)
{
#if defined(CONFIG_SYSCTL)
if (!sysctl_userprocess_debug)
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
return;
#endif
#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
printk("User process fault: interruption code 0x%lX\n",
interruption_code);
if (!unhandled_signal(current, signr))
return;
if (!printk_ratelimit())
return;
printk("User process fault: interruption code 0x%lX ", int_code);
print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
printk("\n");
show_regs(regs);
#endif
}
int is_valid_bugaddr(unsigned long addr)
@ -354,7 +349,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
tsk->thread.trap_no = interruption_code & 0xffff;
force_sig_info(signr, info, tsk);
report_user_fault(interruption_code, regs);
report_user_fault(regs, interruption_code, signr);
} else {
const struct exception_table_entry *fixup;
fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@ -390,8 +385,8 @@ static void default_trap_handler(struct pt_regs * regs, long interruption_code)
{
if (regs->psw.mask & PSW_MASK_PSTATE) {
local_irq_enable();
report_user_fault(regs, interruption_code, SIGSEGV);
do_exit(SIGSEGV);
report_user_fault(interruption_code, regs);
} else
die("Unknown program exception", regs, interruption_code);
}

View file

@ -23,6 +23,7 @@
#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/compat.h>
#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
@ -101,11 +102,7 @@ static void vdso_init_per_cpu_data(int cpu, struct vdso_per_cpu_data *vpcd)
/*
* Allocate/free per cpu vdso data.
*/
#ifdef CONFIG_64BIT
#define SEGMENT_ORDER 2
#else
#define SEGMENT_ORDER 1
#endif
int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore)
{

View file

@ -38,13 +38,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,2f
ahi %r0,-1
2: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0
lhi %r0,1000
l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 3f
ahi %r0,1000
a %r0,__VDSO_NTP_MULT(%r5)
3: alr %r0,%r2
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
@ -86,13 +86,13 @@ __kernel_clock_gettime:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,12f
ahi %r0,-1
12: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
lr %r2,%r0
lhi %r0,1000
l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 13f
ahi %r0,1000
a %r0,__VDSO_NTP_MULT(%r5)
13: alr %r0,%r2
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */

View file

@ -35,13 +35,13 @@ __kernel_gettimeofday:
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
brc 3,3f
ahi %r0,-1
3: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
st %r0,24(%r15)
lhi %r0,1000
l %r0,__VDSO_NTP_MULT(%r5)
ltr %r1,%r1
mr %r0,%r0
jnm 4f
ahi %r0,1000
a %r0,__VDSO_NTP_MULT(%r5)
4: al %r0,24(%r15)
srdl %r0,12
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */

View file

@ -36,7 +36,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5)
@ -64,7 +64,7 @@ __kernel_clock_gettime:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
lg %r0,__VDSO_XTIME_SEC(%r5)

View file

@ -31,7 +31,7 @@ __kernel_gettimeofday:
stck 48(%r15) /* Store TOD clock */
lg %r1,48(%r15)
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
mghi %r1,1000
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */

View file

@ -121,32 +121,35 @@ void account_system_vtime(struct task_struct *tsk)
}
EXPORT_SYMBOL_GPL(account_system_vtime);
void vtime_start_cpu(void)
void vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
{
struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
__u64 idle_time, expires;
if (idle->idle_enter == 0ULL)
return;
/* Account time spent with enabled wait psw loaded as idle time. */
idle_time = S390_lowcore.int_clock - idle->idle_enter;
idle_time = int_clock - idle->idle_enter;
account_idle_time(idle_time);
S390_lowcore.steal_timer +=
idle->idle_enter - S390_lowcore.last_update_clock;
S390_lowcore.last_update_clock = S390_lowcore.int_clock;
S390_lowcore.last_update_clock = int_clock;
/* Account system time spent going idle. */
S390_lowcore.system_timer += S390_lowcore.last_update_timer - vq->idle;
S390_lowcore.last_update_timer = S390_lowcore.async_enter_timer;
S390_lowcore.last_update_timer = enter_timer;
/* Restart vtime CPU timer */
if (vq->do_spt) {
/* Program old expire value but first save progress. */
expires = vq->idle - S390_lowcore.async_enter_timer;
expires = vq->idle - enter_timer;
expires += get_vtimer();
set_vtimer(expires);
} else {
/* Don't account the CPU timer delta while the cpu was idle. */
vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer;
vq->elapsed -= vq->idle - enter_timer;
}
idle->sequence++;

View file

@ -35,6 +35,7 @@ config KVM
# OK, it's a little counter-intuitive to do this, but it puts it neatly under
# the virtualization menu.
source drivers/vhost/Kconfig
source drivers/virtio/Kconfig
endif # VIRTUALIZATION

View file

@ -39,7 +39,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
vcpu->run->s390_reset_flags = 0;
break;
default:
return -ENOTSUPP;
return -EOPNOTSUPP;
}
atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@ -62,6 +62,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
case 0x308:
return __diag_ipl_functions(vcpu);
default:
return -ENOTSUPP;
return -EOPNOTSUPP;
}
}

Some files were not shown because too many files have changed in this diff Show more