1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2023, Tencent, Inc. 4 */ 5 6 #include <stdint.h> 7 8 #include <linux/kernel.h> 9 10 #include "kvm_util.h" 11 #include "processor.h" 12 #include "pmu.h" 13 14 const uint64_t intel_pmu_arch_events[] = { 15 INTEL_ARCH_CPU_CYCLES, 16 INTEL_ARCH_INSTRUCTIONS_RETIRED, 17 INTEL_ARCH_REFERENCE_CYCLES, 18 INTEL_ARCH_LLC_REFERENCES, 19 INTEL_ARCH_LLC_MISSES, 20 INTEL_ARCH_BRANCHES_RETIRED, 21 INTEL_ARCH_BRANCHES_MISPREDICTED, 22 INTEL_ARCH_TOPDOWN_SLOTS, 23 INTEL_ARCH_TOPDOWN_BE_BOUND, 24 INTEL_ARCH_TOPDOWN_BAD_SPEC, 25 INTEL_ARCH_TOPDOWN_FE_BOUND, 26 INTEL_ARCH_TOPDOWN_RETIRING, 27 INTEL_ARCH_LBR_INSERTS, 28 }; 29 kvm_static_assert(ARRAY_SIZE(intel_pmu_arch_events) == NR_INTEL_ARCH_EVENTS); 30 31 const uint64_t amd_pmu_zen_events[] = { 32 AMD_ZEN_CORE_CYCLES, 33 AMD_ZEN_INSTRUCTIONS_RETIRED, 34 AMD_ZEN_BRANCHES_RETIRED, 35 AMD_ZEN_BRANCHES_MISPREDICTED, 36 }; 37 kvm_static_assert(ARRAY_SIZE(amd_pmu_zen_events) == NR_AMD_ZEN_EVENTS); 38 39 /* 40 * For Intel Atom CPUs, the PMU events "Instruction Retired" or 41 * "Branch Instruction Retired" may be overcounted for some certain 42 * instructions, like FAR CALL/JMP, RETF, IRET, VMENTRY/VMEXIT/VMPTRLD 43 * and complex SGX/SMX/CSTATE instructions/flows. 44 * 45 * The detailed information can be found in the errata (section SRF7): 46 * https://edc.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/sierra-forest/xeon-6700-series-processor-with-e-cores-specification-update/errata-details/ 47 * 48 * For the Atom platforms before Sierra Forest (including Sierra Forest), 49 * Both 2 events "Instruction Retired" and "Branch Instruction Retired" would 50 * be overcounted on these certain instructions, but for Clearwater Forest 51 * only "Instruction Retired" event is overcounted on these instructions. 52 */ 53 static uint64_t get_pmu_errata(void) 54 { 55 if (!this_cpu_is_intel()) 56 return 0; 57 58 if (this_cpu_family() != 0x6) 59 return 0; 60 61 switch (this_cpu_model()) { 62 case 0xDD: /* Clearwater Forest */ 63 return BIT_ULL(INSTRUCTIONS_RETIRED_OVERCOUNT); 64 case 0xAF: /* Sierra Forest */ 65 case 0x4D: /* Avaton, Rangely */ 66 case 0x5F: /* Denverton */ 67 case 0x86: /* Jacobsville */ 68 return BIT_ULL(INSTRUCTIONS_RETIRED_OVERCOUNT) | 69 BIT_ULL(BRANCHES_RETIRED_OVERCOUNT); 70 default: 71 return 0; 72 } 73 } 74 75 uint64_t pmu_errata_mask; 76 77 void kvm_init_pmu_errata(void) 78 { 79 pmu_errata_mask = get_pmu_errata(); 80 } 81