[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 40/51] target/arm/kvm64: max cpu: Enable SVE when available
From: |
Peter Maydell |
Subject: |
[PULL 40/51] target/arm/kvm64: max cpu: Enable SVE when available |
Date: |
Thu, 24 Oct 2019 17:27:13 +0100 |
From: Andrew Jones <address@hidden>
Enable SVE in the KVM guest when the 'max' cpu type is configured
and KVM supports it. KVM SVE requires use of the new finalize
vcpu ioctl, so we add that now too. For starters SVE can only be
turned on or off, getting all vector lengths the host CPU supports
when on. We'll add the other SVE CPU properties in later patches.
Signed-off-by: Andrew Jones <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
Reviewed-by: Eric Auger <address@hidden>
Tested-by: Masayoshi Mizuma <address@hidden>
Reviewed-by: Beata Michalska <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
target/arm/kvm_arm.h | 27 +++++++++++++++++++++++++++
target/arm/cpu64.c | 17 ++++++++++++++---
target/arm/kvm.c | 5 +++++
target/arm/kvm64.c | 20 +++++++++++++++++++-
tests/arm-cpu-features.c | 4 ++++
5 files changed, 69 insertions(+), 4 deletions(-)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index b4e19457a09..7c12f1501a8 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -27,6 +27,20 @@
*/
int kvm_arm_vcpu_init(CPUState *cs);
+/**
+ * kvm_arm_vcpu_finalize
+ * @cs: CPUState
+ * @feature: int
+ *
+ * Finalizes the configuration of the specified VCPU feature by
+ * invoking the KVM_ARM_VCPU_FINALIZE ioctl. Features requiring
+ * this are documented in the "KVM_ARM_VCPU_FINALIZE" section of
+ * KVM's API documentation.
+ *
+ * Returns: 0 if success else < 0 error code
+ */
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature);
+
/**
* kvm_arm_register_device:
* @mr: memory region for this device
@@ -225,6 +239,14 @@ bool kvm_arm_aarch32_supported(CPUState *cs);
*/
bool kvm_arm_pmu_supported(CPUState *cs);
+/**
+ * bool kvm_arm_sve_supported:
+ * @cs: CPUState
+ *
+ * Returns true if the KVM VCPU can enable SVE and false otherwise.
+ */
+bool kvm_arm_sve_supported(CPUState *cs);
+
/**
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
* IPA address space supported by KVM
@@ -276,6 +298,11 @@ static inline bool kvm_arm_pmu_supported(CPUState *cs)
return false;
}
+static inline bool kvm_arm_sve_supported(CPUState *cs)
+{
+ return false;
+}
+
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
{
return -ENOENT;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 34b0ba2cf6f..a771a28daa5 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -493,6 +493,11 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const
char *name,
return;
}
+ if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
+ error_setg(errp, "'sve' feature not supported by KVM on this host");
+ return;
+ }
+
t = cpu->isar.id_aa64pfr0;
t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
cpu->isar.id_aa64pfr0 = t;
@@ -507,11 +512,16 @@ static void aarch64_max_initfn(Object *obj)
{
ARMCPU *cpu = ARM_CPU(obj);
uint32_t vq;
+ uint64_t t;
if (kvm_enabled()) {
kvm_arm_set_cpu_features_from_host(cpu);
+ if (kvm_arm_sve_supported(CPU(cpu))) {
+ t = cpu->isar.id_aa64pfr0;
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
+ cpu->isar.id_aa64pfr0 = t;
+ }
} else {
- uint64_t t;
uint32_t u;
aarch64_a57_initfn(obj);
@@ -612,8 +622,6 @@ static void aarch64_max_initfn(Object *obj)
object_property_add(obj, "sve-max-vq", "uint32",
cpu_max_get_sve_max_vq,
cpu_max_set_sve_max_vq, NULL, NULL, &error_fatal);
- object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
- cpu_arm_set_sve, NULL, NULL, &error_fatal);
for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
char name[8];
@@ -622,6 +630,9 @@ static void aarch64_max_initfn(Object *obj)
cpu_arm_set_sve_vq, NULL, NULL, &error_fatal);
}
}
+
+ object_property_add(obj, "sve", "bool", cpu_arm_get_sve,
+ cpu_arm_set_sve, NULL, NULL, &error_fatal);
}
struct ARMCPUInfo {
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b473c63edb1..f07332bbda3 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -51,6 +51,11 @@ int kvm_arm_vcpu_init(CPUState *cs)
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
}
+int kvm_arm_vcpu_finalize(CPUState *cs, int feature)
+{
+ return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_FINALIZE, &feature);
+}
+
void kvm_arm_init_serror_injection(CPUState *cs)
{
cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 4c0b11d105a..850da1b5e6a 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -602,6 +602,13 @@ bool kvm_arm_aarch32_supported(CPUState *cpu)
return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
}
+bool kvm_arm_sve_supported(CPUState *cpu)
+{
+ KVMState *s = KVM_STATE(current_machine->accelerator);
+
+ return kvm_check_extension(s, KVM_CAP_ARM_SVE);
+}
+
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
int kvm_arch_init_vcpu(CPUState *cs)
@@ -630,13 +637,17 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
}
if (!kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
- cpu->has_pmu = false;
+ cpu->has_pmu = false;
}
if (cpu->has_pmu) {
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
} else {
unset_feature(&env->features, ARM_FEATURE_PMU);
}
+ if (cpu_isar_feature(aa64_sve, cpu)) {
+ assert(kvm_arm_sve_supported(cs));
+ cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
+ }
/* Do KVM_ARM_VCPU_INIT ioctl */
ret = kvm_arm_vcpu_init(cs);
@@ -644,6 +655,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
return ret;
}
+ if (cpu_isar_feature(aa64_sve, cpu)) {
+ ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_SVE);
+ if (ret) {
+ return ret;
+ }
+ }
+
/*
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
* Currently KVM has its own idea about MPIDR assignment, so we
diff --git a/tests/arm-cpu-features.c b/tests/arm-cpu-features.c
index 5eecd38f6c6..3efc168d62a 100644
--- a/tests/arm-cpu-features.c
+++ b/tests/arm-cpu-features.c
@@ -391,12 +391,16 @@ static void test_query_cpu_model_expansion_kvm(const void
*data)
assert_has_feature(qts, "host", "aarch64");
assert_has_feature(qts, "host", "pmu");
+ assert_has_feature(qts, "max", "sve");
+
assert_error(qts, "cortex-a15",
"We cannot guarantee the CPU type 'cortex-a15' works "
"with KVM on this host", NULL);
} else {
assert_has_not_feature(qts, "host", "aarch64");
assert_has_not_feature(qts, "host", "pmu");
+
+ assert_has_not_feature(qts, "max", "sve");
}
qtest_quit(qts);
--
2.20.1
- [PULL 28/51] hw/timer/xilinx_timer.c: Switch to transaction-based ptimer API, (continued)
- [PULL 28/51] hw/timer/xilinx_timer.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 29/51] hw/dma/xilinx_axidma.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 30/51] hw/timer/slavio_timer: Remove useless check for NULL t->timer, Peter Maydell, 2019/10/24
- [PULL 32/51] hw/timer/grlib_gptimer.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 34/51] hw/watchdog/milkymist-sysctl.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 31/51] hw/timer/slavio_timer.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 33/51] hw/m68k/mcf5206.c: Switch to transaction-based ptimer API, Peter Maydell, 2019/10/24
- [PULL 35/51] target/arm/monitor: Introduce qmp_query_cpu_model_expansion, Peter Maydell, 2019/10/24
- [PULL 36/51] tests: arm: Introduce cpu feature tests, Peter Maydell, 2019/10/24
- [PULL 37/51] target/arm: Allow SVE to be disabled via a CPU property, Peter Maydell, 2019/10/24
- [PULL 40/51] target/arm/kvm64: max cpu: Enable SVE when available,
Peter Maydell <=
- [PULL 41/51] target/arm/kvm: scratch vcpu: Preserve input kvm_vcpu_init features, Peter Maydell, 2019/10/24
- [PULL 39/51] target/arm/kvm64: Add kvm_arch_get/put_sve, Peter Maydell, 2019/10/24
- [PULL 38/51] target/arm/cpu64: max cpu: Introduce sve<N> properties, Peter Maydell, 2019/10/24
- [PULL 44/51] hw/misc/bcm2835_thermal: Add a dummy BCM2835 thermal sensor, Peter Maydell, 2019/10/24
- [PULL 45/51] hw/arm/bcm2835_peripherals: Use the thermal sensor block, Peter Maydell, 2019/10/24
- [PULL 43/51] target/arm/kvm: host cpu: Add support for sve<N> properties, Peter Maydell, 2019/10/24
- [PULL 47/51] hw/arm/bcm2835_peripherals: Use the SYS_timer, Peter Maydell, 2019/10/24
- [PULL 46/51] hw/timer/bcm2835: Add the BCM2835 SYS_timer, Peter Maydell, 2019/10/24
- [PULL 48/51] hw/arm/bcm2836: Make the SoC code modular, Peter Maydell, 2019/10/24
- [PULL 42/51] target/arm/cpu64: max cpu: Support sve properties with KVM, Peter Maydell, 2019/10/24