[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 17/22] target/arm/cpu: Set number of PMU counters in KVM
From: |
Jean-Philippe Brucker |
Subject: |
[PATCH v2 17/22] target/arm/cpu: Set number of PMU counters in KVM |
Date: |
Fri, 19 Apr 2024 16:57:05 +0100 |
Add a "num-pmu-counters" CPU parameter to configure the number of
counters that KVM presents to the guest. This is needed for Realm VMs,
whose parameters include the number of PMU counters and influence the
Realm Initial Measurement.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
---
v1->v2: new
---
target/arm/cpu.h | 3 +++
target/arm/kvm_arm.h | 1 +
target/arm/arm-qmp-cmds.c | 2 +-
target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++++
target/arm/kvm.c | 34 +++++++++++++++++++++++++++++++-
5 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 24080da2b7..84f3a67dab 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1093,6 +1093,7 @@ struct ArchCPU {
/* Allows to override the default configuration */
uint8_t num_bps;
uint8_t num_wps;
+ int8_t num_pmu_ctrs;
};
typedef struct ARMCPUInfo {
@@ -2312,6 +2313,8 @@ FIELD(MFAR, FPA, 12, 40)
FIELD(MFAR, NSE, 62, 1)
FIELD(MFAR, NS, 63, 1)
+FIELD(PMCR, N, 11, 5)
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <=
R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index b040686eab..62e39e7184 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -17,6 +17,7 @@
#define KVM_ARM_VGIC_V3 (1 << 1)
#define KVM_REG_ARM_ID_AA64DFR0_EL1 ARM64_SYS_REG(3, 0, 0, 5, 0)
+#define KVM_REG_ARM_PMCR_EL0 ARM64_SYS_REG(3, 3, 9, 12, 0)
/**
* kvm_arm_register_device:
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
index 0f574bb1dd..985d4270b8 100644
--- a/target/arm/arm-qmp-cmds.c
+++ b/target/arm/arm-qmp-cmds.c
@@ -95,7 +95,7 @@ static const char *cpu_model_advertised_features[] = {
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
"kvm-no-adjvtime", "kvm-steal-time",
"pauth", "pauth-impdef", "pauth-qarma3",
- "num-breakpoints", "num-watchpoints",
+ "num-breakpoints", "num-watchpoints", "num-pmu-counters",
NULL
};
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 9ca74eb019..6c2b922d93 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -638,12 +638,53 @@ static void arm_cpu_set_num_bps(Object *obj, Visitor *v,
const char *name,
cpu->num_bps = val;
}
+static void arm_cpu_get_num_pmu_ctrs(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint8_t val;
+ ARMCPU *cpu = ARM_CPU(obj);
+
+ if (cpu->num_pmu_ctrs == -1) {
+ val = FIELD_EX64(cpu->isar.reset_pmcr_el0, PMCR, N);
+ } else {
+ val = cpu->num_pmu_ctrs;
+ }
+
+ visit_type_uint8(v, name, &val, errp);
+}
+
+static void arm_cpu_set_num_pmu_ctrs(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ uint8_t val;
+ ARMCPU *cpu = ARM_CPU(obj);
+ uint8_t max_ctrs = FIELD_EX64(cpu->isar.reset_pmcr_el0, PMCR, N);
+
+ if (!visit_type_uint8(v, name, &val, errp)) {
+ return;
+ }
+
+ if (val > max_ctrs) {
+ error_setg(errp, "invalid number of PMU counters");
+ return;
+ }
+
+ cpu->num_pmu_ctrs = val;
+}
+
static void aarch64_add_kvm_writable_properties(Object *obj)
{
+ ARMCPU *cpu = ARM_CPU(obj);
+
object_property_add(obj, "num-breakpoints", "uint8", arm_cpu_get_num_bps,
arm_cpu_set_num_bps, NULL, NULL);
object_property_add(obj, "num-watchpoints", "uint8", arm_cpu_get_num_wps,
arm_cpu_set_num_wps, NULL, NULL);
+
+ cpu->num_pmu_ctrs = -1;
+ object_property_add(obj, "num-pmu-counters", "uint8",
+ arm_cpu_get_num_pmu_ctrs, arm_cpu_set_num_pmu_ctrs,
+ NULL, NULL);
}
#endif /* CONFIG_KVM */
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 623980a25b..9855cadb1b 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -418,7 +418,7 @@ static bool
kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
if (pmu_supported) {
/* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */
err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0,
- ARM64_SYS_REG(3, 3, 9, 12, 0));
+ KVM_REG_ARM_PMCR_EL0);
}
if (sve_supported) {
@@ -919,9 +919,41 @@ static void kvm_arm_configure_aa64dfr0(ARMCPU *cpu)
}
}
+static void kvm_arm_configure_pmcr(ARMCPU *cpu)
+{
+ int ret;
+ uint64_t val, newval;
+ CPUState *cs = CPU(cpu);
+
+ if (cpu->num_pmu_ctrs == -1) {
+ return;
+ }
+
+ newval = FIELD_DP64(cpu->isar.reset_pmcr_el0, PMCR, N, cpu->num_pmu_ctrs);
+ ret = kvm_set_one_reg(cs, KVM_REG_ARM_PMCR_EL0, &newval);
+ if (ret) {
+ error_report("Failed to set KVM_REG_ARM_PMCR_EL0");
+ return;
+ }
+
+ /*
+ * Check if the write succeeded, since older versions of KVM ignore it.
+ */
+ ret = kvm_get_one_reg(cs, KVM_REG_ARM_PMCR_EL0, &val);
+ if (ret) {
+ error_report("Failed to get KVM_REG_ARM_PMCR_EL0");
+ return;
+ }
+
+ if (val != newval) {
+ error_report("Failed to update KVM_REG_ARM_PMCR_EL0");
+ }
+}
+
static void kvm_arm_configure_vcpu_regs(ARMCPU *cpu)
{
kvm_arm_configure_aa64dfr0(cpu);
+ kvm_arm_configure_pmcr(cpu);
}
/**
--
2.44.0
- [PATCH v2 06/22] hw/arm/virt: Disable DTB randomness for confidential VMs, (continued)
- [PATCH v2 06/22] hw/arm/virt: Disable DTB randomness for confidential VMs, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 04/22] target/arm/kvm-rme: Initialize realm, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 14/22] target/arm/kvm-rme: Add Realm Personalization Value parameter, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 19/22] target/arm/cpu: Inform about reading confidential CPU registers, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 21/22] hw/arm/virt: Move virt_flash_create() to machvirt_init(), Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 22/22] hw/arm/virt: Use RAM instead of flash for confidential guest firmware, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 17/22] target/arm/cpu: Set number of PMU counters in KVM,
Jean-Philippe Brucker <=
- [PATCH v2 01/22] kvm: Merge kvm_check_extension() and kvm_vm_check_extension(), Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 05/22] hw/arm/virt: Add support for Arm RME, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 15/22] target/arm/kvm-rme: Add measurement algorithm property, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 08/22] target/arm/kvm: Split kvm_arch_get/put_registers, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 07/22] hw/arm/virt: Reserve one bit of guest-physical address for RME, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 03/22] target/arm/kvm: Return immediately on error in kvm_arch_init(), Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 09/22] target/arm/kvm-rme: Initialize vCPU, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 10/22] target/arm/kvm: Create scratch VM as Realm if necessary, Jean-Philippe Brucker, 2024/04/19
- [PATCH v2 11/22] hw/core/loader: Add ROM loader notifier, Jean-Philippe Brucker, 2024/04/19