diff --git a/configure b/configure
index d152414..3690041 100755
--- a/configure
+++ b/configure
@@ -7,7 +7,7 @@ objcopy=objcopy
 objdump=objdump
 ar=ar
 addr2line=addr2line
-arch=`uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/'`
+arch=`uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/;s/s390x.*/s390x/'`
 host=$arch
 cross_prefix=
 endian=""
diff --git a/lib/s390x/asm/barrier.h b/lib/s390x/asm/barrier.h
new file mode 100644
index 0000000..5e77984
--- /dev/null
+++ b/lib/s390x/asm/barrier.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <asm-generic/barrier.h>
+
+#ifndef _ASM_S390X_BARRIER_H_
+#define _ASM_S390X_BARRIER_H_
+
+#endif
diff --git a/lib/s390x/asm/io.h b/lib/s390x/asm/io.h
new file mode 100644
index 0000000..feb4115
--- /dev/null
+++ b/lib/s390x/asm/io.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#ifndef _ASMS390X_IO_H_
+#define _ASMS390X_IO_H_
+
+#define __iomem
+
+#include <asm-generic/io.h>
+#endif
diff --git a/lib/s390x/asm/page.h b/lib/s390x/asm/page.h
new file mode 100644
index 0000000..c67b251
--- /dev/null
+++ b/lib/s390x/asm/page.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <asm-generic/page.h>
+
+#ifndef _ASMS390X_PAGE_H_
+#define _ASMS390X_PAGE_H_
+
+#endif
diff --git a/lib/s390x/asm/spinlock.h b/lib/s390x/asm/spinlock.h
new file mode 100644
index 0000000..9d40a94
--- /dev/null
+++ b/lib/s390x/asm/spinlock.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <asm-generic/spinlock.h>
+
+#ifndef __ASMS390X_SPINLOCK_H
+#define __ASMS390X_SPINLOCK_H
+
+#endif
diff --git a/lib/s390x/asm/stack.h b/lib/s390x/asm/stack.h
new file mode 100644
index 0000000..e36d975
--- /dev/null
+++ b/lib/s390x/asm/stack.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#ifndef _ASMS390X_STACK_H_
+#define _ASMS390X_STACK_H_
+
+#ifndef _STACK_H_
+#error Do not directly include <asm/stack.h>. Just use <stack.h>.
+#endif
+
+#define HAVE_ARCH_BACKTRACE_FRAME
+#define HAVE_ARCH_BACKTRACE
+
+#endif
diff --git a/lib/s390x/io.c b/lib/s390x/io.c
new file mode 100644
index 0000000..a652124
--- /dev/null
+++ b/lib/s390x/io.c
@@ -0,0 +1,48 @@
+/*
+ * s390x io implementation
+ *
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <libcflat.h>
+#include <asm/spinlock.h>
+
+extern void setup_args_progname(const char *args);
+extern char ipl_args[];
+
+static struct spinlock lock;
+
+void puts(const char *s)
+{
+	spin_lock(&lock);
+	/* FIXME */
+	(void)s;
+	spin_unlock(&lock);
+}
+
+static void sigp_stop()
+{
+	register unsigned long status asm ("1") = 0;
+	register unsigned long cpu asm ("2") = 0;
+
+	asm volatile(
+		"	sigp %0,%1,0(%2)\n"
+		: "+d" (status)  : "d" (cpu), "d" (5) : "cc");
+}
+
+void setup()
+{
+	setup_args_progname(ipl_args);
+}
+
+void exit(int code)
+{
+	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+	sigp_stop();
+}
diff --git a/lib/s390x/stack.c b/lib/s390x/stack.c
new file mode 100644
index 0000000..cd34b20
--- /dev/null
+++ b/lib/s390x/stack.c
@@ -0,0 +1,28 @@
+/*
+ * s390x stack implementation
+ *
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+#include <libcflat.h>
+#include <stack.h>
+
+int backtrace_frame(const void *frame, const void **return_addrs, int max_depth)
+{
+	printf("TODO: Implement backtrace_frame(%p, %p, %d) function!\n",
+	       frame, return_addrs, max_depth);
+	return 0;
+}
+
+int backtrace(const void **return_addrs, int max_depth)
+{
+	printf("TODO: Implement backtrace(%p, %d) function!\n",
+	       return_addrs, max_depth);
+	return 0;
+}
diff --git a/s390x/Makefile b/s390x/Makefile
new file mode 100644
index 0000000..f9468bb
--- /dev/null
+++ b/s390x/Makefile
@@ -0,0 +1,32 @@
+all: test_cases
+
+test_cases: $(tests)
+
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -Wextra
+CFLAGS += -I lib
+CFLAGS += -O2
+CFLAGS += -msoft-float
+CFLAGS += -march=z900
+LDFLAGS += -nostdlib
+
+# We want to keep intermediate files
+.PRECIOUS: %.o
+
+cflatobjs += lib/util.o
+cflatobjs += lib/alloc.o
+cflatobjs += lib/s390x/io.o
+cflatobjs += lib/s390x/stack.o
+
+cstart.o = $(TEST_DIR)/cstart64.o
+
+FLATLIBS = $(libcflat)
+%.elf: %.o $(FLATLIBS) s390x/flat.lds $(cstart.o)
+	$(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) lib/auxinfo.c -DPROGNAME=\"$@\"
+	$(CC) $(LDFLAGS) -o $@ -T s390x/flat.lds -Ttext=0x10000 \
+		$(filter %.o, $^) $(FLATLIBS) $(@:.elf=.aux.o)
+	$(RM) $(@:.elf=.aux.o)
+
+arch_clean:
+	$(RM) $(TEST_DIR)/*.{o,elf} $(TEST_DIR)/.*.d lib/s390x/.*.d
diff --git a/s390x/cstart64.S b/s390x/cstart64.S
new file mode 100644
index 0000000..b5741c2
--- /dev/null
+++ b/s390x/cstart64.S
@@ -0,0 +1,39 @@
+/*
+ * s390x startup code
+ *
+ * Copyright (c) 2017 Red Hat Inc
+ *
+ * Authors:
+ *  Thomas Huth <thuth@redhat.com>
+ *  David Hildenbrand <david@redhat.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License version 2.
+ */
+.section .init
+
+/* entry point - for KVM + TCG we directly start in 64 bit mode */
+	.globl start
+start:
+	/* setup stack */
+	larl	%r15, stacktop
+	/* setup initial PSW mask */
+	larl	%r1, initital_psw
+	lpswe	0(%r1)
+init_psw_cont:
+	/* call setup() */
+	brasl	%r14, setup
+	/* forward test parameter */
+	larl	%r2, __argc
+	llgf	%r2, 0(%r2)
+	larl	%r3, __argv
+	/* call to main() */
+	brasl	%r14, main
+	/* forward exit code */
+	lgr	%r3, %r2
+	/* call exit() */
+	j exit
+
+	.align	8
+initital_psw:
+	.quad	0x0000000180000000, init_psw_cont
diff --git a/s390x/flat.lds b/s390x/flat.lds
new file mode 100644
index 0000000..b6e2172
--- /dev/null
+++ b/s390x/flat.lds
@@ -0,0 +1,42 @@
+SECTIONS
+{
+	.text : {
+		*(.init)
+		. = 0x480;
+		ipl_args = .;
+		. = 0x600;
+		*(.text)
+		*(.text.*)
+	}
+	. = ALIGN(64K);
+	etext = .;
+	.opd : { *(.opd) }
+	. = ALIGN(16);
+	.dynamic : {
+		dynamic_start = .;
+		*(.dynamic)
+	}
+	.dynsym : {
+		dynsym_start = .;
+		*(.dynsym)
+	}
+	.rela.dyn : { *(.rela*) }
+	. = ALIGN(16);
+	.data : {
+		*(.data)
+		*(.data.rel*)
+	}
+	. = ALIGN(16);
+	.rodata : { *(.rodata) *(.rodata.*) }
+	. = ALIGN(16);
+	.bss : { *(.bss) }
+	. = ALIGN(64K);
+	edata = .;
+	. += 64K;
+	. = ALIGN(64K);
+	/*
+	 * stackptr set with initial stack frame preallocated
+	 */
+	stackptr = . - 160;
+	stacktop = .;
+}
diff --git a/s390x/run b/s390x/run
new file mode 100755
index 0000000..cf333de
--- /dev/null
+++ b/s390x/run
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+if [ -z "$STANDALONE" ]; then
+	if [ ! -f config.mak ]; then
+		echo "run ./configure && make first. See ./configure -h"
+		exit 2
+	fi
+	source config.mak
+	source scripts/arch-run.bash
+fi
+
+if [ -c /dev/kvm ]; then
+	if [ "$HOST" = "s390x" ] && [ "$ARCH" = "s390x" ]; then
+		kvm_available=yes
+	fi
+fi
+
+if [ "$ACCEL" = "kvm" ] && [ "$kvm_available" != "yes" ]; then
+	echo "KVM is needed, but not available on this host"
+	exit 2
+fi
+
+if [ -z "$ACCEL" ]; then
+	if [ "$kvm_available" = "yes" ]; then
+		ACCEL="kvm"
+	else
+		ACCEL="tcg"
+	fi
+fi
+
+qemu=$(search_qemu_binary)
+
+M='-machine s390-ccw-virtio'
+M+=",accel=$ACCEL"
+command="$qemu -nodefaults -nographic $M"
+command+=" -chardev stdio,id=con0 -device sclpconsole,chardev=con0"
+[ -f "$ENV" ] && command+=" -initrd $ENV"
+command+=" -kernel"
+command="$(timeout_cmd) $command"
+echo $command "$@"
+
+# We return the exit code via stdout, not via the QEMU return code
+lines=$(run_qemu $command "$@")
+ret=$?
+echo "$lines"
+if [ $ret -eq 1 ]; then
+	testret=$(grep '^EXIT: ' <<<"$lines" | sed 's/.*STATUS=\([0-9][0-9]*\).*/\1/')
+	if [ "$testret" ]; then
+		if [ $testret -eq 1 ]; then
+			ret=0
+		else
+			ret=$testret
+		fi
+	fi
+fi
+exit $ret
diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
new file mode 100644
index 0000000..b1e0b1e
--- /dev/null
+++ b/s390x/unittests.cfg
@@ -0,0 +1,19 @@
+##############################################################################
+# unittest configuration
+#
+# [unittest_name]
+# file = <name>.elf		# Name of the elf file to be used.
+# extra_params = -append <params...>	# Additional parameters used.
+# groups = <group_name1> <group_name2> ... # Used to identify test cases
+#					   # with run_tests -g ...
+#					   # Specify group_name=nodefault
+#					   # to have test not run by default
+# accel = kvm|tcg		# Optionally specify if test must run with
+#				# kvm or tcg. If not specified, then kvm will
+#				# be used when available.
+# timeout = <duration>		# Optionally specify a timeout.
+# check = <path>=<value> # check a file for a particular value before running
+#			 # a test. The check line can contain multiple files
+#			 # to check separated by a space but each check
+#			 # parameter needs to be of the form <path>=<value>
+##############################################################################
