All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhao Liu <zhao1.liu@linux.intel.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
	Sean Christopherson <seanjc@google.com>,
	"Rafael J . Wysocki" <rafael@kernel.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	"H . Peter Anvin" <hpa@zytor.com>,
	kvm@vger.kernel.org, linux-pm@vger.kernel.org,
	linux-kernel@vger.kernel.org, x86@kernel.org
Cc: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>,
	Len Brown <len.brown@intel.com>, Zhang Rui <rui.zhang@intel.com>,
	Zhenyu Wang <zhenyu.z.wang@intel.com>,
	Zhuocheng Ding <zhuocheng.ding@intel.com>,
	Dapeng Mi <dapeng1.mi@intel.com>,
	Yanting Jiang <yanting.jiang@intel.com>,
	Yongwei Ma <yongwei.ma@intel.com>,
	Vineeth Pillai <vineeth@bitbyteword.org>,
	Suleiman Souhlal <suleiman@google.com>,
	Masami Hiramatsu <mhiramat@google.com>,
	David Dai <davidai@google.com>,
	Saravana Kannan <saravanak@google.com>,
	Zhao Liu <zhao1.liu@intel.com>
Subject: [RFC 18/26] KVM: VMX: Emulate HFI related bits in package thermal MSRs
Date: Sat,  3 Feb 2024 17:12:06 +0800	[thread overview]
Message-ID: <20240203091214.411862-19-zhao1.liu@linux.intel.com> (raw)
In-Reply-To: <20240203091214.411862-1-zhao1.liu@linux.intel.com>

From: Zhao Liu <zhao1.liu@intel.com>

The HFI feature adds the new bits in MSR_IA32_PACKAGE_THERM_STATUS and
MSR_IA32_PACKAGE_THERM_INTERRUPT to control HFI status and notification:

* MSR_IA32_PACKAGE_THERM_STATUS: PACKAGE_THERM_STATUS_HFI_UPDATED bit.

  This bit indicates if there's the new HFI update. Whenever the HFI
  table is updated, the hardware sends an HFI notification and sets this
  bit to 1. Only when the OS clears this bit to 0 will the HFI table
  continue to be updated.

  Emulate the logic of this bit to coordinate with the update of the
  Guest HFI table and also to support Guest's clear 0 write.

* MSR_IA32_PACKAGE_THERM_INTERRUPT: PACKAGE_THERM_INT_HFI_ENABLE bit.

  This bit controls the HFI notification enabling. If it's set to 1,
  every time when HFI table has update, hardware will send a thermal
  interrupt to notify OS.

  Therefore, also emulate this bit to support thermal interrupt when
  Guest HFI table is updated.

These status/control bits correspond to the flags in struct hfi_desc,
(this is hfi_update_status and hfi_int_enabled).

Note that for the thermal interrupt-related features, we only fully
emulate HFI, so MSR_IA32_PACKAGE_THERM_STATUS and
MSR_IA32_PACKAGE_THERM_INTERRUPT do not (and should not, even though
we do not disable the initial exception MSR value via KVM_SET_MSRS)
take effect by setting other bits.

Tested-by: Yanting Jiang <yanting.jiang@intel.com>
Co-developed-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Signed-off-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 arch/x86/kvm/vmx/vmx.c | 129 +++++++++++++++++++++++++++++++++++------
 1 file changed, 111 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 97bb7b304213..92dded89ae3c 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -183,7 +183,6 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
 	THERM_MASK_THRESHOLD0 | THERM_INT_THRESHOLD0_ENABLE | \
 	THERM_MASK_THRESHOLD1 | THERM_INT_THRESHOLD1_ENABLE)
 
-/* HFI (CPUID.06H:EAX[19]) is not emulated in kvm yet. */
 #define MSR_IA32_PACKAGE_THERM_STATUS_RO_MASK (PACKAGE_THERM_STATUS_PROCHOT | \
 	PACKAGE_THERM_STATUS_PROCHOT_EVENT | PACKAGE_THERM_STATUS_CRITICAL_TEMP | \
 	THERM_STATUS_THRESHOLD0 | THERM_STATUS_THRESHOLD1 | \
@@ -191,20 +190,17 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
 #define MSR_IA32_PACKAGE_THERM_STATUS_RWC0_MASK (PACKAGE_THERM_STATUS_PROCHOT_LOG | \
 	PACKAGE_THERM_STATUS_PROCHOT_EVENT_LOG | PACKAGE_THERM_STATUS_CRITICAL_TEMP_LOG | \
 	THERM_LOG_THRESHOLD0 | THERM_LOG_THRESHOLD1 | \
-	PACKAGE_THERM_STATUS_POWER_LIMIT_LOG)
+	PACKAGE_THERM_STATUS_POWER_LIMIT_LOG | PACKAGE_THERM_STATUS_HFI_UPDATED)
 /* MSR_IA32_PACKAGE_THERM_STATUS unavailable bits mask: unsupported and reserved bits. */
 #define MSR_IA32_PACKAGE_THERM_STATUS_UNAVAIL_MASK (~(MSR_IA32_PACKAGE_THERM_STATUS_RO_MASK | \
 	MSR_IA32_PACKAGE_THERM_STATUS_RWC0_MASK))
 
-/*
- * MSR_IA32_PACKAGE_THERM_INTERRUPT available bits mask.
- * HFI (CPUID.06H:EAX[19]) is not emulated in kvm yet.
- */
-#define MSR_IA32_PACKAGE_THERM_INTERRUPT_AVAIL_MASK (PACKAGE_THERM_INT_HIGH_ENABLE | \
+#define MSR_IA32_PACKAGE_THERM_INTERRUPT_MASK (PACKAGE_THERM_INT_HIGH_ENABLE | \
 	PACKAGE_THERM_INT_LOW_ENABLE | PACKAGE_THERM_INT_PROCHOT_ENABLE | \
 	PACKAGE_THERM_INT_OVERHEAT_ENABLE | THERM_MASK_THRESHOLD0 | \
 	THERM_INT_THRESHOLD0_ENABLE | THERM_MASK_THRESHOLD1 | \
-	THERM_INT_THRESHOLD1_ENABLE | PACKAGE_THERM_INT_PLN_ENABLE)
+	THERM_INT_THRESHOLD1_ENABLE | PACKAGE_THERM_INT_PLN_ENABLE | \
+	PACKAGE_THERM_INT_HFI_ENABLE)
 
 /*
  * List of MSRs that can be directly passed to the guest.
@@ -2417,7 +2413,16 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has(vcpu, X86_FEATURE_PTS))
 			return 1;
+
+		mutex_lock(&kvm_vmx->pkg_therm.pkg_therm_lock);
+		if (kvm_vmx->pkg_therm.hfi_desc.hfi_update_status)
+			kvm_vmx->pkg_therm.msr_pkg_therm_status |=
+				PACKAGE_THERM_STATUS_HFI_UPDATED;
+		else
+			kvm_vmx->pkg_therm.msr_pkg_therm_status &=
+				~PACKAGE_THERM_STATUS_HFI_UPDATED;
 		msr_info->data = kvm_vmx->pkg_therm.msr_pkg_therm_status;
+		mutex_unlock(&kvm_vmx->pkg_therm.pkg_therm_lock);
 		break;
 	default:
 	find_uret_msr:
@@ -2471,6 +2476,87 @@ static inline u64 vmx_set_msr_rwc0_bits(u64 new_val, u64 old_val, u64 rwc0_mask)
 	return ((new_rwc0 | ~old_rwc0) & old_rwc0) | (new_val & ~rwc0_mask);
 }
 
+static int vmx_set_pkg_therm_int_msr(struct kvm_vcpu *vcpu,
+				     struct msr_data *msr_info)
+{
+	struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm);
+	struct hfi_desc *kvm_vmx_hfi = &kvm_vmx->pkg_therm.hfi_desc;
+	u64 data = msr_info->data;
+	bool hfi_int_enabled, hfi_int_changed;
+
+	hfi_int_enabled = data & PACKAGE_THERM_INT_HFI_ENABLE;
+	hfi_int_changed = vmx_hfi_int_enabled(kvm_vmx) != hfi_int_enabled;
+
+	kvm_vmx->pkg_therm.msr_pkg_therm_int = data;
+	kvm_vmx_hfi->hfi_int_enabled = hfi_int_enabled;
+
+	/*
+	 * Only HFI notification is supported, otherwise behave as a
+	 * dummy MSR.
+	 */
+	if (!intel_hfi_enabled() ||
+	    !guest_cpuid_has(vcpu, X86_FEATURE_HFI) ||
+	    !hfi_int_changed)
+		return 0;
+
+	if (!hfi_int_enabled)
+		return 0;
+
+	/*
+	 * SDM: (For IA32_HW_FEEDBACK_CONFIG) no (HFI) status bit
+	 * set, no interrupt is generated.
+	 */
+	if (!kvm_vmx_hfi->hfi_enabled)
+		return 0;
+
+	/*
+	 * When HFI interrupt enable bit transitions from 0 to 1,
+	 * try to inject initial interrupt. No need to force
+	 * injection of the interrupt if there's no HFI table update.
+	 */
+	vmx_update_hfi_table(vcpu->kvm, false);
+
+	return 0;
+}
+
+static int vmx_set_pkg_therm_status_msr(struct kvm_vcpu *vcpu,
+					struct msr_data *msr_info)
+{
+	struct kvm_vmx *kvm_vmx = to_kvm_vmx(vcpu->kvm);
+	struct hfi_desc *kvm_vmx_hfi = &kvm_vmx->pkg_therm.hfi_desc;
+	u64 data = msr_info->data;
+	bool hfi_status_updated, hfi_status_changed;
+
+	if (!msr_info->host_initiated) {
+		data = vmx_set_msr_rwc0_bits(data, kvm_vmx->pkg_therm.msr_pkg_therm_status,
+					     MSR_IA32_PACKAGE_THERM_STATUS_RWC0_MASK);
+		data = vmx_set_msr_ro_bits(data, kvm_vmx->pkg_therm.msr_pkg_therm_status,
+					   MSR_IA32_PACKAGE_THERM_STATUS_RO_MASK);
+	}
+
+	hfi_status_updated = data & PACKAGE_THERM_STATUS_HFI_UPDATED;
+	hfi_status_changed = kvm_vmx_hfi->hfi_update_status != hfi_status_updated;
+
+	kvm_vmx->pkg_therm.msr_pkg_therm_status = data;
+	kvm_vmx_hfi->hfi_update_status = hfi_status_updated;
+
+	if (!intel_hfi_enabled() ||
+	    !guest_cpuid_has(vcpu, X86_FEATURE_HFI) ||
+	    !hfi_status_changed)
+		return 0;
+
+	/*
+	 * From SDM, once the HFI (thermal) status bit is set, the hardware
+	 * will not generate any further updates to HFI table until the OS
+	 * clears this bit by writing 0. When this bit is cleared, apply any
+	 * pending updates to guest HFI table.
+	 */
+	if (!kvm_vmx_hfi->hfi_update_status && kvm_vmx_hfi->hfi_update_pending)
+		vmx_update_hfi_table(vcpu->kvm, false);
+
+	return 0;
+}
+
 /*
  * Writes msr value into the appropriate "register".
  * Returns 0 on success, non-0 otherwise.
@@ -2801,11 +2887,19 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		if (!msr_info->host_initiated &&
 		    !guest_cpuid_has(vcpu, X86_FEATURE_PTS))
 			return 1;
-		/* Unsupported and reserved bits: generate the exception. */
+		/* Unsupported bit: generate the exception. */
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has(vcpu, X86_FEATURE_HFI) &&
+		    data & PACKAGE_THERM_INT_HFI_ENABLE)
+			return 1;
+		/* Reserved bits: generate the exception. */
 		if (!msr_info->host_initiated &&
-		    data & ~MSR_IA32_PACKAGE_THERM_INTERRUPT_AVAIL_MASK)
+		    data & ~MSR_IA32_PACKAGE_THERM_INTERRUPT_MASK)
 			return 1;
-		kvm_vmx->pkg_therm.msr_pkg_therm_int = data;
+
+		mutex_lock(&kvm_vmx->pkg_therm.pkg_therm_lock);
+		ret = vmx_set_pkg_therm_int_msr(vcpu, msr_info);
+		mutex_unlock(&kvm_vmx->pkg_therm.pkg_therm_lock);
 		break;
 	case MSR_IA32_PACKAGE_THERM_STATUS:
 		if (!msr_info->host_initiated &&
@@ -2815,15 +2909,14 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 		if (!msr_info->host_initiated &&
 		    data & MSR_IA32_PACKAGE_THERM_STATUS_UNAVAIL_MASK)
 			return 1;
+		/* Unsupported bit: generate the exception. */
+		if (!msr_info->host_initiated &&
+		    !guest_cpuid_has(vcpu, X86_FEATURE_HFI) &&
+		    data & PACKAGE_THERM_STATUS_HFI_UPDATED)
+			return 1;
 
 		mutex_lock(&kvm_vmx->pkg_therm.pkg_therm_lock);
-		if (!msr_info->host_initiated) {
-			data = vmx_set_msr_rwc0_bits(data, kvm_vmx->pkg_therm.msr_pkg_therm_status,
-						     MSR_IA32_PACKAGE_THERM_STATUS_RWC0_MASK);
-			data = vmx_set_msr_ro_bits(data, kvm_vmx->pkg_therm.msr_pkg_therm_status,
-						   MSR_IA32_PACKAGE_THERM_STATUS_RO_MASK);
-		}
-		kvm_vmx->pkg_therm.msr_pkg_therm_status = data;
+		ret = vmx_set_pkg_therm_status_msr(vcpu, msr_info);
 		mutex_unlock(&kvm_vmx->pkg_therm.pkg_therm_lock);
 		break;
 	default:
-- 
2.34.1


  parent reply	other threads:[~2024-02-03  9:01 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-03  9:11 [RFC 00/26] Intel Thread Director Virtualization Zhao Liu
2024-02-03  9:11 ` [RFC 01/26] thermal: Add bit definition for x86 thermal related MSRs Zhao Liu
2024-02-03  9:11 ` [RFC 02/26] thermal: intel: hfi: Add helpers to build HFI/ITD structures Zhao Liu
2024-02-03  9:11 ` [RFC 03/26] thermal: intel: hfi: Add HFI notifier helpers to notify HFI update Zhao Liu
2024-02-03  9:11 ` [RFC 04/26] KVM: Add kvm_arch_sched_out() hook Zhao Liu
2024-02-03  9:11 ` [RFC 05/26] KVM: x86: Reset hardware history at vCPU's sched_in/out Zhao Liu
2024-02-03  9:11 ` [RFC 06/26] KVM: VMX: Add helpers to handle the writes to MSR's R/O and R/WC0 bits Zhao Liu
2024-02-03  9:11 ` [RFC 07/26] KVM: VMX: Emulate ACPI (CPUID.0x01.edx[bit 22]) feature Zhao Liu
2024-02-03  9:11 ` [RFC 08/26] KVM: x86: Expose TM/ACC (CPUID.0x01.edx[bit 29]) feature bit to VM Zhao Liu
2024-02-03  9:11 ` [RFC 09/26] KVM: x86: cpuid: Define CPUID 0x06.eax by kvm_cpu_cap_mask() Zhao Liu
2024-02-03  9:11 ` [RFC 10/26] KVM: VMX: Emulate PTM/PTS (CPUID.0x06.eax[bit 6]) feature Zhao Liu
2024-02-03  9:11 ` [RFC 11/26] KVM: VMX: Introduce HFI description structure Zhao Liu
2024-02-03  9:12 ` [RFC 12/26] KVM: VMX: Introduce HFI table index for vCPU Zhao Liu
2024-02-03  9:12 ` [RFC 13/26] KVM: VMX: Support virtual HFI table for VM Zhao Liu
2024-02-03  9:12 ` [RFC 14/26] KVM: x86: Introduce the HFI dynamic update request and kvm_x86_ops Zhao Liu
2024-02-03  9:12 ` [RFC 15/26] KVM: VMX: Sync update of Host HFI table to Guest Zhao Liu
2024-02-03  9:12 ` [RFC 16/26] KVM: VMX: Update HFI table when vCPU migrates Zhao Liu
2024-02-03  9:12 ` [RFC 17/26] KVM: VMX: Allow to inject thermal interrupt without HFI update Zhao Liu
2024-02-03  9:12 ` Zhao Liu [this message]
2024-02-03  9:12 ` [RFC 19/26] KVM: VMX: Emulate the MSRs of HFI feature Zhao Liu
2024-02-03  9:12 ` [RFC 20/26] KVM: x86: Expose HFI feature bit and HFI info in CPUID Zhao Liu
2024-02-03  9:12 ` [RFC 21/26] KVM: VMX: Extend HFI table and MSR emulation to support ITD Zhao Liu
2024-02-03  9:12 ` [RFC 22/26] KVM: VMX: Pass through ITD classification related MSRs to Guest Zhao Liu
2024-02-03  9:12 ` [RFC 23/26] KVM: x86: Expose ITD feature bit and related info in CPUID Zhao Liu
2024-02-03  9:12 ` [RFC 24/26] KVM: VMX: Emulate the MSR of HRESET feature Zhao Liu
2024-02-03  9:12 ` [RFC 25/26] KVM: x86: Expose HRESET feature's CPUID to Guest Zhao Liu
2024-02-03  9:12 ` [RFC 26/26] Documentation: KVM: Add description of pkg_therm_lock Zhao Liu
2024-02-22  7:42 ` [RFC 00/26] Intel Thread Director Virtualization Zhao Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240203091214.411862-19-zhao1.liu@linux.intel.com \
    --to=zhao1.liu@linux.intel.com \
    --cc=bp@alien8.de \
    --cc=daniel.lezcano@linaro.org \
    --cc=dapeng1.mi@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=davidai@google.com \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=len.brown@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mhiramat@google.com \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rafael@kernel.org \
    --cc=ricardo.neri-calderon@linux.intel.com \
    --cc=rui.zhang@intel.com \
    --cc=saravanak@google.com \
    --cc=seanjc@google.com \
    --cc=suleiman@google.com \
    --cc=tglx@linutronix.de \
    --cc=vineeth@bitbyteword.org \
    --cc=x86@kernel.org \
    --cc=yanting.jiang@intel.com \
    --cc=yongwei.ma@intel.com \
    --cc=zhao1.liu@intel.com \
    --cc=zhenyu.z.wang@intel.com \
    --cc=zhuocheng.ding@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.