aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRoman Kagan <rkagan@virtuozzo.com>2018-09-21 11:22:09 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2018-10-19 13:44:14 +0200
commit606c34bfd57a0ecda67b395bea022bb307a5384e (patch)
tree448b94dd535847b0cd358a13332e46085d563c6f /target
parent729ce7e1b6b6e035012544f51878d1ef5864bf39 (diff)
downloadqemu-606c34bfd57a0ecda67b395bea022bb307a5384e.zip
qemu-606c34bfd57a0ecda67b395bea022bb307a5384e.tar.gz
qemu-606c34bfd57a0ecda67b395bea022bb307a5384e.tar.bz2
hyperv: qom-ify SynIC
Make Hyper-V SynIC a device which is attached as a child to a CPU. For now it only makes SynIC visibile in the qom hierarchy, and maintains its internal fields in sync with the respecitve msrs of the parent cpu (the fields will be used in followup patches). Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> Message-Id: <20180921082217.29481-3-rkagan@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target')
-rw-r--r--target/i386/hyperv-stub.c13
-rw-r--r--target/i386/hyperv.c25
-rw-r--r--target/i386/hyperv.h4
-rw-r--r--target/i386/kvm.c9
-rw-r--r--target/i386/machine.c9
5 files changed, 60 insertions, 0 deletions
diff --git a/target/i386/hyperv-stub.c b/target/i386/hyperv-stub.c
index 5919ba8..fe548cb 100644
--- a/target/i386/hyperv-stub.c
+++ b/target/i386/hyperv-stub.c
@@ -33,3 +33,16 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
}
}
#endif
+
+int hyperv_x86_synic_add(X86CPU *cpu)
+{
+ return -ENOSYS;
+}
+
+void hyperv_x86_synic_reset(X86CPU *cpu)
+{
+}
+
+void hyperv_x86_synic_update(X86CPU *cpu)
+{
+}
diff --git a/target/i386/hyperv.c b/target/i386/hyperv.c
index 1eac727..0216735 100644
--- a/target/i386/hyperv.c
+++ b/target/i386/hyperv.c
@@ -16,6 +16,28 @@
#include "hw/hyperv/hyperv.h"
#include "hyperv-proto.h"
+int hyperv_x86_synic_add(X86CPU *cpu)
+{
+ hyperv_synic_add(CPU(cpu));
+ return 0;
+}
+
+void hyperv_x86_synic_reset(X86CPU *cpu)
+{
+ hyperv_synic_reset(CPU(cpu));
+}
+
+void hyperv_x86_synic_update(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+ bool enable = env->msr_hv_synic_control & HV_SYNIC_ENABLE;
+ hwaddr msg_page_addr = (env->msr_hv_synic_msg_page & HV_SIMP_ENABLE) ?
+ (env->msr_hv_synic_msg_page & TARGET_PAGE_MASK) : 0;
+ hwaddr event_page_addr = (env->msr_hv_synic_evt_page & HV_SIEFP_ENABLE) ?
+ (env->msr_hv_synic_evt_page & TARGET_PAGE_MASK) : 0;
+ hyperv_synic_update(CPU(cpu), enable, msg_page_addr, event_page_addr);
+}
+
int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
{
CPUX86State *env = &cpu->env;
@@ -44,6 +66,9 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
default:
return -1;
}
+
+ hyperv_x86_synic_update(cpu);
+
return 0;
case KVM_EXIT_HYPERV_HCALL: {
uint16_t code;
diff --git a/target/i386/hyperv.h b/target/i386/hyperv.h
index f0a27c3..6754329 100644
--- a/target/i386/hyperv.h
+++ b/target/i386/hyperv.h
@@ -22,4 +22,8 @@
int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit);
#endif
+int hyperv_x86_synic_add(X86CPU *cpu);
+void hyperv_x86_synic_reset(X86CPU *cpu);
+void hyperv_x86_synic_update(X86CPU *cpu);
+
#endif
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 2e5b9f6..cf6270a 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -790,6 +790,13 @@ static int hyperv_init_vcpu(X86CPU *cpu)
strerror(-ret));
return ret;
}
+
+ ret = hyperv_x86_synic_add(cpu);
+ if (ret < 0) {
+ error_report("failed to create HyperV SynIC: %s",
+ strerror(-ret));
+ return ret;
+ }
}
return 0;
@@ -1250,6 +1257,8 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) {
env->msr_hv_synic_sint[i] = HV_SINT_MASKED;
}
+
+ hyperv_x86_synic_reset(cpu);
}
}
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 084c2c7..225b5d4 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -7,6 +7,7 @@
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
#include "migration/cpu.h"
+#include "hyperv.h"
#include "sysemu/kvm.h"
@@ -672,11 +673,19 @@ static bool hyperv_synic_enable_needed(void *opaque)
return false;
}
+static int hyperv_synic_post_load(void *opaque, int version_id)
+{
+ X86CPU *cpu = opaque;
+ hyperv_x86_synic_update(cpu);
+ return 0;
+}
+
static const VMStateDescription vmstate_msr_hyperv_synic = {
.name = "cpu/msr_hyperv_synic",
.version_id = 1,
.minimum_version_id = 1,
.needed = hyperv_synic_enable_needed,
+ .post_load = hyperv_synic_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU),
VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU),