diff options
author | Peter Maydell | 2020-10-08 22:41:20 +0200 |
---|---|---|
committer | Peter Maydell | 2020-10-08 22:41:20 +0200 |
commit | 497d415d76b9f59fcae27f22df1ca2c3fa4df64e (patch) | |
tree | e4c09699e7ad90a4ae2d2ece477c25a6569420e5 /target | |
parent | Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20201008' into staging (diff) | |
parent | target/arm: Make '-cpu max' have a 48-bit PA (diff) | |
download | qemu-497d415d76b9f59fcae27f22df1ca2c3fa4df64e.tar.gz qemu-497d415d76b9f59fcae27f22df1ca2c3fa4df64e.tar.xz qemu-497d415d76b9f59fcae27f22df1ca2c3fa4df64e.zip |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20201008-1' into staging
target-arm queue:
* hw/ssi/npcm7xx_fiu: Fix handling of unsigned integer
* hw/arm/fsl-imx25: Fix a typo
* hw/arm/sbsa-ref : Fix SMMUv3 Initialisation
* hw/arm/sbsa-ref : allocate IRQs for SMMUv3
* hw/char/bcm2835_aux: Allow less than 32-bit accesses
* hw/arm/virt: Implement kvm-steal-time
* target/arm: Make '-cpu max' have a 48-bit PA
# gpg: Signature made Thu 08 Oct 2020 21:40:31 BST
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20201008-1:
target/arm: Make '-cpu max' have a 48-bit PA
hw/arm/virt: Implement kvm-steal-time
tests/qtest: Restore aarch64 arm-cpu-features test
hw/arm/virt: Move kvm pmu setup to virt_cpu_post_init
hw/arm/virt: Move post cpu realize check into its own function
target/arm/kvm: Make uncalled stubs explicitly unreachable
linux headers: sync to 5.9-rc7
hw/char/bcm2835_aux: Allow less than 32-bit accesses
hw/arm/sbsa-ref : allocate IRQs for SMMUv3
hw/arm/sbsa-ref : Fix SMMUv3 Initialisation
hw/arm/fsl-imx25: Fix a typo
hw/ssi/npcm7xx_fiu: Fix handling of unsigned integer
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 8 | ||||
-rw-r--r-- | target/arm/cpu.h | 4 | ||||
-rw-r--r-- | target/arm/cpu64.c | 4 | ||||
-rw-r--r-- | target/arm/kvm.c | 16 | ||||
-rw-r--r-- | target/arm/kvm64.c | 64 | ||||
-rw-r--r-- | target/arm/kvm_arm.h | 94 | ||||
-rw-r--r-- | target/arm/monitor.c | 2 |
7 files changed, 167 insertions, 25 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 858c5a4bcb..056319859f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1310,6 +1310,14 @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp) return; } } + + if (kvm_enabled()) { + kvm_arm_steal_time_finalize(cpu, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + } } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index e4549a8cc0..cfff1b5c8f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -24,6 +24,7 @@ #include "hw/registerfields.h" #include "cpu-qom.h" #include "exec/cpu-defs.h" +#include "qapi/qapi-types-common.h" /* ARM processors have a weak memory model */ #define TCG_GUEST_DEFAULT_MO (0) @@ -863,6 +864,9 @@ struct ARMCPU { bool kvm_vtime_dirty; uint64_t kvm_vtime; + /* KVM steal time */ + OnOffAuto kvm_steal_time; + /* Uniprocessor system with MP extensions */ bool mp_is_up; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index e00271b932..649213082f 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -653,6 +653,10 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR1, MTE, 2); cpu->isar.id_aa64pfr1 = t; + t = cpu->isar.id_aa64mmfr0; + t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */ + cpu->isar.id_aa64mmfr0 = t; + t = cpu->isar.id_aa64mmfr1; t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 0dcb9bfe13..ffe186de8d 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -192,6 +192,16 @@ static void kvm_no_adjvtime_set(Object *obj, bool value, Error **errp) ARM_CPU(obj)->kvm_adjvtime = !value; } +static bool kvm_steal_time_get(Object *obj, Error **errp) +{ + return ARM_CPU(obj)->kvm_steal_time != ON_OFF_AUTO_OFF; +} + +static void kvm_steal_time_set(Object *obj, bool value, Error **errp) +{ + ARM_CPU(obj)->kvm_steal_time = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + /* KVM VCPU properties should be prefixed with "kvm-". */ void kvm_arm_add_vcpu_properties(Object *obj) { @@ -207,6 +217,12 @@ void kvm_arm_add_vcpu_properties(Object *obj) "the virtual counter. VM stopped time " "will be counted."); } + + cpu->kvm_steal_time = ON_OFF_AUTO_AUTO; + object_property_add_bool(obj, "kvm-steal-time", kvm_steal_time_get, + kvm_steal_time_set); + object_property_set_description(obj, "kvm-steal-time", + "Set off to disable KVM steal time."); } bool kvm_arm_pmu_supported(void) diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index fae07c3f04..f74bac2457 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -17,6 +17,7 @@ #include <linux/kvm.h> #include "qemu-common.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu/timer.h" #include "qemu/error-report.h" @@ -397,19 +398,20 @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr) return NULL; } -static bool kvm_arm_pmu_set_attr(CPUState *cs, struct kvm_device_attr *attr) +static bool kvm_arm_set_device_attr(CPUState *cs, struct kvm_device_attr *attr, + const char *name) { int err; err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); if (err != 0) { - error_report("PMU: KVM_HAS_DEVICE_ATTR: %s", strerror(-err)); + error_report("%s: KVM_HAS_DEVICE_ATTR: %s", name, strerror(-err)); return false; } err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); if (err != 0) { - error_report("PMU: KVM_SET_DEVICE_ATTR: %s", strerror(-err)); + error_report("%s: KVM_SET_DEVICE_ATTR: %s", name, strerror(-err)); return false; } @@ -426,7 +428,7 @@ void kvm_arm_pmu_init(CPUState *cs) if (!ARM_CPU(cs)->has_pmu) { return; } - if (!kvm_arm_pmu_set_attr(cs, &attr)) { + if (!kvm_arm_set_device_attr(cs, &attr, "PMU")) { error_report("failed to init PMU"); abort(); } @@ -443,12 +445,29 @@ void kvm_arm_pmu_set_irq(CPUState *cs, int irq) if (!ARM_CPU(cs)->has_pmu) { return; } - if (!kvm_arm_pmu_set_attr(cs, &attr)) { + if (!kvm_arm_set_device_attr(cs, &attr, "PMU")) { error_report("failed to set irq for PMU"); abort(); } } +void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa) +{ + struct kvm_device_attr attr = { + .group = KVM_ARM_VCPU_PVTIME_CTRL, + .attr = KVM_ARM_VCPU_PVTIME_IPA, + .addr = (uint64_t)&ipa, + }; + + if (ARM_CPU(cs)->kvm_steal_time == ON_OFF_AUTO_OFF) { + return; + } + if (!kvm_arm_set_device_attr(cs, &attr, "PVTIME IPA")) { + error_report("failed to init PVTIME IPA"); + abort(); + } +} + static int read_sys_reg32(int fd, uint32_t *pret, uint64_t id) { uint64_t ret; @@ -655,6 +674,36 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) return true; } +void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp) +{ + bool has_steal_time = kvm_arm_steal_time_supported(); + + if (cpu->kvm_steal_time == ON_OFF_AUTO_AUTO) { + if (!has_steal_time || !arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + cpu->kvm_steal_time = ON_OFF_AUTO_OFF; + } else { + cpu->kvm_steal_time = ON_OFF_AUTO_ON; + } + } else if (cpu->kvm_steal_time == ON_OFF_AUTO_ON) { + if (!has_steal_time) { + error_setg(errp, "'kvm-steal-time' cannot be enabled " + "on this host"); + return; + } else if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { + /* + * DEN0057A chapter 2 says "This specification only covers + * systems in which the Execution state of the hypervisor + * as well as EL1 of virtual machines is AArch64.". And, + * to ensure that, the smc/hvc calls are only specified as + * smc64/hvc64. + */ + error_setg(errp, "'kvm-steal-time' cannot be enabled " + "for AArch32 guests"); + return; + } + } +} + bool kvm_arm_aarch32_supported(void) { return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT); @@ -665,6 +714,11 @@ bool kvm_arm_sve_supported(void) return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE); } +bool kvm_arm_steal_time_supported(void) +{ + return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME); +} + QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1); void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index bc178eeb84..eb81b7059e 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -268,6 +268,24 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); void kvm_arm_add_vcpu_properties(Object *obj); /** + * kvm_arm_steal_time_finalize: + * @cpu: ARMCPU for which to finalize kvm-steal-time + * @errp: Pointer to Error* for error propagation + * + * Validate the kvm-steal-time property selection and set its default + * based on KVM support and guest configuration. + */ +void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp); + +/** + * kvm_arm_steal_time_supported: + * + * Returns: true if KVM can enable steal time reporting + * and false otherwise. + */ +bool kvm_arm_steal_time_supported(void); + +/** * kvm_arm_aarch32_supported: * * Returns: true if KVM can enable AArch32 mode @@ -340,22 +358,24 @@ int kvm_arm_vgic_probe(void); void kvm_arm_pmu_set_irq(CPUState *cs, int irq); void kvm_arm_pmu_init(CPUState *cs); -int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); -#else +/** + * kvm_arm_pvtime_init: + * @cs: CPUState + * @ipa: Per-vcpu guest physical base address of the pvtime structures + * + * Initializes PVTIME for the VCPU, setting the PVTIME IPA to @ipa. + */ +void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa); -static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) -{ - /* - * This should never actually be called in the "not KVM" case, - * but set up the fields to indicate an error anyway. - */ - cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE; - cpu->host_cpu_probe_failed = true; -} +int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); -static inline void kvm_arm_add_vcpu_properties(Object *obj) {} +#else +/* + * It's safe to call these functions without KVM support. + * They should either do nothing or return "not supported". + */ static inline bool kvm_arm_aarch32_supported(void) { return false; @@ -371,23 +391,59 @@ static inline bool kvm_arm_sve_supported(void) return false; } +static inline bool kvm_arm_steal_time_supported(void) +{ + return false; +} + +/* + * These functions should never actually be called without KVM support. + */ +static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu) +{ + g_assert_not_reached(); +} + +static inline void kvm_arm_add_vcpu_properties(Object *obj) +{ + g_assert_not_reached(); +} + static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms) { - return -ENOENT; + g_assert_not_reached(); } static inline int kvm_arm_vgic_probe(void) { - return 0; + g_assert_not_reached(); +} + +static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) +{ + g_assert_not_reached(); +} + +static inline void kvm_arm_pmu_init(CPUState *cs) +{ + g_assert_not_reached(); +} + +static inline void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa) +{ + g_assert_not_reached(); } -static inline void kvm_arm_pmu_set_irq(CPUState *cs, int irq) {} -static inline void kvm_arm_pmu_init(CPUState *cs) {} +static inline void kvm_arm_steal_time_finalize(ARMCPU *cpu, Error **errp) +{ + g_assert_not_reached(); +} -static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) {} +static inline void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map) +{ + g_assert_not_reached(); +} -static inline void kvm_arm_get_virtual_time(CPUState *cs) {} -static inline void kvm_arm_put_virtual_time(CPUState *cs) {} #endif static inline const char *gic_class_name(void) diff --git a/target/arm/monitor.c b/target/arm/monitor.c index 375f34bfaa..169d8a64b6 100644 --- a/target/arm/monitor.c +++ b/target/arm/monitor.c @@ -103,7 +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", + "kvm-no-adjvtime", "kvm-steal-time", NULL }; |