KVM: s390: rewrite vcpu_post_run and drop out early
Let's rewrite this function to better reflect how we actually handle exit_code. By dropping out early we can save a few cycles. This especially speeds up sie exits caused by host irqs. Also, let's move the special -EOPNOTSUPP for intercepts to the place where it belongs and convert it to -EREMOTE. Reviewed-by: Dominik Dingel <dingel@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
Родитель
4bd33b5688
Коммит
71f116bfed
|
@ -54,9 +54,6 @@ void kvm_s390_rewind_psw(struct kvm_vcpu *vcpu, int ilc)
|
||||||
static int handle_noop(struct kvm_vcpu *vcpu)
|
static int handle_noop(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
switch (vcpu->arch.sie_block->icptcode) {
|
switch (vcpu->arch.sie_block->icptcode) {
|
||||||
case 0x0:
|
|
||||||
vcpu->stat.exit_null++;
|
|
||||||
break;
|
|
||||||
case 0x10:
|
case 0x10:
|
||||||
vcpu->stat.exit_external_request++;
|
vcpu->stat.exit_external_request++;
|
||||||
break;
|
break;
|
||||||
|
@ -338,8 +335,10 @@ static int handle_partial_execution(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
|
if (kvm_is_ucontrol(vcpu->kvm))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
switch (vcpu->arch.sie_block->icptcode) {
|
switch (vcpu->arch.sie_block->icptcode) {
|
||||||
case 0x00:
|
|
||||||
case 0x10:
|
case 0x10:
|
||||||
case 0x18:
|
case 0x18:
|
||||||
return handle_noop(vcpu);
|
return handle_noop(vcpu);
|
||||||
|
|
|
@ -2071,8 +2071,6 @@ static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
|
static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
|
||||||
{
|
{
|
||||||
int rc = -1;
|
|
||||||
|
|
||||||
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
|
VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
|
||||||
vcpu->arch.sie_block->icptcode);
|
vcpu->arch.sie_block->icptcode);
|
||||||
trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
|
trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode);
|
||||||
|
@ -2080,40 +2078,35 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
|
||||||
if (guestdbg_enabled(vcpu))
|
if (guestdbg_enabled(vcpu))
|
||||||
kvm_s390_restore_guest_per_regs(vcpu);
|
kvm_s390_restore_guest_per_regs(vcpu);
|
||||||
|
|
||||||
if (exit_reason >= 0) {
|
memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
|
||||||
rc = 0;
|
|
||||||
|
if (vcpu->arch.sie_block->icptcode > 0) {
|
||||||
|
int rc = kvm_handle_sie_intercept(vcpu);
|
||||||
|
|
||||||
|
if (rc != -EOPNOTSUPP)
|
||||||
|
return rc;
|
||||||
|
vcpu->run->exit_reason = KVM_EXIT_S390_SIEIC;
|
||||||
|
vcpu->run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
|
||||||
|
vcpu->run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
|
||||||
|
vcpu->run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
|
||||||
|
return -EREMOTE;
|
||||||
|
} else if (exit_reason != -EFAULT) {
|
||||||
|
vcpu->stat.exit_null++;
|
||||||
|
return 0;
|
||||||
} else if (kvm_is_ucontrol(vcpu->kvm)) {
|
} else if (kvm_is_ucontrol(vcpu->kvm)) {
|
||||||
vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL;
|
vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL;
|
||||||
vcpu->run->s390_ucontrol.trans_exc_code =
|
vcpu->run->s390_ucontrol.trans_exc_code =
|
||||||
current->thread.gmap_addr;
|
current->thread.gmap_addr;
|
||||||
vcpu->run->s390_ucontrol.pgm_code = 0x10;
|
vcpu->run->s390_ucontrol.pgm_code = 0x10;
|
||||||
rc = -EREMOTE;
|
return -EREMOTE;
|
||||||
|
|
||||||
} else if (current->thread.gmap_pfault) {
|
} else if (current->thread.gmap_pfault) {
|
||||||
trace_kvm_s390_major_guest_pfault(vcpu);
|
trace_kvm_s390_major_guest_pfault(vcpu);
|
||||||
current->thread.gmap_pfault = 0;
|
current->thread.gmap_pfault = 0;
|
||||||
if (kvm_arch_setup_async_pf(vcpu)) {
|
if (kvm_arch_setup_async_pf(vcpu))
|
||||||
rc = 0;
|
return 0;
|
||||||
} else {
|
return kvm_arch_fault_in_page(vcpu, current->thread.gmap_addr, 1);
|
||||||
gpa_t gpa = current->thread.gmap_addr;
|
|
||||||
rc = kvm_arch_fault_in_page(vcpu, gpa, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return vcpu_post_run_fault_in_sie(vcpu);
|
||||||
if (rc == -1)
|
|
||||||
rc = vcpu_post_run_fault_in_sie(vcpu);
|
|
||||||
|
|
||||||
memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
|
|
||||||
|
|
||||||
if (rc == 0) {
|
|
||||||
if (kvm_is_ucontrol(vcpu->kvm))
|
|
||||||
/* Don't exit for host interrupts. */
|
|
||||||
rc = vcpu->arch.sie_block->icptcode ? -EOPNOTSUPP : 0;
|
|
||||||
else
|
|
||||||
rc = kvm_handle_sie_intercept(vcpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __vcpu_run(struct kvm_vcpu *vcpu)
|
static int __vcpu_run(struct kvm_vcpu *vcpu)
|
||||||
|
@ -2233,18 +2226,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == -EOPNOTSUPP) {
|
|
||||||
/* intercept cannot be handled in-kernel, prepare kvm-run */
|
|
||||||
kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
|
|
||||||
kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode;
|
|
||||||
kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa;
|
|
||||||
kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb;
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc == -EREMOTE) {
|
if (rc == -EREMOTE) {
|
||||||
/* intercept was handled, but userspace support is needed
|
/* userspace support is needed, kvm_run has been prepared */
|
||||||
* kvm_run has been prepared by the handler */
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче