get-intel-temp allows querying the per-core CPU temperature and
per-package one on Intel processors (as usual Dom0 drivers cannot
work due to misalignment between Dom0 vCPU and pCPUs).
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
---
v2: moved from a separate command to xenpm
tools/misc/xenpm.c | 93 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 1 deletion(-)
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index 682d092479..ef9abee48e 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -37,6 +37,7 @@
static xc_interface *xc_handle;
static unsigned int max_cpu_nr;
+static xc_physinfo_t physinfo;
/* help message */
void show_help(void)
@@ -93,6 +94,7 @@ void show_help(void)
" units default to \"us\" if unspecified.\n"
" truncates un-representable values.\n"
" 0 lets the hardware decide.\n"
+ " get-intel-temp [cpuid] get Intel CPU temperature of <cpuid> or all\n"
" start [seconds] start collect Cx/Px statistics,\n"
" output after CTRL-C or SIGINT or several seconds.\n"
" enable-turbo-mode [cpuid] enable Turbo Mode for processors that support it.\n"
@@ -1354,6 +1356,95 @@ void enable_turbo_mode(int argc, char *argv[])
errno, strerror(errno));
}
+#define MSR_DTS_THERM_STATUS 0x0000019c
+#define MSR_DTS_TEMPERATURE_TARGET 0x000001a2
+#define MSR_DTS_PACKAGE_THERM_STATUS 0x000001b1
+
+static 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_DTS_PACKAGE_THERM_STATUS : MSR_DTS_THERM_STATUS
+ },
+ (xc_resource_entry_t){ .idx = MSR_DTS_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] MSR_IA32_TEMPERATURE_TARGET is not supported, assume "
+ "tjmax=100°C, readings may be incorrect\n", cpu);
+ tjmax = 100;
+ }
+
+ *temp = tjmax - ((entries[0].val >> 16) & 0xff);
+ return 0;
+}
+
+
+void get_intel_temp(int argc, char *argv[])
+{
+ int temp, cpu = -1, socket;
+ bool has_data = false;
+
+ if (argc > 0)
+ parse_cpuid(argv[0], &cpu);
+
+ if (cpu != -1)
+ {
+ if ( !fetch_dts_temp(xc_handle, cpu, false, &temp) )
+ printf("CPU%d: %d°C\n", cpu, temp);
+ else
+ printf("No data\n");
+ return;
+ }
+
+ /* Per socket measurement */
+ for ( socket = 0, cpu = 0; cpu < max_cpu_nr;
+ socket++, cpu += physinfo.cores_per_socket * physinfo.threads_per_core )
+ {
+ if ( !fetch_dts_temp(xc_handle, cpu, true, &temp) )
+ {
+ has_data = true;
+ printf("Package%d: %d°C\n", socket, temp);
+ }
+ }
+
+ if ( has_data )
+ /* Avoid inserting a trailing line if we have nothing */
+ printf("\n");
+
+ for ( cpu = 0; cpu < max_cpu_nr; cpu += physinfo.threads_per_core )
+ {
+ if ( fetch_dts_temp(xc_handle, cpu, false, &temp) )
+ continue;
+
+ has_data = true;
+ printf("CPU%d: %d°C\n", cpu, temp);
+ }
+
+ if ( !has_data )
+ printf("No data\n");
+}
+
void disable_turbo_mode(int argc, char *argv[])
{
int cpuid = -1;
@@ -1618,12 +1709,12 @@ struct {
{ "set-max-cstate", set_max_cstate_func},
{ "enable-turbo-mode", enable_turbo_mode },
{ "disable-turbo-mode", disable_turbo_mode },
+ { "get-intel-temp", get_intel_temp },
};
int main(int argc, char *argv[])
{
int i, ret = 0;
- xc_physinfo_t physinfo;
int nr_matches = 0;
int matches_main_options[ARRAY_SIZE(main_options)];
--
2.51.2
--
Teddy Astie | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
© 2016 - 2025 Red Hat, Inc.