summary refs log tree commit diff stats
path: root/target/s390x
diff options
context:
space:
mode:
Diffstat (limited to 'target/s390x')
-rw-r--r--target/s390x/arch_dump.c18
-rw-r--r--target/s390x/cpu.h8
-rw-r--r--target/s390x/cpu_features.c54
-rw-r--r--target/s390x/cpu_features.h4
-rw-r--r--target/s390x/cpu_features_def.h77
-rw-r--r--target/s390x/cpu_models.c57
-rw-r--r--target/s390x/cpu_models.h2
-rw-r--r--target/s390x/gdbstub.c24
-rw-r--r--target/s390x/gen-features.c105
-rw-r--r--target/s390x/kvm.c169
-rw-r--r--target/s390x/machine.c17
11 files changed, 479 insertions, 56 deletions
diff --git a/target/s390x/arch_dump.c b/target/s390x/arch_dump.c
index 105ae9a5d8..96c9fb97cb 100644
--- a/target/s390x/arch_dump.c
+++ b/target/s390x/arch_dump.c
@@ -57,6 +57,12 @@ struct S390xElfVregsHiStruct {
 
 typedef struct S390xElfVregsHiStruct S390xElfVregsHi;
 
+struct S390xElfGSCBStruct {
+    uint64_t gsregs[4];
+} QEMU_PACKED;
+
+typedef struct S390xElfGSCBStruct S390xElfGSCB;
+
 typedef struct noteStruct {
     Elf64_Nhdr hdr;
     char name[8];
@@ -65,6 +71,7 @@ typedef struct noteStruct {
         S390xElfFpregset fpregset;
         S390xElfVregsLo vregslo;
         S390xElfVregsHi vregshi;
+        S390xElfGSCB gscb;
         uint32_t prefix;
         uint64_t timer;
         uint64_t todcmp;
@@ -126,6 +133,16 @@ static void s390x_write_elf64_vregshi(Note *note, S390CPU *cpu, int id)
     }
 }
 
+static void s390x_write_elf64_gscb(Note *note, S390CPU *cpu, int id)
+{
+    int i;
+
+    note->hdr.n_type = cpu_to_be32(NT_S390_GS_CB);
+    for (i = 0; i < 4; i++) {
+        note->contents.gscb.gsregs[i] = cpu_to_be64(cpu->env.gscb[i]);
+    }
+}
+
 static void s390x_write_elf64_timer(Note *note, S390CPU *cpu, int id)
 {
     note->hdr.n_type = cpu_to_be32(NT_S390_TIMER);
@@ -181,6 +198,7 @@ static const NoteFuncDesc note_linux[] = {
     {sizeof(((Note *)0)->contents.todpreg),  s390x_write_elf64_todpreg},
     {sizeof(((Note *)0)->contents.vregslo),  s390x_write_elf64_vregslo},
     {sizeof(((Note *)0)->contents.vregshi),  s390x_write_elf64_vregshi},
+    {sizeof(((Note *)0)->contents.gscb),     s390x_write_elf64_gscb},
     { 0, NULL}
 };
 
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index bdb9bdbc9d..7732d01784 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -89,6 +89,7 @@ typedef struct CPUS390XState {
     CPU_DoubleU vregs[32][2];  /* vector registers */
     uint32_t aregs[16];    /* access registers */
     uint8_t riccb[64];     /* runtime instrumentation control */
+    uint64_t gscb[4];      /* guarded storage control */
 
     /* Fields up to this point are not cleared by initial CPU reset */
     struct {} start_initial_reset_fields;
@@ -1158,6 +1159,7 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
                                     int vq, bool assign);
 int kvm_s390_cpu_restart(S390CPU *cpu);
 int kvm_s390_get_memslot_count(KVMState *s);
+int kvm_s390_cmma_active(void);
 void kvm_s390_cmma_reset(void);
 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state);
 void kvm_s390_reset_vcpu(S390CPU *cpu);
@@ -1165,6 +1167,7 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit);
 void kvm_s390_vcpu_interrupt_pre_save(S390CPU *cpu);
 int kvm_s390_vcpu_interrupt_post_load(S390CPU *cpu);
 int kvm_s390_get_ri(void);
+int kvm_s390_get_gs(void);
 void kvm_s390_crypto_reset(void);
 #else
 static inline void kvm_s390_io_interrupt(uint16_t subchannel_id,
@@ -1219,6 +1222,10 @@ static inline int kvm_s390_get_ri(void)
 {
     return 0;
 }
+static inline int kvm_s390_get_gs(void)
+{
+    return 0;
+}
 static inline void kvm_s390_crypto_reset(void)
 {
 }
@@ -1327,6 +1334,7 @@ static inline bool s390_get_squash_mcss(void)
 #define MCIC_VB_CR 0x0000000400000000ULL
 #define MCIC_VB_ST 0x0000000100000000ULL
 #define MCIC_VB_AR 0x0000000040000000ULL
+#define MCIC_VB_GS 0x0000000008000000ULL
 #define MCIC_VB_PR 0x0000000000200000ULL
 #define MCIC_VB_FC 0x0000000000100000ULL
 #define MCIC_VB_CT 0x0000000000020000ULL
diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index 42fd9d792b..fa887d9b6f 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -59,6 +59,7 @@ static const S390FeatDef s390_features[] = {
     FEAT_INIT("exrl", S390_FEAT_TYPE_STFL, 35, "Execute-extensions facility"),
     FEAT_INIT("emon", S390_FEAT_TYPE_STFL, 36, "Enhanced-monitor facility"),
     FEAT_INIT("fpe", S390_FEAT_TYPE_STFL, 37, "Floating-point extension facility"),
+    FEAT_INIT("opc", S390_FEAT_TYPE_STFL, 38, "Order Preserving Compression facility"),
     FEAT_INIT("sprogp", S390_FEAT_TYPE_STFL, 40, "Set-program-parameters facility"),
     FEAT_INIT("fpseh", S390_FEAT_TYPE_STFL, 41, "Floating-point-support-enhancement facilities"),
     FEAT_INIT("dfp", S390_FEAT_TYPE_STFL, 42, "DFP (decimal-floating-point) facility"),
@@ -72,8 +73,15 @@ static const S390FeatDef s390_features[] = {
     FEAT_INIT("ltlbc", S390_FEAT_TYPE_STFL, 51, "Local-TLB-clearing facility"),
     FEAT_INIT("iacc2", S390_FEAT_TYPE_STFL, 52, "Interlocked-access facility 2"),
     FEAT_INIT("stfle53", S390_FEAT_TYPE_STFL, 53, "Various facilities introduced with z13"),
+    FEAT_INIT("eec", S390_FEAT_TYPE_STFL, 54, "Entropy encoding compression facility"),
     FEAT_INIT("msa5-base", S390_FEAT_TYPE_STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)"),
+    FEAT_INIT("minste2", S390_FEAT_TYPE_STFL, 58, "Miscellaneous-instruction-extensions facility 2"),
+    FEAT_INIT("sema", S390_FEAT_TYPE_STFL, 59, "Semaphore-assist facility"),
+    FEAT_INIT("tsi", S390_FEAT_TYPE_STFL, 60, "Time-slice Instrumentation facility"),
     FEAT_INIT("ri", S390_FEAT_TYPE_STFL, 64, "CPU runtime-instrumentation facility"),
+    FEAT_INIT("zpci", S390_FEAT_TYPE_STFL, 69, "z/PCI facility"),
+    FEAT_INIT("aen", S390_FEAT_TYPE_STFL, 71, "General-purpose-adapter-event-notification facility"),
+    FEAT_INIT("ais", S390_FEAT_TYPE_STFL, 72, "General-purpose-adapter-interruption-suppression facility"),
     FEAT_INIT("te", S390_FEAT_TYPE_STFL, 73, "Transactional-execution facility"),
     FEAT_INIT("sthyi", S390_FEAT_TYPE_STFL, 74, "Store-hypervisor-information facility"),
     FEAT_INIT("aefsi", S390_FEAT_TYPE_STFL, 75, "Access-exception-fetch/store-indication facility"),
@@ -82,10 +90,24 @@ static const S390FeatDef s390_features[] = {
     FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
     FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
     FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
-
+    FEAT_INIT("iep", S390_FEAT_TYPE_STFL, 130, "Instruction-execution-protection facility"),
+    FEAT_INIT("sea_esop2", S390_FEAT_TYPE_STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2"),
+    FEAT_INIT("gs", S390_FEAT_TYPE_STFL, 133, "Guarded-storage facility"),
+    FEAT_INIT("vxpd", S390_FEAT_TYPE_STFL, 134, "Vector packed decimal facility"),
+    FEAT_INIT("vxeh", S390_FEAT_TYPE_STFL, 135, "Vector enhancements facility"),
+    FEAT_INIT("mepoch", S390_FEAT_TYPE_STFL, 139, "Multiple-epoch facility"),
+    FEAT_INIT("tpei", S390_FEAT_TYPE_STFL, 144, "Test-pending-external-interruption facility"),
+    FEAT_INIT("irbm", S390_FEAT_TYPE_STFL, 145, "Insert-reference-bits-multiple facility"),
+    FEAT_INIT("msa8-base", S390_FEAT_TYPE_STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)"),
+    FEAT_INIT("cmmnt", S390_FEAT_TYPE_STFL, 147, "CMM: ESSA-enhancement (no translate) facility"),
+
+    /* SCLP SCCB Byte 80 - 98  (bit numbers relative to byte-80) */
     FEAT_INIT("gsls", S390_FEAT_TYPE_SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility"),
     FEAT_INIT("esop", S390_FEAT_TYPE_SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility"),
+    FEAT_INIT("hpma2", S390_FEAT_TYPE_SCLP_CONF_CHAR, 90, "Host page management assist 2 Facility"), /* 91-2 */
+    FEAT_INIT("kss", S390_FEAT_TYPE_SCLP_CONF_CHAR, 151, "SIE: Keyless-subset facility"),  /* 98-7 */
 
+    /* SCLP SCCB Byte 116 - 119 (bit numbers relative to byte-116) */
     FEAT_INIT("64bscao", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility"),
     FEAT_INIT("cmma", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist"),
     FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility"),
@@ -182,10 +204,23 @@ static const S390FeatDef s390_features[] = {
     FEAT_INIT("kimd-sha-1", S390_FEAT_TYPE_KIMD, 1, "KIMD SHA-1"),
     FEAT_INIT("kimd-sha-256", S390_FEAT_TYPE_KIMD, 2, "KIMD SHA-256"),
     FEAT_INIT("kimd-sha-512", S390_FEAT_TYPE_KIMD, 3, "KIMD SHA-512"),
+    FEAT_INIT("kimd-sha3-224", S390_FEAT_TYPE_KIMD, 32, "KIMD SHA3-224"),
+    FEAT_INIT("kimd-sha3-256", S390_FEAT_TYPE_KIMD, 33, "KIMD SHA3-256"),
+    FEAT_INIT("kimd-sha3-384", S390_FEAT_TYPE_KIMD, 34, "KIMD SHA3-384"),
+    FEAT_INIT("kimd-sha3-512", S390_FEAT_TYPE_KIMD, 35, "KIMD SHA3-512"),
+    FEAT_INIT("kimd-shake-128", S390_FEAT_TYPE_KIMD, 36, "KIMD SHAKE-128"),
+    FEAT_INIT("kimd-shake-256", S390_FEAT_TYPE_KIMD, 37, "KIMD SHAKE-256"),
     FEAT_INIT("kimd-ghash", S390_FEAT_TYPE_KIMD, 65, "KIMD GHASH"),
+
     FEAT_INIT("klmd-sha-1", S390_FEAT_TYPE_KLMD, 1, "KLMD SHA-1"),
     FEAT_INIT("klmd-sha-256", S390_FEAT_TYPE_KLMD, 2, "KLMD SHA-256"),
     FEAT_INIT("klmd-sha-512", S390_FEAT_TYPE_KLMD, 3, "KLMD SHA-512"),
+    FEAT_INIT("klmd-sha3-224", S390_FEAT_TYPE_KLMD, 32, "KLMD SHA3-224"),
+    FEAT_INIT("klmd-sha3-256", S390_FEAT_TYPE_KLMD, 33, "KLMD SHA3-256"),
+    FEAT_INIT("klmd-sha3-384", S390_FEAT_TYPE_KLMD, 34, "KLMD SHA3-384"),
+    FEAT_INIT("klmd-sha3-512", S390_FEAT_TYPE_KLMD, 35, "KLMD SHA3-512"),
+    FEAT_INIT("klmd-shake-128", S390_FEAT_TYPE_KLMD, 36, "KLMD SHAKE-128"),
+    FEAT_INIT("klmd-shake-256", S390_FEAT_TYPE_KLMD, 37, "KLMD SHAKE-256"),
 
     FEAT_INIT("pckmo-edea", S390_FEAT_TYPE_PCKMO, 1, "PCKMO Encrypted-DEA-Key"),
     FEAT_INIT("pckmo-etdea-128", S390_FEAT_TYPE_PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key"),
@@ -251,6 +286,15 @@ static const S390FeatDef s390_features[] = {
     FEAT_INIT("pcc-xts-eaes-256", S390_FEAT_TYPE_PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256"),
 
     FEAT_INIT("ppno-sha-512-drng", S390_FEAT_TYPE_PPNO, 3, "PPNO SHA-512-DRNG"),
+    FEAT_INIT("prno-trng-qrtcr", S390_FEAT_TYPE_PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio"),
+    FEAT_INIT("prno-trng", S390_FEAT_TYPE_PPNO, 114, "PRNO TRNG"),
+
+    FEAT_INIT("kma-gcm-aes-128", S390_FEAT_TYPE_KMA, 18, "KMA GCM-AES-128"),
+    FEAT_INIT("kma-gcm-aes-192", S390_FEAT_TYPE_KMA, 19, "KMA GCM-AES-192"),
+    FEAT_INIT("kma-gcm-aes-256", S390_FEAT_TYPE_KMA, 20, "KMA GCM-AES-256"),
+    FEAT_INIT("kma-gcm-eaes-128", S390_FEAT_TYPE_KMA, 26, "KMA GCM-Encrypted-AES-128"),
+    FEAT_INIT("kma-gcm-eaes-192", S390_FEAT_TYPE_KMA, 27, "KMA GCM-Encrypted-AES-192"),
+    FEAT_INIT("kma-gcm-eaes-256", S390_FEAT_TYPE_KMA, 28, "KMA GCM-Encrypted-AES-256"),
 };
 
 const S390FeatDef *s390_feat_def(S390Feat feat)
@@ -293,8 +337,9 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
     int bit_nr;
 
     if (type == S390_FEAT_TYPE_STFL && test_bit(S390_FEAT_ZARCH, features)) {
-        /* z/Architecture is always active if around */
-        data[0] |= 0x20;
+        /* Features that are always active */
+        data[0] |= 0x20;  /* z/Architecture */
+        data[17] |= 0x20; /* Configuration-z-architectural-mode */
     }
 
     feat = find_first_bit(features, S390_FEAT_MAX);
@@ -383,6 +428,9 @@ static S390FeatGroupDef s390_feature_groups[] = {
     FEAT_GROUP_INIT("msa3", MSA_EXT_3, "Message-security-assist-extension 3 facility"),
     FEAT_GROUP_INIT("msa4", MSA_EXT_4, "Message-security-assist-extension 4 facility"),
     FEAT_GROUP_INIT("msa5", MSA_EXT_5, "Message-security-assist-extension 5 facility"),
+    FEAT_GROUP_INIT("msa6", MSA_EXT_6, "Message-security-assist-extension 6 facility"),
+    FEAT_GROUP_INIT("msa7", MSA_EXT_7, "Message-security-assist-extension 7 facility"),
+    FEAT_GROUP_INIT("msa8", MSA_EXT_8, "Message-security-assist-extension 8 facility"),
 };
 
 const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group)
diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h
index d669121786..14bc311dbe 100644
--- a/target/s390x/cpu_features.h
+++ b/target/s390x/cpu_features.h
@@ -37,6 +37,7 @@ typedef enum {
     S390_FEAT_TYPE_KMO,
     S390_FEAT_TYPE_PCC,
     S390_FEAT_TYPE_PPNO,
+    S390_FEAT_TYPE_KMA,
 } S390FeatType;
 
 /* Definition of a CPU feature */
@@ -74,6 +75,9 @@ typedef enum {
     S390_FEAT_GROUP_MSA_EXT_3,
     S390_FEAT_GROUP_MSA_EXT_4,
     S390_FEAT_GROUP_MSA_EXT_5,
+    S390_FEAT_GROUP_MSA_EXT_6,
+    S390_FEAT_GROUP_MSA_EXT_7,
+    S390_FEAT_GROUP_MSA_EXT_8,
     S390_FEAT_GROUP_MAX,
 } S390FeatGroup;
 
diff --git a/target/s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h
index aa5ab8d371..4b6d4e9cc0 100644
--- a/target/s390x/cpu_features_def.h
+++ b/target/s390x/cpu_features_def.h
@@ -15,6 +15,7 @@
 #define TARGET_S390X_CPU_FEATURES_DEF_H
 
 typedef enum {
+    /* Stfle */
     S390_FEAT_ESAN3 = 0,
     S390_FEAT_ZARCH,
     S390_FEAT_DAT_ENH,
@@ -49,6 +50,7 @@ typedef enum {
     S390_FEAT_EXECUTE_EXT,
     S390_FEAT_ENHANCED_MONITOR,
     S390_FEAT_FLOATING_POINT_EXT,
+    S390_FEAT_ORDER_PRESERVING_COMPRESSION,
     S390_FEAT_SET_PROGRAM_PARAMETERS,
     S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
     S390_FEAT_DFP,
@@ -62,8 +64,15 @@ typedef enum {
     S390_FEAT_LOCAL_TLB_CLEARING,
     S390_FEAT_INTERLOCKED_ACCESS_2,
     S390_FEAT_STFLE_53,
+    S390_FEAT_ENTROPY_ENC_COMP,
     S390_FEAT_MSA_EXT_5,
+    S390_FEAT_MISC_INSTRUCTION_EXT,
+    S390_FEAT_SEMAPHORE_ASSIST,
+    S390_FEAT_TIME_SLICE_INSTRUMENTATION,
     S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_ZPCI,
+    S390_FEAT_ADAPTER_EVENT_NOTIFICATION,
+    S390_FEAT_ADAPTER_INT_SUPPRESSION,
     S390_FEAT_TRANSACTIONAL_EXE,
     S390_FEAT_STORE_HYPERVISOR_INFO,
     S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
@@ -72,12 +81,30 @@ typedef enum {
     S390_FEAT_EDAT_2,
     S390_FEAT_DFP_PACKED_CONVERSION,
     S390_FEAT_VECTOR,
+    S390_FEAT_INSTRUCTION_EXEC_PROT,
+    S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
+    S390_FEAT_GUARDED_STORAGE,
+    S390_FEAT_VECTOR_PACKED_DECIMAL,
+    S390_FEAT_VECTOR_ENH,
+    S390_FEAT_MULTIPLE_EPOCH,
+    S390_FEAT_TEST_PENDING_EXT_INTERRUPTION,
+    S390_FEAT_INSERT_REFERENCE_BITS_MULT,
+    S390_FEAT_MSA_EXT_8,
+    S390_FEAT_CMM_NT,
+
+    /* Sclp Conf Char */
     S390_FEAT_SIE_GSLS,
     S390_FEAT_ESOP,
+    S390_FEAT_HPMA2,
+    S390_FEAT_SIE_KSS,
+
+    /* Sclp Conf Char Ext */
     S390_FEAT_SIE_64BSCAO,
     S390_FEAT_SIE_CMMA,
     S390_FEAT_SIE_PFMFI,
     S390_FEAT_SIE_IBS,
+
+    /* Sclp Cpu */
     S390_FEAT_SIE_F2,
     S390_FEAT_SIE_SKEY,
     S390_FEAT_SIE_GPERE,
@@ -85,8 +112,12 @@ typedef enum {
     S390_FEAT_SIE_SIGPIF,
     S390_FEAT_SIE_IB,
     S390_FEAT_SIE_CEI,
+
+    /* Misc */
     S390_FEAT_DAT_ENH_2,
     S390_FEAT_CMM,
+
+    /* PLO */
     S390_FEAT_PLO_CL,
     S390_FEAT_PLO_CLG,
     S390_FEAT_PLO_CLGR,
@@ -111,6 +142,8 @@ typedef enum {
     S390_FEAT_PLO_CSTSTG,
     S390_FEAT_PLO_CSTSTGR,
     S390_FEAT_PLO_CSTSTX,
+
+    /* PTFF */
     S390_FEAT_PTFF_QTO,
     S390_FEAT_PTFF_QSI,
     S390_FEAT_PTFF_QPT,
@@ -118,6 +151,8 @@ typedef enum {
     S390_FEAT_PTFF_QTOU,
     S390_FEAT_PTFF_STO,
     S390_FEAT_PTFF_STOU,
+
+    /* KMAC */
     S390_FEAT_KMAC_DEA,
     S390_FEAT_KMAC_TDEA_128,
     S390_FEAT_KMAC_TDEA_192,
@@ -130,6 +165,8 @@ typedef enum {
     S390_FEAT_KMAC_EAES_128,
     S390_FEAT_KMAC_EAES_192,
     S390_FEAT_KMAC_EAES_256,
+
+    /* KMC */
     S390_FEAT_KMC_DEA,
     S390_FEAT_KMC_TDEA_128,
     S390_FEAT_KMC_TDEA_192,
@@ -143,6 +180,8 @@ typedef enum {
     S390_FEAT_KMC_EAES_192,
     S390_FEAT_KMC_EAES_256,
     S390_FEAT_KMC_PRNG,
+
+    /* KM */
     S390_FEAT_KM_DEA,
     S390_FEAT_KM_TDEA_128,
     S390_FEAT_KM_TDEA_192,
@@ -159,19 +198,39 @@ typedef enum {
     S390_FEAT_KM_XTS_AES_256,
     S390_FEAT_KM_XTS_EAES_128,
     S390_FEAT_KM_XTS_EAES_256,
+
+    /* KIMD */
     S390_FEAT_KIMD_SHA_1,
     S390_FEAT_KIMD_SHA_256,
     S390_FEAT_KIMD_SHA_512,
+    S390_FEAT_KIMD_SHA3_224,
+    S390_FEAT_KIMD_SHA3_256,
+    S390_FEAT_KIMD_SHA3_384,
+    S390_FEAT_KIMD_SHA3_512,
+    S390_FEAT_KIMD_SHAKE_128,
+    S390_FEAT_KIMD_SHAKE_256,
     S390_FEAT_KIMD_GHASH,
+
+    /* KLMD */
     S390_FEAT_KLMD_SHA_1,
     S390_FEAT_KLMD_SHA_256,
     S390_FEAT_KLMD_SHA_512,
+    S390_FEAT_KLMD_SHA3_224,
+    S390_FEAT_KLMD_SHA3_256,
+    S390_FEAT_KLMD_SHA3_384,
+    S390_FEAT_KLMD_SHA3_512,
+    S390_FEAT_KLMD_SHAKE_128,
+    S390_FEAT_KLMD_SHAKE_256,
+
+    /* PCKMO */
     S390_FEAT_PCKMO_EDEA,
     S390_FEAT_PCKMO_ETDEA_128,
     S390_FEAT_PCKMO_ETDEA_256,
     S390_FEAT_PCKMO_AES_128,
     S390_FEAT_PCKMO_AES_192,
     S390_FEAT_PCKMO_AES_256,
+
+    /* KMCTR */
     S390_FEAT_KMCTR_DEA,
     S390_FEAT_KMCTR_TDEA_128,
     S390_FEAT_KMCTR_TDEA_192,
@@ -184,6 +243,8 @@ typedef enum {
     S390_FEAT_KMCTR_EAES_128,
     S390_FEAT_KMCTR_EAES_192,
     S390_FEAT_KMCTR_EAES_256,
+
+    /* KMF */
     S390_FEAT_KMF_DEA,
     S390_FEAT_KMF_TDEA_128,
     S390_FEAT_KMF_TDEA_192,
@@ -196,6 +257,8 @@ typedef enum {
     S390_FEAT_KMF_EAES_128,
     S390_FEAT_KMF_EAES_192,
     S390_FEAT_KMF_EAES_256,
+
+    /* KMO */
     S390_FEAT_KMO_DEA,
     S390_FEAT_KMO_TDEA_128,
     S390_FEAT_KMO_TDEA_192,
@@ -208,6 +271,8 @@ typedef enum {
     S390_FEAT_KMO_EAES_128,
     S390_FEAT_KMO_EAES_192,
     S390_FEAT_KMO_EAES_256,
+
+    /* PCC */
     S390_FEAT_PCC_CMAC_DEA,
     S390_FEAT_PCC_CMAC_TDEA_128,
     S390_FEAT_PCC_CMAC_TDEA_192,
@@ -224,7 +289,19 @@ typedef enum {
     S390_FEAT_PCC_XTS_AES_256,
     S390_FEAT_PCC_XTS_EAES_128,
     S390_FEAT_PCC_XTS_EAES_256,
+
+    /* PPNO/PRNO */
     S390_FEAT_PPNO_SHA_512_DRNG,
+    S390_FEAT_PRNO_TRNG_QRTCR,
+    S390_FEAT_PRNO_TRNG,
+
+    /* KMA */
+    S390_FEAT_KMA_GCM_AES_128,
+    S390_FEAT_KMA_GCM_AES_192,
+    S390_FEAT_KMA_GCM_AES_256 ,
+    S390_FEAT_KMA_GCM_EAES_128,
+    S390_FEAT_KMA_GCM_EAES_192,
+    S390_FEAT_KMA_GCM_EAES_256,
     S390_FEAT_MAX,
 } S390Feat;
 
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 7cb55dc7e3..c654279a6c 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -77,6 +77,32 @@ static S390CPUDef s390_cpu_defs[] = {
     CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"),
 };
 
+void s390_cpudef_featoff(uint8_t gen, uint8_t ec_ga, S390Feat feat)
+{
+    const S390CPUDef *def;
+
+    def = s390_find_cpu_def(0, gen, ec_ga, NULL);
+    clear_bit(feat, (unsigned long *)&def->default_feat);
+}
+
+void s390_cpudef_featoff_greater(uint8_t gen, uint8_t ec_ga, S390Feat feat)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
+        const S390CPUDef *def = &s390_cpu_defs[i];
+
+        if (def->gen < gen) {
+            continue;
+        }
+        if (def->gen == gen && def->ec_ga < ec_ga) {
+            continue;
+        }
+
+        clear_bit(feat, (unsigned long *)&def->default_feat);
+    }
+}
+
 uint32_t s390_get_hmfai(void)
 {
     static S390CPU *cpu;
@@ -671,15 +697,40 @@ static void check_consistency(const S390CPUModel *model)
         { S390_FEAT_SIE_CMMA, S390_FEAT_CMM },
         { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS },
         { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT },
+        { S390_FEAT_MSA_EXT_8, S390_FEAT_MSA_EXT_3 },
+        { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING },
+        { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR },
+        { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR },
+        { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 },
+        { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP },
+        { S390_FEAT_CMM_NT, S390_FEAT_CMM },
+        { S390_FEAT_GUARDED_STORAGE, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 },
+        { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_STORE_CLOCK_FAST },
+        { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING },
+        { S390_FEAT_SEMAPHORE_ASSIST, S390_FEAT_STFLE_49 },
+        { S390_FEAT_KIMD_SHA3_224, S390_FEAT_MSA },
+        { S390_FEAT_KIMD_SHA3_256, S390_FEAT_MSA },
+        { S390_FEAT_KIMD_SHA3_384, S390_FEAT_MSA },
+        { S390_FEAT_KIMD_SHA3_512, S390_FEAT_MSA },
+        { S390_FEAT_KIMD_SHAKE_128, S390_FEAT_MSA },
+        { S390_FEAT_KIMD_SHAKE_256, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHA3_224, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHA3_256, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHA3_384, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA },
+        { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA },
+        { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 },
+        { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 },
     };
     int i;
 
     for (i = 0; i < ARRAY_SIZE(dep); i++) {
         if (test_bit(dep[i][0], model->features) &&
             !test_bit(dep[i][1], model->features)) {
-            error_report("Warning: \'%s\' requires \'%s\'.",
-                         s390_feat_def(dep[i][0])->name,
-                         s390_feat_def(dep[i][1])->name);
+            warn_report("\'%s\' requires \'%s\'.",
+                        s390_feat_def(dep[i][0])->name,
+                        s390_feat_def(dep[i][1])->name);
         }
     }
 }
diff --git a/target/s390x/cpu_models.h b/target/s390x/cpu_models.h
index d41f8d6e38..c0bee15d7a 100644
--- a/target/s390x/cpu_models.h
+++ b/target/s390x/cpu_models.h
@@ -72,6 +72,8 @@ typedef struct S390CPUModel {
 #define ibc_gen(x)        (x == 0 ? 0 : ((x >> 4) + S390_GEN_Z10))
 #define ibc_ec_ga(x)      (x & 0xf)
 
+void s390_cpudef_featoff(uint8_t gen, uint8_t ec_ga, S390Feat feat);
+void s390_cpudef_featoff_greater(uint8_t gen, uint8_t ec_ga, S390Feat feat);
 uint32_t s390_get_hmfai(void);
 uint8_t s390_get_mha_pow(void);
 uint32_t s390_get_ibc_val(void);
diff --git a/target/s390x/gdbstub.c b/target/s390x/gdbstub.c
index 94ab74d58f..a7efafee9f 100644
--- a/target/s390x/gdbstub.c
+++ b/target/s390x/gdbstub.c
@@ -286,6 +286,26 @@ static int cpu_write_virt_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
 }
 #endif
 
+/* the values represent the positions in s390-gs.xml */
+#define S390_GS_RESERVED_REGNUM 0
+#define S390_GS_GSD_REGNUM      1
+#define S390_GS_GSSM_REGNUM     2
+#define S390_GS_GSEPLA_REGNUM   3
+/* total number of registers in s390-gs.xml */
+#define S390_NUM_GS_REGS 4
+
+static int cpu_read_gs_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
+{
+    return gdb_get_regl(mem_buf, env->gscb[n]);
+}
+
+static int cpu_write_gs_reg(CPUS390XState *env, uint8_t *mem_buf, int n)
+{
+    env->gscb[n] = ldtul_p(mem_buf);
+    cpu_synchronize_post_init(ENV_GET_CPU(env));
+    return 8;
+}
+
 void s390_cpu_gdb_init(CPUState *cs)
 {
     gdb_register_coprocessor(cs, cpu_read_ac_reg,
@@ -300,6 +320,10 @@ void s390_cpu_gdb_init(CPUState *cs)
                              cpu_write_vreg,
                              S390_NUM_VREGS, "s390-vx.xml", 0);
 
+    gdb_register_coprocessor(cs, cpu_read_gs_reg,
+                             cpu_write_gs_reg,
+                             S390_NUM_GS_REGS, "s390-gs.xml", 0);
+
 #ifndef CONFIG_USER_ONLY
     gdb_register_coprocessor(cs, cpu_read_c_reg,
                              cpu_write_c_reg,
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index e674738ae3..af14b11199 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -182,6 +182,33 @@
     S390_FEAT_MSA_EXT_5, \
     S390_FEAT_PPNO_SHA_512_DRNG
 
+#define S390_FEAT_GROUP_MSA_EXT_6 \
+    S390_FEAT_KIMD_SHA3_224, \
+    S390_FEAT_KIMD_SHA3_256, \
+    S390_FEAT_KIMD_SHA3_384, \
+    S390_FEAT_KIMD_SHA3_512, \
+    S390_FEAT_KIMD_SHAKE_128, \
+    S390_FEAT_KIMD_SHAKE_256, \
+    S390_FEAT_KLMD_SHA3_224, \
+    S390_FEAT_KLMD_SHA3_256, \
+    S390_FEAT_KLMD_SHA3_384, \
+    S390_FEAT_KLMD_SHA3_512, \
+    S390_FEAT_KLMD_SHAKE_128, \
+    S390_FEAT_KLMD_SHAKE_256
+
+#define S390_FEAT_GROUP_MSA_EXT_7 \
+    S390_FEAT_PRNO_TRNG_QRTCR, \
+    S390_FEAT_PRNO_TRNG
+
+#define S390_FEAT_GROUP_MSA_EXT_8 \
+    S390_FEAT_MSA_EXT_8, \
+    S390_FEAT_KMA_GCM_AES_128, \
+    S390_FEAT_KMA_GCM_AES_192, \
+    S390_FEAT_KMA_GCM_AES_256 , \
+    S390_FEAT_KMA_GCM_EAES_128, \
+    S390_FEAT_KMA_GCM_EAES_192, \
+    S390_FEAT_KMA_GCM_EAES_256
+
 /* cpu feature groups */
 static uint16_t group_PLO[] = {
     S390_FEAT_GROUP_PLO,
@@ -210,15 +237,30 @@ static uint16_t group_MSA_EXT_4[] = {
 static uint16_t group_MSA_EXT_5[] = {
     S390_FEAT_GROUP_MSA_EXT_5,
 };
+static uint16_t group_MSA_EXT_6[] = {
+    S390_FEAT_GROUP_MSA_EXT_6,
+};
+static uint16_t group_MSA_EXT_7[] = {
+    S390_FEAT_GROUP_MSA_EXT_7,
+};
+static uint16_t group_MSA_EXT_8[] = {
+    S390_FEAT_GROUP_MSA_EXT_8,
+};
 
-/* base features in order of release */
+/* Base features (in order of release)
+ * Only non-hypervisor managed features belong here.
+ * Base feature sets are static meaning they do not change in future QEMU
+ * releases.
+ */
 static uint16_t base_GEN7_GA1[] = {
     S390_FEAT_GROUP_PLO,
     S390_FEAT_ESAN3,
     S390_FEAT_ZARCH,
 };
+
 #define base_GEN7_GA2 EmptyFeat
 #define base_GEN7_GA3 EmptyFeat
+
 static uint16_t base_GEN8_GA1[] = {
     S390_FEAT_DAT_ENH,
     S390_FEAT_EXTENDED_TRANSLATION_2,
@@ -227,10 +269,12 @@ static uint16_t base_GEN8_GA1[] = {
     S390_FEAT_LONG_DISPLACEMENT_FAST,
     S390_FEAT_HFP_MADDSUB,
 };
+
 #define base_GEN8_GA2 EmptyFeat
 #define base_GEN8_GA3 EmptyFeat
 #define base_GEN8_GA4 EmptyFeat
 #define base_GEN8_GA5 EmptyFeat
+
 static uint16_t base_GEN9_GA1[] = {
     S390_FEAT_IDTE_SEGMENT,
     S390_FEAT_ASN_LX_REUSE,
@@ -245,8 +289,10 @@ static uint16_t base_GEN9_GA1[] = {
     S390_FEAT_ETF3_ENH,
     S390_FEAT_DAT_ENH_2,
 };
+
 #define base_GEN9_GA2 EmptyFeat
 #define base_GEN9_GA3 EmptyFeat
+
 static uint16_t base_GEN10_GA1[] = {
     S390_FEAT_CONDITIONAL_SSKE,
     S390_FEAT_PARSING_ENH,
@@ -263,6 +309,7 @@ static uint16_t base_GEN10_GA1[] = {
 };
 #define base_GEN10_GA2 EmptyFeat
 #define base_GEN10_GA3 EmptyFeat
+
 static uint16_t base_GEN11_GA1[] = {
     S390_FEAT_NONQ_KEY_SETTING,
     S390_FEAT_ENHANCED_MONITOR,
@@ -272,21 +319,30 @@ static uint16_t base_GEN11_GA1[] = {
     S390_FEAT_CMPSC_ENH,
     S390_FEAT_INTERLOCKED_ACCESS_2,
 };
+
 #define base_GEN11_GA2 EmptyFeat
+
 static uint16_t base_GEN12_GA1[] = {
     S390_FEAT_DFP_ZONED_CONVERSION,
     S390_FEAT_STFLE_49,
     S390_FEAT_LOCAL_TLB_CLEARING,
 };
+
 #define base_GEN12_GA2 EmptyFeat
+
 static uint16_t base_GEN13_GA1[] = {
     S390_FEAT_STFLE_53,
     S390_FEAT_DFP_PACKED_CONVERSION,
     S390_FEAT_GROUP_GEN13_PTFF,
 };
+
 #define base_GEN13_GA2 EmptyFeat
 
-/* full features differing to the base in order of release */
+/* Full features (in order of release)
+ * Automatically includes corresponding base features.
+ * Full features are all features this hardware supports even if kvm/QEMU do not
+ * support these features yet.
+ */
 static uint16_t full_GEN7_GA1[] = {
     S390_FEAT_SIE_F2,
     S390_FEAT_SIE_SKEY,
@@ -294,30 +350,38 @@ static uint16_t full_GEN7_GA1[] = {
     S390_FEAT_SIE_IB,
     S390_FEAT_SIE_CEI,
 };
+
 static uint16_t full_GEN7_GA2[] = {
     S390_FEAT_EXTENDED_TRANSLATION_2,
 };
+
 static uint16_t full_GEN7_GA3[] = {
     S390_FEAT_LONG_DISPLACEMENT,
     S390_FEAT_SIE_SIIF,
 };
+
 static uint16_t full_GEN8_GA1[] = {
     S390_FEAT_SIE_GSLS,
     S390_FEAT_SIE_64BSCAO,
 };
+
 #define full_GEN8_GA2 EmptyFeat
+
 static uint16_t full_GEN8_GA3[] = {
     S390_FEAT_ASN_LX_REUSE,
     S390_FEAT_EXTENDED_TRANSLATION_3,
 };
+
 #define full_GEN8_GA4 EmptyFeat
 #define full_GEN8_GA5 EmptyFeat
+
 static uint16_t full_GEN9_GA1[] = {
     S390_FEAT_STORE_HYPERVISOR_INFO,
     S390_FEAT_GROUP_MSA_EXT_1,
     S390_FEAT_CMM,
     S390_FEAT_SIE_CMMA,
 };
+
 static uint16_t full_GEN9_GA2[] = {
     S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
     S390_FEAT_EXTRACT_CPU_TIME,
@@ -325,10 +389,12 @@ static uint16_t full_GEN9_GA2[] = {
     S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
     S390_FEAT_DFP,
 };
+
 static uint16_t full_GEN9_GA3[] = {
     S390_FEAT_CONDITIONAL_SSKE,
     S390_FEAT_PFPO,
 };
+
 static uint16_t full_GEN10_GA1[] = {
     S390_FEAT_EDAT,
     S390_FEAT_CONFIGURATION_TOPOLOGY,
@@ -337,34 +403,50 @@ static uint16_t full_GEN10_GA1[] = {
     S390_FEAT_SIE_PFMFI,
     S390_FEAT_SIE_SIGPIF,
 };
+
 static uint16_t full_GEN10_GA2[] = {
     S390_FEAT_SET_PROGRAM_PARAMETERS,
     S390_FEAT_SIE_IBS,
 };
+
 static uint16_t full_GEN10_GA3[] = {
     S390_FEAT_GROUP_MSA_EXT_3,
 };
+
 static uint16_t full_GEN11_GA1[] = {
     S390_FEAT_IPTE_RANGE,
     S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
     S390_FEAT_GROUP_MSA_EXT_4,
 };
+
 #define full_GEN11_GA2 EmptyFeat
+
 static uint16_t full_GEN12_GA1[] = {
     S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
     S390_FEAT_TRANSACTIONAL_EXE,
     S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_ZPCI,
+    S390_FEAT_ADAPTER_EVENT_NOTIFICATION,
+    S390_FEAT_ADAPTER_INT_SUPPRESSION,
     S390_FEAT_EDAT_2,
+    S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
 };
+
 static uint16_t full_GEN12_GA2[] = {
     S390_FEAT_GROUP_MSA_EXT_5,
 };
+
 static uint16_t full_GEN13_GA1[] = {
     S390_FEAT_VECTOR,
 };
+
 #define full_GEN13_GA2 EmptyFeat
 
-/* default features differing to the base in order of release */
+/* Default features (in order of release)
+ * Automatically includes corresponding base features.
+ * Default features are all features this version of QEMU supports for this
+ * hardware model. Default feature sets can grow with new QEMU releases.
+ */
 #define default_GEN7_GA1 EmptyFeat
 #define default_GEN7_GA2 EmptyFeat
 #define default_GEN7_GA3 EmptyFeat
@@ -373,37 +455,51 @@ static uint16_t full_GEN13_GA1[] = {
 #define default_GEN8_GA3 EmptyFeat
 #define default_GEN8_GA4 EmptyFeat
 #define default_GEN8_GA5 EmptyFeat
+
 static uint16_t default_GEN9_GA1[] = {
     S390_FEAT_STORE_HYPERVISOR_INFO,
     S390_FEAT_GROUP_MSA_EXT_1,
     S390_FEAT_CMM,
 };
+
 #define default_GEN9_GA2 EmptyFeat
 #define default_GEN9_GA3 EmptyFeat
+
 static uint16_t default_GEN10_GA1[] = {
     S390_FEAT_EDAT,
     S390_FEAT_GROUP_MSA_EXT_2,
 };
+
 #define default_GEN10_GA2 EmptyFeat
 #define default_GEN10_GA3 EmptyFeat
+
 static uint16_t default_GEN11_GA1[] = {
     S390_FEAT_GROUP_MSA_EXT_3,
     S390_FEAT_IPTE_RANGE,
     S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
     S390_FEAT_GROUP_MSA_EXT_4,
 };
+
 #define default_GEN11_GA2 EmptyFeat
+
 static uint16_t default_GEN12_GA1[] = {
     S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
     S390_FEAT_TRANSACTIONAL_EXE,
     S390_FEAT_RUNTIME_INSTRUMENTATION,
+    S390_FEAT_ZPCI,
+    S390_FEAT_ADAPTER_EVENT_NOTIFICATION,
     S390_FEAT_EDAT_2,
+    S390_FEAT_ESOP,
+    S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
 };
+
 #define default_GEN12_GA2 EmptyFeat
+
 static uint16_t default_GEN13_GA1[] = {
     S390_FEAT_GROUP_MSA_EXT_5,
     S390_FEAT_VECTOR,
 };
+
 #define default_GEN13_GA2 EmptyFeat
 
 /****** END FEATURE DEFS ******/
@@ -491,6 +587,9 @@ static FeatGroupDefSpec FeatGroupDef[] = {
     FEAT_GROUP_INITIALIZER(MSA_EXT_3),
     FEAT_GROUP_INITIALIZER(MSA_EXT_4),
     FEAT_GROUP_INITIALIZER(MSA_EXT_5),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_6),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_7),
+    FEAT_GROUP_INITIALIZER(MSA_EXT_8),
 };
 
 static void set_bits(uint64_t list[], BitSpec bits)
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index a3d00196f4..831492f9a2 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -139,6 +139,9 @@ static int cap_async_pf;
 static int cap_mem_op;
 static int cap_s390_irq;
 static int cap_ri;
+static int cap_gs;
+
+static int active_cmma;
 
 static void *legacy_s390_alloc(size_t size, uint64_t *align);
 
@@ -177,6 +180,11 @@ int kvm_s390_set_mem_limit(KVMState *s, uint64_t new_limit, uint64_t *hw_limit)
     return kvm_vm_ioctl(s, KVM_SET_DEVICE_ATTR, &attr);
 }
 
+int kvm_s390_cmma_active(void)
+{
+    return active_cmma;
+}
+
 static bool kvm_s390_cmma_available(void)
 {
     static bool initialized, value;
@@ -197,7 +205,7 @@ void kvm_s390_cmma_reset(void)
         .attr = KVM_S390_VM_MEM_CLR_CMMA,
     };
 
-    if (mem_path || !kvm_s390_cmma_available()) {
+    if (!kvm_s390_cmma_active()) {
         return;
     }
 
@@ -213,7 +221,13 @@ static void kvm_s390_enable_cmma(void)
         .attr = KVM_S390_VM_MEM_ENABLE_CMMA,
     };
 
+    if (mem_path) {
+        error_report("Warning: CMM will not be enabled because it is not "
+                     "compatible to hugetlbfs.");
+        return;
+    }
     rc = kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
+    active_cmma = !rc;
     trace_kvm_enable_cmma(rc);
 }
 
@@ -288,6 +302,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
             cap_ri = 1;
         }
     }
+    if (gs_allowed()) {
+        if (kvm_vm_enable_cap(s, KVM_CAP_S390_GS, 0) == 0) {
+            cap_gs = 1;
+        }
+    }
+
+    /* Try to enable AIS facility */
+    kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
 
     qemu_mutex_init(&qemu_sigp_mutex);
 
@@ -456,6 +478,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
         }
     }
 
+    if (can_sync_regs(cs, KVM_SYNC_GSCB)) {
+        memcpy(cs->kvm_run->s.regs.gscb, env->gscb, 32);
+        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_GSCB;
+    }
+
     /* Finally the prefix */
     if (can_sync_regs(cs, KVM_SYNC_PREFIX)) {
         cs->kvm_run->s.regs.prefix = env->psa;
@@ -562,6 +589,10 @@ int kvm_arch_get_registers(CPUState *cs)
         memcpy(env->riccb, cs->kvm_run->s.regs.riccb, 64);
     }
 
+    if (can_sync_regs(cs, KVM_SYNC_GSCB)) {
+        memcpy(env->gscb, cs->kvm_run->s.regs.gscb, 32);
+    }
+
     /* pfault parameters */
     if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
         env->pfault_token = cs->kvm_run->s.regs.pft;
@@ -1193,7 +1224,21 @@ static int kvm_stpcifc_service_call(S390CPU *cpu, struct kvm_run *run)
 
 static int kvm_sic_service_call(S390CPU *cpu, struct kvm_run *run)
 {
-    /* NOOP */
+    CPUS390XState *env = &cpu->env;
+    uint8_t r1 = (run->s390_sieic.ipa & 0x00f0) >> 4;
+    uint8_t r3 = run->s390_sieic.ipa & 0x000f;
+    uint8_t isc;
+    uint16_t mode;
+    int r;
+
+    cpu_synchronize_state(CPU(cpu));
+    mode = env->regs[r1] & 0xffff;
+    isc = (env->regs[r3] >> 27) & 0x7;
+    r = css_do_sic(env, isc, mode);
+    if (r) {
+        enter_pgmcheck(cpu, -r);
+    }
+
     return 0;
 }
 
@@ -1444,22 +1489,28 @@ static void sigp_stop(CPUState *cs, run_on_cpu_data arg)
     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
 }
 
-#define ADTL_SAVE_AREA_SIZE 1024
-static int kvm_s390_store_adtl_status(S390CPU *cpu, hwaddr addr)
+#define ADTL_GS_OFFSET   1024 /* offset of GS data in adtl save area */
+#define ADTL_GS_MIN_SIZE 2048 /* minimal size of adtl save area for GS */
+static int do_store_adtl_status(S390CPU *cpu, hwaddr addr, hwaddr len)
 {
+    hwaddr save = len;
     void *mem;
-    hwaddr len = ADTL_SAVE_AREA_SIZE;
 
-    mem = cpu_physical_memory_map(addr, &len, 1);
+    mem = cpu_physical_memory_map(addr, &save, 1);
     if (!mem) {
         return -EFAULT;
     }
-    if (len != ADTL_SAVE_AREA_SIZE) {
+    if (save != len) {
         cpu_physical_memory_unmap(mem, len, 1, 0);
         return -EFAULT;
     }
 
-    memcpy(mem, &cpu->env.vregs, 512);
+    if (s390_has_feat(S390_FEAT_VECTOR)) {
+        memcpy(mem, &cpu->env.vregs, 512);
+    }
+    if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) && len >= ADTL_GS_MIN_SIZE) {
+        memcpy(mem + ADTL_GS_OFFSET, &cpu->env.gscb, 32);
+    }
 
     cpu_physical_memory_unmap(mem, len, 1, len);
 
@@ -1555,12 +1606,17 @@ static void sigp_store_status_at_address(CPUState *cs, run_on_cpu_data arg)
     si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
 }
 
+#define ADTL_SAVE_LC_MASK  0xfUL
 static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg)
 {
     S390CPU *cpu = S390_CPU(cs);
     SigpInfo *si = arg.host_ptr;
+    uint8_t lc = si->param & ADTL_SAVE_LC_MASK;
+    hwaddr addr = si->param & ~ADTL_SAVE_LC_MASK;
+    hwaddr len = 1UL << (lc ? lc : 10);
 
-    if (!s390_has_feat(S390_FEAT_VECTOR)) {
+    if (!s390_has_feat(S390_FEAT_VECTOR) &&
+        !s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
         set_sigp_status(si, SIGP_STAT_INVALID_ORDER);
         return;
     }
@@ -1571,15 +1627,32 @@ static void sigp_store_adtl_status(CPUState *cs, run_on_cpu_data arg)
         return;
     }
 
-    /* parameter must be aligned to 1024-byte boundary */
-    if (si->param & 0x3ff) {
+    /* address must be aligned to length */
+    if (addr & (len - 1)) {
+        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
+        return;
+    }
+
+    /* no GS: only lc == 0 is valid */
+    if (!s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
+        lc != 0) {
+        set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
+        return;
+    }
+
+    /* GS: 0, 10, 11, 12 are valid */
+    if (s390_has_feat(S390_FEAT_GUARDED_STORAGE) &&
+        lc != 0 &&
+        lc != 10 &&
+        lc != 11 &&
+        lc != 12) {
         set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
         return;
     }
 
     cpu_synchronize_state(cs);
 
-    if (kvm_s390_store_adtl_status(cpu, si->param)) {
+    if (do_store_adtl_status(cpu, addr, len)) {
         set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
         return;
     }
@@ -1727,41 +1800,25 @@ static int sigp_set_architecture(S390CPU *cpu, uint32_t param,
 {
     CPUState *cur_cs;
     S390CPU *cur_cpu;
+    bool all_stopped = true;
 
-    /* due to the BQL, we are the only active cpu */
     CPU_FOREACH(cur_cs) {
         cur_cpu = S390_CPU(cur_cs);
-        if (cur_cpu->env.sigp_order != 0) {
-            return SIGP_CC_BUSY;
+
+        if (cur_cpu == cpu) {
+            continue;
         }
-        cpu_synchronize_state(cur_cs);
-        /* all but the current one have to be stopped */
-        if (cur_cpu != cpu &&
-            s390_cpu_get_state(cur_cpu) != CPU_STATE_STOPPED) {
-            *status_reg &= 0xffffffff00000000ULL;
-            *status_reg |= SIGP_STAT_INCORRECT_STATE;
-            return SIGP_CC_STATUS_STORED;
+        if (s390_cpu_get_state(cur_cpu) != CPU_STATE_STOPPED) {
+            all_stopped = false;
         }
     }
 
-    switch (param & 0xff) {
-    case SIGP_MODE_ESA_S390:
-        /* not supported */
-        return SIGP_CC_NOT_OPERATIONAL;
-    case SIGP_MODE_Z_ARCH_TRANS_ALL_PSW:
-    case SIGP_MODE_Z_ARCH_TRANS_CUR_PSW:
-        CPU_FOREACH(cur_cs) {
-            cur_cpu = S390_CPU(cur_cs);
-            cur_cpu->env.pfault_token = -1UL;
-        }
-        break;
-    default:
-        *status_reg &= 0xffffffff00000000ULL;
-        *status_reg |= SIGP_STAT_INVALID_PARAMETER;
-        return SIGP_CC_STATUS_STORED;
-    }
+    *status_reg &= 0xffffffff00000000ULL;
 
-    return SIGP_CC_ORDER_CODE_ACCEPTED;
+    /* Reject set arch order, with czam we're always in z/Arch mode. */
+    *status_reg |= (all_stopped ? SIGP_STAT_INVALID_PARAMETER :
+                    SIGP_STAT_INCORRECT_STATE);
+    return SIGP_CC_STATUS_STORED;
 }
 
 static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
@@ -2174,6 +2231,9 @@ static uint64_t build_channel_report_mcic(void)
     if (s390_has_feat(S390_FEAT_VECTOR)) {
         mcic |= MCIC_VB_VR;
     }
+    if (s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
+        mcic |= MCIC_VB_GS;
+    }
     return mcic;
 }
 
@@ -2239,6 +2299,11 @@ int kvm_s390_get_ri(void)
     return cap_ri;
 }
 
+int kvm_s390_get_gs(void)
+{
+    return cap_gs;
+}
+
 int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
 {
     struct kvm_mp_state mp_state = {};
@@ -2417,6 +2482,9 @@ static int query_cpu_subfunc(S390FeatBitmap features)
     if (test_bit(S390_FEAT_MSA_EXT_5, features)) {
         s390_add_from_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
     }
+    if (test_bit(S390_FEAT_MSA_EXT_8, features)) {
+        s390_add_from_feat_block(features, S390_FEAT_TYPE_KMA, prop.kma);
+    }
     return 0;
 }
 
@@ -2470,6 +2538,10 @@ static int configure_cpu_subfunc(const S390FeatBitmap features)
         s390_fill_feat_block(features, S390_FEAT_TYPE_PPNO, prop.ppno);
         prop.ppno[0] |= 0x80; /* query is always available */
     }
+    if (test_bit(S390_FEAT_MSA_EXT_8, features)) {
+        s390_fill_feat_block(features, S390_FEAT_TYPE_KMA, prop.kma);
+        prop.kma[0] |= 0x80; /* query is always available */
+    }
     return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr);
 }
 
@@ -2487,6 +2559,7 @@ static int kvm_to_feat[][2] = {
     { KVM_S390_VM_CPU_FEAT_CMMA, S390_FEAT_SIE_CMMA },
     { KVM_S390_VM_CPU_FEAT_PFMFI, S390_FEAT_SIE_PFMFI},
     { KVM_S390_VM_CPU_FEAT_SIGPIF, S390_FEAT_SIE_SIGPIF},
+    { KVM_S390_VM_CPU_FEAT_KSS, S390_FEAT_SIE_KSS},
 };
 
 static int query_cpu_feat(S390FeatBitmap features)
@@ -2606,8 +2679,15 @@ void kvm_s390_get_host_cpu_model(S390CPUModel *model, Error **errp)
     /* with cpu model support, CMM is only indicated if really available */
     if (kvm_s390_cmma_available()) {
         set_bit(S390_FEAT_CMM, model->features);
+    } else {
+        /* no cmm -> no cmm nt */
+        clear_bit(S390_FEAT_CMM_NT, model->features);
     }
 
+    /* set zpci and aen facilities */
+    set_bit(S390_FEAT_ZPCI, model->features);
+    set_bit(S390_FEAT_ADAPTER_EVENT_NOTIFICATION, model->features);
+
     if (s390_known_cpu_type(cpu_type)) {
         /* we want the exact model, even if some features are missing */
         model->def = s390_find_cpu_def(cpu_type, ibc_gen(unblocked_ibc),
@@ -2641,7 +2721,7 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
 
     if (!model) {
         /* compatibility handling if cpu models are disabled */
-        if (kvm_s390_cmma_available() && !mem_path) {
+        if (kvm_s390_cmma_available()) {
             kvm_s390_enable_cmma();
         }
         return;
@@ -2672,13 +2752,8 @@ void kvm_s390_apply_cpu_model(const S390CPUModel *model, Error **errp)
         error_setg(errp, "KVM: Error configuring CPU subfunctions: %d", rc);
         return;
     }
-    /* enable CMM via CMMA - disable on hugetlbfs */
+    /* enable CMM via CMMA */
     if (test_bit(S390_FEAT_CMM, model->features)) {
-        if (mem_path) {
-            error_report("Warning: CMM will not be enabled because it is not "
-                         "compatible to hugetlbfs.");
-        } else {
-            kvm_s390_enable_cmma();
-        }
+        kvm_s390_enable_cmma();
     }
 }
diff --git a/target/s390x/machine.c b/target/s390x/machine.c
index 8f908bbe82..2dcadfdd29 100644
--- a/target/s390x/machine.c
+++ b/target/s390x/machine.c
@@ -174,6 +174,22 @@ const VMStateDescription vmstate_exval = {
     }
 };
 
+static bool gscb_needed(void *opaque)
+{
+    return kvm_s390_get_gs();
+}
+
+const VMStateDescription vmstate_gscb = {
+    .name = "cpu/gscb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = gscb_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(env.gscb, S390CPU, 4),
+        VMSTATE_END_OF_LIST()
+        }
+};
+
 const VMStateDescription vmstate_s390_cpu = {
     .name = "cpu",
     .post_load = cpu_post_load,
@@ -207,6 +223,7 @@ const VMStateDescription vmstate_s390_cpu = {
         &vmstate_vregs,
         &vmstate_riccb,
         &vmstate_exval,
+        &vmstate_gscb,
         NULL
     },
 };