Hi @TeddyAstie,
I use a Ryzen 7 5875u CPU (Zen3) shipped in 2022.
The sensor/K10temp approach doesn't work (nothing detected).
AFAIK Zen3 temp support was introduced around the. kernel 5.14 late 2021.
If it's not supported yet, I guess that it won't, right?
Is there another solution to monitor temp except to wait for a future xcp-ng v9 version?
I was wondering if the amd cpu temp be probed the way you did for the intel cpu.
(Disclamer the following patch is a first draft AI generated because I don't have the skills. I share it because even I can spot it's not perfect as is, it doesn't look bloated)
diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/asm/msr-index.h
index df52587c85..9d8f7bd4d1 100644
--- a/xen/arch/x86/include/asm/msr-index.h
+++ b/xen/arch/x86/include/asm/msr-index.h
@@ -115,6 +115,9 @@
#define MCU_OPT_CTRL_GDS_MIT_DIS (_AC(1, ULL) << 4)
#define MCU_OPT_CTRL_GDS_MIT_LOCK (_AC(1, ULL) << 5)
+/* AMD Hardware Thermal Control */
+#define MSR_AMD_HARDWARE_THERMAL_CONTROL 0xc0010292
+
#define MSR_FRED_RSP_SL0 0x000001cc
#define MSR_FRED_RSP_SL1 0x000001cd
#define MSR_FRED_RSP_SL2 0x000001ce
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 79bb99e0b6..e84a2ddd3e 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -86,6 +86,13 @@ static bool msr_read_allowed(unsigned int msr)
case MSR_MCU_OPT_CTRL:
return cpu_has_srbds_ctrl;
+
+ /* Intel MSRs (From Vates Patch) */
+ case MSR_IA32_THERM_STATUS:
+ case MSR_IA32_TEMPERATURE_TARGET:
+ return boot_cpu_data.x86_vendor == X86_VENDOR_INTEL;
+
+ /* AMD MSR */
+ case MSR_AMD_HARDWARE_THERMAL_CONTROL:
+ return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
}
if ( ppin_msr && msr == ppin_msr )
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index 3a228c2..f9b8c71 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -1553,6 +1554,81 @@ void get_core_temp(int argc, char *argv[])
{
xc_physinfo_t physinfo = { 0 };
int i, max_cpu_nr;
+ bool is_amd = false;
+ bool is_intel = false;
if ( argc > 0 )
{
- fprintf(stderr, "Usage: xenpm get-core-temp\n");
+ fprintf(stderr, "Usage: xenpm get-core-temp\n"
+ " (Supports Intel via TjMax and AMD via HTC)\n");
exit(EINVAL);
}
if ( xc_physinfo(xc_handle, &physinfo) )
{
fprintf(stderr, "Failed to get xc_physinfo. Err: %s\n", strerror(errno));
exit(EINVAL);
}
max_cpu_nr = physinfo.max_cpu_id + 1;
+ /* Probe CPU 0 to determine vendor based on allowed MSRs */
+ xc_resource_op_t probe_intel = {
+ .cpu = 0,
+ .cmd = XEN_RESOURCE_OP_read_msr,
+ .u.msr = { .msr = 0x19c } /* MSR_IA32_THERM_STATUS */
+ };
+ xc_resource_op_t probe_amd = {
+ .cpu = 0,
+ .cmd = XEN_RESOURCE_OP_read_msr,
+ .u.msr = { .msr = 0xc0010292 } /* MSR_AMD_HARDWARE_THERMAL_CONTROL */
+ };
+
+ if ( xc_resource_op(xc_handle, 1, &probe_intel) == 0 )
+ is_intel = true;
+ else if ( xc_resource_op(xc_handle, 1, &probe_amd) == 0 )
+ is_amd = true;
+ else
+ {
+ fprintf(stderr, "Error: Current CPU architecture is not supported for temperature reading.\n");
+ exit(ENOTSUP);
+ }
+
printf("CPU\tCurrent Temperature\n");
for ( i = 0; i < max_cpu_nr; i++ )
{
- /*
- * ... Existing Vates Intel logic ...
- * (Reading MSR_IA32_TEMPERATURE_TARGET and MSR_IA32_THERM_STATUS)
- */
+ if ( is_intel )
+ {
+ /* --- INTEL LOGIC (Vates implementation) --- */
+ xc_resource_op_t op_tjmax = { .cpu = i, .cmd = XEN_RESOURCE_OP_read_msr, .u.msr = { .msr = 0x1a2 } };
+ xc_resource_op_t op_therm = { .cpu = i, .cmd = XEN_RESOURCE_OP_read_msr, .u.msr = { .msr = 0x19c } };
+
+ if ( xc_resource_op(xc_handle, 1, &op_tjmax) || xc_resource_op(xc_handle, 1, &op_therm) )
+ continue;
+
+ uint32_t tjmax = (op_tjmax.u.msr.value >> 16) & 0xFF;
+ uint32_t readout = (op_therm.u.msr.value >> 16) & 0x7F;
+
+ printf("%d\t%d C\n", i, tjmax - readout);
+ }
+ else if ( is_amd )
+ {
+ /* --- AMD LOGIC --- */
+ xc_resource_op_t op_amd = {
+ .cpu = i,
+ .cmd = XEN_RESOURCE_OP_read_msr,
+ .u.msr = { .msr = 0xc0010292 }
+ };
+
+ if ( xc_resource_op(xc_handle, 1, &op_amd) )
+ continue; /* Skip offline/unavailable CPUs */
+
+ uint64_t msr_val = op_amd.u.msr.value;
+
+ /* Extract CurTmp (bits [31:21]) and multiply by 0.125°C */
+ uint32_t cur_tmp_raw = (msr_val >> 21) & 0x7FF;
+ float temp_c = cur_tmp_raw * 0.125;
+
+ printf("%d\t%.2f C\n", i, temp_c);
+ }
}
}