aboutsummaryrefslogtreecommitdiff
path: root/target-s390x/kvm.c
diff options
context:
space:
mode:
authorFan Zhang <zhangfan@linux.vnet.ibm.com>2016-03-09 13:11:17 +0100
committerCornelia Huck <cornelia.huck@de.ibm.com>2016-05-17 15:50:29 +0200
commit9700230b0d6d68d8650206ffd10d132219678db1 (patch)
tree14b645e6981f227520f4decb3317b45c397e620e /target-s390x/kvm.c
parent946e55f3c7ff3eb9fa49e57e15c209858aaa9ac9 (diff)
s390x: enable runtime instrumentation
Introduce run-time-instrumentation support when running under kvm for virtio-ccw 2.7 machine and make sure older machines can not enable it. The new ri_allowed field in the s390MachineClass serves as an indicator whether the feature can be used by the machine and should therefore be activated if available. riccb_needed() is used to check whether riccb is needed or not in live migration. Signed-off-by: Fan Zhang <zhangfan@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'target-s390x/kvm.c')
-rw-r--r--target-s390x/kvm.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index e1859cae04..55ae6d3304 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -46,6 +46,7 @@
#include "hw/s390x/ipl.h"
#include "hw/s390x/ebcdic.h"
#include "exec/memattrs.h"
+#include "hw/s390x/s390-virtio-ccw.h"
/* #define DEBUG_KVM */
@@ -135,6 +136,7 @@ static int cap_sync_regs;
static int cap_async_pf;
static int cap_mem_op;
static int cap_s390_irq;
+static int cap_ri;
static void *legacy_s390_alloc(size_t size, uint64_t *align);
@@ -270,6 +272,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0);
kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0);
kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0);
+ if (ri_allowed()) {
+ if (kvm_vm_enable_cap(s, KVM_CAP_S390_RI, 0) == 0) {
+ cap_ri = 1;
+ }
+ }
return 0;
}
@@ -386,6 +393,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
kvm_set_one_reg(cs, KVM_REG_S390_PP, &env->pp);
}
+ if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
+ memcpy(cs->kvm_run->s.regs.riccb, env->riccb, 64);
+ cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_RICCB;
+ }
+
/* pfault parameters */
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
cs->kvm_run->s.regs.pft = env->pfault_token;
@@ -528,6 +540,10 @@ int kvm_arch_get_registers(CPUState *cs)
kvm_get_one_reg(cs, KVM_REG_S390_PP, &env->pp);
}
+ if (can_sync_regs(cs, KVM_SYNC_RICCB)) {
+ memcpy(env->riccb, cs->kvm_run->s.regs.riccb, 64);
+ }
+
/* pfault parameters */
if (can_sync_regs(cs, KVM_SYNC_PFAULT)) {
env->pfault_token = cs->kvm_run->s.regs.pft;
@@ -2136,6 +2152,11 @@ int kvm_s390_get_memslot_count(KVMState *s)
return kvm_check_extension(s, KVM_CAP_NR_MEMSLOTS);
}
+int kvm_s390_get_ri(void)
+{
+ return cap_ri;
+}
+
int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
{
struct kvm_mp_state mp_state = {};