From 730f72105b478553c4f22555c29b0f64224ff914 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 31 Jan 2020 14:23:14 +0000 Subject: [PATCH 12/15] target/arm/cpu: Add the kvm-no-adjvtime CPU property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Andrew Jones Message-id: <20200131142314.13175-6-drjones@redhat.com> Patchwork-id: 93623 O-Subject: [RHEL-AV-8.2.0 qemu-kvm PATCH 5/5] target/arm/cpu: Add the kvm-no-adjvtime CPU property Bugzilla: 1647366 RH-Acked-by: Philippe Mathieu-Daudé RH-Acked-by: Auger Eric RH-Acked-by: Gavin Shan Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1647366 Author: Andrew Jones Date: Thu, 30 Jan 2020 16:02:06 +0000 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 Message-id: 20200120101023.16030-7-drjones@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell (cherry picked from commit dea101a1ae9968c9fec6ab0291489dad7c49f36f) Signed-off-by: Danilo C. L. de Paula Conflicts: Dropped the second hunk of the hw/arm/virt.c changes as they would patch dead code. Signed-off-by: Danilo C. L. de Paula --- docs/arm-cpu-features.rst | 37 ++++++++++++++++++++++++++++++++++++- hw/arm/virt.c | 5 +++++ include/hw/arm/virt.h | 1 + target/arm/cpu.c | 2 ++ target/arm/cpu64.c | 1 + target/arm/kvm.c | 28 ++++++++++++++++++++++++++++ target/arm/kvm_arm.h | 11 +++++++++++ target/arm/monitor.c | 1 + tests/arm-cpu-features.c | 4 ++++ 9 files changed, 89 insertions(+), 1 deletion(-) diff --git a/docs/arm-cpu-features.rst b/docs/arm-cpu-features.rst index 1b367e2..45d1eb6 100644 --- a/docs/arm-cpu-features.rst +++ b/docs/arm-cpu-features.rst @@ -31,7 +31,9 @@ supporting the feature or only supporting the feature under certain configurations. For example, the `aarch64` CPU feature, which, when disabled, enables the optional AArch32 CPU feature, is only supported 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 =================== @@ -171,6 +173,39 @@ disabling many SVE vector lengths would be quite verbose, the `sve` CPU properties have special semantics (see "SVE CPU Property Parsing 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 ================== diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e108391..d30d38c 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1707,6 +1707,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)) { object_property_set_bool(cpuobj, false, "pmu", NULL); } diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 53fdf16..77828ce 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -109,6 +109,7 @@ typedef struct { bool smbios_old_sys_ver; bool no_highmem_ecam; bool no_ged; /* Machines < 4.2 has no support for ACPI GED device */ + bool kvm_no_adjvtime; } VirtMachineClass; typedef struct { diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 3788fc3..e46efe9 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2482,6 +2482,7 @@ static void arm_max_initfn(Object *obj) if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); + kvm_arm_add_vcpu_properties(obj); } else { cortex_a15_initfn(obj); @@ -2673,6 +2674,7 @@ static void arm_host_initfn(Object *obj) if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { aarch64_add_sve_properties(obj); } + kvm_arm_add_vcpu_properties(obj); arm_cpu_post_init(obj); } diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index a39d6fc..3cd416d 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -605,6 +605,7 @@ static void aarch64_max_initfn(Object *obj) if (kvm_enabled()) { kvm_arm_set_cpu_features_from_host(cpu); + kvm_arm_add_vcpu_properties(obj); } else { uint64_t t; uint32_t u; diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 26d7f8b..4be9497 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -17,6 +17,8 @@ #include "qemu/timer.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" +#include "qom/object.h" +#include "qapi/error.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.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; } +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) { KVMState *s = KVM_STATE(current_machine->accelerator); diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 01a9a18..ae9e075 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -256,6 +256,15 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map); 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: * @cs: CPUState * @@ -345,6 +354,8 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) 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) { return false; diff --git a/target/arm/monitor.c b/target/arm/monitor.c index fa054f8..9725dff 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -103,6 +103,7 @@ static const char *cpu_model_advertised_features[] = { "sve128", "sve256", "sve384", "sve512", "sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280", "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048", + "kvm-no-adjvtime", NULL }; diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c index 89285ca..ba1a6fe 100644 --- a/tests/arm-cpu-features.c +++ b/tests/arm-cpu-features.c @@ -428,6 +428,8 @@ static void test_query_cpu_model_expansion(const void *data) assert_has_feature_enabled(qts, "cortex-a15", "pmu"); 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")) { assert_has_feature_enabled(qts, "max", "aarch64"); assert_has_feature_enabled(qts, "max", "sve"); @@ -462,6 +464,8 @@ static void test_query_cpu_model_expansion_kvm(const void *data) return; } + assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime"); + if (g_str_equal(qtest_get_arch(), "aarch64")) { bool kvm_supports_sve; char max_name[8], name[8]; -- 1.8.3.1