Skip to content

Commit

Permalink
s390: Fix error handling and condition code of service call
Browse files Browse the repository at this point in the history
Invalid sccb addresses will cause specification or addressing exception.
Lets add those checks. Furthermore, the good case (cc=0) was incorrect
for KVM, we did not set the CC at all. We now use return codes < 0
as program checks and return codes > 0 as condition code values.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
borntraeger authored and agraf committed Aug 15, 2012
1 parent 03834e2 commit 9abf567
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
5 changes: 3 additions & 2 deletions target-s390x/kvm.c
Expand Up @@ -273,9 +273,10 @@ static int kvm_sclp_service_call(CPUS390XState *env, struct kvm_run *run,
code = env->regs[(ipbh0 & 0xf0) >> 4];

r = sclp_service_call(env, sccb, code);
if (r) {
setcc(env, 3);
if (r < 0) {
enter_pgmcheck(env, -r);
}
setcc(env, r);

return 0;
}
Expand Down
27 changes: 18 additions & 9 deletions target-s390x/op_helper.c
Expand Up @@ -19,6 +19,8 @@
*/

#include "cpu.h"
#include "memory.h"
#include "cputlb.h"
#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
Expand Down Expand Up @@ -2366,6 +2368,9 @@ static void ext_interrupt(CPUS390XState *env, int type, uint32_t param,
cpu_inject_ext(env, type, param, param64);
}

/*
* ret < 0 indicates program check, ret = 0,1,2,3 -> cc
*/
int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
{
int r = 0;
Expand All @@ -2375,10 +2380,12 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
#endif

/* basic checks */
if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
return -PGM_ADDRESSING;
}
if (sccb & ~0x7ffffff8ul) {
fprintf(stderr, "KVM: invalid sccb address 0x%x\n", sccb);
r = -1;
goto out;
return -PGM_SPECIFICATION;
}

switch(code) {
Expand All @@ -2405,22 +2412,24 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
#ifdef DEBUG_HELPER
printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
#endif
r = -1;
r = 3;
break;
}

out:
return r;
}

/* SCLP service call */
uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
{
if (sclp_service_call(env, r1, r2)) {
return 3;
}
int r;

return 0;
r = sclp_service_call(env, r1, r2);
if (r < 0) {
program_interrupt(env, -r, 4);
return 0;
}
return r;
}

/* DIAG */
Expand Down

0 comments on commit 9abf567

Please sign in to comment.