diff options
author | Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com> | 2013-06-19 17:27:15 +0200 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2013-08-30 12:48:25 +0200 |
commit | 268846ba93de2529630d623b6ded72cee1221106 (patch) | |
tree | e1315fefaa27f40dbc08af86577d72308d85bb50 /target-s390x/misc_helper.c | |
parent | 39fbc5c62ce83f34e7f5b62238305d83ce8b4489 (diff) |
s390/kvm: basic implementation of diagnose 308 subcode 6
Linux uses a check for subcode 6 to decide if other subcodes are
available. Provide a minimal implementation for subcode 6, as well
as for subcode 5.
Signed-off-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
[Move code from kvm.c into misc_helper.c]
Diffstat (limited to 'target-s390x/misc_helper.c')
-rw-r--r-- | target-s390x/misc_helper.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index 454960aa01..9b4423a031 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -179,6 +179,46 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2) return r; } +#ifndef CONFIG_USER_ONLY +#define DIAG_308_RC_NO_CONF 0x0102 +#define DIAG_308_RC_INVALID 0x0402 +void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3) +{ + uint64_t addr = env->regs[r1]; + uint64_t subcode = env->regs[r3]; + + if (env->psw.mask & PSW_MASK_PSTATE) { + program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC); + return; + } + + if ((subcode & ~0x0ffffULL) || (subcode > 6)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC); + return; + } + + switch (subcode) { + case 5: + if ((r1 & 1) || (addr & 0x0fffULL)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC); + return; + } + env->regs[r1+1] = DIAG_308_RC_INVALID; + return; + case 6: + if ((r1 & 1) || (addr & 0x0fffULL)) { + program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC); + return; + } + env->regs[r1+1] = DIAG_308_RC_NO_CONF; + return; + default: + hw_error("Unhandled diag308 subcode %" PRIx64, subcode); + break; + } +} +#endif + /* DIAG */ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem, uint64_t code) |