summaryrefslogtreecommitdiff
path: root/target-s390x
diff options
context:
space:
mode:
authorDominik Dingel <dingel@linux.vnet.ibm.com>2013-09-05 13:54:39 +0200
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-02-27 09:51:25 +0100
commit819bd3091e986c1b6b10203a7138a53b849a53e0 (patch)
treee495be403908960a21e782ff6853e0b20e5e0106 /target-s390x
parent3a553fc65826e0e682ed0fff770ad0d421c6d407 (diff)
s390x/async_pf: Check for apf extension and enable pfault
S390 can also use async page faults, to enhance guest scheduling. In case of live migration we want to disable the feature and let all pending request finish. Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'target-s390x')
-rw-r--r--target-s390x/cpu.c6
-rw-r--r--target-s390x/cpu.h4
-rw-r--r--target-s390x/kvm.c48
3 files changed, 58 insertions, 0 deletions
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index ff57b806e4..f1319e55a6 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -83,6 +83,7 @@ static void s390_cpu_reset(CPUState *s)
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
CPUS390XState *env = &cpu->env;
+ env->pfault_token = -1UL;
s390_del_running_cpu(cpu);
scc->parent_reset(s);
#if !defined(CONFIG_USER_ONLY)
@@ -105,6 +106,8 @@ static void s390_cpu_initial_reset(CPUState *s)
/* architectured initial values for CR 0 and 14 */
env->cregs[0] = CR0_RESET;
env->cregs[14] = CR14_RESET;
+
+ env->pfault_token = -1UL;
}
/* CPUClass:reset() */
@@ -123,6 +126,9 @@ static void s390_cpu_full_reset(CPUState *s)
/* architectured initial values for CR 0 and 14 */
env->cregs[0] = CR0_RESET;
env->cregs[14] = CR14_RESET;
+
+ env->pfault_token = -1UL;
+
/* set halted to 1 to make sure we can add the cpu in
* s390_ipl_cpu code, where CPUState::halted is set back to 0
* after incrementing the cpu counter */
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 96c2b4a7e9..b09ff92099 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -121,6 +121,10 @@ typedef struct CPUS390XState {
uint64_t cputm;
uint32_t todpr;
+ uint64_t pfault_token;
+ uint64_t pfault_compare;
+ uint64_t pfault_select;
+
CPU_COMMON
/* reset does memset(0) up to here */
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index f60ccdc326..9430a35b02 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -87,12 +87,14 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
};
static int cap_sync_regs;
+static int cap_async_pf;
static void *legacy_s390_alloc(size_t size);
int kvm_arch_init(KVMState *s)
{
cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
+ cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
if (!kvm_check_extension(s, KVM_CAP_S390_GMAP)
|| !kvm_check_extension(s, KVM_CAP_S390_COW)) {
phys_mem_set_alloc(legacy_s390_alloc);
@@ -178,6 +180,29 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
+ if (cap_async_pf) {
+ reg.id = KVM_REG_S390_PFTOKEN;
+ reg.addr = (__u64)&(env->pfault_token);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ return ret;
+ }
+
+ reg.id = KVM_REG_S390_PFCOMPARE;
+ reg.addr = (__u64)&(env->pfault_compare);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ return ret;
+ }
+
+ reg.id = KVM_REG_S390_PFSELECT;
+ reg.addr = (__u64)&(env->pfault_select);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
if (cap_sync_regs &&
cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&
cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {
@@ -282,6 +307,29 @@ int kvm_arch_get_registers(CPUState *cs)
return r;
}
+ if (cap_async_pf) {
+ reg.id = KVM_REG_S390_PFTOKEN;
+ reg.addr = (__u64)&(env->pfault_token);
+ r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (r < 0) {
+ return r;
+ }
+
+ reg.id = KVM_REG_S390_PFCOMPARE;
+ reg.addr = (__u64)&(env->pfault_compare);
+ r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (r < 0) {
+ return r;
+ }
+
+ reg.id = KVM_REG_S390_PFSELECT;
+ reg.addr = (__u64)&(env->pfault_select);
+ r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (r < 0) {
+ return r;
+ }
+ }
+
return 0;
}