Commit 3526a66b authored by David Hildenbrand's avatar David Hildenbrand Committed by Christian Borntraeger

KVM: s390: sigp: dispatch orders with one target in a separate function

All sigp orders except SIGP SET ARCHITECTURE target exactly one vcpu.

Let's move the dispatch code for these orders into a separate function to
prepare for cleaner target availability checks.
Signed-off-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent a36c5393
...@@ -349,32 +349,15 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) ...@@ -349,32 +349,15 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
return rc; return rc;
} }
int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
u16 cpu_addr, u32 parameter, u64 *status_reg)
{ {
int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
int r3 = vcpu->arch.sie_block->ipa & 0x000f;
u32 parameter;
u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
u8 order_code;
int rc; int rc;
/* sigp in userspace can exit */
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
order_code = kvm_s390_get_base_disp_rs(vcpu);
if (r1 % 2)
parameter = vcpu->run->s.regs.gprs[r1];
else
parameter = vcpu->run->s.regs.gprs[r1 + 1];
trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
switch (order_code) { switch (order_code) {
case SIGP_SENSE: case SIGP_SENSE:
vcpu->stat.instruction_sigp_sense++; vcpu->stat.instruction_sigp_sense++;
rc = __sigp_sense(vcpu, cpu_addr, rc = __sigp_sense(vcpu, cpu_addr, status_reg);
&vcpu->run->s.regs.gprs[r1]);
break; break;
case SIGP_EXTERNAL_CALL: case SIGP_EXTERNAL_CALL:
vcpu->stat.instruction_sigp_external_call++; vcpu->stat.instruction_sigp_external_call++;
...@@ -395,25 +378,19 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) ...@@ -395,25 +378,19 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
break; break;
case SIGP_STORE_STATUS_AT_ADDRESS: case SIGP_STORE_STATUS_AT_ADDRESS:
rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
&vcpu->run->s.regs.gprs[r1]); status_reg);
break;
case SIGP_SET_ARCHITECTURE:
vcpu->stat.instruction_sigp_arch++;
rc = __sigp_set_arch(vcpu, parameter);
break; break;
case SIGP_SET_PREFIX: case SIGP_SET_PREFIX:
vcpu->stat.instruction_sigp_prefix++; vcpu->stat.instruction_sigp_prefix++;
rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, status_reg);
&vcpu->run->s.regs.gprs[r1]);
break; break;
case SIGP_COND_EMERGENCY_SIGNAL: case SIGP_COND_EMERGENCY_SIGNAL:
rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
&vcpu->run->s.regs.gprs[r1]); status_reg);
break; break;
case SIGP_SENSE_RUNNING: case SIGP_SENSE_RUNNING:
vcpu->stat.instruction_sigp_sense_running++; vcpu->stat.instruction_sigp_sense_running++;
rc = __sigp_sense_running(vcpu, cpu_addr, rc = __sigp_sense_running(vcpu, cpu_addr, status_reg);
&vcpu->run->s.regs.gprs[r1]);
break; break;
case SIGP_START: case SIGP_START:
rc = sigp_check_callable(vcpu, cpu_addr); rc = sigp_check_callable(vcpu, cpu_addr);
...@@ -432,7 +409,42 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) ...@@ -432,7 +409,42 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
} }
break; break;
default: default:
return -EOPNOTSUPP; rc = -EOPNOTSUPP;
}
return rc;
}
int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
{
int r1 = (vcpu->arch.sie_block->ipa & 0x00f0) >> 4;
int r3 = vcpu->arch.sie_block->ipa & 0x000f;
u32 parameter;
u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
u8 order_code;
int rc;
/* sigp in userspace can exit */
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
order_code = kvm_s390_get_base_disp_rs(vcpu);
if (r1 % 2)
parameter = vcpu->run->s.regs.gprs[r1];
else
parameter = vcpu->run->s.regs.gprs[r1 + 1];
trace_kvm_s390_handle_sigp(vcpu, order_code, cpu_addr, parameter);
switch (order_code) {
case SIGP_SET_ARCHITECTURE:
vcpu->stat.instruction_sigp_arch++;
rc = __sigp_set_arch(vcpu, parameter);
break;
default:
rc = handle_sigp_dst(vcpu, order_code, cpu_addr,
parameter,
&vcpu->run->s.regs.gprs[r1]);
} }
if (rc < 0) if (rc < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment