From 2494b56a496c4e65da3013a9cc3aff268844f047 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Tue, 5 Jan 2021 17:35:57 +0100 Subject: [PATCH 1/3] [X86] Fix compilation error in MacOS. MacOS does not provide any method to bin threads to cores, so its pretty hard to get apic ids. This first approach is really dark and I hope I can improve it in the future --- src/x86/apic.c | 77 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/src/x86/apic.c b/src/x86/apic.c index 7352016..518cd02 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -1,14 +1,17 @@ #ifdef _WIN32 #include -#else +#elif defined __linux__ #define _GNU_SOURCE #include +#elif defined __APPLE__ +#define UNUSED(x) (void)(x) #endif #include #include #include #include +#include #include "apic.h" #include "cpuid_asm.h" @@ -66,6 +69,7 @@ uint32_t get_apic_id(bool x2apic_id) { } } +#ifndef __APPLE__ bool bind_to_cpu(int cpu_id) { #ifdef _WIN32 HANDLE process = GetCurrentProcess(); @@ -82,6 +86,7 @@ bool bind_to_cpu(int cpu_id) { return true; #endif } +#endif bool fill_topo_masks_apic(struct topology* topo) { uint32_t eax = 0x00000001; @@ -254,8 +259,60 @@ void get_cache_topology_from_apic(struct topology* topo) { } } +bool apic_array_full(uint32_t* apic_ids, int n) { + for(int i=0; i < n; i++) { + if(apic_ids[i] == (uint32_t) -1) return false; + } + return true; +} + +void add_apic_to_array(uint32_t apic, uint32_t* apic_ids, int n) { + int i=0; + int last=0; + bool found = false; + + while(!found && i < n) { + if(apic_ids[i] == apic) found = true; + if(apic_ids[i] != (uint32_t) -1) last = i+1; + i++; + } + + if(!found) { + apic_ids[last] = apic; + //printf("Added %d\n", apic); + } +} + +bool fill_apic_ids(uint32_t* apic_ids, int n, bool x2apic_id) { +#ifdef __APPLE__ + // macOS extremely dirty approach... + printf("cpufetch is computing APIC IDs, please wait..."); + bool end = false; + uint32_t apic; + for(int i=0; i < n; i++) apic_ids[i] = (uint32_t) -1; + + while(!end) { + apic = get_apic_id(x2apic_id); + + add_apic_to_array(apic, apic_ids, n); + end = apic_array_full(apic_ids, n); + usleep(1000); + } +#else + for(int i=0; i < n; i++) { + if(!bind_to_cpu(i)) { + printErr("Failed binding to CPU %d", i); + return false; + } + apic_ids[i] = get_apic_id(x2apic_id); + } +#endif + return true; +} + bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) { - uint32_t apic_id; + uint32_t apic_id; + uint32_t* apic_ids = malloc(sizeof(uint32_t) * topo->total_cores); uint32_t* apic_pkg = malloc(sizeof(uint32_t) * topo->total_cores); uint32_t* apic_core = malloc(sizeof(uint32_t) * topo->total_cores); uint32_t* apic_smt = malloc(sizeof(uint32_t) * topo->total_cores); @@ -281,12 +338,11 @@ bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) { get_cache_topology_from_apic(topo); - for(int i=0; i < topo->total_cores; i++) { - if(!bind_to_cpu(i)) { - printErr("Failed binding to CPU %d", i); - return false; - } - apic_id = get_apic_id(x2apic_id); + if(!fill_apic_ids(apic_ids, topo->total_cores, x2apic_id)) + return false; + + for(int i=0; i < topo->total_cores; i++) { + apic_id = apic_ids[i]; apic_pkg[i] = (apic_id & topo->apic->pkg_mask) >> topo->apic->pkg_mask_shift; apic_core[i] = (apic_id & topo->apic->core_mask) >> topo->apic->smt_mask_width; @@ -337,6 +393,10 @@ bool get_topology_from_apic(struct cpuInfo* cpu, struct topology* topo) { } uint32_t is_smt_enabled_amd(struct topology* topo) { +#ifdef __APPLE__ + UNUSED(topo); + return 1; +#else uint32_t id; for(int i = 0; i < topo->total_cores; i++) { @@ -349,4 +409,5 @@ uint32_t is_smt_enabled_amd(struct topology* topo) { } return 1; +#endif } From 3b624f3025f56ccf9cad21bf86793b07ae8f93e5 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Tue, 5 Jan 2021 17:36:22 +0100 Subject: [PATCH 2/3] [X86] Fix bug where unknown hypervisor caused a segfault. This should solve issue #38 --- src/x86/cpuid.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index f6286a1..fc3fde5 100755 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -27,7 +27,6 @@ static const char *hv_vendors_string[] = { [HV_VENDOR_VMWARE] = "VMwareVMware", [HV_VENDOR_XEN] = "XenVMMXenVMM", [HV_VENDOR_PARALLELS] = "lrpepyh vr", - [HV_VENDOR_INVALID] = NULL }; static char *hv_vendors_name[] = { From 697a921042de40e047772871c354c6704edd85bf Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Sun, 10 Jan 2021 09:01:50 +0100 Subject: [PATCH 3/3] [X86] Avoid checking /sys directory in macOS to find frequency --- src/x86/apic.c | 2 +- src/x86/cpuid.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/x86/apic.c b/src/x86/apic.c index 518cd02..f42fba6 100644 --- a/src/x86/apic.c +++ b/src/x86/apic.c @@ -286,7 +286,7 @@ void add_apic_to_array(uint32_t apic, uint32_t* apic_ids, int n) { bool fill_apic_ids(uint32_t* apic_ids, int n, bool x2apic_id) { #ifdef __APPLE__ // macOS extremely dirty approach... - printf("cpufetch is computing APIC IDs, please wait..."); + printf("cpufetch is computing APIC IDs, please wait...\n"); bool end = false; uint32_t apic; for(int i=0; i < n; i++) apic_ids[i] = (uint32_t) -1; diff --git a/src/x86/cpuid.c b/src/x86/cpuid.c index fc3fde5..83faf84 100755 --- a/src/x86/cpuid.c +++ b/src/x86/cpuid.c @@ -668,6 +668,10 @@ struct frequency* get_frequency_info(struct cpuInfo* cpu) { } freq->base = UNKNOWN_FREQ; freq->max = UNKNOWN_FREQ; + #elif defined __APPLE__ + printErr("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X)", 0x00000016, cpu->maxLevels); + freq->base = UNKNOWN_FREQ; + freq->max = UNKNOWN_FREQ; #else printWarn("Can't read frequency information from cpuid (needed level is 0x%.8X, max is 0x%.8X). Using udev", 0x00000016, cpu->maxLevels); freq->base = UNKNOWN_FREQ;