Blame SOURCES/kvm-s390-kvm-fix-diag318-propagation-and-reset-functiona.patch

c687bc
From a0ad4344984c50939be8c99371af0988551fb776 Mon Sep 17 00:00:00 2001
c687bc
From: Thomas Huth <thuth@redhat.com>
c687bc
Date: Fri, 20 Nov 2020 11:46:09 -0500
c687bc
Subject: [PATCH 17/18] s390/kvm: fix diag318 propagation and reset
c687bc
 functionality
c687bc
c687bc
RH-Author: Thomas Huth <thuth@redhat.com>
c687bc
Message-id: <20201120114609.408610-2-thuth@redhat.com>
c687bc
Patchwork-id: 99787
c687bc
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/1] s390/kvm: fix diag318 propagation and reset functionality
c687bc
Bugzilla: 1659412
c687bc
RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
c687bc
RH-Acked-by: Cornelia Huck <cohuck@redhat.com>
c687bc
RH-Acked-by: David Hildenbrand <david@redhat.com>
c687bc
c687bc
From: Collin Walling <walling@linux.ibm.com>
c687bc
c687bc
The Control Program Name Code (CPNC) portion of the diag318
c687bc
info must be set within the SIE block of each VCPU in the
c687bc
configuration. The handler will iterate through each VCPU
c687bc
and dirty the diag318_info reg to be synced with KVM on a
c687bc
subsequent sync_regs call.
c687bc
c687bc
Additionally, the diag318 info resets must be handled via
c687bc
userspace. As such, QEMU will reset this value for each
c687bc
VCPU during a modified clear, load normal, and load clear
c687bc
reset event.
c687bc
c687bc
Fixes: fabdada9357b ("s390: guest support for diagnose 0x318")
c687bc
Signed-off-by: Collin Walling <walling@linux.ibm.com>
c687bc
Message-Id: <20201113221022.257054-1-walling@linux.ibm.com>
c687bc
Reviewed-by: Thomas Huth <thuth@redhat.com>
c687bc
Reviewed-by: Janosch Frank <frankja@de.ibm.com>
c687bc
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
c687bc
(cherry picked from commit e2c6cd567422bfa563be026b9741a1854aecdc06)
c687bc
Signed-off-by: Thomas Huth <thuth@redhat.com>
c687bc
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
c687bc
---
c687bc
 hw/s390x/s390-virtio-ccw.c |  4 ++++
c687bc
 target/s390x/cpu.c         |  7 +++++++
c687bc
 target/s390x/cpu.h         |  1 +
c687bc
 target/s390x/kvm-stub.c    |  4 ++++
c687bc
 target/s390x/kvm.c         | 22 +++++++++++++++++-----
c687bc
 target/s390x/kvm_s390x.h   |  1 +
c687bc
 6 files changed, 34 insertions(+), 5 deletions(-)
c687bc
c687bc
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
c687bc
index e6ed13b649a..5905d2b7adc 100644
c687bc
--- a/hw/s390x/s390-virtio-ccw.c
c687bc
+++ b/hw/s390x/s390-virtio-ccw.c
c687bc
@@ -489,6 +489,10 @@ static void s390_machine_reset(MachineState *machine)
c687bc
     default:
c687bc
         g_assert_not_reached();
c687bc
     }
c687bc
+
c687bc
+    CPU_FOREACH(t) {
c687bc
+        run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
c687bc
+    }
c687bc
     s390_ipl_clear_reset_request();
c687bc
 }
c687bc
 
c687bc
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
c687bc
index 371b91b2d72..820cab96e12 100644
c687bc
--- a/target/s390x/cpu.c
c687bc
+++ b/target/s390x/cpu.c
c687bc
@@ -445,6 +445,13 @@ void s390_enable_css_support(S390CPU *cpu)
c687bc
         kvm_s390_enable_css_support(cpu);
c687bc
     }
c687bc
 }
c687bc
+
c687bc
+void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
c687bc
+{
c687bc
+    if (kvm_enabled()) {
c687bc
+        kvm_s390_set_diag318(cs, arg.host_ulong);
c687bc
+    }
c687bc
+}
c687bc
 #endif
c687bc
 
c687bc
 static gchar *s390_gdb_arch_name(CPUState *cs)
c687bc
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
c687bc
index 1dc21cd311d..83a23a11b96 100644
c687bc
--- a/target/s390x/cpu.h
c687bc
+++ b/target/s390x/cpu.h
c687bc
@@ -774,6 +774,7 @@ int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit);
c687bc
 void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
c687bc
 void s390_cmma_reset(void);
c687bc
 void s390_enable_css_support(S390CPU *cpu);
c687bc
+void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
c687bc
 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
c687bc
                                 int vq, bool assign);
c687bc
 #ifndef CONFIG_USER_ONLY
c687bc
diff --git a/target/s390x/kvm-stub.c b/target/s390x/kvm-stub.c
c687bc
index aa185017a2a..9970b5a8c70 100644
c687bc
--- a/target/s390x/kvm-stub.c
c687bc
+++ b/target/s390x/kvm-stub.c
c687bc
@@ -120,3 +120,7 @@ void kvm_s390_stop_interrupt(S390CPU *cpu)
c687bc
 void kvm_s390_restart_interrupt(S390CPU *cpu)
c687bc
 {
c687bc
 }
c687bc
+
c687bc
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
c687bc
+{
c687bc
+}
c687bc
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
c687bc
index 6edb52f6d25..8d4406124b9 100644
c687bc
--- a/target/s390x/kvm.c
c687bc
+++ b/target/s390x/kvm.c
c687bc
@@ -1611,10 +1611,23 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct kvm_run *run)
c687bc
     return -ENOENT;
c687bc
 }
c687bc
 
c687bc
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
c687bc
+{
c687bc
+    CPUS390XState *env = &S390_CPU(cs)->env;
c687bc
+
c687bc
+    /* Feat bit is set only if KVM supports sync for diag318 */
c687bc
+    if (s390_has_feat(S390_FEAT_DIAG_318)) {
c687bc
+        env->diag318_info = diag318_info;
c687bc
+        cs->kvm_run->s.regs.diag318 = diag318_info;
c687bc
+        cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
c687bc
+    }
c687bc
+}
c687bc
+
c687bc
 static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
c687bc
 {
c687bc
     uint64_t reg = (run->s390_sieic.ipa & 0x00f0) >> 4;
c687bc
     uint64_t diag318_info = run->s.regs.gprs[reg];
c687bc
+    CPUState *t;
c687bc
 
c687bc
     /*
c687bc
      * DIAG 318 can only be enabled with KVM support. As such, let's
c687bc
@@ -1622,13 +1635,12 @@ static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
c687bc
      */
c687bc
     if (!s390_has_feat(S390_FEAT_DIAG_318)) {
c687bc
         kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
c687bc
+        return;
c687bc
     }
c687bc
 
c687bc
-    cpu->env.diag318_info = diag318_info;
c687bc
-
c687bc
-    if (can_sync_regs(CPU(cpu), KVM_SYNC_DIAG318)) {
c687bc
-        run->s.regs.diag318 = diag318_info;
c687bc
-        run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
c687bc
+    CPU_FOREACH(t) {
c687bc
+        run_on_cpu(t, s390_do_cpu_set_diag318,
c687bc
+                   RUN_ON_CPU_HOST_ULONG(diag318_info));
c687bc
     }
c687bc
 }
c687bc
 
c687bc
diff --git a/target/s390x/kvm_s390x.h b/target/s390x/kvm_s390x.h
c687bc
index 6ab17c81b73..25bbe98b251 100644
c687bc
--- a/target/s390x/kvm_s390x.h
c687bc
+++ b/target/s390x/kvm_s390x.h
c687bc
@@ -45,5 +45,6 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
c687bc
 void kvm_s390_crypto_reset(void);
c687bc
 void kvm_s390_restart_interrupt(S390CPU *cpu);
c687bc
 void kvm_s390_stop_interrupt(S390CPU *cpu);
c687bc
+void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info);
c687bc
 
c687bc
 #endif /* KVM_S390X_H */
c687bc
-- 
c687bc
2.27.0
c687bc