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:
		
							parent
							
								
									71ed827abd
								
							
						
					
					
						commit
						c1e8dfb5e8
					
				@ -528,50 +528,19 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
 | 
				
			|||||||
        no_cc = 1;
 | 
					        no_cc = 1;
 | 
				
			||||||
        r = ioinst_handle_sal(env, env->regs[1]);
 | 
					        r = ioinst_handle_sal(env, env->regs[1]);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    default:
 | 
					    case PRIV_SIGA:
 | 
				
			||||||
        r = -1;
 | 
					        /* Not provided, set CC = 3 for subchannel not operational */
 | 
				
			||||||
 | 
					        r = 3;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (r >= 0) {
 | 
					    if (r >= 0 && !no_cc) {
 | 
				
			||||||
        if (!no_cc) {
 | 
					 | 
				
			||||||
        setcc(cpu, r);
 | 
					        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)
 | 
					    return 0;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int handle_priv(S390CPU *cpu, struct kvm_run *run,
 | 
					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);
 | 
					            r = kvm_sclp_service_call(cpu, run, ipbh0);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            if (is_ioinst(ipa0, ipa1, ipb)) {
 | 
					 | 
				
			||||||
            r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
 | 
					            r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
 | 
				
			||||||
            if (r == -1) {
 | 
					            if (r == -1) {
 | 
				
			||||||
                    setcc(cpu, 3);
 | 
					                DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1);
 | 
				
			||||||
                    r = 0;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                DPRINTF("KVM: unknown PRIV: 0x%x\n", ipa1);
 | 
					 | 
				
			||||||
                r = -1;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user