Merge tag 'kvm-s390-next-5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 5 Feb 2020 15:15:05 +0000 (16:15 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 5 Feb 2020 15:15:05 +0000 (16:15 +0100)
KVM: s390: Fixes and cleanups for 5.6
- fix register corruption
- ENOTSUPP/EOPNOTSUPP mixed
- reset cleanups/fixes
- selftests

Documentation/virt/kvm/api.txt
arch/s390/include/asm/kvm_host.h
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
include/uapi/linux/kvm.h
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/s390x/resets.c [new file with mode: 0644]

index 3a0c819c357327ee0d7da4677e33c5a74ec379e9..c6e1ce5d40de992df7acd2c3782d619fd0838721 100644 (file)
@@ -4177,6 +4177,42 @@ This ioctl issues an ultravisor call to terminate the secure guest,
 unpins the VPA pages and releases all the device pages that are used to
 track the secure pages by hypervisor.
 
+4.122 KVM_S390_NORMAL_RESET
+
+Capability: KVM_CAP_S390_VCPU_RESETS
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the cpu reset definition in the POP (Principles Of Operation).
+
+4.123 KVM_S390_INITIAL_RESET
+
+Capability: none
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the initial cpu reset definition in the POP. However, the cpu is not
+put into ESA mode. This reset is a superset of the normal reset.
+
+4.124 KVM_S390_CLEAR_RESET
+
+Capability: KVM_CAP_S390_VCPU_RESETS
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the clear cpu reset definition in the POP. However, the cpu is not put
+into ESA mode. This reset is a superset of the initial reset.
+
+
 5. The kvm_run structure
 ------------------------
 
@@ -5405,3 +5441,10 @@ handling by KVM (as some KVM hypercall may be mistakenly treated as TLB
 flush hypercalls by Hyper-V) so userspace should disable KVM identification
 in CPUID and only exposes Hyper-V identification. In this case, guest
 thinks it's running on Hyper-V and only use Hyper-V hypercalls.
+
+8.22 KVM_CAP_S390_VCPU_RESETS
+
+Architectures: s390
+
+This capability indicates that the KVM_S390_NORMAL_RESET and
+KVM_S390_CLEAR_RESET ioctls are available.
index 11ecc4071a29f800d2b1246d91542db5dcc6bb0e..1726224e77727f273350b86bb678f8da9b9a84c7 100644 (file)
@@ -122,6 +122,11 @@ struct mcck_volatile_info {
        __u32 reserved;
 };
 
+#define CR0_INITIAL_MASK (CR0_UNUSED_56 | CR0_INTERRUPT_KEY_SUBMASK | \
+                         CR0_MEASUREMENT_ALERT_SUBMASK)
+#define CR14_INITIAL_MASK (CR14_UNUSED_32 | CR14_UNUSED_33 | \
+                          CR14_EXTERNAL_DAMAGE_SUBMASK)
+
 #define CPUSTAT_STOPPED    0x80000000
 #define CPUSTAT_WAIT       0x10000000
 #define CPUSTAT_ECALL_PEND 0x08000000
index 165dea4c7f193477529ae3ae2f9ce7691ed5b842..c06c89d370a737bc5c2bf9df2d25ea34dc3d0f8a 100644 (file)
@@ -2190,7 +2190,7 @@ static int flic_ais_mode_get_all(struct kvm *kvm, struct kvm_device_attr *attr)
                return -EINVAL;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        mutex_lock(&fi->ais_lock);
        ais.simm = fi->simm;
@@ -2499,7 +2499,7 @@ static int modify_ais_mode(struct kvm *kvm, struct kvm_device_attr *attr)
        int ret = 0;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req)))
                return -EFAULT;
@@ -2579,7 +2579,7 @@ static int flic_ais_mode_set_all(struct kvm *kvm, struct kvm_device_attr *attr)
        struct kvm_s390_ais_all ais;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais)))
                return -EFAULT;
index 8646c99217f285443a5973c1a62832767a4ddc48..d7ff30e45589935890ad1c1f67c0f36eaa4d480e 100644 (file)
@@ -529,6 +529,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_S390_CMMA_MIGRATION:
        case KVM_CAP_S390_AIS:
        case KVM_CAP_S390_AIS_MIGRATION:
+       case KVM_CAP_S390_VCPU_RESETS:
                r = 1;
                break;
        case KVM_CAP_S390_HPAGE_1M:
@@ -2808,35 +2809,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 }
 
-static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
-{
-       /* this equals initial cpu reset in pop, but we don't switch to ESA */
-       vcpu->arch.sie_block->gpsw.mask = 0UL;
-       vcpu->arch.sie_block->gpsw.addr = 0UL;
-       kvm_s390_set_prefix(vcpu, 0);
-       kvm_s390_set_cpu_timer(vcpu, 0);
-       vcpu->arch.sie_block->ckc       = 0UL;
-       vcpu->arch.sie_block->todpr     = 0;
-       memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
-       vcpu->arch.sie_block->gcr[0]  = CR0_UNUSED_56 |
-                                       CR0_INTERRUPT_KEY_SUBMASK |
-                                       CR0_MEASUREMENT_ALERT_SUBMASK;
-       vcpu->arch.sie_block->gcr[14] = CR14_UNUSED_32 |
-                                       CR14_UNUSED_33 |
-                                       CR14_EXTERNAL_DAMAGE_SUBMASK;
-       /* make sure the new fpc will be lazily loaded */
-       save_fpu_regs();
-       current->thread.fpu.fpc = 0;
-       vcpu->arch.sie_block->gbea = 1;
-       vcpu->arch.sie_block->pp = 0;
-       vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
-       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
-       kvm_clear_async_pf_completion_queue(vcpu);
-       if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
-               kvm_s390_vcpu_stop(vcpu);
-       kvm_s390_clear_local_irqs(vcpu);
-}
-
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
        mutex_lock(&vcpu->kvm->lock);
@@ -3279,10 +3251,53 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
        return r;
 }
 
-static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
+static void kvm_arch_vcpu_ioctl_normal_reset(struct kvm_vcpu *vcpu)
 {
-       kvm_s390_vcpu_initial_reset(vcpu);
-       return 0;
+       vcpu->arch.sie_block->gpsw.mask &= ~PSW_MASK_RI;
+       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
+       memset(vcpu->run->s.regs.riccb, 0, sizeof(vcpu->run->s.regs.riccb));
+
+       kvm_clear_async_pf_completion_queue(vcpu);
+       if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
+               kvm_s390_vcpu_stop(vcpu);
+       kvm_s390_clear_local_irqs(vcpu);
+}
+
+static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
+{
+       /* Initial reset is a superset of the normal reset */
+       kvm_arch_vcpu_ioctl_normal_reset(vcpu);
+
+       /* this equals initial cpu reset in pop, but we don't switch to ESA */
+       vcpu->arch.sie_block->gpsw.mask = 0;
+       vcpu->arch.sie_block->gpsw.addr = 0;
+       kvm_s390_set_prefix(vcpu, 0);
+       kvm_s390_set_cpu_timer(vcpu, 0);
+       vcpu->arch.sie_block->ckc = 0;
+       vcpu->arch.sie_block->todpr = 0;
+       memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr));
+       vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK;
+       vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK;
+       vcpu->run->s.regs.fpc = 0;
+       vcpu->arch.sie_block->gbea = 1;
+       vcpu->arch.sie_block->pp = 0;
+       vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
+}
+
+static void kvm_arch_vcpu_ioctl_clear_reset(struct kvm_vcpu *vcpu)
+{
+       struct kvm_sync_regs *regs = &vcpu->run->s.regs;
+
+       /* Clear reset is a superset of the initial reset */
+       kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+
+       memset(&regs->gprs, 0, sizeof(regs->gprs));
+       memset(&regs->vrs, 0, sizeof(regs->vrs));
+       memset(&regs->acrs, 0, sizeof(regs->acrs));
+       memset(&regs->gscb, 0, sizeof(regs->gscb));
+
+       regs->etoken = 0;
+       regs->etoken_extension = 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
@@ -4343,7 +4358,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        switch (ioctl) {
        case KVM_S390_STORE_STATUS:
                idx = srcu_read_lock(&vcpu->kvm->srcu);
-               r = kvm_s390_vcpu_store_status(vcpu, arg);
+               r = kvm_s390_store_status_unloaded(vcpu, arg);
                srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        case KVM_S390_SET_INITIAL_PSW: {
@@ -4355,8 +4370,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
                break;
        }
+       case KVM_S390_CLEAR_RESET:
+               r = 0;
+               kvm_arch_vcpu_ioctl_clear_reset(vcpu);
+               break;
        case KVM_S390_INITIAL_RESET:
-               r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               r = 0;
+               kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               break;
+       case KVM_S390_NORMAL_RESET:
+               r = 0;
+               kvm_arch_vcpu_ioctl_normal_reset(vcpu);
                break;
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {
index f0a16b4adbbd63c421006f6ca9b0fd9a892f7a5d..4b95f9a31a2f5e227f57f4cbba907c0508c5e3a9 100644 (file)
@@ -1009,6 +1009,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176
 #define KVM_CAP_ARM_NISV_TO_USER 177
 #define KVM_CAP_ARM_INJECT_EXT_DABT 178
+#define KVM_CAP_S390_VCPU_RESETS 179
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1473,6 +1474,10 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_ARM_SVE */
 #define KVM_ARM_VCPU_FINALIZE    _IOW(KVMIO,  0xc2, int)
 
+/* Available with  KVM_CAP_S390_VCPU_RESETS */
+#define KVM_S390_NORMAL_RESET  _IO(KVMIO,   0xc3)
+#define KVM_S390_CLEAR_RESET   _IO(KVMIO,   0xc4)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
        /* Guest initialization commands */
index 608fa835c764dacebd0e1020e8b991dbdd068755..67abc1dd50ee6aeaf082445a9fe78ad103dacf90 100644 (file)
@@ -36,6 +36,7 @@ TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
 
 TEST_GEN_PROGS_s390x = s390x/memop
 TEST_GEN_PROGS_s390x += s390x/sync_regs_test
+TEST_GEN_PROGS_s390x += s390x/resets
 TEST_GEN_PROGS_s390x += dirty_log_test
 TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
 
index 29cccaf96baf6322dc3b5f8d266096fdb2c06d7c..ae0d14c2540aa37608f59af67e0c283b2de5ab30 100644 (file)
@@ -125,6 +125,12 @@ void vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
                    struct kvm_sregs *sregs);
 int _vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
                    struct kvm_sregs *sregs);
+void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
+                 struct kvm_fpu *fpu);
+void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
+                 struct kvm_fpu *fpu);
+void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
+void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 #ifdef __KVM_HAVE_VCPU_EVENTS
 void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
                     struct kvm_vcpu_events *events);
index 41cf45416060fc6e9ce04fcb2d92d7511e62abb0..a6dd0401eb50c851da8d6f82448cd3cc85e50233 100644 (file)
@@ -1373,6 +1373,42 @@ int _vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_sregs *sregs)
        return ioctl(vcpu->fd, KVM_SET_SREGS, sregs);
 }
 
+void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_GET_FPU, fpu);
+       TEST_ASSERT(ret == 0, "KVM_GET_FPU failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_FPU, fpu);
+       TEST_ASSERT(ret == 0, "KVM_SET_FPU failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, reg);
+       TEST_ASSERT(ret == 0, "KVM_GET_ONE_REG failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, reg);
+       TEST_ASSERT(ret == 0, "KVM_SET_ONE_REG failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
 /*
  * VCPU Ioctl
  *
diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390x/resets.c
new file mode 100644 (file)
index 0000000..1485bc6
--- /dev/null
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test for s390x CPU resets
+ *
+ * Copyright (C) 2020, IBM
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+
+#define VCPU_ID 3
+#define LOCAL_IRQS 32
+
+struct kvm_s390_irq buf[VCPU_ID + LOCAL_IRQS];
+
+struct kvm_vm *vm;
+struct kvm_run *run;
+struct kvm_sync_regs *regs;
+static uint64_t regs_null[16];
+
+static uint64_t crs[16] = { 0x40000ULL,
+                           0x42000ULL,
+                           0, 0, 0, 0, 0,
+                           0x43000ULL,
+                           0, 0, 0, 0, 0,
+                           0x44000ULL,
+                           0, 0
+};
+
+static void guest_code_initial(void)
+{
+       /* Round toward 0 */
+       uint32_t fpc = 0x11;
+
+       /* Dirty registers */
+       asm volatile (
+               "       lctlg   0,15,%0\n"
+               "       sfpc    %1\n"
+               : : "Q" (crs), "d" (fpc));
+       GUEST_SYNC(0);
+}
+
+static void test_one_reg(uint64_t id, uint64_t value)
+{
+       struct kvm_one_reg reg;
+       uint64_t eval_reg;
+
+       reg.addr = (uintptr_t)&eval_reg;
+       reg.id = id;
+       vcpu_get_reg(vm, VCPU_ID, &reg);
+       TEST_ASSERT(eval_reg == value, "value == %s", value);
+}
+
+static void assert_noirq(void)
+{
+       struct kvm_s390_irq_state irq_state;
+       int irqs;
+
+       irq_state.len = sizeof(buf);
+       irq_state.buf = (unsigned long)buf;
+       irqs = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_GET_IRQ_STATE, &irq_state);
+       /*
+        * irqs contains the number of retrieved interrupts. Any interrupt
+        * (notably, the emergency call interrupt we have injected) should
+        * be cleared by the resets, so this should be 0.
+        */
+       TEST_ASSERT(irqs >= 0, "Could not fetch IRQs: errno %d\n", errno);
+       TEST_ASSERT(!irqs, "IRQ pending");
+}
+
+static void assert_clear(void)
+{
+       struct kvm_sregs sregs;
+       struct kvm_regs regs;
+       struct kvm_fpu fpu;
+
+       vcpu_regs_get(vm, VCPU_ID, &regs);
+       TEST_ASSERT(!memcmp(&regs.gprs, regs_null, sizeof(regs.gprs)), "grs == 0");
+
+       vcpu_sregs_get(vm, VCPU_ID, &sregs);
+       TEST_ASSERT(!memcmp(&sregs.acrs, regs_null, sizeof(sregs.acrs)), "acrs == 0");
+
+       vcpu_fpu_get(vm, VCPU_ID, &fpu);
+       TEST_ASSERT(!memcmp(&fpu.fprs, regs_null, sizeof(fpu.fprs)), "fprs == 0");
+}
+
+static void assert_initial(void)
+{
+       struct kvm_sregs sregs;
+       struct kvm_fpu fpu;
+
+       vcpu_sregs_get(vm, VCPU_ID, &sregs);
+       TEST_ASSERT(sregs.crs[0] == 0xE0UL, "cr0 == 0xE0");
+       TEST_ASSERT(sregs.crs[14] == 0xC2000000UL, "cr14 == 0xC2000000");
+       TEST_ASSERT(!memcmp(&sregs.crs[1], regs_null, sizeof(sregs.crs[1]) * 12),
+                   "cr1-13 == 0");
+       TEST_ASSERT(sregs.crs[15] == 0, "cr15 == 0");
+
+       vcpu_fpu_get(vm, VCPU_ID, &fpu);
+       TEST_ASSERT(!fpu.fpc, "fpc == 0");
+
+       test_one_reg(KVM_REG_S390_GBEA, 1);
+       test_one_reg(KVM_REG_S390_PP, 0);
+       test_one_reg(KVM_REG_S390_TODPR, 0);
+       test_one_reg(KVM_REG_S390_CPU_TIMER, 0);
+       test_one_reg(KVM_REG_S390_CLOCK_COMP, 0);
+}
+
+static void assert_normal(void)
+{
+       test_one_reg(KVM_REG_S390_PFTOKEN, KVM_S390_PFAULT_TOKEN_INVALID);
+       assert_noirq();
+}
+
+static void inject_irq(int cpu_id)
+{
+       struct kvm_s390_irq_state irq_state;
+       struct kvm_s390_irq *irq = &buf[0];
+       int irqs;
+
+       /* Inject IRQ */
+       irq_state.len = sizeof(struct kvm_s390_irq);
+       irq_state.buf = (unsigned long)buf;
+       irq->type = KVM_S390_INT_EMERGENCY;
+       irq->u.emerg.code = cpu_id;
+       irqs = _vcpu_ioctl(vm, cpu_id, KVM_S390_SET_IRQ_STATE, &irq_state);
+       TEST_ASSERT(irqs >= 0, "Error injecting EMERGENCY IRQ errno %d\n", errno);
+}
+
+static void test_normal(void)
+{
+       printf("Testing normal reset\n");
+       /* Create VM */
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_NORMAL_RESET, 0);
+       assert_normal();
+       kvm_vm_free(vm);
+}
+
+static void test_initial(void)
+{
+       printf("Testing initial reset\n");
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_INITIAL_RESET, 0);
+       assert_normal();
+       assert_initial();
+       kvm_vm_free(vm);
+}
+
+static void test_clear(void)
+{
+       printf("Testing clear reset\n");
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_CLEAR_RESET, 0);
+       assert_normal();
+       assert_initial();
+       assert_clear();
+       kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+       setbuf(stdout, NULL);   /* Tell stdout not to buffer its content */
+
+       test_initial();
+       if (kvm_check_cap(KVM_CAP_S390_VCPU_RESETS)) {
+               test_normal();
+               test_clear();
+       }
+       return 0;
+}