summaryrefslogtreecommitdiff
path: root/hw/s390x
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2014-01-13 12:55:55 +0100
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-02-27 09:51:25 +0100
commit6e25280216fc23c8387892f76d961559da124528 (patch)
treeb9ad13209c579336fab439eb9eea7f2e6e18eb48 /hw/s390x
parenta0fa2cb8ccf0b73cfd3ac01d557401a2303c0de4 (diff)
downloadqemu-6e25280216fc23c8387892f76d961559da124528.tar.gz
s390x/sclp: Add missing checks to SCLP handler
If the 51 most significant bits of the SCCB address are zero or equal to the prefix, we should throw an specification exception, too. Also moved the check for privileged mode to sclp_service_call() to have all program checks in one place now. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'hw/s390x')
-rw-r--r--hw/s390x/sclp.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 6134d4f904..98809777c8 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -107,7 +107,7 @@ static void sclp_execute(SCCB *sccb, uint32_t code)
}
}
-int sclp_service_call(uint64_t sccb, uint32_t code)
+int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
{
int r = 0;
SCCB work_sccb;
@@ -115,11 +115,16 @@ int sclp_service_call(uint64_t sccb, uint32_t code)
hwaddr sccb_len = sizeof(SCCB);
/* first some basic checks on program checks */
+ if (env->psw.mask & PSW_MASK_PSTATE) {
+ r = -PGM_PRIVILEGED;
+ goto out;
+ }
if (cpu_physical_memory_is_io(sccb)) {
r = -PGM_ADDRESSING;
goto out;
}
- if (sccb & ~0x7ffffff8ul) {
+ if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
+ || (sccb & ~0x7ffffff8UL) != 0) {
r = -PGM_SPECIFICATION;
goto out;
}