[PATCH] virhostcpu: fix getting CPU freq for Apple Silicon

Menci huanghaorui301 at gmail.com
Sat Feb 5 04:42:10 UTC 2022


The current implementation of virHostCPUGetInfo for macOS (__APPLE__)
reads "hw.cpufrequency" from sysctl, which is available only on x86_64
architecture.

On Apple Silicon ARM Macs, it's not available:

  $ sysctl hw.cpufrequency              # No output
  $ arch -x86_64 sysctl hw.cpufrequency # Run with Rosetta 2
  hw.cpufrequency: 2400000000

When running libvirtd on Apple Silicon, I got the error:

  cannot obtain CPU freq: No such file or directory.

To fix it, we can calculate it with "hw.tbfrequency" and
"kern.clockrate" instead:

  $ sysctl hw.tbfrequency
  hw.tbfrequency: 24000000
  $ sysctl kern.clockrate
  kern.clockrate: { hz = 100, tick = 10000, tickadj = 0, profhz = 100, stathz = 100 }

The result value would be hw.tbfrequency * kern.clockrate.hz.

Signed-off-by: Menci <huanghaorui301 at gmail.com>
---
 src/util/virhostcpu.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index a07c00a0e9..72983c91f3 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -927,9 +927,18 @@ virHostCPUGetInfo(virArch hostarch G_GNUC_UNUSED,
 
     *mhz = cpu_freq;
 # else
+    /* This works for Intel Macs */
     if (sysctlbyname("hw.cpufrequency", &cpu_freq, &cpu_freq_len, NULL, 0) < 0) {
-        virReportSystemError(errno, "%s", _("cannot obtain CPU freq"));
-        return -1;
+        /* On Apple Silicon fallback to hw.tbfrequency and kern.clockrate.hz */
+        struct clockinfo clockrate;
+        size_t clockrate_len = sizeof(clockrate);
+        if (sysctlbyname("hw.tbfrequency", &cpu_freq, &cpu_freq_len, NULL, 0) < 0 ||
+            sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0) < 0) {
+            virReportSystemError(errno, "%s", _("cannot obtain CPU freq"));
+            return -1;
+        }
+
+        cpu_freq *= clockrate.hz;
     }
 
     *mhz = cpu_freq / 1000000;
-- 
2.34.1




More information about the libvir-list mailing list