| .. | .. |
|---|
| 3 | 3 | #include <linux/interrupt.h> |
|---|
| 4 | 4 | |
|---|
| 5 | 5 | #include <asm/xen/hypercall.h> |
|---|
| 6 | +#include <xen/xen.h> |
|---|
| 6 | 7 | #include <xen/page.h> |
|---|
| 7 | 8 | #include <xen/interface/xen.h> |
|---|
| 8 | 9 | #include <xen/interface/vcpu.h> |
|---|
| .. | .. |
|---|
| 90 | 91 | k7_counters_mirrored = 0; |
|---|
| 91 | 92 | break; |
|---|
| 92 | 93 | } |
|---|
| 94 | + } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { |
|---|
| 95 | + amd_num_counters = F10H_NUM_COUNTERS; |
|---|
| 96 | + amd_counters_base = MSR_K7_PERFCTR0; |
|---|
| 97 | + amd_ctrls_base = MSR_K7_EVNTSEL0; |
|---|
| 98 | + amd_msr_step = 1; |
|---|
| 99 | + k7_counters_mirrored = 0; |
|---|
| 93 | 100 | } else { |
|---|
| 94 | 101 | uint32_t eax, ebx, ecx, edx; |
|---|
| 95 | 102 | |
|---|
| .. | .. |
|---|
| 285 | 292 | |
|---|
| 286 | 293 | bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err) |
|---|
| 287 | 294 | { |
|---|
| 288 | | - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { |
|---|
| 295 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { |
|---|
| 289 | 296 | if (is_amd_pmu_msr(msr)) { |
|---|
| 290 | 297 | if (!xen_amd_pmu_emulate(msr, val, 1)) |
|---|
| 291 | 298 | *val = native_read_msr_safe(msr, err); |
|---|
| .. | .. |
|---|
| 308 | 315 | { |
|---|
| 309 | 316 | uint64_t val = ((uint64_t)high << 32) | low; |
|---|
| 310 | 317 | |
|---|
| 311 | | - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { |
|---|
| 318 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { |
|---|
| 312 | 319 | if (is_amd_pmu_msr(msr)) { |
|---|
| 313 | 320 | if (!xen_amd_pmu_emulate(msr, &val, 0)) |
|---|
| 314 | 321 | *err = native_write_msr_safe(msr, low, high); |
|---|
| .. | .. |
|---|
| 379 | 386 | |
|---|
| 380 | 387 | unsigned long long xen_read_pmc(int counter) |
|---|
| 381 | 388 | { |
|---|
| 382 | | - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) |
|---|
| 389 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) |
|---|
| 383 | 390 | return xen_amd_read_pmc(counter); |
|---|
| 384 | 391 | else |
|---|
| 385 | 392 | return xen_intel_read_pmc(counter); |
|---|
| .. | .. |
|---|
| 505 | 512 | return ret; |
|---|
| 506 | 513 | } |
|---|
| 507 | 514 | |
|---|
| 508 | | -bool is_xen_pmu(int cpu) |
|---|
| 509 | | -{ |
|---|
| 510 | | - return (get_xenpmu_data() != NULL); |
|---|
| 511 | | -} |
|---|
| 515 | +bool is_xen_pmu; |
|---|
| 512 | 516 | |
|---|
| 513 | 517 | void xen_pmu_init(int cpu) |
|---|
| 514 | 518 | { |
|---|
| .. | .. |
|---|
| 519 | 523 | |
|---|
| 520 | 524 | BUILD_BUG_ON(sizeof(struct xen_pmu_data) > PAGE_SIZE); |
|---|
| 521 | 525 | |
|---|
| 522 | | - if (xen_hvm_domain()) |
|---|
| 526 | + if (xen_hvm_domain() || (cpu != 0 && !is_xen_pmu)) |
|---|
| 523 | 527 | return; |
|---|
| 524 | 528 | |
|---|
| 525 | 529 | xenpmu_data = (struct xen_pmu_data *)get_zeroed_page(GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 540 | 544 | per_cpu(xenpmu_shared, cpu).xenpmu_data = xenpmu_data; |
|---|
| 541 | 545 | per_cpu(xenpmu_shared, cpu).flags = 0; |
|---|
| 542 | 546 | |
|---|
| 543 | | - if (cpu == 0) { |
|---|
| 547 | + if (!is_xen_pmu) { |
|---|
| 548 | + is_xen_pmu = true; |
|---|
| 544 | 549 | perf_register_guest_info_callbacks(&xen_guest_cbs); |
|---|
| 545 | 550 | xen_pmu_arch_init(); |
|---|
| 546 | 551 | } |
|---|