| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * x86_energy_perf_policy -- set the energy versus performance |
|---|
| 3 | 4 | * policy preference bias on recent X86 processors. |
|---|
| .. | .. |
|---|
| 5 | 6 | /* |
|---|
| 6 | 7 | * Copyright (c) 2010 - 2017 Intel Corporation. |
|---|
| 7 | 8 | * Len Brown <len.brown@intel.com> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is released under GPL v2 |
|---|
| 10 | 9 | */ |
|---|
| 11 | 10 | |
|---|
| 12 | 11 | #define _GNU_SOURCE |
|---|
| .. | .. |
|---|
| 623 | 622 | } |
|---|
| 624 | 623 | } |
|---|
| 625 | 624 | |
|---|
| 625 | +/* |
|---|
| 626 | + * Open a file, and exit on failure |
|---|
| 627 | + */ |
|---|
| 628 | +FILE *fopen_or_die(const char *path, const char *mode) |
|---|
| 629 | +{ |
|---|
| 630 | + FILE *filep = fopen(path, "r"); |
|---|
| 631 | + |
|---|
| 632 | + if (!filep) |
|---|
| 633 | + err(1, "%s: open failed", path); |
|---|
| 634 | + return filep; |
|---|
| 635 | +} |
|---|
| 636 | + |
|---|
| 637 | +void err_on_hypervisor(void) |
|---|
| 638 | +{ |
|---|
| 639 | + FILE *cpuinfo; |
|---|
| 640 | + char *flags, *hypervisor; |
|---|
| 641 | + char *buffer; |
|---|
| 642 | + |
|---|
| 643 | + /* On VMs /proc/cpuinfo contains a "flags" entry for hypervisor */ |
|---|
| 644 | + cpuinfo = fopen_or_die("/proc/cpuinfo", "ro"); |
|---|
| 645 | + |
|---|
| 646 | + buffer = malloc(4096); |
|---|
| 647 | + if (!buffer) { |
|---|
| 648 | + fclose(cpuinfo); |
|---|
| 649 | + err(-ENOMEM, "buffer malloc fail"); |
|---|
| 650 | + } |
|---|
| 651 | + |
|---|
| 652 | + if (!fread(buffer, 1024, 1, cpuinfo)) { |
|---|
| 653 | + fclose(cpuinfo); |
|---|
| 654 | + free(buffer); |
|---|
| 655 | + err(1, "Reading /proc/cpuinfo failed"); |
|---|
| 656 | + } |
|---|
| 657 | + |
|---|
| 658 | + flags = strstr(buffer, "flags"); |
|---|
| 659 | + rewind(cpuinfo); |
|---|
| 660 | + fseek(cpuinfo, flags - buffer, SEEK_SET); |
|---|
| 661 | + if (!fgets(buffer, 4096, cpuinfo)) { |
|---|
| 662 | + fclose(cpuinfo); |
|---|
| 663 | + free(buffer); |
|---|
| 664 | + err(1, "Reading /proc/cpuinfo failed"); |
|---|
| 665 | + } |
|---|
| 666 | + fclose(cpuinfo); |
|---|
| 667 | + |
|---|
| 668 | + hypervisor = strstr(buffer, "hypervisor"); |
|---|
| 669 | + |
|---|
| 670 | + free(buffer); |
|---|
| 671 | + |
|---|
| 672 | + if (hypervisor) |
|---|
| 673 | + err(-1, |
|---|
| 674 | + "not supported on this virtual machine"); |
|---|
| 675 | +} |
|---|
| 626 | 676 | |
|---|
| 627 | 677 | int get_msr(int cpu, int offset, unsigned long long *msr) |
|---|
| 628 | 678 | { |
|---|
| .. | .. |
|---|
| 636 | 686 | err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname); |
|---|
| 637 | 687 | |
|---|
| 638 | 688 | retval = pread(fd, msr, sizeof(*msr), offset); |
|---|
| 639 | | - if (retval != sizeof(*msr)) |
|---|
| 689 | + if (retval != sizeof(*msr)) { |
|---|
| 690 | + err_on_hypervisor(); |
|---|
| 640 | 691 | err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset); |
|---|
| 692 | + } |
|---|
| 641 | 693 | |
|---|
| 642 | 694 | if (debug > 1) |
|---|
| 643 | 695 | fprintf(stderr, "get_msr(cpu%d, 0x%X, 0x%llX)\n", cpu, offset, *msr); |
|---|
| .. | .. |
|---|
| 1085 | 1137 | |
|---|
| 1086 | 1138 | update_hwp_request(cpu); |
|---|
| 1087 | 1139 | return 0; |
|---|
| 1088 | | -} |
|---|
| 1089 | | - |
|---|
| 1090 | | -/* |
|---|
| 1091 | | - * Open a file, and exit on failure |
|---|
| 1092 | | - */ |
|---|
| 1093 | | -FILE *fopen_or_die(const char *path, const char *mode) |
|---|
| 1094 | | -{ |
|---|
| 1095 | | - FILE *filep = fopen(path, "r"); |
|---|
| 1096 | | - |
|---|
| 1097 | | - if (!filep) |
|---|
| 1098 | | - err(1, "%s: open failed", path); |
|---|
| 1099 | | - return filep; |
|---|
| 1100 | 1140 | } |
|---|
| 1101 | 1141 | |
|---|
| 1102 | 1142 | unsigned int get_pkg_num(int cpu) |
|---|