summaryrefslogtreecommitdiff
path: root/target/s390x/kvm.c
diff options
context:
space:
mode:
authorJanosch Frank <frankja@linux.ibm.com>2020-03-19 09:19:14 -0400
committerCornelia Huck <cohuck@redhat.com>2020-04-29 14:31:32 +0200
commit0f73c5b30b8ba6c0828608be496d2f59a5427539 (patch)
tree1f972b6b4ab69818fedb4cf41c5ecaa9026790d2 /target/s390x/kvm.c
parent7c713b8acb70fb61f9650f8a7702dec546752bb6 (diff)
downloadqemu-0f73c5b30b8ba6c0828608be496d2f59a5427539.zip
s390x: protvirt: SCLP interpretation
SCLP for a protected guest is done over the SIDAD, so we need to use the s390_cpu_pv_mem_* functions to access the SIDAD instead of guest memory when reading/writing SCBs. To not confuse the sclp emulation, we set 0x4000 as the SCCB address, since the function that injects the sclp external interrupt would reject a zero sccb address. Signed-off-by: Janosch Frank <frankja@linux.ibm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Message-Id: <20200319131921.2367-10-frankja@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/kvm.c')
-rw-r--r--target/s390x/kvm.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c
index e0b61680ab..870dd1b52b 100644
--- a/target/s390x/kvm.c
+++ b/target/s390x/kvm.c
@@ -1233,12 +1233,27 @@ static void kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
sccb = env->regs[ipbh0 & 0xf];
code = env->regs[(ipbh0 & 0xf0) >> 4];
- r = sclp_service_call(env, sccb, code);
- if (r < 0) {
- kvm_s390_program_interrupt(cpu, -r);
- return;
+ switch (run->s390_sieic.icptcode) {
+ case ICPT_PV_INSTR_NOTIFICATION:
+ g_assert(s390_is_pv());
+ /* The notification intercepts are currently handled by KVM */
+ error_report("unexpected SCLP PV notification");
+ exit(1);
+ break;
+ case ICPT_PV_INSTR:
+ g_assert(s390_is_pv());
+ sclp_service_call_protected(env, sccb, code);
+ /* Setting the CC is done by the Ultravisor. */
+ break;
+ case ICPT_INSTRUCTION:
+ g_assert(!s390_is_pv());
+ r = sclp_service_call(env, sccb, code);
+ if (r < 0) {
+ kvm_s390_program_interrupt(cpu, -r);
+ return;
+ }
+ setcc(cpu, r);
}
- setcc(cpu, r);
}
static int handle_b2(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)