s390x/kvm: Reworked/fixed handling of cc3 in kvm_handle_css_inst()

Consolidated the setting of the condition code in kvm_handle_css_inst().
For the (unhandled) instructions EQBS and SQBS, we have to return
an operation exception instead of cc3. Also removed the is_ioinst()
function to avoid decoding the opcode twice.

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>
This commit is contained in:
Thomas Huth 2013-06-24 15:17:34 +02:00 committed by Christian Borntraeger
parent 71ed827abd
commit c1e8dfb5e8
1 changed files with 11 additions and 48 deletions

View File

@ -528,50 +528,19 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
no_cc = 1;
r = ioinst_handle_sal(env, env->regs[1]);
break;
case PRIV_SIGA:
/* Not provided, set CC = 3 for subchannel not operational */
r = 3;
break;
default:
r = -1;
break;
return -1;
}
if (r >= 0) {
if (!no_cc) {
setcc(cpu, r);
}
r = 0;
} else if (r < -1) {
r = 0;
}
return r;
}
static int is_ioinst(uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
{
int ret = 0;
uint16_t ipa = (ipa0 << 8) | ipa1;
switch (ipa) {
case IPA0_B2 | PRIV_CSCH:
case IPA0_B2 | PRIV_HSCH:
case IPA0_B2 | PRIV_MSCH:
case IPA0_B2 | PRIV_SSCH:
case IPA0_B2 | PRIV_STSCH:
case IPA0_B2 | PRIV_TPI:
case IPA0_B2 | PRIV_SAL:
case IPA0_B2 | PRIV_RSCH:
case IPA0_B2 | PRIV_STCRW:
case IPA0_B2 | PRIV_STCPS:
case IPA0_B2 | PRIV_RCHP:
case IPA0_B2 | PRIV_SCHM:
case IPA0_B2 | PRIV_CHSC:
case IPA0_B2 | PRIV_SIGA:
case IPA0_B2 | PRIV_XSCH:
case IPA0_B9 | PRIV_EQBS:
case IPA0_EB | PRIV_SQBS:
ret = 1;
break;
if (r >= 0 && !no_cc) {
setcc(cpu, r);
}
return ret;
return 0;
}
static int handle_priv(S390CPU *cpu, struct kvm_run *run,
@ -587,15 +556,9 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run,
r = kvm_sclp_service_call(cpu, run, ipbh0);
break;
default:
if (is_ioinst(ipa0, ipa1, ipb)) {
r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
if (r == -1) {
setcc(cpu, 3);
r = 0;
}
} else {
DPRINTF("KVM: unknown PRIV: 0x%x\n", ipa1);
r = -1;
r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
if (r == -1) {
DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1);
}
break;
}