summaryrefslogtreecommitdiff
path: root/target/s390x/kvm.c
diff options
context:
space:
mode:
authorCollin Walling <walling@linux.ibm.com>2020-11-13 17:10:22 -0500
committerCornelia Huck <cohuck@redhat.com>2020-11-18 16:57:48 +0100
commite2c6cd567422bfa563be026b9741a1854aecdc06 (patch)
treed7a10886fbbd0732ba14bb79ba56fc1ff2892d13 /target/s390x/kvm.c
parentb696f2c6ba8c92ffb5eca49b88a5c7276d0a3e1e (diff)
downloadqemu-e2c6cd567422bfa563be026b9741a1854aecdc06.zip
s390/kvm: fix diag318 propagation and reset functionality
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>
Diffstat (limited to 'target/s390x/kvm.c')
-rw-r--r--target/s390x/kvm.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index baa070fdf7..b8385e6b95 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));
}
}