From: Cornelia Huck <cornelia.huck@de.ibm.com>
To: qemu-devel <qemu-devel@nongnu.org>, KVM <kvm@vger.kernel.org>,
linux-s390 <linux-s390@vger.kernel.org>
Cc: Carsten Otte <cotte@de.ibm.com>,
Anthony Liguori <aliguori@us.ibm.com>,
Gleb Natapov <gleb@redhat.com>,
Sebastian Ott <sebott@linux.vnet.ibm.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
Heiko Carstens <heiko.carstens@de.ibm.com>,
Alexander Graf <agraf@suse.de>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [Qemu-devel] [PATCH 6/8] s390: Wire up channel I/O in kvm.
Date: Fri, 7 Dec 2012 13:50:24 +0100 [thread overview]
Message-ID: <1354884626-15060-7-git-send-email-cornelia.huck@de.ibm.com> (raw)
In-Reply-To: <1354884626-15060-1-git-send-email-cornelia.huck@de.ibm.com>
Trigger the code for our virtual css in case of instruction
intercepts for I/O instructions.
Handle the tsch exit for the subchannel-related part of tsch.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
---
target-s390x/cpu.h | 11 +++
target-s390x/kvm.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 244 insertions(+), 13 deletions(-)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index eb24c6b..1d21ca8 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1178,6 +1178,13 @@ uint32_t set_cc_nz_f64(float64 v);
/* misc_helper.c */
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+#ifdef CONFIG_KVM
+int kvm_s390_io_interrupt(CPUS390XState *env, uint16_t subchannel_id,
+ uint16_t subchannel_nr, uint32_t io_int_parm,
+ uint32_t io_int_word);
+int kvm_s390_crw_mchk(CPUS390XState *env);
+void kvm_s390_enable_css_support(CPUS390XState *env);
+#else
static inline int kvm_s390_io_interrupt(CPUS390XState *env,
uint16_t subchannel_id,
uint16_t subchannel_nr,
@@ -1190,6 +1197,10 @@ static inline int kvm_s390_crw_mchk(CPUS390XState *env)
{
return -EOPNOTSUPP;
}
+static inline void kvm_s390_enable_css_support(CPUS390XState *env)
+{
+}
+#endif
static inline void s390_io_interrupt(CPUS390XState *env,
uint16_t subchannel_id,
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 94de764..c9a4a7d 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -30,6 +30,7 @@
#include "kvm.h"
#include "cpu.h"
#include "device_tree.h"
+#include "ioinst.h"
/* #define DEBUG_KVM */
@@ -43,9 +44,27 @@
#define IPA0_DIAG 0x8300
#define IPA0_SIGP 0xae00
-#define IPA0_PRIV 0xb200
+#define IPA0_B2 0xb200
+#define IPA0_B9 0xb900
+#define IPA0_EB 0xeb00
#define PRIV_SCLP_CALL 0x20
+#define PRIV_CSCH 0x30
+#define PRIV_HSCH 0x31
+#define PRIV_MSCH 0x32
+#define PRIV_SSCH 0x33
+#define PRIV_STSCH 0x34
+#define PRIV_TSCH 0x35
+#define PRIV_TPI 0x36
+#define PRIV_SAL 0x37
+#define PRIV_RSCH 0x38
+#define PRIV_STCRW 0x39
+#define PRIV_STCPS 0x3a
+#define PRIV_RCHP 0x3b
+#define PRIV_SCHM 0x3c
+#define PRIV_CHSC 0x5f
+#define PRIV_SIGA 0x74
+#define PRIV_XSCH 0x76
#define DIAG_KVM_HYPERCALL 0x500
#define DIAG_KVM_BREAKPOINT 0x501
@@ -350,10 +369,120 @@ static int kvm_sclp_service_call(CPUS390XState *env, struct kvm_run *run,
return 0;
}
-static int handle_priv(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1)
+static int kvm_handle_css_inst(CPUS390XState *env, struct kvm_run *run,
+ uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
+{
+ int r = 0;
+ int no_cc = 0;
+
+ if (ipa0 != 0xb2) {
+ /* Not handled for now. */
+ return -1;
+ }
+ cpu_synchronize_state(env);
+ switch (ipa1) {
+ case PRIV_XSCH:
+ r = ioinst_handle_xsch(env, env->regs[1]);
+ break;
+ case PRIV_CSCH:
+ r = ioinst_handle_csch(env, env->regs[1]);
+ break;
+ case PRIV_HSCH:
+ r = ioinst_handle_hsch(env, env->regs[1]);
+ break;
+ case PRIV_MSCH:
+ r = ioinst_handle_msch(env, env->regs[1], run->s390_sieic.ipb);
+ break;
+ case PRIV_SSCH:
+ r = ioinst_handle_ssch(env, env->regs[1], run->s390_sieic.ipb);
+ break;
+ case PRIV_STCRW:
+ r = ioinst_handle_stcrw(env, run->s390_sieic.ipb);
+ break;
+ case PRIV_STSCH:
+ r = ioinst_handle_stsch(env, env->regs[1], run->s390_sieic.ipb);
+ break;
+ case PRIV_TSCH:
+ /* We should only get tsch via KVM_EXIT_S390_TSCH. */
+ fprintf(stderr, "Spurious tsch intercept\n");
+ break;
+ case PRIV_CHSC:
+ r = ioinst_handle_chsc(env, run->s390_sieic.ipb);
+ break;
+ case PRIV_TPI:
+ /* This should have been handled by kvm already. */
+ fprintf(stderr, "Spurious tpi intercept\n");
+ break;
+ case PRIV_SCHM:
+ no_cc = 1;
+ r = ioinst_handle_schm(env, env->regs[1], env->regs[2],
+ run->s390_sieic.ipb);
+ break;
+ case PRIV_RSCH:
+ r = ioinst_handle_rsch(env, env->regs[1]);
+ break;
+ case PRIV_RCHP:
+ r = ioinst_handle_rchp(env, env->regs[1]);
+ break;
+ case PRIV_STCPS:
+ /* We do not provide this instruction, it is suppressed. */
+ no_cc = 1;
+ r = 0;
+ break;
+ case PRIV_SAL:
+ no_cc = 1;
+ r = ioinst_handle_sal(env, env->regs[1]);
+ break;
+ default:
+ r = -1;
+ break;
+ }
+
+ if (r >= 0) {
+ if (!no_cc) {
+ setcc(env, r);
+ }
+ r = 0;
+ } else if (r < -1) {
+ r = 0;
+ }
+ return r;
+}
+
+static int is_ioinst(uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
+{
+ int ret = 0;
+
+ switch (ipa0) {
+ case 0xb2:
+ if (((ipa1 >= 0x30) && (ipa1 <= 0x3c)) ||
+ (ipa1 == 0x5f) ||
+ (ipa1 == 0x74) ||
+ (ipa1 == 0x76)) {
+ ret = 1;
+ }
+ break;
+ case 0xb9:
+ if (ipa1 == 0x9c) {
+ ret = 1;
+ }
+ break;
+ case 0xeb:
+ if (ipb == 0x8a) {
+ ret = 1;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static int handle_priv(CPUS390XState *env, struct kvm_run *run,
+ uint8_t ipa0, uint8_t ipa1)
{
int r = 0;
uint16_t ipbh0 = (run->s390_sieic.ipb & 0xffff0000) >> 16;
+ uint8_t ipb = run->s390_sieic.ipb & 0xff;
dprintf("KVM: PRIV: %d\n", ipa1);
switch (ipa1) {
@@ -361,8 +490,16 @@ static int handle_priv(CPUS390XState *env, struct kvm_run *run, uint8_t ipa1)
r = kvm_sclp_service_call(env, run, ipbh0);
break;
default:
- dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
- r = -1;
+ if (is_ioinst(ipa0, ipa1, ipb)) {
+ r = kvm_handle_css_inst(env, run, ipa0, ipa1, ipb);
+ if (r == -1) {
+ setcc(env, 3);
+ r = 0;
+ }
+ } else {
+ dprintf("KVM: unknown PRIV: 0x%x\n", ipa1);
+ r = -1;
+ }
break;
}
@@ -500,15 +637,17 @@ static int handle_instruction(CPUS390XState *env, struct kvm_run *run)
dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb);
switch (ipa0) {
- case IPA0_PRIV:
- r = handle_priv(env, run, ipa1);
- break;
- case IPA0_DIAG:
- r = handle_diag(env, run, ipb_code);
- break;
- case IPA0_SIGP:
- r = handle_sigp(env, run, ipa1);
- break;
+ case IPA0_B2:
+ case IPA0_B9:
+ case IPA0_EB:
+ r = handle_priv(env, run, ipa0 >> 8, ipa1);
+ break;
+ case IPA0_DIAG:
+ r = handle_diag(env, run, ipb_code);
+ break;
+ case IPA0_SIGP:
+ r = handle_sigp(env, run, ipa1);
+ break;
}
if (r < 0) {
@@ -565,6 +704,38 @@ static int handle_intercept(CPUS390XState *env)
return r;
}
+static int handle_tsch(CPUS390XState *env, struct kvm_run *run, int dequeued,
+ uint16_t subchannel_id, uint16_t subchannel_nr,
+ uint32_t io_int_parm, uint32_t io_int_word)
+{
+ int ret;
+
+ cpu_synchronize_state(env);
+ ret = ioinst_handle_tsch(env, env->regs[1], run->s390_tsch.ipb);
+ if (ret >= 0) {
+ /* Success; set condition code. */
+ setcc(env, ret);
+ ret = 0;
+ } else if (ret < -1) {
+ /*
+ * Failure.
+ * If an I/O interrupt had been dequeued, we have to reinject it.
+ */
+ if (dequeued) {
+ uint32_t type = ((subchannel_id & 0xff00) << 24) |
+ ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
+
+ kvm_s390_interrupt_internal(env, type,
+ ((uint32_t)subchannel_id << 16)
+ | subchannel_nr,
+ ((uint64_t)io_int_parm << 32)
+ | io_int_word, 1);
+ }
+ ret = 0;
+ }
+ return ret;
+}
+
int kvm_arch_handle_exit(CPUS390XState *env, struct kvm_run *run)
{
int ret = 0;
@@ -576,6 +747,13 @@ int kvm_arch_handle_exit(CPUS390XState *env, struct kvm_run *run)
case KVM_EXIT_S390_RESET:
qemu_system_reset_request();
break;
+ case KVM_EXIT_S390_TSCH:
+ ret = handle_tsch(env, run, run->s390_tsch.dequeued,
+ run->s390_tsch.subchannel_id,
+ run->s390_tsch.subchannel_nr,
+ run->s390_tsch.io_int_parm,
+ run->s390_tsch.io_int_word);
+ break;
default:
fprintf(stderr, "Unknown KVM exit: %d\n", run->exit_reason);
break;
@@ -601,3 +779,45 @@ int kvm_arch_on_sigbus(int code, void *addr)
{
return 1;
}
+
+int kvm_s390_io_interrupt(CPUS390XState *env, uint16_t subchannel_id,
+ uint16_t subchannel_nr, uint32_t io_int_parm,
+ uint32_t io_int_word)
+{
+ uint32_t type;
+
+ if (!kvm_enabled()) {
+ return -EOPNOTSUPP;
+ }
+
+ type = ((subchannel_id & 0xff00) << 24) |
+ ((subchannel_id & 0x00060) << 22) | (subchannel_nr << 16);
+ kvm_s390_interrupt_internal(env, type,
+ ((uint32_t)subchannel_id << 16) | subchannel_nr,
+ ((uint64_t)io_int_parm << 32) | io_int_word, 1);
+ return 0;
+}
+
+int kvm_s390_crw_mchk(CPUS390XState *env)
+{
+ if (!kvm_enabled()) {
+ return -EOPNOTSUPP;
+ }
+
+ kvm_s390_interrupt_internal(env, KVM_S390_MCHK, 1 << 28,
+ 0x00400f1d40330000, 1);
+ return 0;
+}
+
+void kvm_s390_enable_css_support(CPUS390XState *env)
+{
+ struct kvm_enable_cap cap = {};
+ int r;
+
+ /* Activate host kernel channel subsystem support. */
+ if (kvm_enabled()) {
+ cap.cap = KVM_CAP_S390_CSS_SUPPORT;
+ r = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap);
+ assert(r == 0);
+ }
+}
--
1.7.12.4
next prev parent reply other threads:[~2012-12-07 12:50 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-07 12:50 [Qemu-devel] [RFC PATCH v4 0/8] s390: channel I/O support in qemu Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 1/8] Update linux headers Cornelia Huck
2012-12-07 13:01 ` Peter Maydell
2012-12-07 14:08 ` Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 2/8] s390: Channel I/O basic defintions Cornelia Huck
2012-12-10 8:07 ` Alexander Graf
2012-12-10 10:18 ` Cornelia Huck
2012-12-11 10:27 ` Alexander Graf
2012-12-11 12:48 ` Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 3/8] s390: I/O interrupt and machine check injection Cornelia Huck
2012-12-10 8:20 ` Alexander Graf
2012-12-10 10:27 ` Cornelia Huck
2012-12-11 0:26 ` Rob Landley
2012-12-11 12:17 ` Cornelia Huck
2012-12-11 10:29 ` Alexander Graf
2012-12-11 12:50 ` Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 4/8] s390: Add channel I/O instructions Cornelia Huck
2012-12-10 9:00 ` Alexander Graf
2012-12-10 9:18 ` Cornelia Huck
2012-12-11 10:18 ` Alexander Graf
2012-12-11 12:53 ` Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 5/8] s390: Virtual channel subsystem support Cornelia Huck
2012-12-07 12:50 ` Cornelia Huck [this message]
2012-12-10 9:40 ` [Qemu-devel] [PATCH 6/8] s390: Wire up channel I/O in kvm Alexander Graf
2012-12-10 10:29 ` Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 7/8] s390-virtio: Factor out some initialization code Cornelia Huck
2012-12-07 12:50 ` [Qemu-devel] [PATCH 8/8] s390: Add new channel I/O based virtio transport Cornelia Huck
2012-12-11 10:53 ` Alexander Graf
2012-12-11 12:06 ` Christian Borntraeger
2012-12-12 0:38 ` Alexander Graf
2012-12-11 13:03 ` Cornelia Huck
2012-12-12 0:39 ` Alexander Graf
2013-01-16 13:24 ` Alexander Graf
2013-01-16 13:53 ` Alexander Graf
2013-01-16 13:58 ` Cornelia Huck
2013-01-16 16:46 ` Richard Henderson
2013-01-16 17:05 ` Alexander Graf
2012-12-10 8:02 ` [Qemu-devel] [RFC PATCH v4 0/8] s390: channel I/O support in qemu Alexander Graf
2012-12-10 10:34 ` Cornelia Huck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1354884626-15060-7-git-send-email-cornelia.huck@de.ibm.com \
--to=cornelia.huck@de.ibm.com \
--cc=agraf@suse.de \
--cc=aliguori@us.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=cotte@de.ibm.com \
--cc=gleb@redhat.com \
--cc=heiko.carstens@de.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=schwidefsky@de.ibm.com \
--cc=sebott@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).