diff --git a/0033-target-loongarch-kvm-Add-pmu-support.patch b/0033-target-loongarch-kvm-Add-pmu-support.patch deleted file mode 100644 index b4881f8d272f43c72d25c9c65eeaae94d98470fb..0000000000000000000000000000000000000000 --- a/0033-target-loongarch-kvm-Add-pmu-support.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 9e21ba794167d715590bb05f373b09b6409da8cc Mon Sep 17 00:00:00 2001 -From: Song Gao -Date: Fri, 22 Mar 2024 19:26:35 +0800 -Subject: [PATCH] target/loongarch/kvm: Add pmu support - -This patch adds PMU support - e.g - '... -cpu max,pmu=on,pmnum=[1-16]'; - '... -cpu max,pmu=on' (default pmnum = 4); - '... -cpu max,pmu=off' (disable PMU) - -Signed-off-by: Song Gao ---- - target/loongarch/cpu.c | 64 +++++++++++++++++++++++++++ - target/loongarch/cpu.h | 2 + - target/loongarch/kvm/kvm.c | 55 ++++++++++++++++++++++- - target/loongarch/loongarch-qmp-cmds.c | 2 +- - 4 files changed, 121 insertions(+), 2 deletions(-) - -diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c -index b098b1c6f3..86d18f89a4 100644 ---- a/target/loongarch/cpu.c -+++ b/target/loongarch/cpu.c -@@ -8,6 +8,7 @@ - #include "qemu/osdep.h" - #include "qemu/log.h" - #include "qemu/qemu-print.h" -+#include "qemu/error-report.h" - #include "qapi/error.h" - #include "qemu/module.h" - #include "sysemu/qtest.h" -@@ -19,6 +20,7 @@ - #include "internals.h" - #include "fpu/softfloat-helpers.h" - #include "cpu-csr.h" -+#include "qapi/visitor.h" - #include "sysemu/reset.h" - #include "vec.h" - #ifdef CONFIG_KVM -@@ -420,6 +422,14 @@ static void loongarch_la464_initfn(Object *obj) - data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1); - env->cpucfg[5] = data; - -+ if (kvm_enabled()) { -+ data = 0; -+ data = FIELD_DP32(data, CPUCFG6, PMP, 1); -+ data = FIELD_DP32(data, CPUCFG6, PMNUM, 3); -+ data = FIELD_DP32(data, CPUCFG6, PMBITS, 63); -+ env->cpucfg[6] = data; -+ } -+ - data = 0; - data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1); - data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1); -@@ -654,6 +664,48 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) - } - } - -+static bool loongarch_get_pmu(Object *obj, Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ -+ return !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)); -+} -+ -+static void loongarch_set_pmu(Object *obj, bool value, Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ -+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value); -+} -+ -+static void loongarch_get_pmnum(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM); -+ -+ visit_type_uint32(v, name, &value, errp); -+} -+ -+static void loongarch_set_pmnum(Object *obj, Visitor *v, -+ const char *name, void *opaque, -+ Error **errp) -+{ -+ LoongArchCPU *cpu = LOONGARCH_CPU(obj); -+ uint32_t *value= opaque; -+ -+ if (!visit_type_uint32(v, name, value, errp)) { -+ return; -+ } -+ if ((*value <= PMNUM_MAX) && (*value > 0)) { -+ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, *value -1); -+ } else { -+ error_report("Performance counter number need be in [1- %d]\n", PMNUM_MAX); -+ exit(EXIT_FAILURE); -+ } -+} -+ - void loongarch_cpu_post_init(Object *obj) - { - LoongArchCPU *cpu = LOONGARCH_CPU(obj); -@@ -666,6 +718,18 @@ void loongarch_cpu_post_init(Object *obj) - object_property_add_bool(obj, "lasx", loongarch_get_lasx, - loongarch_set_lasx); - } -+ -+ if (kvm_enabled()) { -+ object_property_add_bool(obj, "pmu", loongarch_get_pmu, -+ loongarch_set_pmu); -+ if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) { -+ uint32_t value = 4; -+ object_property_add(obj, "pmnum", "uint32", -+ loongarch_get_pmnum, -+ loongarch_set_pmnum, NULL, -+ (void *)&value); -+ } -+ } - } - - static void loongarch_cpu_init(Object *obj) -diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h -index 4749d41c8c..80cad24fa1 100644 ---- a/target/loongarch/cpu.h -+++ b/target/loongarch/cpu.h -@@ -186,6 +186,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4) - FIELD(CPUCFG6, PMBITS, 8, 6) - FIELD(CPUCFG6, UPM, 14, 1) - -+#define PMNUM_MAX 16 -+ - /* cpucfg[16] bits */ - FIELD(CPUCFG16, L1_IUPRE, 0, 1) - FIELD(CPUCFG16, L1_IUUNIFY, 1, 1) -diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c -index 49d02076ad..5dda631b2b 100644 ---- a/target/loongarch/kvm/kvm.c -+++ b/target/loongarch/kvm/kvm.c -@@ -573,6 +573,53 @@ static int kvm_check_cpucfg2(CPUState *cs) - return ret; - } - -+static int kvm_check_cpucfg6(CPUState *cs) -+{ -+ int ret; -+ uint64_t val; -+ struct kvm_device_attr attr = { -+ .group = KVM_LOONGARCH_VCPU_CPUCFG, -+ .attr = 6, -+ .addr = (uint64_t)&val, -+ }; -+ LoongArchCPU *cpu = LOONGARCH_CPU(cs); -+ CPULoongArchState *env = &cpu->env; -+ -+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr); -+ if (!ret) { -+ kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr); -+ -+ if (FIELD_EX32(env->cpucfg[6], CPUCFG6, PMP)) { -+ /* Check PMP */ -+ if (!FIELD_EX32(val, CPUCFG6, PMP)) { -+ error_report("'pmu' feature not supported by KVM on this host" -+ " Please disable 'pmu' with " -+ "'... -cpu XXX,pmu=off ...'\n"); -+ exit(EXIT_FAILURE); -+ } -+ /* Check PMNUM */ -+ int guest_pmnum = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMNUM); -+ int host_pmnum = FIELD_EX32(val, CPUCFG6, PMNUM); -+ if (guest_pmnum > host_pmnum){ -+ warn_report("The guest pmnum %d larger than KVM support %d\n", -+ guest_pmnum, host_pmnum); -+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, -+ PMNUM, host_pmnum); -+ } -+ /* Check PMBITS */ -+ int guest_pmbits = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMBITS); -+ int host_pmbits = FIELD_EX32(val, CPUCFG6, PMBITS); -+ if (guest_pmbits != host_pmbits) { -+ warn_report("The host not support PMBITS %d\n", guest_pmbits); -+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, -+ PMBITS, host_pmbits); -+ } -+ } -+ } -+ -+ return ret; -+} -+ - static int kvm_loongarch_put_cpucfg(CPUState *cs) - { - int i, ret = 0; -@@ -586,7 +633,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) - if (ret) { - return ret; - } -- } -+ } -+ if (i == 6) { -+ ret = kvm_check_cpucfg6(cs); -+ if (ret) { -+ return ret; -+ } -+ } - val = env->cpucfg[i]; - ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val); - if (ret < 0) { -diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c -index 645672ff59..2612f43de9 100644 ---- a/target/loongarch/loongarch-qmp-cmds.c -+++ b/target/loongarch/loongarch-qmp-cmds.c -@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) - } - - static const char *cpu_model_advertised_features[] = { -- "lsx", "lasx", NULL -+ "lsx", "lasx", "pmu", "pmnum", NULL - }; - - CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, --- -2.33.0 - diff --git a/0033-target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch b/0033-target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch new file mode 100644 index 0000000000000000000000000000000000000000..72cfef06a737d10a193987a28be583ee8379045e --- /dev/null +++ b/0033-target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch @@ -0,0 +1,229 @@ +From c03824f6bb72d4874e90f55c2e3df35e6d4e8809 Mon Sep 17 00:00:00 2001 +From: Song Gao +Date: Fri, 14 Jun 2024 09:38:48 +0800 +Subject: [PATCH 1/1] target/loongarch/kvm: Implement LoongArch PMU extension. + +Implement PMU extension for LoongArch kvm mode. Use OnOffAuto type +variable pmu to check the PMU feature. If the PMU Feature is not supported +with KVM host, it reports error if there is pmu=on command line. + +If there is no any command line about pmu parameter, it checks whether +KVM host supports the PMU Feature and set the corresponding value in cpucfg. + +Signed-off-by: Song Gao +Message-Id: <20240614013848.53474-1-gaosong@loongson.cn> +--- + linux-headers/asm-loongarch/kvm.h | 3 ++ + target/loongarch/cpu.h | 6 +++ + target/loongarch/kvm/kvm_loongarch.h | 16 +++++++ + target/loongarch/cpu.c | 64 ++++++++++++++++++++++++--- + target/loongarch/kvm/kvm.c | 16 +++++++ + target/loongarch/loongarch-qmp-cmds.c | 2 +- + 6 files changed, 99 insertions(+), 8 deletions(-) + +diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h +index 4cec8c1601..b40b640a63 100644 +--- a/linux-headers/asm-loongarch/kvm.h ++++ b/linux-headers/asm-loongarch/kvm.h +@@ -85,6 +85,9 @@ struct kvm_fpu { + #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) + #define KVM_LOONGARCH_VCPU_CPUCFG 0 + ++#define KVM_LOONGARCH_VM_FEAT_CTRL 1000 ++#define KVM_LOONGARCH_VM_FEAT_PMU 1000 ++ + struct kvm_debug_exit_arch { + }; + +diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h +index 4749d41c8c..f07ed497c3 100644 +--- a/target/loongarch/cpu.h ++++ b/target/loongarch/cpu.h +@@ -18,6 +18,7 @@ + #endif + #include "cpu-csr.h" + #include "cpu-qom.h" ++#include "qapi/qapi-types-common.h" + + #define IOCSRF_TEMP 0 + #define IOCSRF_NODECNT 1 +@@ -281,6 +282,10 @@ struct LoongArchTLB { + }; + typedef struct LoongArchTLB LoongArchTLB; + ++enum loongarch_features { ++ LOONGARCH_FEATURE_PMU, ++}; ++ + typedef struct CPUArchState { + uint64_t gpr[32]; + uint64_t pc; +@@ -377,6 +382,7 @@ struct ArchCPU { + CPULoongArchState env; + QEMUTimer timer; + uint32_t phy_id; ++ OnOffAuto pmu; + + /* 'compatible' string for this CPU for Linux device trees */ + const char *dtb_compatible; +diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h +index d945b6bb82..bdb4f180eb 100644 +--- a/target/loongarch/kvm/kvm_loongarch.h ++++ b/target/loongarch/kvm/kvm_loongarch.h +@@ -13,4 +13,20 @@ + int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); + void kvm_arch_reset_vcpu(CPULoongArchState *env); + ++#ifdef CONFIG_KVM ++/* ++ * kvm_feature_supported: ++ * ++ * Returns: true if KVM supports specified feature ++ * and false otherwise. ++ */ ++bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature); ++#else ++static inline bool kvm_feature_supported(CPUState *cs, ++ enum loongarch_features feature) ++{ ++ return false; ++} ++#endif ++ + #endif +diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c +index b098b1c6f3..17d944875a 100644 +--- a/target/loongarch/cpu.c ++++ b/target/loongarch/cpu.c +@@ -582,6 +582,35 @@ static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) + info->print_insn = print_insn_loongarch; + } + ++static void loongarch_cpu_check_pmu(CPUState *cs, Error **errp) ++{ ++ LoongArchCPU *cpu = LOONGARCH_CPU(cs); ++ bool kvm_supported; ++ ++ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU); ++ if (cpu->pmu == ON_OFF_AUTO_ON) { ++ if (kvm_supported) { ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, 1); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 3); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMBITS, 63); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, UPM, 1); ++ } else { ++ error_setg(errp, "'pmu' feature not supported by KVM on this host."); ++ return; ++ } ++ } else if ((cpu->pmu == ON_OFF_AUTO_AUTO) && kvm_supported) { ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, 1); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 3); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMBITS, 63); ++ cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, UPM, 1); ++ } ++} ++ ++static void loongarch_cpu_feature_realize(CPUState *cs, Error **errp) ++{ ++ loongarch_cpu_check_pmu(cs, errp); ++} ++ + static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) + { + CPUState *cs = CPU(dev); +@@ -595,6 +624,11 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) + } + + loongarch_cpu_register_gdb_regs_for_features(cs); ++ loongarch_cpu_feature_realize(cs, &local_err); ++ if (local_err != NULL) { ++ error_propagate(errp, local_err); ++ return; ++ } + + cpu_reset(cs); + qemu_init_vcpu(cs); +@@ -654,17 +688,33 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) + } + } + ++static bool loongarch_get_pmu(Object *obj, Error **errp) ++{ ++ return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF; ++} ++ ++static void loongarch_set_pmu(Object *obj, bool value, Error **errp) ++{ ++ LoongArchCPU *cpu = LOONGARCH_CPU(obj); ++ ++ cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; ++} ++ + void loongarch_cpu_post_init(Object *obj) + { + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) { +- object_property_add_bool(obj, "lsx", loongarch_get_lsx, +- loongarch_set_lsx); +- } +- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) { +- object_property_add_bool(obj, "lasx", loongarch_get_lasx, +- loongarch_set_lasx); ++ object_property_add_bool(obj, "lsx", loongarch_get_lsx, ++ loongarch_set_lsx); ++ object_property_add_bool(obj, "lasx", loongarch_get_lasx, ++ loongarch_set_lasx); ++ ++ if (kvm_enabled()) { ++ cpu->pmu = ON_OFF_AUTO_AUTO; ++ object_property_add_bool(obj, "pmu", loongarch_get_pmu, ++ loongarch_set_pmu); ++ } else { ++ cpu->pmu = ON_OFF_AUTO_OFF; + } + } + +diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c +index 49d02076ad..afcd917b21 100644 +--- a/target/loongarch/kvm/kvm.c ++++ b/target/loongarch/kvm/kvm.c +@@ -874,6 +874,22 @@ int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) + return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr); + } + ++bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) ++{ ++ struct kvm_device_attr attr; ++ int ret; ++ ++ switch (feature) { ++ case LOONGARCH_FEATURE_PMU: ++ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; ++ attr.attr = KVM_LOONGARCH_VM_FEAT_PMU; ++ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); ++ return (ret == 0); ++ default: ++ return false; ++ } ++} ++ + void kvm_arch_accel_class_init(ObjectClass *oc) + { + } +diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c +index 645672ff59..de92ec6c22 100644 +--- a/target/loongarch/loongarch-qmp-cmds.c ++++ b/target/loongarch/loongarch-qmp-cmds.c +@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) + } + + static const char *cpu_model_advertised_features[] = { +- "lsx", "lasx", NULL ++ "lsx", "lasx", "pmu", NULL + }; + + CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, +-- +2.34.1 + diff --git a/qemu.spec b/qemu.spec index ce4a4b5919b4b277cfefb98103bd7167a145f3b1..2f5a7a902caca26bf5e6f8d429f9fc1284ce95ce 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,4 +1,4 @@ -%define anolis_release 17 +%define anolis_release 18 %bcond_with check @@ -295,7 +295,7 @@ Patch0029: 0029-target-loongarch-kvm-Add-software-breakpoint-support.patch Patch0030: 0030-hw-intc-loongarch_extioi-Add-virt-extension-support.patch Patch0031: 0031-target-loongarch-kvm-sync-kernel-header-files.patch Patch0032: 0032-hw-intc-loongarch_extioi-Add-virt-extension-support-.patch -Patch0033: 0033-target-loongarch-kvm-Add-pmu-support.patch +Patch0033: 0033-target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch Patch0034: 0034-target-loongarch-Fix-qemu-system-loongarch64-assert-.patch Patch0035: 0035-newfeature-support-vpsp.patch @@ -1920,6 +1920,10 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Wed Jul 17 2024 Song Gao -2.8.2.0-18 +- Patch0033: 0033-target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch + (Update PMU support patch) + * Mon Jun 20 2024 Wencheng Yang - 2:8.2.0-17 - Patch1053: 1053-target-i386-csv-Release-CSV3-shared-pages-after-unma.patch (Release CSV3 shared pages after unmapping DMA)