s390x/kvm: avoid syscalls by syncing registers with kvm_run
We can avoid loads of syscalls when dropping to user space by storing the values of more registers directly within kvm_run. Support is added for: - ARCH0: CPU timer, clock comparator, TOD programmable register, guest breaking-event register, program parameter - PFAULT: pfault parameters (token, select, compare) Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Acked-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
This commit is contained in:
parent
fdb78ec006
commit
59ac15326e
@ -252,18 +252,33 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These ONE_REGS are not protected by a capability. As they are only
|
||||
* necessary for migration we just trace a possible error, but don't
|
||||
* return with an error return code.
|
||||
*/
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
||||
if (can_sync_regs(cs, KVM_SYNC_ARCH0)) {
|
||||
cs->kvm_run->s.regs.cputm = env->cputm;
|
||||
cs->kvm_run->s.regs.ckc = env->ckc;
|
||||
cs->kvm_run->s.regs.todpr = env->todpr;
|
||||
cs->kvm_run->s.regs.gbea = env->gbea;
|
||||
cs->kvm_run->s.regs.pp = env->pp;
|
||||
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_ARCH0;
|
||||
} else {
|
||||
/*
|
||||
* These ONE_REGS are not protected by a capability. As they are only
|
||||
* necessary for migration we just trace a possible error, but don't
|
||||
* return with an error return code.
|
||||
*/
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
|
||||
kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
||||
}
|
||||
|
||||
if (cap_async_pf) {
|
||||
/* pfault parameters */
|
||||
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
|
||||
cs->kvm_run->s.regs.pft = env->pfault_token;
|
||||
cs->kvm_run->s.regs.pfs = env->pfault_select;
|
||||
cs->kvm_run->s.regs.pfc = env->pfault_compare;
|
||||
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_PFAULT;
|
||||
} else if (cap_async_pf) {
|
||||
r = kvm_set_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
@ -367,18 +382,31 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
env->psa = cs->kvm_run->s.regs.prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
* These ONE_REGS are not protected by a capability. As they are only
|
||||
* necessary for migration we just trace a possible error, but don't
|
||||
* return with an error return code.
|
||||
*/
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
||||
if (can_sync_regs(cs, KVM_SYNC_ARCH0)) {
|
||||
env->cputm = cs->kvm_run->s.regs.cputm;
|
||||
env->ckc = cs->kvm_run->s.regs.ckc;
|
||||
env->todpr = cs->kvm_run->s.regs.todpr;
|
||||
env->gbea = cs->kvm_run->s.regs.gbea;
|
||||
env->pp = cs->kvm_run->s.regs.pp;
|
||||
} else {
|
||||
/*
|
||||
* These ONE_REGS are not protected by a capability. As they are only
|
||||
* necessary for migration we just trace a possible error, but don't
|
||||
* return with an error return code.
|
||||
*/
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_CPU_TIMER, &env->cputm);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_CLOCK_COMP, &env->ckc);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_GBEA, &env->gbea);
|
||||
kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
||||
}
|
||||
|
||||
if (cap_async_pf) {
|
||||
/* pfault parameters */
|
||||
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
|
||||
env->pfault_token = cs->kvm_run->s.regs.pft;
|
||||
env->pfault_select = cs->kvm_run->s.regs.pfs;
|
||||
env->pfault_compare = cs->kvm_run->s.regs.pfc;
|
||||
} else if (cap_async_pf) {
|
||||
r = kvm_get_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user