mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
target-i386: Move hyperv_* static globals to X86CPU
- since hyperv_* helper functions are used only in target-i386/kvm.c move them there as static helpers Requested-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
99a0b03650
commit
92067bf4bf
7 changed files with 46 additions and 125 deletions
|
@ -3,7 +3,7 @@ obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
|
||||||
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
|
obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
|
||||||
obj-y += gdbstub.o
|
obj-y += gdbstub.o
|
||||||
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
|
obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
|
||||||
obj-$(CONFIG_KVM) += kvm.o hyperv.o
|
obj-$(CONFIG_KVM) += kvm.o
|
||||||
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
obj-$(CONFIG_NO_KVM) += kvm-stub.o
|
||||||
obj-$(CONFIG_LINUX_USER) += ioport-user.o
|
obj-$(CONFIG_LINUX_USER) += ioport-user.o
|
||||||
obj-$(CONFIG_BSD_USER) += ioport-user.o
|
obj-$(CONFIG_BSD_USER) += ioport-user.o
|
||||||
|
|
|
@ -66,6 +66,10 @@ typedef struct X86CPU {
|
||||||
|
|
||||||
CPUX86State env;
|
CPUX86State env;
|
||||||
|
|
||||||
|
bool hyperv_vapic;
|
||||||
|
bool hyperv_relaxed_timing;
|
||||||
|
int hyperv_spinlock_attempts;
|
||||||
|
|
||||||
/* Features that were filtered out because of missing host capabilities */
|
/* Features that were filtered out because of missing host capabilities */
|
||||||
uint32_t filtered_features[FEATURE_WORDS];
|
uint32_t filtered_features[FEATURE_WORDS];
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
#include "sysemu/arch_init.h"
|
#include "sysemu/arch_init.h"
|
||||||
|
|
||||||
#include "hyperv.h"
|
|
||||||
|
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
#if defined(CONFIG_KVM)
|
#if defined(CONFIG_KVM)
|
||||||
#include <linux/kvm_para.h>
|
#include <linux/kvm_para.h>
|
||||||
|
@ -1591,12 +1589,19 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||||
object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
|
object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
|
||||||
} else if (!strcmp(featurestr, "hv-spinlocks")) {
|
} else if (!strcmp(featurestr, "hv-spinlocks")) {
|
||||||
char *err;
|
char *err;
|
||||||
|
const int min = 0xFFF;
|
||||||
numvalue = strtoul(val, &err, 0);
|
numvalue = strtoul(val, &err, 0);
|
||||||
if (!*val || *err) {
|
if (!*val || *err) {
|
||||||
error_setg(errp, "bad numerical value %s", val);
|
error_setg(errp, "bad numerical value %s", val);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
hyperv_set_spinlock_retries(numvalue);
|
if (numvalue < min) {
|
||||||
|
fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
|
||||||
|
", fixup will be removed in future versions\n",
|
||||||
|
min);
|
||||||
|
numvalue = min;
|
||||||
|
}
|
||||||
|
cpu->hyperv_spinlock_attempts = numvalue;
|
||||||
} else {
|
} else {
|
||||||
error_setg(errp, "unrecognized feature %s", featurestr);
|
error_setg(errp, "unrecognized feature %s", featurestr);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1606,9 +1611,9 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
|
||||||
} else if (!strcmp(featurestr, "enforce")) {
|
} else if (!strcmp(featurestr, "enforce")) {
|
||||||
check_cpuid = enforce_cpuid = 1;
|
check_cpuid = enforce_cpuid = 1;
|
||||||
} else if (!strcmp(featurestr, "hv_relaxed")) {
|
} else if (!strcmp(featurestr, "hv_relaxed")) {
|
||||||
hyperv_enable_relaxed_timing(true);
|
cpu->hyperv_relaxed_timing = true;
|
||||||
} else if (!strcmp(featurestr, "hv_vapic")) {
|
} else if (!strcmp(featurestr, "hv_vapic")) {
|
||||||
hyperv_enable_vapic_recommended(true);
|
cpu->hyperv_vapic = true;
|
||||||
} else {
|
} else {
|
||||||
error_setg(errp, "feature string `%s' not in format (+feature|"
|
error_setg(errp, "feature string `%s' not in format (+feature|"
|
||||||
"-feature|feature=xyz)", featurestr);
|
"-feature|feature=xyz)", featurestr);
|
||||||
|
@ -2489,6 +2494,7 @@ static void x86_cpu_initfn(Object *obj)
|
||||||
x86_cpu_get_feature_words,
|
x86_cpu_get_feature_words,
|
||||||
NULL, NULL, (void *)cpu->filtered_features, NULL);
|
NULL, NULL, (void *)cpu->filtered_features, NULL);
|
||||||
|
|
||||||
|
cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
|
||||||
env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
|
env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
|
||||||
|
|
||||||
/* init various static tables used in TCG mode */
|
/* init various static tables used in TCG mode */
|
||||||
|
|
|
@ -549,6 +549,10 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
|
||||||
#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
|
#define CPUID_MWAIT_IBE (1 << 1) /* Interrupts can exit capability */
|
||||||
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
|
#define CPUID_MWAIT_EMX (1 << 0) /* enumeration supported */
|
||||||
|
|
||||||
|
#ifndef HYPERV_SPINLOCK_NEVER_RETRY
|
||||||
|
#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EXCP00_DIVZ 0
|
#define EXCP00_DIVZ 0
|
||||||
#define EXCP01_DB 1
|
#define EXCP01_DB 1
|
||||||
#define EXCP02_NMI 2
|
#define EXCP02_NMI 2
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU Hyper-V support
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2011
|
|
||||||
*
|
|
||||||
* Author: Vadim Rozenfeld <vrozenfe@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hyperv.h"
|
|
||||||
|
|
||||||
static bool hyperv_vapic;
|
|
||||||
static bool hyperv_relaxed_timing;
|
|
||||||
static int hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
|
|
||||||
|
|
||||||
void hyperv_enable_vapic_recommended(bool val)
|
|
||||||
{
|
|
||||||
hyperv_vapic = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hyperv_enable_relaxed_timing(bool val)
|
|
||||||
{
|
|
||||||
hyperv_relaxed_timing = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hyperv_set_spinlock_retries(int val)
|
|
||||||
{
|
|
||||||
hyperv_spinlock_attempts = val;
|
|
||||||
if (hyperv_spinlock_attempts < 0xFFF) {
|
|
||||||
hyperv_spinlock_attempts = 0xFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hyperv_enabled(void)
|
|
||||||
{
|
|
||||||
return hyperv_hypercall_available() || hyperv_relaxed_timing_enabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hyperv_hypercall_available(void)
|
|
||||||
{
|
|
||||||
if (hyperv_vapic ||
|
|
||||||
(hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hyperv_vapic_recommended(void)
|
|
||||||
{
|
|
||||||
return hyperv_vapic;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hyperv_relaxed_timing_enabled(void)
|
|
||||||
{
|
|
||||||
return hyperv_relaxed_timing;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hyperv_get_spinlock_retries(void)
|
|
||||||
{
|
|
||||||
return hyperv_spinlock_attempts;
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* QEMU Hyper-V support
|
|
||||||
*
|
|
||||||
* Copyright Red Hat, Inc. 2011
|
|
||||||
*
|
|
||||||
* Author: Vadim Rozenfeld <vrozenfe@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef QEMU_HW_HYPERV_H
|
|
||||||
#define QEMU_HW_HYPERV_H 1
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
#ifdef CONFIG_KVM
|
|
||||||
#include <asm/hyperv.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HYPERV_SPINLOCK_NEVER_RETRY
|
|
||||||
#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KVM_CPUID_SIGNATURE_NEXT
|
|
||||||
#define KVM_CPUID_SIGNATURE_NEXT 0x40000100
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_KVM)
|
|
||||||
void hyperv_enable_vapic_recommended(bool val);
|
|
||||||
void hyperv_enable_relaxed_timing(bool val);
|
|
||||||
void hyperv_set_spinlock_retries(int val);
|
|
||||||
#else
|
|
||||||
static inline void hyperv_enable_vapic_recommended(bool val) { }
|
|
||||||
static inline void hyperv_enable_relaxed_timing(bool val) { }
|
|
||||||
static inline void hyperv_set_spinlock_retries(int val) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool hyperv_enabled(void);
|
|
||||||
bool hyperv_hypercall_available(void);
|
|
||||||
bool hyperv_vapic_recommended(void);
|
|
||||||
bool hyperv_relaxed_timing_enabled(void);
|
|
||||||
int hyperv_get_spinlock_retries(void);
|
|
||||||
|
|
||||||
#endif /* QEMU_HW_HYPERV_H */
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "hw/i386/pc.h"
|
#include "hw/i386/pc.h"
|
||||||
#include "hw/i386/apic.h"
|
#include "hw/i386/apic.h"
|
||||||
#include "exec/ioport.h"
|
#include "exec/ioport.h"
|
||||||
#include "hyperv.h"
|
#include <asm/hyperv.h>
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
|
|
||||||
//#define DEBUG_KVM
|
//#define DEBUG_KVM
|
||||||
|
@ -420,6 +420,22 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs)
|
||||||
return cpu->env.cpuid_apic_id;
|
return cpu->env.cpuid_apic_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef KVM_CPUID_SIGNATURE_NEXT
|
||||||
|
#define KVM_CPUID_SIGNATURE_NEXT 0x40000100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool hyperv_hypercall_available(X86CPU *cpu)
|
||||||
|
{
|
||||||
|
return cpu->hyperv_vapic ||
|
||||||
|
(cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool hyperv_enabled(X86CPU *cpu)
|
||||||
|
{
|
||||||
|
return hyperv_hypercall_available(cpu) ||
|
||||||
|
cpu->hyperv_relaxed_timing;
|
||||||
|
}
|
||||||
|
|
||||||
#define KVM_MAX_CPUID_ENTRIES 100
|
#define KVM_MAX_CPUID_ENTRIES 100
|
||||||
|
|
||||||
int kvm_arch_init_vcpu(CPUState *cs)
|
int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
|
@ -442,7 +458,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
memset(c, 0, sizeof(*c));
|
memset(c, 0, sizeof(*c));
|
||||||
c->function = KVM_CPUID_SIGNATURE;
|
c->function = KVM_CPUID_SIGNATURE;
|
||||||
if (!hyperv_enabled()) {
|
if (!hyperv_enabled(cpu)) {
|
||||||
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
|
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
|
||||||
c->eax = 0;
|
c->eax = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -458,7 +474,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
c->function = KVM_CPUID_FEATURES;
|
c->function = KVM_CPUID_FEATURES;
|
||||||
c->eax = env->features[FEAT_KVM];
|
c->eax = env->features[FEAT_KVM];
|
||||||
|
|
||||||
if (hyperv_enabled()) {
|
if (hyperv_enabled(cpu)) {
|
||||||
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
|
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
|
||||||
c->eax = signature[0];
|
c->eax = signature[0];
|
||||||
|
|
||||||
|
@ -471,10 +487,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
memset(c, 0, sizeof(*c));
|
memset(c, 0, sizeof(*c));
|
||||||
c->function = HYPERV_CPUID_FEATURES;
|
c->function = HYPERV_CPUID_FEATURES;
|
||||||
if (hyperv_relaxed_timing_enabled()) {
|
if (cpu->hyperv_relaxed_timing) {
|
||||||
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
|
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
|
||||||
}
|
}
|
||||||
if (hyperv_vapic_recommended()) {
|
if (cpu->hyperv_vapic) {
|
||||||
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
|
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
|
||||||
c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
|
c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
@ -482,13 +498,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
memset(c, 0, sizeof(*c));
|
memset(c, 0, sizeof(*c));
|
||||||
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
|
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
|
||||||
if (hyperv_relaxed_timing_enabled()) {
|
if (cpu->hyperv_relaxed_timing) {
|
||||||
c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED;
|
c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED;
|
||||||
}
|
}
|
||||||
if (hyperv_vapic_recommended()) {
|
if (cpu->hyperv_vapic) {
|
||||||
c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED;
|
c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED;
|
||||||
}
|
}
|
||||||
c->ebx = hyperv_get_spinlock_retries();
|
c->ebx = cpu->hyperv_spinlock_attempts;
|
||||||
|
|
||||||
c = &cpuid_data.entries[cpuid_i++];
|
c = &cpuid_data.entries[cpuid_i++];
|
||||||
memset(c, 0, sizeof(*c));
|
memset(c, 0, sizeof(*c));
|
||||||
|
@ -1114,11 +1130,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
|
||||||
kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
|
kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
|
||||||
env->steal_time_msr);
|
env->steal_time_msr);
|
||||||
}
|
}
|
||||||
if (hyperv_hypercall_available()) {
|
if (hyperv_hypercall_available(cpu)) {
|
||||||
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
|
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
|
||||||
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
|
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
|
||||||
}
|
}
|
||||||
if (hyperv_vapic_recommended()) {
|
if (cpu->hyperv_vapic) {
|
||||||
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
|
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue