[RFC PATCH for-4.22 2/2] tools: Introduce xen-inteltemp tool

Teddy Astie posted 2 patches 2 days, 4 hours ago
There is a newer version of this series
[RFC PATCH for-4.22 2/2] tools: Introduce xen-inteltemp tool
Posted by Teddy Astie 2 days, 4 hours ago
Introduce a new tool to fetch Intel CPU temperatures through the
Intel DTS interface using XENPF_resource_op hypercall.

Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
---
 tools/misc/.gitignore      |  1 +
 tools/misc/Makefile        |  4 ++
 tools/misc/xen-inteltemp.c | 98 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 tools/misc/xen-inteltemp.c

diff --git a/tools/misc/.gitignore b/tools/misc/.gitignore
index 28af46280f..65048eb901 100644
--- a/tools/misc/.gitignore
+++ b/tools/misc/.gitignore
@@ -5,6 +5,7 @@ xen-diag
 xen-hptool
 xen-hvmcrash
 xen-hvmctx
+xen-inteltemp
 xen-livepatch
 xen-lowmemd
 xen-mceinj
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index c26e544e83..6498b47ec0 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -25,6 +25,7 @@ INSTALL_SBIN-$(CONFIG_X86)     += xen-memshare
 INSTALL_SBIN-$(CONFIG_X86)     += xen-mfndump
 INSTALL_SBIN-$(CONFIG_X86)     += xen-ucode
 INSTALL_SBIN-$(CONFIG_X86)     += xen-vmtrace
+INSTALL_SBIN-$(CONFIG_X86)     += xen-inteltemp
 INSTALL_SBIN                   += xencov
 INSTALL_SBIN                   += xenhypfs
 INSTALL_SBIN                   += xenlockprof
@@ -89,6 +90,9 @@ xen-memshare: xen-memshare.o
 xen-vmtrace: xen-vmtrace.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenforeignmemory) $(APPEND_LDFLAGS)
 
+xen-inteltemp: xen-inteltemp.o
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+
 xen-mceinj: xen-mceinj.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
 
diff --git a/tools/misc/xen-inteltemp.c b/tools/misc/xen-inteltemp.c
new file mode 100644
index 0000000000..624c74ca7f
--- /dev/null
+++ b/tools/misc/xen-inteltemp.c
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xen-inteltemp.c
+ *
+ * Get the CPU temperature of Intel processors.
+ *
+ * Copyright 2025 Teddy Astie <teddy.astie@vates.tech>
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <xenctrl.h>
+
+#define MSR_IA32_THERM_STATUS         0x0000019c
+#define MSR_IA32_TEMPERATURE_TARGET   0x000001a2
+#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
+
+int fetch_dts_temp(xc_interface *xch, uint32_t cpu, bool package, int *temp)
+{
+    xc_resource_entry_t entries[2] = {
+        (xc_resource_entry_t){
+            .idx = package ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS
+        },
+        (xc_resource_entry_t){ .idx = MSR_IA32_TEMPERATURE_TARGET },
+    };
+    struct xc_resource_op ops = {
+        .cpu = cpu,
+        .entries = entries,
+        .nr_entries = 2,
+    };
+    int tjmax;
+
+    int ret = xc_resource_op(xch, 1, &ops);
+
+    if ( ret <= 0 )
+        /* This CPU isn't online or can't query this MSR */
+        return ret ?: -EOPNOTSUPP;
+
+    if ( ret == 2 )
+        tjmax = (entries[1].val >> 16) & 0xff;
+    else
+    {
+        /*
+         * The CPU doesn't support MSR_IA32_TEMPERATURE_TARGET, we assume it's 100 which
+         * is correct aside a few selected Atom CPUs. Check coretemp source code for more
+         * information.
+         */
+        fprintf(stderr, "CPU%d doesn't support MSR_IA32_TEMPERATURE_TARGET, assume "
+               "tjmax=100°C, readings may be incorrect\n", cpu);
+        tjmax = 100;
+    }
+    
+    *temp = tjmax - ((entries[0].val >> 16) & 0xff);
+    return 0;
+}
+
+int main(void)
+{
+    int rc = 0, temp, cpu, socket;
+    bool has_data = false;
+    xc_interface *xch = xc_interface_open(0, 0, 0);
+    xc_physinfo_t info;
+
+    if ( (rc = xc_physinfo(xch, &info)) < 0 )
+    {
+        perror("Getting physinfo failed");
+        return rc;
+    }
+
+    /* Per socket measurement */
+    for ( socket = 0, cpu = 0;
+          cpu < (info.max_cpu_id + 1);
+          socket++, cpu += info.cores_per_socket * info.threads_per_core )
+    {
+        if ( !fetch_dts_temp(xch, cpu, true, &temp) )
+        {
+            has_data = true;
+            printf("Package%d: %d°C\n", socket, temp);
+        }
+    }
+
+    printf("\n");
+
+    for ( cpu = 0; cpu < (info.max_cpu_id + 1); cpu += info.threads_per_core )
+    {
+        if ( fetch_dts_temp(xch, cpu, false, &temp) )
+            continue;
+
+        has_data = true;
+        printf("CPU%d: %d°C\n", cpu, temp);
+    }
+
+    if ( !has_data )
+        printf("No data\n");
+
+    xc_interface_close(xch);
+    return 0;
+}
\ No newline at end of file
-- 
2.51.1



--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech
Re: [RFC PATCH for-4.22 2/2] tools: Introduce xen-inteltemp tool
Posted by Jan Beulich 1 day, 12 hours ago
On 27.10.2025 18:26, Teddy Astie wrote:
> Introduce a new tool to fetch Intel CPU temperatures through the
> Intel DTS interface using XENPF_resource_op hypercall.
> 
> Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
> ---
>  tools/misc/.gitignore      |  1 +
>  tools/misc/Makefile        |  4 ++
>  tools/misc/xen-inteltemp.c | 98 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 103 insertions(+)
>  create mode 100644 tools/misc/xen-inteltemp.c

Instead of introducing a new tool, might this not fit in xenpm?

> --- /dev/null
> +++ b/tools/misc/xen-inteltemp.c
> @@ -0,0 +1,98 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * xen-inteltemp.c
> + *
> + * Get the CPU temperature of Intel processors.
> + *
> + * Copyright 2025 Teddy Astie <teddy.astie@vates.tech>
> + */
> +
> +#include <stdio.h>
> +#include <errno.h>
> +#include <xenctrl.h>
> +
> +#define MSR_IA32_THERM_STATUS         0x0000019c
> +#define MSR_IA32_TEMPERATURE_TARGET   0x000001a2
> +#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
> +
> +int fetch_dts_temp(xc_interface *xch, uint32_t cpu, bool package, int *temp)
> +{
> +    xc_resource_entry_t entries[2] = {
> +        (xc_resource_entry_t){
> +            .idx = package ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS
> +        },
> +        (xc_resource_entry_t){ .idx = MSR_IA32_TEMPERATURE_TARGET },
> +    };
> +    struct xc_resource_op ops = {
> +        .cpu = cpu,
> +        .entries = entries,
> +        .nr_entries = 2,
> +    };
> +    int tjmax;
> +
> +    int ret = xc_resource_op(xch, 1, &ops);
> +
> +    if ( ret <= 0 )
> +        /* This CPU isn't online or can't query this MSR */
> +        return ret ?: -EOPNOTSUPP;
> +
> +    if ( ret == 2 )
> +        tjmax = (entries[1].val >> 16) & 0xff;
> +    else
> +    {
> +        /*
> +         * The CPU doesn't support MSR_IA32_TEMPERATURE_TARGET, we assume it's 100 which
> +         * is correct aside a few selected Atom CPUs. Check coretemp source code for more
> +         * information.
> +         */
> +        fprintf(stderr, "CPU%d doesn't support MSR_IA32_TEMPERATURE_TARGET, assume "
> +               "tjmax=100°C, readings may be incorrect\n", cpu);
> +        tjmax = 100;
> +    }
> +    
> +    *temp = tjmax - ((entries[0].val >> 16) & 0xff);
> +    return 0;
> +}
> +
> +int main(void)
> +{
> +    int rc = 0, temp, cpu, socket;
> +    bool has_data = false;
> +    xc_interface *xch = xc_interface_open(0, 0, 0);
> +    xc_physinfo_t info;
> +
> +    if ( (rc = xc_physinfo(xch, &info)) < 0 )
> +    {
> +        perror("Getting physinfo failed");
> +        return rc;
> +    }
> +
> +    /* Per socket measurement */
> +    for ( socket = 0, cpu = 0;
> +          cpu < (info.max_cpu_id + 1);
> +          socket++, cpu += info.cores_per_socket * info.threads_per_core )
> +    {
> +        if ( !fetch_dts_temp(xch, cpu, true, &temp) )
> +        {
> +            has_data = true;
> +            printf("Package%d: %d°C\n", socket, temp);
> +        }
> +    }
> +
> +    printf("\n");
> +
> +    for ( cpu = 0; cpu < (info.max_cpu_id + 1); cpu += info.threads_per_core )
> +    {
> +        if ( fetch_dts_temp(xch, cpu, false, &temp) )
> +            continue;
> +
> +        has_data = true;
> +        printf("CPU%d: %d°C\n", cpu, temp);
> +    }
> +
> +    if ( !has_data )
> +        printf("No data\n");
> +
> +    xc_interface_close(xch);
> +    return 0;
> +}
> \ No newline at end of file

Please never introduce files without trailing newline.

Jan