From: zhangyuan zhangyuan162@huawei.com
KVM: arm64: limit PMU version to PMUv3 for ARMv8.1
Backport patches from upstream to fix the issue of PMU.
Signed-off-by: Yuan Zhang zhangyuan162@huawei.com --- kernel.spec | 5 +- ...eature-Extract-capped-perfmon-fields.patch | 80 +++++++++++++++++ ...mit-PMU-version-to-PMUv3-for-ARMv8.1.patch | 90 +++++++++++++++++++ series.conf | 2 + 4 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 patches/0758-arm64-cpufeature-Extract-capped-perfmon-fields.patch create mode 100644 patches/0759-KVM-arm64-limit-PMU-version-to-PMUv3-for-ARMv8.1.patch
diff --git a/kernel.spec b/kernel.spec index 0ddbd93..7a06c2c 100644 --- a/kernel.spec +++ b/kernel.spec @@ -32,7 +32,7 @@
Name: kernel Version: 4.19.90 -Release: %{hulkrelease}.0252 +Release: %{hulkrelease}.0253 Summary: Linux Kernel License: GPLv2 URL: http://www.kernel.org/ @@ -849,6 +849,9 @@ fi %endif
%changelog +* Tue Nov 28 2023 Yuan Zhang zhangyuan162@huawei.com - 4.19.90-2311.5.0.0253 +- arm64: cpufeature: Extract capped perfmon fields +- KVM: arm64: limit PMU version to PMUv3 for ARMv8.1
* Tue Nov 28 2023 Li Xiaodong lixiaodong67@huawei.com - 4.19.90-2311.5.0.0252 - !3000 [openEuler-1.0-LTS] add Phytium drivers CONFIG diff --git a/patches/0758-arm64-cpufeature-Extract-capped-perfmon-fields.patch b/patches/0758-arm64-cpufeature-Extract-capped-perfmon-fields.patch new file mode 100644 index 0000000..de1db70 --- /dev/null +++ b/patches/0758-arm64-cpufeature-Extract-capped-perfmon-fields.patch @@ -0,0 +1,80 @@ +From a207eaeac98757a86cce704be6c4e097439503c5 Mon Sep 17 00:00:00 2001 +From: Andrew Murray andrew.murray@arm.com +Date: Tue, 28 Nov 2023 15:46:32 +0800 +Subject: [PATCH 1/2] arm64: cpufeature: Extract capped perfmon fields + +mainline inclusion +from mainline-v5.7-rc1 +commit 8e35aa642ee4dab01b16cc4b2df59d1936f3b3c2 +category: bugfix +bugzilla: https://gitee.com/openeuler/kernel/issues/I8K8XV +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... + +----------------------------------- + +commit 8e35aa642ee4dab01b16cc4b2df59d1936f3b3c2 upstream. + +When emulating ID registers there is often a need to cap the version +bits of a feature such that the guest will not use features that the +host is not aware of. For example, when KVM mediates access to the PMU +by emulating register accesses. + +Let's add a helper that extracts a performance monitors ID field and +caps the version to a given value. + +Fields that identify the version of the Performance Monitors Extension +do not follow the standard ID scheme, and instead follow the scheme +described in ARM DDI 0487E.a page D13-2825 "Alternative ID scheme used +for the Performance Monitors Extension version". The value 0xF means an +IMPLEMENTATION DEFINED PMU is present, and values 0x0-OxE can be treated +the same as an unsigned field with 0x0 meaning no PMU is present. + +Signed-off-by: Andrew Murray andrew.murray@arm.com +Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com +[Mark: rework to handle perfmon fields] +Signed-off-by: Mark Rutland mark.rutland@arm.com +Signed-off-by: Will Deacon will@kernel.org +Signed-off-by: zhangyuan zhangyuan162@huawei.com +--- + arch/arm64/include/asm/cpufeature.h | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h +index eef5a9c9b823..e2ba573644d5 100644 +--- a/arch/arm64/include/asm/cpufeature.h ++++ b/arch/arm64/include/asm/cpufeature.h +@@ -449,6 +449,29 @@ cpuid_feature_extract_unsigned_field(u64 features, int field) + return cpuid_feature_extract_unsigned_field_width(features, field, 4); + } + ++/* ++ * Fields that identify the version of the Performance Monitors Extension do ++ * not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825, ++ * "Alternative ID scheme used for the Performance Monitors Extension version". ++ */ ++static inline u64 __attribute_const__ ++cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap) ++{ ++ u64 val = cpuid_feature_extract_unsigned_field(features, field); ++ u64 mask = GENMASK_ULL(field + 3, field); ++ ++ /* Treat IMPLEMENTATION DEFINED functionality as unimplemented */ ++ if (val == 0xf) ++ val = 0; ++ ++ if (val > cap) { ++ features &= ~mask; ++ features |= (cap << field) & mask; ++ } ++ ++ return features; ++} ++ + static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp) + { + return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift); +-- +2.33.0 + diff --git a/patches/0759-KVM-arm64-limit-PMU-version-to-PMUv3-for-ARMv8.1.patch b/patches/0759-KVM-arm64-limit-PMU-version-to-PMUv3-for-ARMv8.1.patch new file mode 100644 index 0000000..1f72f92 --- /dev/null +++ b/patches/0759-KVM-arm64-limit-PMU-version-to-PMUv3-for-ARMv8.1.patch @@ -0,0 +1,90 @@ +From 6a416c5efa3ce99f5f0f7e9c603b42b0e047481c Mon Sep 17 00:00:00 2001 +From: Andrew Murray andrew.murray@arm.com +Date: Tue, 28 Nov 2023 15:46:33 +0800 +Subject: [PATCH 2/2] KVM: arm64: limit PMU version to PMUv3 for ARMv8.1 + +mainline inclusion +from mainline-v5.7-rc1 +commit c854188ea01062f5a5fd7f05658feb1863774eaa +category: bugfix +bugzilla: https://gitee.com/openeuler/kernel/issues/I8K8XV +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... + +----------------------------------- + +commit c854188ea01062f5a5fd7f05658feb1863774eaa upstream. + +We currently expose the PMU version of the host to the guest via +emulation of the DFR0_EL1 and AA64DFR0_EL1 debug feature registers. +However many of the features offered beyond PMUv3 for 8.1 are not +supported in KVM. Examples of this include support for the PMMIR +registers (added in PMUv3 for ARMv8.4) and 64-bit event counters +added in (PMUv3 for ARMv8.5). + +Let's trap the Debug Feature Registers in order to limit +PMUVer/PerfMon in the Debug Feature Registers to PMUv3 for ARMv8.1 +to avoid unexpected behaviour. + +Both ID_AA64DFR0.PMUVer and ID_DFR0.PerfMon follow the "Alternative ID +scheme used for the Performance Monitors Extension version" where 0xF +means an IMPLEMENTATION DEFINED PMU is implemented, and values 0x0-0xE +are treated as with an unsigned field (with 0x0 meaning no PMU is +present). As we don't expect to expose an IMPLEMENTATION DEFINED PMU, +and our cap is below 0xF, we can treat these fields as unsigned when +applying the cap. + +Signed-off-by: Andrew Murray andrew.murray@arm.com +Reviewed-by: Suzuki K Poulose suzuki.poulose@arm.com +[Mark: make field names consistent, use perfmon cap] +Signed-off-by: Mark Rutland mark.rutland@arm.com +Signed-off-by: Will Deacon will@kernel.org +[zhangyuan162@huawei.com: adjust the context in read_id_reg()] +Signed-off-by: zhangyuan zhangyuan162@huawei.com +--- + arch/arm64/include/asm/sysreg.h | 6 ++++++ + arch/arm64/kvm/sys_regs.c | 10 ++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h +index de4c31f073bb..041100c28cab 100644 +--- a/arch/arm64/include/asm/sysreg.h ++++ b/arch/arm64/include/asm/sysreg.h +@@ -637,6 +637,12 @@ + #define ID_AA64DFR0_TRACEVER_SHIFT 4 + #define ID_AA64DFR0_DEBUGVER_SHIFT 0 + ++#define ID_AA64DFR0_PMUVER_8_1 0x4 ++ ++#define ID_DFR0_PERFMON_SHIFT 24 ++ ++#define ID_DFR0_PERFMON_8_1 0x4 ++ + #define ID_AA64DFR0_PMSVER_8_2 0x1 + #define ID_AA64DFR0_PMSVER_8_3 0x2 + +diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c +index 25caa9ec95e4..cc824a208684 100644 +--- a/arch/arm64/kvm/sys_regs.c ++++ b/arch/arm64/kvm/sys_regs.c +@@ -1082,6 +1082,16 @@ static u64 read_id_reg(struct kvm_vcpu *vcpu, + kvm_debug("LORegions unsupported for guests, suppressing\n"); + + val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT); ++ } else if (id == SYS_ID_AA64DFR0_EL1) { ++ /* Limit guests to PMUv3 for ARMv8.1 */ ++ val = cpuid_feature_cap_perfmon_field(val, ++ ID_AA64DFR0_PMUVER_SHIFT, ++ ID_AA64DFR0_PMUVER_8_1); ++ } else if (id == SYS_ID_DFR0_EL1) { ++ /* Limit guests to PMUv3 for ARMv8.1 */ ++ val = cpuid_feature_cap_perfmon_field(val, ++ ID_DFR0_PERFMON_SHIFT, ++ ID_DFR0_PERFMON_8_1); + } + + return val; +-- +2.33.0 + diff --git a/series.conf b/series.conf index f5f2522..67b9be0 100644 --- a/series.conf +++ b/series.conf @@ -758,3 +758,5 @@ patches/0754-scsi-hisi_sas_v3_hw-Remove-extra-function-calls-for-.patch patches/0755-config-arm64-Enable-dubugfs-config-of-hisi-sas.patch patches/0756-crypto-hisilicon-Add-value-profile-support-for-kerne.patch patches/0757-Revert-genirq-Increase-the-number-of-IRQ-descriptors.patch +patches/arm64-cpufeature-Extract-capped-perfmon-fields.patch +patches/KVM-arm64-limit-PMU-version-to-PMUv3-for-ARMv8.1.patch