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