summaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/sclp_early_core.c
diff options
context:
space:
mode:
authorClaudio Imbrenda <imbrenda@linux.vnet.ibm.com>2018-01-23 16:50:43 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2018-02-22 15:31:24 +0100
commit0b0d1173d8aef75e821c0cceedb0e8178834ec1b (patch)
treeeceecae57a15d49a22440434cc3aeb0ed0e97831 /drivers/s390/char/sclp_early_core.c
parentb843563518c1e06521c446b9a043b7d352df02e0 (diff)
downloadop-kernel-dev-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.zip
op-kernel-dev-0b0d1173d8aef75e821c0cceedb0e8178834ec1b.tar.gz
s390/sclp: 32 bit event mask compatibility mode
Qemu before version 2.11 does not implement the architecture correctly, and does not allow for a mask size of size different than 4. This patch introduces a compatibility mode for such systems, forcing the mask sizes to 4. Since the mask size is currently still 4 anyway, this patch should have no impact whatsoever by itself, but it will be needed when the mask size is increased to 64 bits in the next patch. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp_early_core.c')
-rw-r--r--drivers/s390/char/sclp_early_core.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c
index c8c5326..5f8d9ea 100644
--- a/drivers/s390/char/sclp_early_core.c
+++ b/drivers/s390/char/sclp_early_core.c
@@ -14,6 +14,11 @@
char sclp_early_sccb[PAGE_SIZE] __aligned(PAGE_SIZE) __section(.data);
int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
+/*
+ * Used to keep track of the size of the event masks. Qemu until version 2.11
+ * only supports 4 and needs a workaround.
+ */
+bool sclp_mask_compat_mode;
void sclp_early_wait_irq(void)
{
@@ -145,13 +150,21 @@ int sclp_early_set_event_mask(struct init_sccb *sccb,
sccb_mask_t receive_mask,
sccb_mask_t send_mask)
{
+retry:
memset(sccb, 0, sizeof(*sccb));
sccb->header.length = sizeof(*sccb);
- sccb->mask_length = sizeof(sccb_mask_t);
+ if (sclp_mask_compat_mode)
+ sccb->mask_length = SCLP_MASK_SIZE_COMPAT;
+ else
+ sccb->mask_length = sizeof(sccb_mask_t);
sccb_set_recv_mask(sccb, receive_mask);
sccb_set_send_mask(sccb, send_mask);
if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_MASK, sccb))
return -EIO;
+ if ((sccb->header.response_code == 0x74f0) && !sclp_mask_compat_mode) {
+ sclp_mask_compat_mode = true;
+ goto retry;
+ }
if (sccb->header.response_code != 0x20)
return -EIO;
return 0;
OpenPOWER on IntegriCloud