diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/i386/hyperv-stub.c | 13 | ||||
-rw-r--r-- | target/i386/hyperv.c | 25 | ||||
-rw-r--r-- | target/i386/hyperv.h | 4 | ||||
-rw-r--r-- | target/i386/kvm.c | 9 | ||||
-rw-r--r-- | target/i386/machine.c | 9 |
5 files changed, 60 insertions, 0 deletions
diff --git a/target/i386/hyperv-stub.c b/target/i386/hyperv-stub.c index 5919ba851c..fe548cbae2 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 1eac727774..0216735d67 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 f0a27c3d73..67543296c3 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 2e5b9f63eb..cf6270ae39 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 084c2c73a8..225b5d433b 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), |