* [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration
@ 2025-02-14 15:13 Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally Shameer Kolothum
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
Hi,
v6-->v7
https://lore.kernel.org/kvmarm/20250205132222.55816-1-shameerali.kolothum.thodi@huawei.com/
Changes:
-Introduced KVM_REG_ARM_VENDOR_HYP_BMAP_2 register for new hypercall
support(patch #3)
-Added selftest for KVM_REG_ARM_VENDOR_HYP_BMAP_2(patch #5).
This can be sanity tested by the Qemu branch here,
https://github.com/hisilicon/qemu/tree/v9.0-nv-rfcv4-vcpu-model-v2-target-cpu-errata
(branch based on Eric's/Connie's NV + custom CPU series)
Eg: to specify target impl CPUs,
-machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2
Please take a look and let me know your feedback.
Thanks,
Shameer
v5 --> v6
https://lore.kernel.org/kvmarm/20250124151732.6072-1-shameerali.kolothum.thodi@huawei.com/
-Addressed comments from Oliver,
-Changed version to 32 bit to match SMCCC_VERSION
-Don't advertise pKVM hypercalls to guests.
-Moved hypercall invocation to kvm_guest.c
v4 --> v5
https://lore.kernel.org/kvmarm/20241218105345.73472-1-shameerali.kolothum.thodi@huawei.com/
-Addressed comments from Marc,
-Added an hypercall to retrieve version and number of supported target
impl CPUs.
-Added a check for KVM hypercall services availability.
-Removed R-by tags from Connie & Sebastian as patches 2 & 4 are now
changed a bit. Please take another look.
v3 --> v4(Minor updates)
https://lore.kernel.org/kvmarm/20241209115311.40496-1-shameerali.kolothum.thodi@huawei.com/
-Changed MIDR/REVIDR to 64 bits based on feedback from Connie
and Marc(Patch #3).
-Added R-by tags from Sebastian (Thanks!).
RFC v2 --> v3
https://lore.kernel.org/kvmarm/20241024094012.29452-1-shameerali.kolothum.thodi@huawei.com/
-Addressed comments from Oliver(Thanks!).
-Using implementation CPUs MIDR/REVIDR when it is set for
_midr_range() functions(Patch 1 & 3)
-New hypercall for retrieving implementation CPUs(Patch #2).
-Dropped RFC.
RFC v1 --> RFCv2:
https://lore.kernel.org/kvmarm/20241011075053.80540-1-shameerali.kolothum.thodi@huawei.com/
-Introduced hypercalls to retrieve target CPUs info from user space VMM.
see patch #1 for details.
-Patch #2 uses the hypercall to retrieve the target CPU info if any.
-Use the target CPUs MIDR/REVIDR in errata enablement. See patch #3.
Background from v1:
On ARM64 platforms most of the errata workarounds are based on CPU
MIDR/REVIDR values and a number of these workarounds need to be
implemented by the Guest kernel as well. This creates a problem when
Guest needs to be migrated to a platform that differs in these
MIDR/REVIDR values even if the VMM can come up with a common minimum
feature list for the Guest using the recently introduced "Writable
ID registers" support.
(This is roughly based on a discussion I had with Marc and Oliver
at KVM forum. Marc outlined his idea for a solution and this is an
attempt to implement it. Thanks to both and I take all the blame
if this is nowhere near what is intended/required)
Shameer Kolothum (5):
arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
KVM: arm64: Introduce hypercall support for retrieving target
implementations
KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2
smccc/kvm_guest: Enable errata based on implementation CPUs
KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2
.../virt/kvm/arm/fw-pseudo-registers.rst | 15 ++++-
Documentation/virt/kvm/arm/hypercalls.rst | 59 +++++++++++++++++
arch/arm64/include/asm/cputype.h | 50 ++++++++++-----
arch/arm64/include/asm/hypervisor.h | 1 +
arch/arm64/include/asm/kvm_host.h | 3 +-
arch/arm64/include/asm/mmu.h | 3 +-
arch/arm64/include/uapi/asm/kvm.h | 12 ++++
arch/arm64/kernel/cpu_errata.c | 37 ++++++++---
arch/arm64/kernel/cpufeature.c | 8 ++-
arch/arm64/kernel/image-vars.h | 2 +
arch/arm64/kernel/proton-pack.c | 17 +++--
arch/arm64/kvm/hypercalls.c | 13 ++++
arch/arm64/kvm/vgic/vgic-v3.c | 2 +-
drivers/clocksource/arm_arch_timer.c | 2 +-
drivers/firmware/smccc/kvm_guest.c | 63 +++++++++++++++++++
include/linux/arm-smccc.h | 15 +++++
tools/arch/arm64/include/uapi/asm/kvm.h | 12 ++++
.../selftests/kvm/arm64/get-reg-list.c | 1 +
.../testing/selftests/kvm/arm64/hypercalls.c | 46 +++++++++++---
19 files changed, 308 insertions(+), 53 deletions(-)
--
2.47.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
@ 2025-02-14 15:13 ` Shameer Kolothum
2025-02-14 16:02 ` Sebastian Ott
2025-02-14 15:13 ` [PATCH v7 2/5] KVM: arm64: Introduce hypercall support for retrieving target implementations Shameer Kolothum
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
These changes lay the groundwork for adding support for guest kernels,
allowing them to leverage target CPU implementations provided by the
VMM.
No functional changes intended.
Suggested-by: Oliver Upton <oliver.upton@linux.dev>
Reviewed-by: Sebastian Ott <sebott@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
arch/arm64/include/asm/cputype.h | 28 ++++++++++++++--------------
arch/arm64/include/asm/mmu.h | 3 +--
arch/arm64/kernel/cpu_errata.c | 23 +++++++++++++----------
arch/arm64/kernel/cpufeature.c | 6 +++---
arch/arm64/kernel/proton-pack.c | 17 ++++++++---------
arch/arm64/kvm/vgic/vgic-v3.c | 2 +-
drivers/clocksource/arm_arch_timer.c | 2 +-
7 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 6f3f4142e214..2a76f0e30006 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -231,6 +231,16 @@
#define read_cpuid(reg) read_sysreg_s(SYS_ ## reg)
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant. Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline u32 __attribute_const__ read_cpuid_id(void)
+{
+ return read_cpuid(MIDR_EL1);
+}
+
/*
* Represent a range of MIDR values for a given CPU model and a
* range of variant/revision values.
@@ -266,31 +276,21 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
return _model == model && rv >= rv_min && rv <= rv_max;
}
-static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
+static inline bool is_midr_in_range(struct midr_range const *range)
{
- return midr_is_cpu_model_range(midr, range->model,
+ return midr_is_cpu_model_range(read_cpuid_id(), range->model,
range->rv_min, range->rv_max);
}
static inline bool
-is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
+is_midr_in_range_list(struct midr_range const *ranges)
{
while (ranges->model)
- if (is_midr_in_range(midr, ranges++))
+ if (is_midr_in_range(ranges++))
return true;
return false;
}
-/*
- * The CPU ID never changes at run time, so we might as well tell the
- * compiler that it's constant. Use this function to read the CPU ID
- * rather than directly reading processor_id or read_cpuid() directly.
- */
-static inline u32 __attribute_const__ read_cpuid_id(void)
-{
- return read_cpuid(MIDR_EL1);
-}
-
static inline u64 __attribute_const__ read_cpuid_mpidr(void)
{
return read_cpuid(MPIDR_EL1);
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 662471cfc536..30a29e88994b 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -101,8 +101,7 @@ static inline bool kaslr_requires_kpti(void)
if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
extern const struct midr_range cavium_erratum_27456_cpus[];
- if (is_midr_in_range_list(read_cpuid_id(),
- cavium_erratum_27456_cpus))
+ if (is_midr_in_range_list(cavium_erratum_27456_cpus))
return false;
}
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 7ce555862895..99b55893fc4e 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -15,30 +15,34 @@
#include <asm/smp_plat.h>
static bool __maybe_unused
-is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+__is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
+ u32 midr, u32 revidr)
{
const struct arm64_midr_revidr *fix;
- u32 midr = read_cpuid_id(), revidr;
-
- WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
- if (!is_midr_in_range(midr, &entry->midr_range))
+ if (!is_midr_in_range(&entry->midr_range))
return false;
midr &= MIDR_REVISION_MASK | MIDR_VARIANT_MASK;
- revidr = read_cpuid(REVIDR_EL1);
for (fix = entry->fixed_revs; fix && fix->revidr_mask; fix++)
if (midr == fix->midr_rv && (revidr & fix->revidr_mask))
return false;
-
return true;
}
+static bool __maybe_unused
+is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
+{
+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+ return __is_affected_midr_range(entry, read_cpuid_id(),
+ read_cpuid(REVIDR_EL1));
+}
+
static bool __maybe_unused
is_affected_midr_range_list(const struct arm64_cpu_capabilities *entry,
int scope)
{
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
- return is_midr_in_range_list(read_cpuid_id(), entry->midr_range_list);
+ return is_midr_in_range_list(entry->midr_range_list);
}
static bool __maybe_unused
@@ -186,12 +190,11 @@ static bool __maybe_unused
has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
int scope)
{
- u32 midr = read_cpuid_id();
bool has_dic = read_cpuid_cachetype() & BIT(CTR_EL0_DIC_SHIFT);
const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
- return is_midr_in_range(midr, &range) && has_dic;
+ return is_midr_in_range(&range) && has_dic;
}
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4eb7c6698ae4..72e876f37cd4 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1792,7 +1792,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
char const *str = "kpti command line option";
bool meltdown_safe;
- meltdown_safe = is_midr_in_range_list(read_cpuid_id(), kpti_safe_list);
+ meltdown_safe = is_midr_in_range_list(kpti_safe_list);
/* Defer to CPU feature registers */
if (has_cpuid_feature(entry, scope))
@@ -1862,7 +1862,7 @@ static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
!(has_cpuid_feature(entry, scope) ||
- is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
+ is_midr_in_range_list(nv1_ni_list)));
}
#if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
@@ -2045,7 +2045,7 @@ static bool cpu_has_broken_dbm(void)
{},
};
- return is_midr_in_range_list(read_cpuid_id(), cpus);
+ return is_midr_in_range_list(cpus);
}
static bool cpu_can_use_dbm(const struct arm64_cpu_capabilities *cap)
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index da53722f95d4..a573fa40d4b6 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -172,7 +172,7 @@ static enum mitigation_state spectre_v2_get_cpu_hw_mitigation_state(void)
return SPECTRE_UNAFFECTED;
/* Alternatively, we have a list of unaffected CPUs */
- if (is_midr_in_range_list(read_cpuid_id(), spectre_v2_safe_list))
+ if (is_midr_in_range_list(spectre_v2_safe_list))
return SPECTRE_UNAFFECTED;
return SPECTRE_VULNERABLE;
@@ -331,7 +331,7 @@ bool has_spectre_v3a(const struct arm64_cpu_capabilities *entry, int scope)
};
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
- return is_midr_in_range_list(read_cpuid_id(), spectre_v3a_unsafe_list);
+ return is_midr_in_range_list(spectre_v3a_unsafe_list);
}
void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused)
@@ -475,7 +475,7 @@ static enum mitigation_state spectre_v4_get_cpu_hw_mitigation_state(void)
{ /* sentinel */ },
};
- if (is_midr_in_range_list(read_cpuid_id(), spectre_v4_safe_list))
+ if (is_midr_in_range_list(spectre_v4_safe_list))
return SPECTRE_UNAFFECTED;
/* CPU features are detected first */
@@ -878,13 +878,13 @@ u8 spectre_bhb_loop_affected(int scope)
{},
};
- if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list))
+ if (is_midr_in_range_list(spectre_bhb_k32_list))
k = 32;
- else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+ else if (is_midr_in_range_list(spectre_bhb_k24_list))
k = 24;
- else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
+ else if (is_midr_in_range_list(spectre_bhb_k11_list))
k = 11;
- else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+ else if (is_midr_in_range_list(spectre_bhb_k8_list))
k = 8;
max_bhb_k = max(max_bhb_k, k);
@@ -926,8 +926,7 @@ static bool is_spectre_bhb_fw_affected(int scope)
MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
{},
};
- bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(),
- spectre_bhb_firmware_mitigated_list);
+ bool cpu_in_list = is_midr_in_range_list(spectre_bhb_firmware_mitigated_list);
if (scope != SCOPE_LOCAL_CPU)
return system_affected;
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index d7233ab982d0..87a8a96c7a41 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -633,7 +633,7 @@ static const struct midr_range broken_seis[] = {
static bool vgic_v3_broken_seis(void)
{
return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
- is_midr_in_range_list(read_cpuid_id(), broken_seis));
+ is_midr_in_range_list(broken_seis));
}
/**
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 808f259781fd..981a578043a5 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -842,7 +842,7 @@ static u64 __arch_timer_check_delta(void)
{},
};
- if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) {
+ if (is_midr_in_range_list(broken_cval_midrs)) {
pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n");
return CLOCKSOURCE_MASK(31);
}
--
2.47.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 2/5] KVM: arm64: Introduce hypercall support for retrieving target implementations
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally Shameer Kolothum
@ 2025-02-14 15:13 ` Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 3/5] KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
If the Guest requires migration to multiple targets, these hypercalls
will provide a way to retrieve the target CPU implementations from
the user space VMM.
Subsequent patch will use this to enable the associated errata.
Suggested-by: Oliver Upton <oliver.upton@linux.dev>
Suggested-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
Documentation/virt/kvm/arm/hypercalls.rst | 59 +++++++++++++++++++++++
include/linux/arm-smccc.h | 15 ++++++
2 files changed, 74 insertions(+)
diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst
index af7bc2c2e0cb..7400a89aabf8 100644
--- a/Documentation/virt/kvm/arm/hypercalls.rst
+++ b/Documentation/virt/kvm/arm/hypercalls.rst
@@ -142,3 +142,62 @@ region is equal to the memory protection granule advertised by
| | | +---------------------------------------------+
| | | | ``INVALID_PARAMETER (-3)`` |
+---------------------+----------+----+---------------------------------------------+
+
+``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID``
+-------------------------------------------------------
+Request the target CPU implementation version information and the number of target
+implementations for the Guest VM.
+
++---------------------+-------------------------------------------------------------+
+| Presence: | Optional; KVM/ARM64 Guests only |
++---------------------+-------------------------------------------------------------+
+| Calling convention: | HVC64 |
++---------------------+----------+--------------------------------------------------+
+| Function ID: | (uint32) | 0xC6000040 |
++---------------------+----------+--------------------------------------------------+
+| Arguments: | None |
++---------------------+----------+----+---------------------------------------------+
+| Return Values: | (int64) | R0 | ``SUCCESS (0)`` |
+| | | +---------------------------------------------+
+| | | | ``NOT_SUPPORTED (-1)`` |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R1 | Bits [63:32] Reserved/Must be zero |
+| | | +---------------------------------------------+
+| | | | Bits [31:16] Major version |
+| | | +---------------------------------------------+
+| | | | Bits [15:0] Minor version |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R2 | Number of target implementations |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R3 | Reserved / Must be zero |
++---------------------+----------+----+---------------------------------------------+
+
+``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID``
+-------------------------------------------------------
+
+Request the target CPU implementation information for the Guest VM. The Guest kernel
+will use this information to enable the associated errata.
+
++---------------------+-------------------------------------------------------------+
+| Presence: | Optional; KVM/ARM64 Guests only |
++---------------------+-------------------------------------------------------------+
+| Calling convention: | HVC64 |
++---------------------+----------+--------------------------------------------------+
+| Function ID: | (uint32) | 0xC6000041 |
++---------------------+----------+----+---------------------------------------------+
+| Arguments: | (uint64) | R1 | selected implementation index |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R2 | Reserved / Must be zero |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R3 | Reserved / Must be zero |
++---------------------+----------+----+---------------------------------------------+
+| Return Values: | (int64) | R0 | ``SUCCESS (0)`` |
+| | | +---------------------------------------------+
+| | | | ``INVALID_PARAMETER (-3)`` |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R1 | MIDR_EL1 of the selected implementation |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R2 | REVIDR_EL1 of the selected implementation |
+| +----------+----+---------------------------------------------+
+| | (uint64) | R3 | AIDR_EL1 of the selected implementation |
++---------------------+----------+----+---------------------------------------------+
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 67f6fdf2e7cd..f19be5754090 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -179,6 +179,9 @@
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63
/* End of pKVM hypercall range */
+#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64
+#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65
+
#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
#define ARM_SMCCC_KVM_NUM_FUNCS 128
@@ -225,6 +228,18 @@
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
+#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_VENDOR_HYP, \
+ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER)
+
+#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+ ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_VENDOR_HYP, \
+ ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
+
/* ptp_kvm counter type ID */
#define KVM_PTP_VIRT_COUNTER 0
#define KVM_PTP_PHYS_COUNTER 1
--
2.47.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 3/5] KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 2/5] KVM: arm64: Introduce hypercall support for retrieving target implementations Shameer Kolothum
@ 2025-02-14 15:13 ` Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs Shameer Kolothum
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
The vendor_hyp_bmap bitmap holds the information about the Vendor Hyp
services available to the user space and can be get/set using
{G, S}ET_ONE_REG interfaces. This is done using the pseudo-firmware
bitmap register KVM_REG_ARM_VENDOR_HYP_BMAP.
At present, this bitmap is a 64 bit one and since the function numbers
for newly added DISCOVER_IPML_* hypercalls are 64-65, introduce
another pseudo-firmware bitmap register KVM_REG_ARM_VENDOR_HYP_BMAP_2.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
.../virt/kvm/arm/fw-pseudo-registers.rst | 15 ++++++++++++++-
arch/arm64/include/asm/kvm_host.h | 3 ++-
arch/arm64/include/uapi/asm/kvm.h | 12 ++++++++++++
arch/arm64/kvm/hypercalls.c | 13 +++++++++++++
4 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/Documentation/virt/kvm/arm/fw-pseudo-registers.rst b/Documentation/virt/kvm/arm/fw-pseudo-registers.rst
index b90fd0b0fa66..d78b53b05dfc 100644
--- a/Documentation/virt/kvm/arm/fw-pseudo-registers.rst
+++ b/Documentation/virt/kvm/arm/fw-pseudo-registers.rst
@@ -116,7 +116,7 @@ The pseudo-firmware bitmap register are as follows:
ARM DEN0057A.
* KVM_REG_ARM_VENDOR_HYP_BMAP:
- Controls the bitmap of the Vendor specific Hypervisor Service Calls.
+ Controls the bitmap of the Vendor specific Hypervisor Service Calls[0-63].
The following bits are accepted:
@@ -127,6 +127,19 @@ The pseudo-firmware bitmap register are as follows:
Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
The bit represents the Precision Time Protocol KVM service.
+* KVM_REG_ARM_VENDOR_HYP_BMAP_2:
+ Controls the bitmap of the Vendor specific Hypervisor Service Calls[64-127].
+
+ The following bits are accepted:
+
+ Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER
+ This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID
+ function-id. This is reset to 0.
+
+ Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS
+ This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID
+ function-id. This is reset to 0.
+
Errors:
======= =============================================================
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7cfa024de4e3..4cea172ebaaa 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -237,7 +237,8 @@ struct kvm_arch_memory_slot {
struct kvm_smccc_features {
unsigned long std_bmap;
unsigned long std_hyp_bmap;
- unsigned long vendor_hyp_bmap;
+ unsigned long vendor_hyp_bmap; /* Function numbers 0-63 */
+ unsigned long vendor_hyp_bmap_2; /* Function numbers 64-127 */
};
typedef unsigned int pkvm_handle_t;
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 568bf858f319..072feeff74d0 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -371,6 +371,7 @@ enum {
#endif
};
+/* Vendor hyper call function numbers 0-63 */
#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
enum {
@@ -381,6 +382,17 @@ enum {
#endif
};
+/* Vendor hyper call function numbers 64-127 */
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2 KVM_REG_ARM_FW_FEAT_BMAP_REG(3)
+
+enum {
+ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER = 0,
+ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS = 1,
+#ifdef __KERNEL__
+ KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT,
+#endif
+};
+
/* Device Control API on vm fd */
#define KVM_ARM_VM_SMCCC_CTRL 0
#define KVM_ARM_VM_SMCCC_FILTER 0
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 27ce4cb44904..569941eeb3fe 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -15,6 +15,8 @@
GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES \
GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0)
+#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2 \
+ GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT - 1, 0)
static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
{
@@ -360,6 +362,8 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
break;
case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
val[0] = smccc_feat->vendor_hyp_bmap;
+ /* Function numbers 2-63 are reserved for pKVM for now */
+ val[2] = smccc_feat->vendor_hyp_bmap_2;
break;
case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
kvm_ptp_get_time(vcpu, val);
@@ -387,6 +391,7 @@ static const u64 kvm_arm_fw_reg_ids[] = {
KVM_REG_ARM_STD_BMAP,
KVM_REG_ARM_STD_HYP_BMAP,
KVM_REG_ARM_VENDOR_HYP_BMAP,
+ KVM_REG_ARM_VENDOR_HYP_BMAP_2,
};
void kvm_arm_init_hypercalls(struct kvm *kvm)
@@ -497,6 +502,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case KVM_REG_ARM_VENDOR_HYP_BMAP:
val = READ_ONCE(smccc_feat->vendor_hyp_bmap);
break;
+ case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
+ val = READ_ONCE(smccc_feat->vendor_hyp_bmap_2);
+ break;
default:
return -ENOENT;
}
@@ -527,6 +535,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
fw_reg_bmap = &smccc_feat->vendor_hyp_bmap;
fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
break;
+ case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
+ fw_reg_bmap = &smccc_feat->vendor_hyp_bmap_2;
+ fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2;
+ break;
default:
return -ENOENT;
}
@@ -633,6 +645,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
case KVM_REG_ARM_STD_BMAP:
case KVM_REG_ARM_STD_HYP_BMAP:
case KVM_REG_ARM_VENDOR_HYP_BMAP:
+ case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
default:
return -ENOENT;
--
2.47.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
` (2 preceding siblings ...)
2025-02-14 15:13 ` [PATCH v7 3/5] KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
@ 2025-02-14 15:13 ` Shameer Kolothum
2025-02-14 16:12 ` Sebastian Ott
2025-02-14 15:13 ` [PATCH v7 5/5] KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
2025-02-14 17:34 ` [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Sebastian Ott
5 siblings, 1 reply; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
Retrieve any migration target implementation CPUs using the hypercall
and enable associated errata.
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
arch/arm64/include/asm/cputype.h | 24 ++++++++++-
arch/arm64/include/asm/hypervisor.h | 1 +
arch/arm64/kernel/cpu_errata.c | 20 +++++++--
arch/arm64/kernel/cpufeature.c | 2 +
arch/arm64/kernel/image-vars.h | 2 +
drivers/firmware/smccc/kvm_guest.c | 63 +++++++++++++++++++++++++++++
6 files changed, 107 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 2a76f0e30006..975fbdfc9354 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -267,6 +267,15 @@ struct midr_range {
#define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
#define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
+struct target_impl_cpu {
+ u64 midr;
+ u64 revidr;
+ u64 aidr;
+};
+
+extern u32 target_impl_cpu_num;
+extern struct target_impl_cpu *target_impl_cpus;
+
static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
u32 rv_max)
{
@@ -278,8 +287,19 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
static inline bool is_midr_in_range(struct midr_range const *range)
{
- return midr_is_cpu_model_range(read_cpuid_id(), range->model,
- range->rv_min, range->rv_max);
+ int i;
+
+ if (!target_impl_cpu_num)
+ return midr_is_cpu_model_range(read_cpuid_id(), range->model,
+ range->rv_min, range->rv_max);
+
+ for (i = 0; i < target_impl_cpu_num; i++) {
+ if (midr_is_cpu_model_range(target_impl_cpus[i].midr,
+ range->model,
+ range->rv_min, range->rv_max))
+ return true;
+ }
+ return false;
}
static inline bool
diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h
index 409e239834d1..a12fd897c877 100644
--- a/arch/arm64/include/asm/hypervisor.h
+++ b/arch/arm64/include/asm/hypervisor.h
@@ -6,6 +6,7 @@
void kvm_init_hyp_services(void);
bool kvm_arm_hyp_service_available(u32 func_id);
+void kvm_arm_target_impl_cpu_init(void);
#ifdef CONFIG_ARM_PKVM_GUEST
void pkvm_init_hyp_services(void);
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 99b55893fc4e..1177a3094cf2 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -14,6 +14,9 @@
#include <asm/kvm_asm.h>
#include <asm/smp_plat.h>
+u32 target_impl_cpu_num;
+struct target_impl_cpu *target_impl_cpus;
+
static bool __maybe_unused
__is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
u32 midr, u32 revidr)
@@ -32,9 +35,20 @@ __is_affected_midr_range(const struct arm64_cpu_capabilities *entry,
static bool __maybe_unused
is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope)
{
- WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
- return __is_affected_midr_range(entry, read_cpuid_id(),
- read_cpuid(REVIDR_EL1));
+ int i;
+
+ if (!target_impl_cpu_num) {
+ WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
+ return __is_affected_midr_range(entry, read_cpuid_id(),
+ read_cpuid(REVIDR_EL1));
+ }
+
+ for (i = 0; i < target_impl_cpu_num; i++) {
+ if (__is_affected_midr_range(entry, target_impl_cpus[i].midr,
+ target_impl_cpus[i].midr))
+ return true;
+ }
+ return false;
}
static bool __maybe_unused
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 72e876f37cd4..5c61d9d9f097 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -86,6 +86,7 @@
#include <asm/kvm_host.h>
#include <asm/mmu_context.h>
#include <asm/mte.h>
+#include <asm/hypervisor.h>
#include <asm/processor.h>
#include <asm/smp.h>
#include <asm/sysreg.h>
@@ -3679,6 +3680,7 @@ unsigned long cpu_get_elf_hwcap3(void)
static void __init setup_boot_cpu_capabilities(void)
{
+ kvm_arm_target_impl_cpu_init();
/*
* The boot CPU's feature register values have been recorded. Detect
* boot cpucaps and local cpucaps for the boot CPU, then enable and
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index ef3a69cc398e..a6926750faaf 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -49,6 +49,8 @@ PROVIDE(__pi_arm64_sw_feature_override = arm64_sw_feature_override);
PROVIDE(__pi_arm64_use_ng_mappings = arm64_use_ng_mappings);
#ifdef CONFIG_CAVIUM_ERRATUM_27456
PROVIDE(__pi_cavium_erratum_27456_cpus = cavium_erratum_27456_cpus);
+PROVIDE(__pi_target_impl_cpu_num = target_impl_cpu_num);
+PROVIDE(__pi_target_impl_cpus = target_impl_cpus);
#endif
PROVIDE(__pi__ctype = _ctype);
PROVIDE(__pi_memstart_offset_seed = memstart_offset_seed);
diff --git a/drivers/firmware/smccc/kvm_guest.c b/drivers/firmware/smccc/kvm_guest.c
index f3319be20b36..c1d2f28b0f58 100644
--- a/drivers/firmware/smccc/kvm_guest.c
+++ b/drivers/firmware/smccc/kvm_guest.c
@@ -6,8 +6,11 @@
#include <linux/bitmap.h>
#include <linux/cache.h>
#include <linux/kernel.h>
+#include <linux/memblock.h>
#include <linux/string.h>
+#include <uapi/linux/psci.h>
+
#include <asm/hypervisor.h>
static DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS) __ro_after_init = { };
@@ -51,3 +54,63 @@ bool kvm_arm_hyp_service_available(u32 func_id)
return test_bit(func_id, __kvm_arm_hyp_services);
}
EXPORT_SYMBOL_GPL(kvm_arm_hyp_service_available);
+
+void __init kvm_arm_target_impl_cpu_init(void)
+{
+ int i;
+ u32 ver;
+ u64 max_cpus;
+ struct arm_smccc_res res;
+
+ /* Check we have already set targets */
+ if (target_impl_cpu_num)
+ return;
+
+ if (!kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER) ||
+ !kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS))
+ return;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID,
+ 0, &res);
+ if (res.a0 != SMCCC_RET_SUCCESS)
+ return;
+
+ /* Version info is in lower 32 bits and is in SMMCCC_VERSION format */
+ ver = lower_32_bits(res.a1);
+ if (PSCI_VERSION_MAJOR(ver) != 1) {
+ pr_warn("Unsupported target CPU implementation version v%d:%d\n",
+ PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver));
+ return;
+ }
+
+ if (!res.a2) {
+ pr_warn("No target implementation CPUs specified\n");
+ return;
+ }
+
+ max_cpus = res.a2;
+ target_impl_cpus = memblock_alloc(sizeof(*target_impl_cpus) * max_cpus,
+ __alignof__(*target_impl_cpus));
+ if (!target_impl_cpus) {
+ pr_warn("Not enough memory for struct target_impl_cpu\n");
+ return;
+ }
+
+ for (i = 0; i < max_cpus; i++) {
+ arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID,
+ i, &res);
+ if (res.a0 != SMCCC_RET_SUCCESS) {
+ memblock_free(target_impl_cpus,
+ sizeof(*target_impl_cpus) * max_cpus);
+ target_impl_cpus = NULL;
+ pr_warn("Discovering target implementation CPUs failed\n");
+ return;
+ }
+ target_impl_cpus[i].midr = res.a1;
+ target_impl_cpus[i].revidr = res.a2;
+ target_impl_cpus[i].aidr = res.a3;
+ };
+
+ target_impl_cpu_num = max_cpus;
+ pr_info("Number of target implementation CPUs is %d\n", target_impl_cpu_num);
+}
--
2.47.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v7 5/5] KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
` (3 preceding siblings ...)
2025-02-14 15:13 ` [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs Shameer Kolothum
@ 2025-02-14 15:13 ` Shameer Kolothum
2025-02-14 17:34 ` [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Sebastian Ott
5 siblings, 0 replies; 11+ messages in thread
From: Shameer Kolothum @ 2025-02-14 15:13 UTC (permalink / raw)
To: kvmarm, maz, oliver.upton
Cc: catalin.marinas, will, mark.rutland, cohuck, eric.auger, sebott,
yuzenghui, wangzhou1, jiangkunkun, jonathan.cameron,
anthony.jebson, linux-arm-kernel, linuxarm
One difference here with other pseudo-firmware bitmap registers
is that the default/reset value for the supported hypercall
function-ids is 0 at present. Hence, modify the test accordingly.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
---
tools/arch/arm64/include/uapi/asm/kvm.h | 12 +++++
.../selftests/kvm/arm64/get-reg-list.c | 1 +
.../testing/selftests/kvm/arm64/hypercalls.c | 46 +++++++++++++++----
3 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
index 66736ff04011..6d44f8c8a18f 100644
--- a/tools/arch/arm64/include/uapi/asm/kvm.h
+++ b/tools/arch/arm64/include/uapi/asm/kvm.h
@@ -374,6 +374,7 @@ enum {
#endif
};
+/* Vendor hyper call function numbers 0-63 */
#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2)
enum {
@@ -384,6 +385,17 @@ enum {
#endif
};
+/* Vendor hyper call function numbers 64-127 */
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2 KVM_REG_ARM_FW_FEAT_BMAP_REG(3)
+
+enum {
+ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER = 0,
+ KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS = 1,
+#ifdef __KERNEL__
+ KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT,
+#endif
+};
+
/* Device Control API on vm fd */
#define KVM_ARM_VM_SMCCC_CTRL 0
#define KVM_ARM_VM_SMCCC_FILTER 0
diff --git a/tools/testing/selftests/kvm/arm64/get-reg-list.c b/tools/testing/selftests/kvm/arm64/get-reg-list.c
index d43fb3f49050..d01798b6b3b4 100644
--- a/tools/testing/selftests/kvm/arm64/get-reg-list.c
+++ b/tools/testing/selftests/kvm/arm64/get-reg-list.c
@@ -332,6 +332,7 @@ static __u64 base_regs[] = {
KVM_REG_ARM_FW_FEAT_BMAP_REG(0), /* KVM_REG_ARM_STD_BMAP */
KVM_REG_ARM_FW_FEAT_BMAP_REG(1), /* KVM_REG_ARM_STD_HYP_BMAP */
KVM_REG_ARM_FW_FEAT_BMAP_REG(2), /* KVM_REG_ARM_VENDOR_HYP_BMAP */
+ KVM_REG_ARM_FW_FEAT_BMAP_REG(3), /* KVM_REG_ARM_VENDOR_HYP_BMAP_2 */
ARM64_SYS_REG(3, 3, 14, 3, 1), /* CNTV_CTL_EL0 */
ARM64_SYS_REG(3, 3, 14, 3, 2), /* CNTV_CVAL_EL0 */
ARM64_SYS_REG(3, 3, 14, 0, 2),
diff --git a/tools/testing/selftests/kvm/arm64/hypercalls.c b/tools/testing/selftests/kvm/arm64/hypercalls.c
index ec54ec7726e9..44cfcf8a7f46 100644
--- a/tools/testing/selftests/kvm/arm64/hypercalls.c
+++ b/tools/testing/selftests/kvm/arm64/hypercalls.c
@@ -21,22 +21,31 @@
#define KVM_REG_ARM_STD_BMAP_BIT_MAX 0
#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX 0
#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX 1
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_MAX 1
+
+#define KVM_REG_ARM_STD_BMAP_RESET_VAL FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_BMAP_BIT_MAX)
+#define KVM_REG_ARM_STD_HYP_BMAP_RESET_VAL FW_REG_ULIMIT_VAL(KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX)
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_RESET_VAL FW_REG_ULIMIT_VAL(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX)
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_2_RESET_VAL 0
struct kvm_fw_reg_info {
uint64_t reg; /* Register definition */
uint64_t max_feat_bit; /* Bit that represents the upper limit of the feature-map */
+ uint64_t reset_val; /* Reset value for the register */
};
#define FW_REG_INFO(r) \
{ \
.reg = r, \
.max_feat_bit = r##_BIT_MAX, \
+ .reset_val = r##_RESET_VAL \
}
static const struct kvm_fw_reg_info fw_reg_info[] = {
FW_REG_INFO(KVM_REG_ARM_STD_BMAP),
FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP),
FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP),
+ FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP_2),
};
enum test_stage {
@@ -171,22 +180,39 @@ static void test_fw_regs_before_vm_start(struct kvm_vcpu *vcpu)
for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
+ uint64_t set_val;
- /* First 'read' should be an upper limit of the features supported */
+ /* First 'read' should be the reset value for the reg */
val = vcpu_get_reg(vcpu, reg_info->reg);
- TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
- "Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
- reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val);
+ TEST_ASSERT(val == reg_info->reset_val,
+ "Unexpected reset value for reg: 0x%lx; expected: 0x%lx; read: 0x%lx",
+ reg_info->reg, reg_info->reset_val, val);
+
+ if (reg_info->reset_val)
+ set_val = 0;
+ else
+ set_val = FW_REG_ULIMIT_VAL(reg_info->max_feat_bit);
- /* Test a 'write' by disabling all the features of the register map */
- ret = __vcpu_set_reg(vcpu, reg_info->reg, 0);
+ ret = __vcpu_set_reg(vcpu, reg_info->reg, set_val);
TEST_ASSERT(ret == 0,
- "Failed to clear all the features of reg: 0x%lx; ret: %d",
- reg_info->reg, errno);
+ "Failed to %s all the features of reg: 0x%lx; ret: %d",
+ (set_val ? "set" : "clear"), reg_info->reg, errno);
val = vcpu_get_reg(vcpu, reg_info->reg);
- TEST_ASSERT(val == 0,
- "Expected all the features to be cleared for reg: 0x%lx", reg_info->reg);
+ TEST_ASSERT(val == set_val,
+ "Expected all the features to be %s for reg: 0x%lx",
+ (set_val ? "set" : "cleared"), reg_info->reg);
+
+ /*
+ * If the reg has been set, clear it as test_fw_regs_after_vm_start()
+ * expects it to be cleared.
+ */
+ if (set_val) {
+ ret = __vcpu_set_reg(vcpu, reg_info->reg, 0);
+ TEST_ASSERT(ret == 0,
+ "Failed to clear all the features of reg: 0x%lx; ret: %d",
+ reg_info->reg, errno);
+ }
/*
* Test enabling a feature that's not supported.
--
2.47.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally
2025-02-14 15:13 ` [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally Shameer Kolothum
@ 2025-02-14 16:02 ` Sebastian Ott
0 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ott @ 2025-02-14 16:02 UTC (permalink / raw)
To: Shameer Kolothum
Cc: kvmarm, maz, oliver.upton, catalin.marinas, will, mark.rutland,
cohuck, eric.auger, yuzenghui, wangzhou1, jiangkunkun,
jonathan.cameron, anthony.jebson, linux-arm-kernel, linuxarm
[-- Attachment #1: Type: text/plain, Size: 642 bytes --]
Hi Shameer,
On Fri, 14 Feb 2025, Shameer Kolothum wrote:
> static inline bool
> -is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
> +is_midr_in_range_list(struct midr_range const *ranges)
> {
> while (ranges->model)
> - if (is_midr_in_range(midr, ranges++))
> + if (is_midr_in_range(ranges++))
> return true;
> return false;
> }
There's one more user of this:
drivers/hwtracing/coresight/coresight-etm4x-core.c:1219:13: error: too many arguments to function ‘is_midr_in_range_list’
1219 | if (is_midr_in_range_list(read_cpuid_id(), etm_wrong_ccitmin_cpus)) {
| ^~~~~~~~~~~~~~~~~~~~~
(sr)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs
2025-02-14 15:13 ` [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs Shameer Kolothum
@ 2025-02-14 16:12 ` Sebastian Ott
2025-02-14 16:43 ` Marc Zyngier
0 siblings, 1 reply; 11+ messages in thread
From: Sebastian Ott @ 2025-02-14 16:12 UTC (permalink / raw)
To: Shameer Kolothum
Cc: kvmarm, maz, oliver.upton, catalin.marinas, will, mark.rutland,
cohuck, eric.auger, yuzenghui, wangzhou1, jiangkunkun,
jonathan.cameron, anthony.jebson, linux-arm-kernel, linuxarm
On Fri, 14 Feb 2025, Shameer Kolothum wrote:
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -14,6 +14,9 @@
> #include <asm/kvm_asm.h>
> #include <asm/smp_plat.h>
>
> +u32 target_impl_cpu_num;
> +struct target_impl_cpu *target_impl_cpus;
These should be exported (for configs using
CONFIG_CORESIGHT_SOURCE_ETM4X=m)
Sebastian
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs
2025-02-14 16:12 ` Sebastian Ott
@ 2025-02-14 16:43 ` Marc Zyngier
2025-02-18 7:40 ` Shameerali Kolothum Thodi
0 siblings, 1 reply; 11+ messages in thread
From: Marc Zyngier @ 2025-02-14 16:43 UTC (permalink / raw)
To: Sebastian Ott
Cc: Shameer Kolothum, kvmarm, oliver.upton, catalin.marinas, will,
mark.rutland, cohuck, eric.auger, yuzenghui, wangzhou1,
jiangkunkun, jonathan.cameron, anthony.jebson, linux-arm-kernel,
linuxarm
On Fri, 14 Feb 2025 16:12:02 +0000,
Sebastian Ott <sebott@redhat.com> wrote:
>
> On Fri, 14 Feb 2025, Shameer Kolothum wrote:
> > +++ b/arch/arm64/kernel/cpu_errata.c
> > @@ -14,6 +14,9 @@
> > #include <asm/kvm_asm.h>
> > #include <asm/smp_plat.h>
> >
> > +u32 target_impl_cpu_num;
> > +struct target_impl_cpu *target_impl_cpus;
>
> These should be exported (for configs using
> CONFIG_CORESIGHT_SOURCE_ETM4X=m)
It might be better to make is_midr_in_range() out of line, and export
that. This could allow making the data static (by implementing a
couple of additional accessors).
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
` (4 preceding siblings ...)
2025-02-14 15:13 ` [PATCH v7 5/5] KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
@ 2025-02-14 17:34 ` Sebastian Ott
5 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ott @ 2025-02-14 17:34 UTC (permalink / raw)
To: Shameer Kolothum
Cc: kvmarm, maz, oliver.upton, catalin.marinas, will, mark.rutland,
cohuck, eric.auger, yuzenghui, wangzhou1, jiangkunkun,
jonathan.cameron, anthony.jebson, linux-arm-kernel, linuxarm
[-- Attachment #1: Type: text/plain, Size: 735 bytes --]
On Fri, 14 Feb 2025, Shameer Kolothum wrote:
> v6-->v7
> https://lore.kernel.org/kvmarm/20250205132222.55816-1-shameerali.kolothum.thodi@huawei.com/
>
> Changes:
> -Introduced KVM_REG_ARM_VENDOR_HYP_BMAP_2 register for new hypercall
> support(patch #3)
> -Added selftest for KVM_REG_ARM_VENDOR_HYP_BMAP_2(patch #5).
>
> This can be sanity tested by the Qemu branch here,
> https://github.com/hisilicon/qemu/tree/v9.0-nv-rfcv4-vcpu-model-v2-target-cpu-errata
> (branch based on Eric's/Connie's NV + custom CPU series)
> Eg: to specify target impl CPUs,
> -machine virt,.., x-target-impl-cpus=0xMIDR1:0xREVIDR1-0xMIDR2:REVIDR2
>
> Please take a look and let me know your feedback.
Reviewed-by: Sebastian Ott <sebott@redhat.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs
2025-02-14 16:43 ` Marc Zyngier
@ 2025-02-18 7:40 ` Shameerali Kolothum Thodi
0 siblings, 0 replies; 11+ messages in thread
From: Shameerali Kolothum Thodi @ 2025-02-18 7:40 UTC (permalink / raw)
To: Marc Zyngier, Sebastian Ott
Cc: kvmarm@lists.linux.dev, oliver.upton@linux.dev,
catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
cohuck@redhat.com, eric.auger@redhat.com, yuzenghui, Wangzhou (B),
jiangkunkun, Jonathan Cameron, Anthony Jebson,
linux-arm-kernel@lists.infradead.org, Linuxarm
> -----Original Message-----
> From: Marc Zyngier <maz@kernel.org>
> Sent: Friday, February 14, 2025 4:43 PM
> To: Sebastian Ott <sebott@redhat.com>
> Cc: Shameerali Kolothum Thodi
> <shameerali.kolothum.thodi@huawei.com>; kvmarm@lists.linux.dev;
> oliver.upton@linux.dev; catalin.marinas@arm.com; will@kernel.org;
> mark.rutland@arm.com; cohuck@redhat.com; eric.auger@redhat.com;
> yuzenghui <yuzenghui@huawei.com>; Wangzhou (B)
> <wangzhou1@hisilicon.com>; jiangkunkun <jiangkunkun@huawei.com>;
> Jonathan Cameron <jonathan.cameron@huawei.com>; Anthony Jebson
> <anthony.jebson@huawei.com>; linux-arm-kernel@lists.infradead.org;
> Linuxarm <linuxarm@huawei.com>
> Subject: Re: [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on
> implementation CPUs
>
> On Fri, 14 Feb 2025 16:12:02 +0000,
> Sebastian Ott <sebott@redhat.com> wrote:
> >
> > On Fri, 14 Feb 2025, Shameer Kolothum wrote:
> > > +++ b/arch/arm64/kernel/cpu_errata.c
> > > @@ -14,6 +14,9 @@
> > > #include <asm/kvm_asm.h>
> > > #include <asm/smp_plat.h>
> > >
> > > +u32 target_impl_cpu_num;
> > > +struct target_impl_cpu *target_impl_cpus;
> >
> > These should be exported (for configs using
> > CONFIG_CORESIGHT_SOURCE_ETM4X=m)
Thanks Sebastian. I missed that.
>
> It might be better to make is_midr_in_range() out of line, and export
> that. This could allow making the data static (by implementing a
> couple of additional accessors).
Ok. I will give it a go.
Thanks,
Shameer
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-02-18 7:42 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-14 15:13 [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 1/5] arm64: Modify _midr_range() functions to read MIDR/REVIDR internally Shameer Kolothum
2025-02-14 16:02 ` Sebastian Ott
2025-02-14 15:13 ` [PATCH v7 2/5] KVM: arm64: Introduce hypercall support for retrieving target implementations Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 3/5] KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
2025-02-14 15:13 ` [PATCH v7 4/5] smccc/kvm_guest: Enable errata based on implementation CPUs Shameer Kolothum
2025-02-14 16:12 ` Sebastian Ott
2025-02-14 16:43 ` Marc Zyngier
2025-02-18 7:40 ` Shameerali Kolothum Thodi
2025-02-14 15:13 ` [PATCH v7 5/5] KVM: selftests: Add test for KVM_REG_ARM_VENDOR_HYP_BMAP_2 Shameer Kolothum
2025-02-14 17:34 ` [PATCH v7 0/5] KVM: arm64: Errata management for VM Live migration Sebastian Ott
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).