summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorHalil Pasic <pasic@linux.vnet.ibm.com>2017-10-17 16:04:49 +0200
committerCornelia Huck <cohuck@redhat.com>2017-10-20 13:32:10 +0200
commit66dc50f7057b9a0191f54e55764412202306858d (patch)
treeaec8322b08d631d8212b333fc6d9614d444adbad /target
parente443ef9f21acdc6459b3fbad04019a40ea8c4e80 (diff)
downloadqemu-66dc50f7057b9a0191f54e55764412202306858d.zip
s390x: improve error handling for SSCH and RSCH
Simplify the error handling of the SSCH and RSCH handler avoiding arbitrary and cryptic error codes being used to tell how the instruction is supposed to end. Let the code detecting the condition tell how it's to be handled in a less ambiguous way. It's best to handle SSCH and RSCH in one go as the emulation of the two shares a lot of code. For passthrough this change isn't pure refactoring, but changes the way kernel reported EFAULT is handled. After clarifying the kernel interface we decided that EFAULT shall be mapped to unit exception. Same goes for unexpected error codes and absence of required ORB flags. Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Message-Id: <20171017140453.51099-4-pasic@linux.vnet.ibm.com> Tested-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [CH: cosmetic changes] Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/s390x/ioinst.c53
1 files changed, 7 insertions, 46 deletions
diff --git a/target/s390x/ioinst.c b/target/s390x/ioinst.c
index 47490f838a..16b5cf2fed 100644
--- a/target/s390x/ioinst.c
+++ b/target/s390x/ioinst.c
@@ -218,8 +218,6 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
SubchDev *sch;
ORB orig_orb, orb;
uint64_t addr;
- int ret = -ENODEV;
- int cc;
CPUS390XState *env = &cpu->env;
uint8_t ar;
@@ -239,33 +237,11 @@ void ioinst_handle_ssch(S390CPU *cpu, uint64_t reg1, uint32_t ipb)
}
trace_ioinst_sch_id("ssch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid);
- if (sch && css_subch_visible(sch)) {
- ret = css_do_ssch(sch, &orb);
- }
- switch (ret) {
- case -ENODEV:
- cc = 3;
- break;
- case -EBUSY:
- cc = 2;
- break;
- case -EFAULT:
- /*
- * TODO:
- * I'm wondering whether there is something better
- * to do for us here (like setting some device or
- * subchannel status).
- */
- program_interrupt(env, PGM_ADDRESSING, 4);
+ if (!sch || !css_subch_visible(sch)) {
+ setcc(cpu, 3);
return;
- case 0:
- cc = 0;
- break;
- default:
- cc = 1;
- break;
}
- setcc(cpu, cc);
+ setcc(cpu, css_do_ssch(sch, &orb));
}
void ioinst_handle_stcrw(S390CPU *cpu, uint32_t ipb)
@@ -784,8 +760,6 @@ void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1)
{
int cssid, ssid, schid, m;
SubchDev *sch;
- int ret = -ENODEV;
- int cc;
if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
program_interrupt(&cpu->env, PGM_OPERAND, 4);
@@ -793,24 +767,11 @@ void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1)
}
trace_ioinst_sch_id("rsch", cssid, ssid, schid);
sch = css_find_subch(m, cssid, ssid, schid);
- if (sch && css_subch_visible(sch)) {
- ret = css_do_rsch(sch);
- }
- switch (ret) {
- case -ENODEV:
- cc = 3;
- break;
- case -EINVAL:
- cc = 2;
- break;
- case 0:
- cc = 0;
- break;
- default:
- cc = 1;
- break;
+ if (!sch || !css_subch_visible(sch)) {
+ setcc(cpu, 3);
+ return;
}
- setcc(cpu, cc);
+ setcc(cpu, css_do_rsch(sch));
}
#define RCHP_REG1_RES(_reg) (_reg & 0x00000000ff00ff00)