mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts: arch/powerpc/Makefile
This commit is contained in:
commit
772320e845
15241 changed files with 1249805 additions and 691683 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
|
|
|
|||
63
arch/s390/boot/compressed/Makefile
Normal file
63
arch/s390/boot/compressed/Makefile
Normal 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)
|
||||
51
arch/s390/boot/compressed/head31.S
Normal file
51
arch/s390/boot/compressed/head31.S
Normal 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
|
||||
48
arch/s390/boot/compressed/head64.S
Normal file
48
arch/s390/boot/compressed/head64.S
Normal 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
|
||||
162
arch/s390/boot/compressed/misc.c
Normal file
162
arch/s390/boot/compressed/misc.c
Normal 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;
|
||||
}
|
||||
|
||||
55
arch/s390/boot/compressed/vmlinux.lds.S
Normal file
55
arch/s390/boot/compressed/vmlinux.lds.S
Normal 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 = .;
|
||||
}
|
||||
10
arch/s390/boot/compressed/vmlinux.scr
Normal file
10
arch/s390/boot/compressed/vmlinux.scr
Normal 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 = .;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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); \
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -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*);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
#define ISA_DMA_THRESHOLD (~0UL)
|
||||
|
||||
#include <asm-generic/scatterlist.h>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* Denis Joseph Barrow,
|
||||
*/
|
||||
|
||||
#include <asm/lowcore.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
#
|
||||
# do_reipl_asm
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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(®s->gprs, ¤t_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;
|
||||
|
|
|
|||
58
arch/s390/kernel/switch_cpu.S
Normal file
58
arch/s390/kernel/switch_cpu.S
Normal 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
|
||||
51
arch/s390/kernel/switch_cpu64.S
Normal file
51
arch/s390/kernel/switch_cpu64.S
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in a new issue