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