aboutsummaryrefslogtreecommitdiff
path: root/target/arm/kvm64.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-10-08 21:41:20 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-10-08 21:41:20 +0100
commit497d415d76b9f59fcae27f22df1ca2c3fa4df64e (patch)
treee4c09699e7ad90a4ae2d2ece477c25a6569420e5 /target/arm/kvm64.c
parente64cf4d569f6461d6b9072e00d6e78d0ab8bd4a7 (diff)
parentd1b6b7017572e8d82f26eb827a1dba0e8cf3cae6 (diff)
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/arm/kvm64.c')
-rw-r--r--target/arm/kvm64.c64
1 files changed, 59 insertions, 5 deletions
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)