target/arm/cpu: Add the kvm-no-adjvtime CPU property
kvm-no-adjvtime is a KVM specific CPU property and a first of its kind. To accommodate it we also add kvm_arm_add_vcpu_properties() and a KVM specific CPU properties description to the CPU features document. Signed-off-by: Andrew Jones <drjones@redhat.com> Message-id: 20200120101023.16030-7-drjones@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
e5ac4200b4
commit
dea101a1ae
|
@ -31,7 +31,9 @@ supporting the feature or only supporting the feature under certain
|
||||||
configurations. For example, the `aarch64` CPU feature, which, when
|
configurations. For example, the `aarch64` CPU feature, which, when
|
||||||
disabled, enables the optional AArch32 CPU feature, is only supported
|
disabled, enables the optional AArch32 CPU feature, is only supported
|
||||||
when using the KVM accelerator and when running on a host CPU type that
|
when using the KVM accelerator and when running on a host CPU type that
|
||||||
supports the feature.
|
supports the feature. While `aarch64` currently only works with KVM,
|
||||||
|
it could work with TCG. CPU features that are specific to KVM are
|
||||||
|
prefixed with "kvm-" and are described in "KVM VCPU Features".
|
||||||
|
|
||||||
CPU Feature Probing
|
CPU Feature Probing
|
||||||
===================
|
===================
|
||||||
|
@ -171,6 +173,39 @@ disabling many SVE vector lengths would be quite verbose, the `sve<N>` CPU
|
||||||
properties have special semantics (see "SVE CPU Property Parsing
|
properties have special semantics (see "SVE CPU Property Parsing
|
||||||
Semantics").
|
Semantics").
|
||||||
|
|
||||||
|
KVM VCPU Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
KVM VCPU features are CPU features that are specific to KVM, such as
|
||||||
|
paravirt features or features that enable CPU virtualization extensions.
|
||||||
|
The features' CPU properties are only available when KVM is enabled and
|
||||||
|
are named with the prefix "kvm-". KVM VCPU features may be probed,
|
||||||
|
enabled, and disabled in the same way as other CPU features. Below is
|
||||||
|
the list of KVM VCPU features and their descriptions.
|
||||||
|
|
||||||
|
kvm-no-adjvtime By default kvm-no-adjvtime is disabled. This
|
||||||
|
means that by default the virtual time
|
||||||
|
adjustment is enabled (vtime is *not not*
|
||||||
|
adjusted).
|
||||||
|
|
||||||
|
When virtual time adjustment is enabled each
|
||||||
|
time the VM transitions back to running state
|
||||||
|
the VCPU's virtual counter is updated to ensure
|
||||||
|
stopped time is not counted. This avoids time
|
||||||
|
jumps surprising guest OSes and applications,
|
||||||
|
as long as they use the virtual counter for
|
||||||
|
timekeeping. However it has the side effect of
|
||||||
|
the virtual and physical counters diverging.
|
||||||
|
All timekeeping based on the virtual counter
|
||||||
|
will appear to lag behind any timekeeping that
|
||||||
|
does not subtract VM stopped time. The guest
|
||||||
|
may resynchronize its virtual counter with
|
||||||
|
other time sources as needed.
|
||||||
|
|
||||||
|
Enable kvm-no-adjvtime to disable virtual time
|
||||||
|
adjustment, also restoring the legacy (pre-5.0)
|
||||||
|
behavior.
|
||||||
|
|
||||||
SVE CPU Properties
|
SVE CPU Properties
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
@ -1663,6 +1663,11 @@ static void machvirt_init(MachineState *machine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vmc->kvm_no_adjvtime &&
|
||||||
|
object_property_find(cpuobj, "kvm-no-adjvtime", NULL)) {
|
||||||
|
object_property_set_bool(cpuobj, true, "kvm-no-adjvtime", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
|
if (vmc->no_pmu && object_property_find(cpuobj, "pmu", NULL)) {
|
||||||
object_property_set_bool(cpuobj, false, "pmu", NULL);
|
object_property_set_bool(cpuobj, false, "pmu", NULL);
|
||||||
}
|
}
|
||||||
|
@ -2153,8 +2158,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 0)
|
||||||
|
|
||||||
static void virt_machine_4_2_options(MachineClass *mc)
|
static void virt_machine_4_2_options(MachineClass *mc)
|
||||||
{
|
{
|
||||||
|
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
|
||||||
|
|
||||||
virt_machine_5_0_options(mc);
|
virt_machine_5_0_options(mc);
|
||||||
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
compat_props_add(mc->compat_props, hw_compat_4_2, hw_compat_4_2_len);
|
||||||
|
vmc->kvm_no_adjvtime = true;
|
||||||
}
|
}
|
||||||
DEFINE_VIRT_MACHINE(4, 2)
|
DEFINE_VIRT_MACHINE(4, 2)
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ typedef struct {
|
||||||
bool smbios_old_sys_ver;
|
bool smbios_old_sys_ver;
|
||||||
bool no_highmem_ecam;
|
bool no_highmem_ecam;
|
||||||
bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
|
bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */
|
||||||
|
bool kvm_no_adjvtime;
|
||||||
} VirtMachineClass;
|
} VirtMachineClass;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -2551,6 +2551,7 @@ static void arm_max_initfn(Object *obj)
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_arm_set_cpu_features_from_host(cpu);
|
kvm_arm_set_cpu_features_from_host(cpu);
|
||||||
|
kvm_arm_add_vcpu_properties(obj);
|
||||||
} else {
|
} else {
|
||||||
cortex_a15_initfn(obj);
|
cortex_a15_initfn(obj);
|
||||||
|
|
||||||
|
@ -2743,6 +2744,7 @@ static void arm_host_initfn(Object *obj)
|
||||||
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
|
||||||
aarch64_add_sve_properties(obj);
|
aarch64_add_sve_properties(obj);
|
||||||
}
|
}
|
||||||
|
kvm_arm_add_vcpu_properties(obj);
|
||||||
arm_cpu_post_init(obj);
|
arm_cpu_post_init(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -605,6 +605,7 @@ static void aarch64_max_initfn(Object *obj)
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_arm_set_cpu_features_from_host(cpu);
|
kvm_arm_set_cpu_features_from_host(cpu);
|
||||||
|
kvm_arm_add_vcpu_properties(obj);
|
||||||
} else {
|
} else {
|
||||||
uint64_t t;
|
uint64_t t;
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
|
#include "qom/object.h"
|
||||||
|
#include "qapi/error.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "sysemu/kvm_int.h"
|
#include "sysemu/kvm_int.h"
|
||||||
|
@ -179,6 +181,32 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
|
||||||
env->features = arm_host_cpu_features.features;
|
env->features = arm_host_cpu_features.features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool kvm_no_adjvtime_get(Object *obj, Error **errp)
|
||||||
|
{
|
||||||
|
return !ARM_CPU(obj)->kvm_adjvtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kvm_no_adjvtime_set(Object *obj, bool value, Error **errp)
|
||||||
|
{
|
||||||
|
ARM_CPU(obj)->kvm_adjvtime = !value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* KVM VCPU properties should be prefixed with "kvm-". */
|
||||||
|
void kvm_arm_add_vcpu_properties(Object *obj)
|
||||||
|
{
|
||||||
|
if (!kvm_enabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARM_CPU(obj)->kvm_adjvtime = true;
|
||||||
|
object_property_add_bool(obj, "kvm-no-adjvtime", kvm_no_adjvtime_get,
|
||||||
|
kvm_no_adjvtime_set, &error_abort);
|
||||||
|
object_property_set_description(obj, "kvm-no-adjvtime",
|
||||||
|
"Set on to disable the adjustment of "
|
||||||
|
"the virtual counter. VM stopped time "
|
||||||
|
"will be counted.", &error_abort);
|
||||||
|
}
|
||||||
|
|
||||||
bool kvm_arm_pmu_supported(CPUState *cpu)
|
bool kvm_arm_pmu_supported(CPUState *cpu)
|
||||||
{
|
{
|
||||||
return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
|
return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
|
||||||
|
|
|
@ -255,6 +255,15 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map);
|
||||||
*/
|
*/
|
||||||
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
|
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* kvm_arm_add_vcpu_properties:
|
||||||
|
* @obj: The CPU object to add the properties to
|
||||||
|
*
|
||||||
|
* Add all KVM specific CPU properties to the CPU object. These
|
||||||
|
* are the CPU properties with "kvm-" prefixed names.
|
||||||
|
*/
|
||||||
|
void kvm_arm_add_vcpu_properties(Object *obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_aarch32_supported:
|
* kvm_arm_aarch32_supported:
|
||||||
* @cs: CPUState
|
* @cs: CPUState
|
||||||
|
@ -345,6 +354,8 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
|
||||||
cpu->host_cpu_probe_failed = true;
|
cpu->host_cpu_probe_failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
|
||||||
|
|
||||||
static inline bool kvm_arm_aarch32_supported(CPUState *cs)
|
static inline bool kvm_arm_aarch32_supported(CPUState *cs)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -103,6 +103,7 @@ static const char *cpu_model_advertised_features[] = {
|
||||||
"sve128", "sve256", "sve384", "sve512",
|
"sve128", "sve256", "sve384", "sve512",
|
||||||
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
|
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
|
||||||
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
|
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
|
||||||
|
"kvm-no-adjvtime",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -428,6 +428,8 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||||
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
|
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
|
||||||
assert_has_not_feature(qts, "cortex-a15", "aarch64");
|
assert_has_not_feature(qts, "cortex-a15", "aarch64");
|
||||||
|
|
||||||
|
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
|
||||||
|
|
||||||
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
||||||
assert_has_feature_enabled(qts, "max", "aarch64");
|
assert_has_feature_enabled(qts, "max", "aarch64");
|
||||||
assert_has_feature_enabled(qts, "max", "sve");
|
assert_has_feature_enabled(qts, "max", "sve");
|
||||||
|
@ -462,6 +464,8 @@ static void test_query_cpu_model_expansion_kvm(const void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
|
||||||
|
|
||||||
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
||||||
bool kvm_supports_sve;
|
bool kvm_supports_sve;
|
||||||
char max_name[8], name[8];
|
char max_name[8], name[8];
|
||||||
|
|
Loading…
Reference in a new issue