diff --git a/Makefile.target b/Makefile.target
index 2262d89..58cfc1b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -190,7 +190,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
 qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx
 	$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@,"  GEN   $(TARGET_DIR)$@")
 
-clean:
+clean: clean-target
 	rm -f *.a *~ $(PROGS)
 	rm -f $(shell find . -name '*.[od]')
 	rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
diff --git a/rules.mak b/rules.mak
index 3a05627..43cf05c 100644
--- a/rules.mak
+++ b/rules.mak
@@ -12,6 +12,7 @@ MAKEFLAGS += -rR
 %.cpp:
 %.m:
 %.mak:
+clean-target:
 
 # Flags for C++ compilation
 QEMU_CXXFLAGS = -D__STDC_LIMIT_MACROS $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls, $(QEMU_CFLAGS))
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index dd62cbd..997dda4 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,3 +3,23 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
+
+# build and run facility generator
+#
+fac = gen-facilities
+fac-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)
+fac-dst = $(BUILD_DIR)/$(TARGET_DIR)
+
+ifneq ($(MAKECMDGOALS),clean)
+GENERATED_HEADERS += $(fac-dst)$(fac).h
+endif
+
+$(fac-dst)$(fac).h: $(fac-dst)$(fac)
+	$(call quiet-command,$< >$@,"  GEN   $(TARGET_DIR)$(fac).h")
+
+$(fac-dst)$(fac): $(fac-src)/$(fac).c $(fac-src)/cpu-facilities.h
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -o $@ $<,"  CC    $(TARGET_DIR)$(fac)")
+
+clean-target:
+	rm -f $(fac).h
+	rm -f $(fac)
diff --git a/target-s390x/gen-facilities.c b/target-s390x/gen-facilities.c
new file mode 100644
index 0000000..f4f4c57
--- /dev/null
+++ b/target-s390x/gen-facilities.c
@@ -0,0 +1,417 @@
+/*
+ * S390 facility list/mask generator
+ *
+ * Copyright 2015 IBM Corp.
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <values.h>
+#include "cpu-facilities.h"
+
+/***** BEGIN FACILITY DEFS *****/
+
+/*******************************
+ * CMOS G7 processors
+ *******************************/
+
+/* 2064-GA1 */
+static uint16_t set_2064_GA1[] = {
+    FAC_N3,
+    FAC_ZARCH,
+    FAC_ZARCH_ACTIVE,
+};
+#define clear_2064_GA1 EmptyFacs
+
+/* 2064-GA2 */
+static uint16_t set_2064_GA2[] = {
+    FAC_EXTENDED_TRANSLATION_2,
+};
+#define clear_2064_GA2 EmptyFacs
+
+/* 2064-GA3 */
+#define set_2064_GA3 EmptyFacs
+#define clear_2064_GA3 EmptyFacs
+
+/* 2066-GA1 */
+#define set_2066_GA1 EmptyFacs
+#define clear_2066_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G8 processors
+ *******************************/
+
+/* 2084-GA1 */
+static uint16_t set_2084_GA1[] = {
+    FAC_DAT_ENH,
+    FAC_MESSAGE_SECURITY_ASSIST,
+    FAC_LONG_DISPLACEMENT,
+    FAC_LONG_DISPLACEMENT_FAST,
+    FAC_HFP_MADDSUB,
+};
+#define clear_2084_GA1 EmptyFacs
+
+/* 2084-GA2 */
+static uint16_t set_2084_GA2[] = {
+    4,
+};
+#define clear_2084_GA2 EmptyFacs
+
+/* 2084-GA3 */
+static uint16_t set_2084_GA3[] = {
+    FAC_ASN_LX_REUSE,
+    FAC_EXTENDED_TRANSLATION_3,
+};
+#define clear_2084_GA3 EmptyFacs
+
+/* 2084-GA4 */
+#define set_2084_GA4 EmptyFacs
+#define clear_2084_GA4 EmptyFacs
+
+/* 2084-GA5 */
+static uint16_t set_2084_GA5[] = {
+    FAC_TOD_CLOCK_STEERING,
+};
+#define clear_2084_GA5 EmptyFacs
+
+/* 2086-GA1 */
+#define set_2086_GA1 EmptyFacs
+#define clear_2086_GA1 EmptyFacs
+
+/* 2086-GA2 */
+#define set_2086_GA2 EmptyFacs
+#define clear_2086_GA2 EmptyFacs
+
+/* 2086-GA3 */
+#define set_2086_GA3 EmptyFacs
+#define clear_2086_GA3 EmptyFacs
+
+/*******************************
+ * CMOS G9 processors
+ *******************************/
+
+/* 2094-GA1 */
+static uint16_t set_2094_GA1[] = {
+    FAC_STFLE,
+    FAC_EXTENDED_IMMEDIATE,
+    FAC_HFP_UNNORMALIZED_EXT,
+    FAC_ETF2_ENH,
+    FAC_STORE_CLOCK_FAST,
+    FAC_ETF3_ENH,
+    FAC_EXTRACT_CPU_TIME,
+};
+#define clear_2094_GA1 EmptyFacs
+
+/* 2094-GA2 */
+static uint16_t set_2094_GA2[] = {
+    FAC_SENSE_RUNNING_STATUS,
+    FAC_MOVE_WITH_OPTIONAL_SPEC,
+    FAC_COMPARE_AND_SWAP_AND_STORE,
+    FAC_FLOATING_POINT_SUPPPORT_ENH,
+    FAC_DFP,
+};
+#define clear_2094_GA2 EmptyFacs
+
+/* 2094-GA3 */
+static uint16_t set_2094_GA3[] = {
+    FAC_PFPO,
+};
+#define clear_2094_GA3 EmptyFacs
+
+/* 2096-GA1 */
+#define set_2096_GA1 EmptyFacs
+#define clear_2096_GA1 EmptyFacs
+
+/* 2096-GA2 */
+#define set_2096_GA2 EmptyFacs
+#define clear_2096_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G10 processors
+ *******************************/
+
+/* 2097-GA1 */
+static uint16_t set_2097_GA1[] = {
+    FAC_ENHANCED_DAT_1,
+    FAC_CONDITIONAL_SSKE,
+    FAC_CONFIGURATION_TOPOLOGY,
+    FAC_PARSING_ENH,
+    FAC_COMPARE_AND_SWAP_AND_STORE_2,
+    FAC_GENERAL_INSTRUCTIONS_EXT,
+    FAC_EXECUTE_EXT,
+    FAC_DFP_FAST,
+};
+#define clear_2097_GA1 EmptyFacs
+
+/* 2097-GA2 */
+static uint16_t set_2097_GA2[] = {
+    65,
+    FAC_CPU_MEASUREMENT_COUNTER,
+    FAC_CPU_MEASUREMENT_SAMPLING,
+};
+#define clear_2097_GA2 EmptyFacs
+
+/* 2097-GA3 */
+static uint16_t set_2097_GA3[] = {
+    FAC_LOAD_PROGRAM_PARAMETERS,
+};
+#define clear_2097_GA3 EmptyFacs
+
+/* 2098-GA1 */
+#define set_2098_GA1 EmptyFacs
+#define clear_2098_GA1 EmptyFacs
+
+/* 2098-GA2 */
+#define set_2098_GA2 EmptyFacs
+#define clear_2098_GA2 EmptyFacs
+
+/*******************************
+ * CMOS G11 processors
+ *******************************/
+
+/* 2817-GA1 */
+static uint16_t set_2817_GA1[] = {
+    FAC_ENHANCED_MONITOR,
+    FAC_FLOATING_POINT_EXT,
+    FAC_MULTI_45,
+    46,
+    FAC_ACCESS_EXCEPTION_FS_INDICATION,
+};
+static uint16_t clear_2817_GA1[] = {
+    65,
+};
+
+/* 2817-GA2 */
+static uint16_t set_2817_GA2[] = {
+    FAC_IPTE_RANGE,
+    FAC_NONQ_KEY_SETTING,
+    FAC_CMPSC_ENH,
+    FAC_RESET_REFERENCE_BITS_MULTIPLE,
+    FAC_MESSAGE_SECURITY_ASSIST_3,
+    FAC_MESSAGE_SECURITY_ASSIST_4,
+};
+#define clear_2817_GA2 EmptyFacs
+
+/* 2818-GA1 */
+#define set_2818_GA1 EmptyFacs
+#define clear_2818_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G12 processors
+ *******************************/
+
+/* 2827-GA1 */
+static uint16_t set_2827_GA1[] = {
+    FAC_DFP_ZONED_CONVERSION,
+    FAC_MULTI_49,
+    FAC_CONSTRAINT_TRANSACTIONAL_EXE,
+    FAC_LOCAL_TLB_CLEARING,
+    FAC_INTERLOCKED_ACCESS_2,
+    FAC_TRANSACTIONAL_EXE,
+    FAC_ENHANCED_DAT_2,
+};
+#define clear_2827_GA1 EmptyFacs
+
+/* 2827-GA2 */
+static uint16_t set_2827_GA2[] = {
+    FAC_MESSAGE_SECURITY_ASSIST_5,
+};
+#define clear_2827_GA2 EmptyFacs
+
+/* 2828-GA1 */
+#define set_2828_GA1 EmptyFacs
+#define clear_2828_GA1 EmptyFacs
+
+/*******************************
+ * CMOS G13 processors
+ *******************************/
+
+/* 2964-GA1 */
+static uint16_t set_2964_GA1[] = {
+    FAC_LOAD_STORE_ON_COND_2,
+    FAC_DFP_PACKED_CONVERSION,
+    FAC_VECTOR,
+    FAC_STORE_CPU_COUNTER_MULTI,
+};
+#define clear_2964_GA1 EmptyFacs
+
+/****** END FACILITY DEFS ******/
+
+#define S390_ARCH_FAC_LIST_SIZE_BYTE \
+    (S390_ARCH_FAC_LIST_SIZE / 8)
+
+#define _YEARS  "2014, 2015"
+#define _NAME_H "TARGET_S390X_GEN_FACILITIES_H"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#define FAC_INITIALIZER(_name)                         \
+    {                                                  \
+        .Name = "FAC_LIST_CPU_S390_" #_name,           \
+        .SetBits =                                     \
+            { .Data = set_##_name,                     \
+              .Length = ARRAY_SIZE(set_##_name) },     \
+        .ClearBits =                                   \
+            { .Data = clear_##_name,                   \
+              .Length = ARRAY_SIZE(clear_##_name) },   \
+    }
+
+enum BitOps {
+    SetBit,
+    ClearBit,
+};
+
+typedef struct BitSpec {
+    uint16_t *Data;
+    uint32_t Length;
+} BitSpec;
+
+typedef struct FacDefSpec {
+    const char *Name;
+    BitSpec SetBits;
+    BitSpec ClearBits;
+} FacDefSpec;
+
+static uint16_t EmptyFacs[] = {};
+
+/*******************************
+ * processor GA series
+ *******************************/
+static FacDefSpec FacDef[] = {
+    FAC_INITIALIZER(2064_GA1),
+    FAC_INITIALIZER(2064_GA2),
+    FAC_INITIALIZER(2064_GA3),
+    FAC_INITIALIZER(2066_GA1),
+    FAC_INITIALIZER(2084_GA1),
+    FAC_INITIALIZER(2084_GA2),
+    FAC_INITIALIZER(2084_GA3),
+    FAC_INITIALIZER(2086_GA1),
+    FAC_INITIALIZER(2084_GA4),
+    FAC_INITIALIZER(2086_GA2),
+    FAC_INITIALIZER(2084_GA5),
+    FAC_INITIALIZER(2086_GA3),
+    FAC_INITIALIZER(2094_GA1),
+    FAC_INITIALIZER(2094_GA2),
+    FAC_INITIALIZER(2094_GA3),
+    FAC_INITIALIZER(2096_GA1),
+    FAC_INITIALIZER(2096_GA2),
+    FAC_INITIALIZER(2097_GA1),
+    FAC_INITIALIZER(2097_GA2),
+    FAC_INITIALIZER(2098_GA1),
+    FAC_INITIALIZER(2097_GA3),
+    FAC_INITIALIZER(2098_GA2),
+    FAC_INITIALIZER(2817_GA1),
+    FAC_INITIALIZER(2817_GA2),
+    FAC_INITIALIZER(2818_GA1),
+    FAC_INITIALIZER(2827_GA1),
+    FAC_INITIALIZER(2827_GA2),
+    FAC_INITIALIZER(2828_GA1),
+    FAC_INITIALIZER(2964_GA1),
+};
+
+/*******************************
+ * QEMU facility list mask
+ *******************************/
+#define set_MASK_QEMU EmptyFacs
+#define clear_MASK_QEMU EmptyFacs
+
+static FacDefSpec QemuMaskDef = FAC_INITIALIZER(MASK_QEMU);
+
+static void BigEndianBitOps(enum BitOps BitOp, uint64_t Facility[],
+                            uint32_t MaxWord, BitSpec Bits)
+{
+    uint32_t i, Bit, Word, WidthInBits;
+
+    WidthInBits = _TYPEBITS(typeof(Facility[0]));
+    for (i = 0; i < Bits.Length; i++) {
+        Bit = (WidthInBits - 1) - (Bits.Data[i] & (WidthInBits - 1));
+        Word = Bits.Data[i] / WidthInBits;
+        assert(Word < MaxWord);
+        switch (BitOp) {
+        case SetBit:
+            Facility[Word] |= __UINT64_C(1) << Bit;
+            break;
+        case ClearBit:
+            Facility[Word] &= ~(__UINT64_C(1) << Bit);
+            break;
+        }
+    }
+}
+
+static uint32_t PrintFacilityList(uint32_t Model, FacDefSpec FacDef[])
+{
+    uint32_t i, Words, Size;
+    uint64_t Facility[FAC_LIST_ARCH_S390_SIZE_UINT8];
+
+    for (Size = ARRAY_SIZE(Facility), i = 0; i < Size; i++) {
+        Facility[i] = __UINT64_C(0);
+    }
+    for (i = 0; i <= Model; i++) {
+        BigEndianBitOps(SetBit, Facility, Size, FacDef[i].SetBits);
+        BigEndianBitOps(ClearBit, Facility, Size, FacDef[i].ClearBits);
+    }
+    for (Words = 0, i = 0; i < Size; i++) {
+        if (Facility[i]) {
+            Words = i;
+        }
+    }
+    printf("#define %s\t", FacDef[Model].Name);
+    for (i = 0; i <= Words; i++) {
+        printf("0x%016"PRIx64"%c", Facility[i], i < Words ? ',' : '\n');
+    }
+    return ++Words;
+}
+
+static inline uint32_t Max(uint32_t uIntA, uint32_t uIntB)
+{
+    if (uIntA > uIntB) {
+        return uIntA;
+    }
+    return uIntB;
+}
+
+static inline void PrintAllFacilityDefs(void)
+{
+    uint32_t i, MaxWords, MaxBytes, MaxBits;
+
+    printf("\n/* CPU model facility list data */\n");
+    for (MaxWords = 0, i = 0; i < ARRAY_SIZE(FacDef); i++) {
+        MaxWords = Max(PrintFacilityList(i, FacDef), MaxWords);
+    }
+    printf("\n/* QEMU facility mask data */\n");
+    MaxWords = Max(PrintFacilityList(0, &QemuMaskDef), MaxWords);
+    MaxBytes = MaxWords * sizeof(uint64_t);
+    MaxBits = MaxBytes * CHARBITS;
+    printf("\n/* facility list/mask sizes */\n");
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT1\t%"PRIu32"\n", MaxBits);
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT8\t%"PRIu32"\n", MaxBytes);
+    printf("#define FAC_LIST_CPU_S390_SIZE_UINT64\t%"PRIu32"\n", MaxWords);
+}
+
+int main(int argc, char *argv[])
+{
+    printf("/*\n"
+           " * AUTOMATICALLY GENERATED, DO NOT MODIFY HERE, EDIT\n"
+           " * SOURCE FILE \"%s\" INSTEAD.\n"
+           " *\n"
+           " * Copyright %s IBM Corp.\n"
+           " *\n"
+           " * This work is licensed under the terms of the GNU GPL, "
+           "version 2 or (at\n * your option) any later version. See "
+           "the COPYING file in the top-level\n * directory.\n"
+           " */\n\n"
+           "#ifndef %s\n#define %s\n", __FILE__, _YEARS, _NAME_H, _NAME_H);
+    PrintAllFacilityDefs();
+    printf("\n#endif\n");
+    return 0;
+}
