77c23f
From e11643b5363262e9f809762a1f2bb5c4a8f26c2a Mon Sep 17 00:00:00 2001
77c23f
From: Thomas Huth <thuth@redhat.com>
77c23f
Date: Fri, 29 May 2020 05:53:56 -0400
77c23f
Subject: [PATCH 14/42] s390x: Add missing vcpu reset functions
77c23f
MIME-Version: 1.0
77c23f
Content-Type: text/plain; charset=UTF-8
77c23f
Content-Transfer-Encoding: 8bit
77c23f
77c23f
RH-Author: Thomas Huth <thuth@redhat.com>
77c23f
Message-id: <20200529055420.16855-15-thuth@redhat.com>
77c23f
Patchwork-id: 97023
77c23f
O-Subject: [RHEL-8.3.0 qemu-kvm PATCH v2 14/38] s390x: Add missing vcpu reset functions
77c23f
Bugzilla: 1828317
77c23f
RH-Acked-by: Claudio Imbrenda <cimbrend@redhat.com>
77c23f
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
77c23f
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
77c23f
RH-Acked-by: David Hildenbrand <david@redhat.com>
77c23f
77c23f
From: Janosch Frank <frankja@linux.ibm.com>
77c23f
77c23f
Up to now we only had an ioctl to reset vcpu data QEMU couldn't reach
77c23f
for the initial reset, which was also called for the clear reset. To
77c23f
be architecture compliant, we also need to clear local interrupts on a
77c23f
normal reset.
77c23f
77c23f
Because of this and the upcoming protvirt support we need to add
77c23f
ioctls for the missing clear and normal resets.
77c23f
77c23f
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
77c23f
Reviewed-by: Thomas Huth <thuth@redhat.com>
77c23f
Acked-by: David Hildenbrand <david@redhat.com>
77c23f
Message-Id: <20200214151636.8764-3-frankja@linux.ibm.com>
77c23f
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
77c23f
(cherry picked from commit b91a03946e0f65ddd22927dd80ca1276bf89c5af)
77c23f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
77c23f
---
77c23f
 target/s390x/cpu.c       | 14 ++++++++++++--
77c23f
 target/s390x/kvm-stub.c  | 10 +++++++++-
77c23f
 target/s390x/kvm.c       | 42 ++++++++++++++++++++++++++++++++--------
77c23f
 target/s390x/kvm_s390x.h |  4 +++-
77c23f
 4 files changed, 58 insertions(+), 12 deletions(-)
77c23f
77c23f
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
77c23f
index e538a4a3e2..c0dd502b84 100644
77c23f
--- a/target/s390x/cpu.c
77c23f
+++ b/target/s390x/cpu.c
77c23f
@@ -144,8 +144,18 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
77c23f
     }
77c23f
 
77c23f
     /* Reset state inside the kernel that we cannot access yet from QEMU. */
77c23f
-    if (kvm_enabled() && type != S390_CPU_RESET_NORMAL) {
77c23f
-        kvm_s390_reset_vcpu(cpu);
77c23f
+    if (kvm_enabled()) {
77c23f
+        switch (type) {
77c23f
+        case S390_CPU_RESET_CLEAR:
77c23f
+            kvm_s390_reset_vcpu_clear(cpu);
77c23f
+            break;
77c23f
+        case S390_CPU_RESET_INITIAL:
77c23f
+            kvm_s390_reset_vcpu_initial(cpu);
77c23f
+            break;
77c23f
+        case S390_CPU_RESET_NORMAL:
77c23f
+            kvm_s390_reset_vcpu_normal(cpu);
77c23f
+            break;
77c23f
+        }
77c23f
     }
77c23f
 }
77c23f
 
77c23f
diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
77c23f
index 5152e2bdf1..c4cd497f85 100644
77c23f
--- a/target/s390x/kvm-stub.c
77c23f
+++ b/target/s390x/kvm-stub.c
77c23f
@@ -83,7 +83,15 @@ void kvm_s390_cmma_reset(void)
77c23f
 {
77c23f
 }
77c23f
 
77c23f
-void kvm_s390_reset_vcpu(S390CPU *cpu)
77c23f
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
77c23f
+{
77c23f
+}
77c23f
+
77c23f
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
77c23f
+{
77c23f
+}
77c23f
+
77c23f
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
77c23f
 {
77c23f
 }
77c23f
 
77c23f
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
77c23f
index 1c5bc7a2f9..75d82af6fc 100644
77c23f
--- a/target/s390x/kvm.c
77c23f
+++ b/target/s390x/kvm.c
77c23f
@@ -151,6 +151,7 @@ static int cap_s390_irq;
77c23f
 static int cap_ri;
77c23f
 static int cap_gs;
77c23f
 static int cap_hpage_1m;
77c23f
+static int cap_vcpu_resets;
77c23f
 
77c23f
 static int active_cmma;
77c23f
 
77c23f
@@ -342,6 +343,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
77c23f
     cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
77c23f
     cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
77c23f
     cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ);
77c23f
+    cap_vcpu_resets = kvm_check_extension(s, KVM_CAP_S390_VCPU_RESETS);
77c23f
 
77c23f
     if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
77c23f
         || !kvm_check_extension(s, KVM_CAP_S390_COW)) {
77c23f
@@ -403,17 +405,41 @@ int kvm_arch_destroy_vcpu(CPUState *cs)
77c23f
     return 0;
77c23f
 }
77c23f
 
77c23f
-void kvm_s390_reset_vcpu(S390CPU *cpu)
77c23f
+static void kvm_s390_reset_vcpu(S390CPU *cpu, unsigned long type)
77c23f
 {
77c23f
     CPUState *cs = CPU(cpu);
77c23f
 
77c23f
-    /* The initial reset call is needed here to reset in-kernel
77c23f
-     * vcpu data that we can't access directly from QEMU
77c23f
-     * (i.e. with older kernels which don't support sync_regs/ONE_REG).
77c23f
-     * Before this ioctl cpu_synchronize_state() is called in common kvm
77c23f
-     * code (kvm-all) */
77c23f
-    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL)) {
77c23f
-        error_report("Initial CPU reset failed on CPU %i", cs->cpu_index);
77c23f
+    /*
77c23f
+     * The reset call is needed here to reset in-kernel vcpu data that
77c23f
+     * we can't access directly from QEMU (i.e. with older kernels
77c23f
+     * which don't support sync_regs/ONE_REG).  Before this ioctl
77c23f
+     * cpu_synchronize_state() is called in common kvm code
77c23f
+     * (kvm-all).
77c23f
+     */
77c23f
+    if (kvm_vcpu_ioctl(cs, type)) {
77c23f
+        error_report("CPU reset failed on CPU %i type %lx",
77c23f
+                     cs->cpu_index, type);
77c23f
+    }
77c23f
+}
77c23f
+
77c23f
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu)
77c23f
+{
77c23f
+    kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
77c23f
+}
77c23f
+
77c23f
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu)
77c23f
+{
77c23f
+    if (cap_vcpu_resets) {
77c23f
+        kvm_s390_reset_vcpu(cpu, KVM_S390_CLEAR_RESET);
77c23f
+    } else {
77c23f
+        kvm_s390_reset_vcpu(cpu, KVM_S390_INITIAL_RESET);
77c23f
+    }
77c23f
+}
77c23f
+
77c23f
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu)
77c23f
+{
77c23f
+    if (cap_vcpu_resets) {
77c23f
+        kvm_s390_reset_vcpu(cpu, KVM_S390_NORMAL_RESET);
77c23f
     }
77c23f
 }
77c23f
 
77c23f
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
77c23f
index caf985955b..0b21789796 100644
77c23f
--- a/target/s390x/kvm_s390x.h
77c23f
+++ b/target/s390x/kvm_s390x.h
77c23f
@@ -34,7 +34,9 @@ int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
77c23f
                                     int vq, bool assign);
77c23f
 int kvm_s390_cmma_active(void);
77c23f
 void kvm_s390_cmma_reset(void);
77c23f
-void kvm_s390_reset_vcpu(S390CPU *cpu);
77c23f
+void kvm_s390_reset_vcpu_clear(S390CPU *cpu);
77c23f
+void kvm_s390_reset_vcpu_normal(S390CPU *cpu);
77c23f
+void kvm_s390_reset_vcpu_initial(S390CPU *cpu);
77c23f
 int kvm_s390_set_mem_limit(uint64_t new_limit, uint64_t *hw_limit);
77c23f
 void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
77c23f
 void kvm_s390_crypto_reset(void);
77c23f
-- 
77c23f
2.27.0
77c23f