Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20141105' into staging Several bugfixes for s390x: - instruction decoding and sparse warning in kvm - overlong input and hangs in the sclp consoles # gpg: Signature made Wed 05 Nov 2014 15:42:14 GMT using RSA key ID C6F02FAF # gpg: Good signature from "Cornelia Huck <huckc@linux.vnet.ibm.com>" # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" * remotes/cohuck/tags/s390x-20141105: s390x/sclpconsole: Avoid hanging SCLP ASCII console s390x/sclpconsole-lm: Fix hanging SCLP line mode console s390x/sclpconsole-lm: truncate input if line is too long s390x/kvm: Fix warning from sparse s390x/kvm: Fix opcode decoding for eb instruction handler Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index 80dd0a9..a9f5e62 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c
@@ -52,7 +52,8 @@ * event_pending is set when a newline character is encountered * * The maximum command line length is limited by the maximum - * space available in an SCCB + * space available in an SCCB. Line mode console input is sent + * truncated to the guest in case it doesn't fit into the SCCB. */ static int chr_can_read(void *opaque) @@ -61,10 +62,8 @@ if (scon->event.event_pending) { return 0; - } else if (SIZE_CONSOLE_BUFFER - scon->length) { - return 1; } - return 0; + return 1; } static void chr_read(void *opaque, const uint8_t *buf, int size) @@ -78,6 +77,10 @@ sclp_service_interrupt(0); return; } + if (scon->length == SIZE_CONSOLE_BUFFER) { + /* Eat the character, but still process CR and LF. */ + return; + } scon->buf[scon->length] = *buf; scon->length += 1; if (scon->echo) { @@ -125,6 +128,7 @@ cons->length = 0; /* data provided and no more data pending */ event->event_pending = false; + qemu_notify_event(); return 0; }
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index fca105d..79891df 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c
@@ -36,6 +36,7 @@ uint32_t iov_bs; /* offset in buf for char layer read operation */ uint32_t iov_data_len; /* length of byte stream in buffer */ uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */ + bool notify; /* qemu_notify_event() req'd if true */ } SCLPConsole; /* character layer call-back functions */ @@ -44,8 +45,12 @@ static int chr_can_read(void *opaque) { SCLPConsole *scon = opaque; + int avail = SIZE_BUFFER_VT220 - scon->iov_data_len; - return SIZE_BUFFER_VT220 - scon->iov_data_len; + if (avail == 0) { + scon->notify = true; + } + return avail; } /* Send data from a char device over to the guest */ @@ -113,6 +118,10 @@ cons->iov_sclp += avail; /* more data pending */ } + if (cons->notify) { + cons->notify = false; + qemu_notify_event(); + } } static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, @@ -229,6 +238,7 @@ scon->iov_bs = 0; scon->iov_data_len = 0; scon->iov_sclp_rest = 0; + scon->notify = false; } static int console_exit(SCLPEvent *event)
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 5b10a25..d247471 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c
@@ -827,18 +827,18 @@ return r; } -static int handle_eb(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1) +static int handle_eb(S390CPU *cpu, struct kvm_run *run, uint8_t ipbl) { int r = 0; - switch (ipa1) { + switch (ipbl) { case PRIV_EB_SQBS: /* just inject exception */ r = -1; break; default: r = -1; - DPRINTF("KVM: unhandled PRIV: 0xeb%x\n", ipa1); + DPRINTF("KVM: unhandled PRIV: 0xeb%x\n", ipbl); break; } @@ -1039,7 +1039,7 @@ r = handle_b9(cpu, run, ipa1); break; case IPA0_EB: - r = handle_eb(cpu, run, ipa1); + r = handle_eb(cpu, run, run->s390_sieic.ipb & 0xff); break; case IPA0_DIAG: r = handle_diag(cpu, run, run->s390_sieic.ipb); @@ -1272,7 +1272,7 @@ struct kvm_s390_irq irq = { .type = KVM_S390_MCHK, .u.mchk.cr14 = 1 << 28, - .u.mchk.mcic = 0x00400f1d40330000, + .u.mchk.mcic = 0x00400f1d40330000ULL, }; kvm_s390_floating_interrupt(&irq); }