150efe82cSAndrey Smetanin /* 250efe82cSAndrey Smetanin * QEMU KVM Hyper-V support 350efe82cSAndrey Smetanin * 450efe82cSAndrey Smetanin * Copyright (C) 2015 Andrey Smetanin <asmetanin@virtuozzo.com> 550efe82cSAndrey Smetanin * 650efe82cSAndrey Smetanin * Authors: 750efe82cSAndrey Smetanin * Andrey Smetanin <asmetanin@virtuozzo.com> 850efe82cSAndrey Smetanin * 950efe82cSAndrey Smetanin * This work is licensed under the terms of the GNU GPL, version 2 or later. 1050efe82cSAndrey Smetanin * See the COPYING file in the top-level directory. 1150efe82cSAndrey Smetanin * 1250efe82cSAndrey Smetanin */ 1350efe82cSAndrey Smetanin 14b6a0aa05SPeter Maydell #include "qemu/osdep.h" 1550efe82cSAndrey Smetanin #include "hyperv.h" 16701189e3SRoman Kagan #include "hw/hyperv/hyperv.h" 175e953812SRoman Kagan #include "hyperv-proto.h" 1850efe82cSAndrey Smetanin 19606c34bfSRoman Kagan int hyperv_x86_synic_add(X86CPU *cpu) 20606c34bfSRoman Kagan { 21606c34bfSRoman Kagan hyperv_synic_add(CPU(cpu)); 22606c34bfSRoman Kagan return 0; 23606c34bfSRoman Kagan } 24606c34bfSRoman Kagan 25606c34bfSRoman Kagan void hyperv_x86_synic_reset(X86CPU *cpu) 26606c34bfSRoman Kagan { 27606c34bfSRoman Kagan hyperv_synic_reset(CPU(cpu)); 28606c34bfSRoman Kagan } 29606c34bfSRoman Kagan 30606c34bfSRoman Kagan void hyperv_x86_synic_update(X86CPU *cpu) 31606c34bfSRoman Kagan { 32606c34bfSRoman Kagan CPUX86State *env = &cpu->env; 33606c34bfSRoman Kagan bool enable = env->msr_hv_synic_control & HV_SYNIC_ENABLE; 34606c34bfSRoman Kagan hwaddr msg_page_addr = (env->msr_hv_synic_msg_page & HV_SIMP_ENABLE) ? 35606c34bfSRoman Kagan (env->msr_hv_synic_msg_page & TARGET_PAGE_MASK) : 0; 36606c34bfSRoman Kagan hwaddr event_page_addr = (env->msr_hv_synic_evt_page & HV_SIEFP_ENABLE) ? 37606c34bfSRoman Kagan (env->msr_hv_synic_evt_page & TARGET_PAGE_MASK) : 0; 38606c34bfSRoman Kagan hyperv_synic_update(CPU(cpu), enable, msg_page_addr, event_page_addr); 39606c34bfSRoman Kagan } 40606c34bfSRoman Kagan 4150efe82cSAndrey Smetanin int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit) 4250efe82cSAndrey Smetanin { 4350efe82cSAndrey Smetanin CPUX86State *env = &cpu->env; 4450efe82cSAndrey Smetanin 4550efe82cSAndrey Smetanin switch (exit->type) { 4650efe82cSAndrey Smetanin case KVM_EXIT_HYPERV_SYNIC: 4750efe82cSAndrey Smetanin if (!cpu->hyperv_synic) { 4850efe82cSAndrey Smetanin return -1; 4950efe82cSAndrey Smetanin } 5050efe82cSAndrey Smetanin 5150efe82cSAndrey Smetanin /* 5250efe82cSAndrey Smetanin * For now just track changes in SynIC control and msg/evt pages msr's. 5350efe82cSAndrey Smetanin * When SynIC messaging/events processing will be added in future 5450efe82cSAndrey Smetanin * here we will do messages queues flushing and pages remapping. 5550efe82cSAndrey Smetanin */ 5650efe82cSAndrey Smetanin switch (exit->u.synic.msr) { 5750efe82cSAndrey Smetanin case HV_X64_MSR_SCONTROL: 5850efe82cSAndrey Smetanin env->msr_hv_synic_control = exit->u.synic.control; 5950efe82cSAndrey Smetanin break; 6050efe82cSAndrey Smetanin case HV_X64_MSR_SIMP: 6150efe82cSAndrey Smetanin env->msr_hv_synic_msg_page = exit->u.synic.msg_page; 6250efe82cSAndrey Smetanin break; 6350efe82cSAndrey Smetanin case HV_X64_MSR_SIEFP: 6450efe82cSAndrey Smetanin env->msr_hv_synic_evt_page = exit->u.synic.evt_page; 6550efe82cSAndrey Smetanin break; 6650efe82cSAndrey Smetanin default: 6750efe82cSAndrey Smetanin return -1; 6850efe82cSAndrey Smetanin } 69606c34bfSRoman Kagan 70606c34bfSRoman Kagan hyperv_x86_synic_update(cpu); 71606c34bfSRoman Kagan 7250efe82cSAndrey Smetanin return 0; 731b0d9b05SAndrey Smetanin case KVM_EXIT_HYPERV_HCALL: { 741b0d9b05SAndrey Smetanin uint16_t code; 751b0d9b05SAndrey Smetanin 761b0d9b05SAndrey Smetanin code = exit->u.hcall.input & 0xffff; 771b0d9b05SAndrey Smetanin switch (code) { 785e953812SRoman Kagan case HV_POST_MESSAGE: 795e953812SRoman Kagan case HV_SIGNAL_EVENT: 801b0d9b05SAndrey Smetanin default: 811b0d9b05SAndrey Smetanin exit->u.hcall.result = HV_STATUS_INVALID_HYPERCALL_CODE; 821b0d9b05SAndrey Smetanin return 0; 831b0d9b05SAndrey Smetanin } 841b0d9b05SAndrey Smetanin } 8550efe82cSAndrey Smetanin default: 8650efe82cSAndrey Smetanin return -1; 8750efe82cSAndrey Smetanin } 8850efe82cSAndrey Smetanin } 89