KVM: s390: Changes for 4.10 (via kvm/next)
Two small optimizations to not do register reloading in vcpu_put/get, instead do it in the ioctl path. This reduces the overhead for schedule-intense workload that does not exit to QEMU. (e.g. KVM guest with eventfd/irqfd that does a lot of context switching with vhost or iothreads). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJYO+yuAAoJEBF7vIC1phx8jGQQALWZ4dnLN3GG52zG0ke4iRrf 7EY4/L+/LbSOHqaQ+6Dg4xkW3mg4nLxi4rcTRO2QCfn9yBJWEAI6++9nAodV3lIw m4R4/7ppAuLLTzVeD9QwGoVyamJkKpd+N3zLHPInI6/pK5b07WBSVGeddGKtz+Z8 qMJohcbyVKXXccgNK4mH/tGI8mDoC4wFbxgETk9meYIqgYbiZE55LQoLEtOJDxF+ /+dCaxbxO/hezI+ktYSu/c+WBO0RKQuV7zyLaAKRVl/Dh6vqVSlNXPDOxtWxRgVa aFEknEV21PCLCJczUuDRXgtvHCiwmGIn6JatVs//b+1e7Ugtsa2sgGWUjXO50SbV ibK/FBgg0WVuSXkMO/pMD4jSvEJjyggK5PNV64F77H9dYelRmDhlt3o9wdmayjdN ENqDUbtAqPFis2RrSH6aVkxh7KaaK9lD0anafdvBnFSQoF8voALza83M+tprAY8H Q5xQ1ckIuGdFYXjvQAfsfjL5ZD+d+KoKnnKMTUsSM/5Lbf+iCSlQ0XuhXlH3m88J K/owMAPiisbiJJwjbmZ41dOUpBGJbU4ii7rvaHWOa13llaNDU4OCbvr/SRso6DnU MjAO271ySwFVaiu8lN7Y6mh3x2KbbuJDjIaFKGRtjraO6sW/gU4ty3qsaRCi1wqj oBt+O/XmRqJS6AZh0kFe =OlEr -----END PGP SIGNATURE----- Merge tag 'kvm-s390-next-4.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux KVM: s390: Changes for 4.10 (via kvm/next) Two small optimizations to not do register reloading in vcpu_put/get, instead do it in the ioctl path. This reduces the overhead for schedule-intense workload that does not exit to QEMU. (e.g. KVM guest with eventfd/irqfd that does a lot of context switching with vhost or iothreads).
This commit is contained in:
Коммит
bf65014d0b
|
@ -415,7 +415,7 @@ static int __write_machine_check(struct kvm_vcpu *vcpu,
|
|||
int rc;
|
||||
|
||||
mci.val = mchk->mcic;
|
||||
/* take care of lazy register loading via vcpu load/put */
|
||||
/* take care of lazy register loading */
|
||||
save_fpu_regs();
|
||||
save_access_regs(vcpu->run->s.regs.acrs);
|
||||
|
||||
|
|
|
@ -1812,22 +1812,7 @@ __u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu)
|
|||
|
||||
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
{
|
||||
/* Save host register state */
|
||||
save_fpu_regs();
|
||||
vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
|
||||
vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
|
||||
|
||||
if (MACHINE_HAS_VX)
|
||||
current->thread.fpu.regs = vcpu->run->s.regs.vrs;
|
||||
else
|
||||
current->thread.fpu.regs = vcpu->run->s.regs.fprs;
|
||||
current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
|
||||
if (test_fp_ctl(current->thread.fpu.fpc))
|
||||
/* User space provided an invalid FPC, let's clear it */
|
||||
current->thread.fpu.fpc = 0;
|
||||
|
||||
save_access_regs(vcpu->arch.host_acrs);
|
||||
restore_access_regs(vcpu->run->s.regs.acrs);
|
||||
gmap_enable(vcpu->arch.enabled_gmap);
|
||||
atomic_or(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
|
||||
if (vcpu->arch.cputm_enabled && !is_vcpu_idle(vcpu))
|
||||
|
@ -1844,16 +1829,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
|
|||
vcpu->arch.enabled_gmap = gmap_get_enabled();
|
||||
gmap_disable(vcpu->arch.enabled_gmap);
|
||||
|
||||
/* Save guest register state */
|
||||
save_fpu_regs();
|
||||
vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
|
||||
|
||||
/* Restore host register state */
|
||||
current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
|
||||
current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
|
||||
|
||||
save_access_regs(vcpu->run->s.regs.acrs);
|
||||
restore_access_regs(vcpu->arch.host_acrs);
|
||||
}
|
||||
|
||||
static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
|
||||
|
@ -2243,7 +2218,6 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
|
|||
{
|
||||
memcpy(&vcpu->run->s.regs.acrs, &sregs->acrs, sizeof(sregs->acrs));
|
||||
memcpy(&vcpu->arch.sie_block->gcr, &sregs->crs, sizeof(sregs->crs));
|
||||
restore_access_regs(vcpu->run->s.regs.acrs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2257,11 +2231,9 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
|
|||
|
||||
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||
{
|
||||
/* make sure the new values will be lazily loaded */
|
||||
save_fpu_regs();
|
||||
if (test_fp_ctl(fpu->fpc))
|
||||
return -EINVAL;
|
||||
current->thread.fpu.fpc = fpu->fpc;
|
||||
vcpu->run->s.regs.fpc = fpu->fpc;
|
||||
if (MACHINE_HAS_VX)
|
||||
convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs,
|
||||
(freg_t *) fpu->fprs);
|
||||
|
@ -2279,7 +2251,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
|||
(__vector128 *) vcpu->run->s.regs.vrs);
|
||||
else
|
||||
memcpy(fpu->fprs, vcpu->run->s.regs.fprs, sizeof(fpu->fprs));
|
||||
fpu->fpc = current->thread.fpu.fpc;
|
||||
fpu->fpc = vcpu->run->s.regs.fpc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2740,6 +2712,20 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||
if (riccb->valid)
|
||||
vcpu->arch.sie_block->ecb3 |= 0x01;
|
||||
}
|
||||
save_access_regs(vcpu->arch.host_acrs);
|
||||
restore_access_regs(vcpu->run->s.regs.acrs);
|
||||
/* save host (userspace) fprs/vrs */
|
||||
save_fpu_regs();
|
||||
vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
|
||||
vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
|
||||
if (MACHINE_HAS_VX)
|
||||
current->thread.fpu.regs = vcpu->run->s.regs.vrs;
|
||||
else
|
||||
current->thread.fpu.regs = vcpu->run->s.regs.fprs;
|
||||
current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
|
||||
if (test_fp_ctl(current->thread.fpu.fpc))
|
||||
/* User space provided an invalid FPC, let's clear it */
|
||||
current->thread.fpu.fpc = 0;
|
||||
|
||||
kvm_run->kvm_dirty_regs = 0;
|
||||
}
|
||||
|
@ -2758,6 +2744,15 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||
kvm_run->s.regs.pft = vcpu->arch.pfault_token;
|
||||
kvm_run->s.regs.pfs = vcpu->arch.pfault_select;
|
||||
kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
|
||||
save_access_regs(vcpu->run->s.regs.acrs);
|
||||
restore_access_regs(vcpu->arch.host_acrs);
|
||||
/* Save guest register state */
|
||||
save_fpu_regs();
|
||||
vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
|
||||
/* Restore will be done lazily at return */
|
||||
current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
|
||||
current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
|
||||
|
||||
}
|
||||
|
||||
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||
|
@ -2874,7 +2869,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
|
|||
{
|
||||
/*
|
||||
* The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy
|
||||
* copying in vcpu load/put. Lets update our copies before we save
|
||||
* switch in the run ioctl. Let's update our copies before we save
|
||||
* it into the save area
|
||||
*/
|
||||
save_fpu_regs();
|
||||
|
|
Загрузка…
Ссылка в новой задаче