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,6 +252,14 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* 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
|
* necessary for migration we just trace a possible error, but don't
|
||||||
@ -262,8 +270,15 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
|||||||
kvm_set_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
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_GBEA, &env->gbea);
|
||||||
kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
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);
|
r = kvm_set_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
@ -367,6 +382,13 @@ int kvm_arch_get_registers(CPUState *cs)
|
|||||||
env->psa = cs->kvm_run->s.regs.prefix;
|
env->psa = cs->kvm_run->s.regs.prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* 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
|
* necessary for migration we just trace a possible error, but don't
|
||||||
@ -377,8 +399,14 @@ int kvm_arch_get_registers(CPUState *cs)
|
|||||||
kvm_get_one_reg(cs, KVM_REG_S390_TODPR, &env->todpr);
|
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_GBEA, &env->gbea);
|
||||||
kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
|
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);
|
r = kvm_get_one_reg(cs, KVM_REG_S390_PFTOKEN, &env->pfault_token);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
return r;
|
return r;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user