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 02/26] thermal: intel: hfi: Add helpers to build HFI/ITD structures
Date: Sat, 3 Feb 2024 17:11:50 +0800 [thread overview]
Message-ID: <20240203091214.411862-3-zhao1.liu@linux.intel.com> (raw)
In-Reply-To: <20240203091214.411862-1-zhao1.liu@linux.intel.com>
From: Zhuocheng Ding <zhuocheng.ding@intel.com>
Virtual machines need to compose their own HFI tables. Provide helper
functions that collect the relevant features and data from the host
machine.
Tested-by: Yanting Jiang <yanting.jiang@intel.com>
Signed-off-by: Zhuocheng Ding <zhuocheng.ding@intel.com>
Co-developed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
arch/x86/include/asm/hfi.h | 20 ++++
drivers/thermal/intel/intel_hfi.c | 149 ++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+)
diff --git a/arch/x86/include/asm/hfi.h b/arch/x86/include/asm/hfi.h
index b7fda3e0e8c8..e0fe5b30fb53 100644
--- a/arch/x86/include/asm/hfi.h
+++ b/arch/x86/include/asm/hfi.h
@@ -82,4 +82,24 @@ struct hfi_features {
unsigned int hdr_size;
};
+#if defined(CONFIG_INTEL_HFI_THERMAL)
+int intel_hfi_max_instances(void);
+int intel_hfi_build_virt_features(struct hfi_features *features, unsigned int nr_classes,
+ unsigned int nr_entries);
+int intel_hfi_build_virt_table(struct hfi_table *table, struct hfi_features *features,
+ unsigned int nr_classes, unsigned int hfi_index,
+ unsigned int cpu);
+static inline bool intel_hfi_enabled(void) { return intel_hfi_max_instances() > 0; }
+#else
+static inline int intel_hfi_max_instances(void) { return 0; }
+static inline int intel_hfi_build_virt_features(struct hfi_features *features,
+ unsigned int nr_classes,
+ unsigned int nr_entries) { return 0; }
+static inline int intel_hfi_build_virt_table(struct hfi_table *table,
+ struct hfi_features *features,
+ unsigned int nr_classes, unsigned int hfi_index,
+ unsigned int cpu) { return 0; }
+static inline bool intel_hfi_enabled(void) { return false; }
+#endif
+
#endif /* _ASM_X86_HFI_H */
diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c
index b69fa234b317..139ce2d4b26b 100644
--- a/drivers/thermal/intel/intel_hfi.c
+++ b/drivers/thermal/intel/intel_hfi.c
@@ -29,6 +29,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/math.h>
+#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/percpu-defs.h>
#include <linux/printk.h>
@@ -642,3 +643,151 @@ void __init intel_hfi_init(void)
kfree(hfi_instances);
hfi_instances = NULL;
}
+
+/**
+ * intel_hfi_max_instances() - Get the maximum number of hfi instances.
+ *
+ * Return: the maximum number of hfi instances.
+ */
+int intel_hfi_max_instances(void)
+{
+ return max_hfi_instances;
+}
+EXPORT_SYMBOL_GPL(intel_hfi_max_instances);
+
+/**
+ * intel_hfi_build_virt_features() - Build a virtual hfi_features structure.
+ *
+ * @features: Feature structure need to be filled
+ * @nr_classes: Maximum number of classes supported. 1 class indicates
+ * only HFI feature is configured and 4 classes indicates
+ * both HFI and ITD features.
+ * @nr_entries: Number of HFI entries in HFI table.
+ *
+ * Fill a virtual hfi_features structure which is used for HFI/ITD virtualization.
+ * HFI and ITD have different feature information, and the virtual feature
+ * structure is based on the corresponding configured number of classes (in Guest
+ * CPUID) to be built.
+ *
+ * Return: -EINVAL if there's the error for the parameters, otherwise 0.
+ */
+int intel_hfi_build_virt_features(struct hfi_features *features,
+ unsigned int nr_classes,
+ unsigned int nr_entries)
+{
+ unsigned int data_size;
+
+ if (!features || !nr_classes || !nr_entries)
+ return -EINVAL;
+
+ /*
+ * The virtual feature must be based on the Host's feature; when Host
+ * enables both HFI and ITD, it is allowed for Guest to create only the
+ * HFI feature structure which has fewer classes than ITD.
+ */
+ if (nr_classes > hfi_features.nr_classes)
+ return -EINVAL;
+
+ features->nr_classes = nr_classes;
+ features->class_stride = hfi_features.class_stride;
+ /*
+ * For the meaning of these two calculations, please refer to the comments
+ * in hfi_parse_features().
+ */
+ features->hdr_size = DIV_ROUND_UP(features->class_stride *
+ features->nr_classes, 8) * 8;
+ features->cpu_stride = DIV_ROUND_UP(features->class_stride *
+ features->nr_classes, 8) * 8;
+
+ data_size = features->hdr_size + nr_entries * features->cpu_stride;
+ features->nr_table_pages = PAGE_ALIGN(data_size) >> PAGE_SHIFT;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(intel_hfi_build_virt_features);
+
+/**
+ * intel_hfi_build_virt_table() - Fill the data of @hfi_index in virtual HFI table.
+ *
+ * @table: HFI table to be filled
+ * @features: Configured feature information of the HFI table
+ * @nr_classes: Number of classes to be updated for @table. This field is
+ * based on the enabled feature, which may be different with
+ * the feature information configured in @features.
+ * @hfi_index: Index of the HFI data in HFI table to be filled
+ * @cpu: CPU whose real HFI data is used to fill the @hfi_index
+ *
+ * Fill the row data of hfi_index in a virtual HFI table which is used for HFI/ITD
+ * virtualization. The size of the virtual HFI table is decided by the configured
+ * feature information in @features, and the filled HFI data range is decided by
+ * specified number of classes @nr_classes.
+ *
+ * Virtual machine may disable ITD at runtime through MSR_IA32_HW_FEEDBACK_CONFIG,
+ * in this case, only 1 class data (class 0) can be dynamically updated in virtual
+ * HFI table (class 0).
+ *
+ * Return: 1 if the @table is changed, 0 if the @table isn't changed, and
+ * -EINVAL/-ENOMEM if there's the error for the parameters.
+ */
+int intel_hfi_build_virt_table(struct hfi_table *table,
+ struct hfi_features *features,
+ unsigned int nr_classes,
+ unsigned int hfi_index,
+ unsigned int cpu)
+{
+ struct hfi_instance *hfi_instance;
+ struct hfi_hdr *hfi_hdr = table->hdr;
+ s16 host_hfi_index;
+ void *src_ptr, *dst_ptr;
+ int table_changed = 0;
+
+ if (!table || !features || !nr_classes)
+ return -EINVAL;
+
+ if (nr_classes > features->nr_classes ||
+ nr_classes > hfi_features.nr_classes)
+ return -EINVAL;
+
+ /*
+ * Make sure that this raw that will be filled doesn't cause overflow.
+ * features->nr_classes indicates the maximum number of possible
+ * classes.
+ */
+ if (features->hdr_size + (hfi_index + 1) * features->cpu_stride >
+ features->nr_table_pages << PAGE_SHIFT)
+ return -ENOMEM;
+
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ if (features->class_stride != hfi_features.class_stride)
+ return -EINVAL;
+
+ hfi_instance = per_cpu(hfi_cpu_info, cpu).hfi_instance;
+ host_hfi_index = per_cpu(hfi_cpu_info, cpu).index;
+
+ src_ptr = hfi_instance->local_table.data +
+ host_hfi_index * hfi_features.cpu_stride;
+ dst_ptr = table->data + hfi_index * features->cpu_stride;
+
+ raw_spin_lock_irq(&hfi_instance->table_lock);
+ for (int i = 0; i < nr_classes; i++) {
+ struct hfi_cpu_data *src = src_ptr + i * hfi_features.class_stride;
+ struct hfi_cpu_data *dst = dst_ptr + i * features->class_stride;
+
+ if (dst->perf_cap != src->perf_cap) {
+ dst->perf_cap = src->perf_cap;
+ hfi_hdr->perf_updated = 1;
+ }
+ if (dst->ee_cap != src->ee_cap) {
+ dst->ee_cap = src->ee_cap;
+ hfi_hdr->ee_updated = 1;
+ }
+ if (hfi_hdr->perf_updated || hfi_hdr->ee_updated)
+ table_changed = 1;
+ hfi_hdr++;
+ }
+ raw_spin_unlock_irq(&hfi_instance->table_lock);
+
+ return table_changed;
+}
+EXPORT_SYMBOL_GPL(intel_hfi_build_virt_table);
--
2.34.1
next prev parent reply other threads:[~2024-02-03 8:59 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 ` Zhao Liu [this message]
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 ` [RFC 18/26] KVM: VMX: Emulate HFI related bits in package thermal MSRs Zhao Liu
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-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).