* [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:40 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.