102 lines
3.7 KiB
Diff
102 lines
3.7 KiB
Diff
From a71b4e5d1ce8bcb7cf076500a1fe8871a674b03c Mon Sep 17 00:00:00 2001
|
|
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Date: Fri, 18 Jul 2025 18:03:46 +0200
|
|
Subject: [PATCH 044/115] i386/tdx: Implement user specified tsc frequency
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
RH-MergeRequest: 391: TDX support, including attestation and device assignment
|
|
RH-Jira: RHEL-15710 RHEL-20798 RHEL-49728
|
|
RH-Acked-by: Yash Mankad <None>
|
|
RH-Acked-by: Peter Xu <peterx@redhat.com>
|
|
RH-Acked-by: David Hildenbrand <david@redhat.com>
|
|
RH-Commit: [44/115] f12a5f1a60aa8bdd69d79e31b92dcf21380b7659 (bonzini/rhel-qemu-kvm)
|
|
|
|
Reuse "-cpu,tsc-frequency=" to get user wanted tsc frequency and call VM
|
|
scope VM_SET_TSC_KHZ to set the tsc frequency of TD before KVM_TDX_INIT_VM.
|
|
|
|
Besides, sanity check the tsc frequency to be in the legal range and
|
|
legal granularity (required by TDX module).
|
|
|
|
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
|
|
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
|
Link: https://lore.kernel.org/r/20250508150002.689633-16-xiaoyao.li@intel.com
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
(cherry picked from commit 0e73b843616e52882940ab89e1b0e86e22be2162)
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
target/i386/kvm/kvm.c | 9 +++++++++
|
|
target/i386/kvm/tdx.c | 25 +++++++++++++++++++++++++
|
|
2 files changed, 34 insertions(+)
|
|
|
|
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
|
|
index 3b71c182ab..fa61221190 100644
|
|
--- a/target/i386/kvm/kvm.c
|
|
+++ b/target/i386/kvm/kvm.c
|
|
@@ -861,6 +861,15 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
|
|
int r, cur_freq;
|
|
bool set_ioctl = false;
|
|
|
|
+ /*
|
|
+ * TSC of TD vcpu is immutable, it cannot be set/changed via vcpu scope
|
|
+ * VM_SET_TSC_KHZ, but only be initialized via VM scope VM_SET_TSC_KHZ
|
|
+ * before ioctl KVM_TDX_INIT_VM in tdx_pre_create_vcpu()
|
|
+ */
|
|
+ if (is_tdx_vm()) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
if (!env->tsc_khz) {
|
|
return 0;
|
|
}
|
|
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
|
|
index c96e8eb7b8..56ad5f599d 100644
|
|
--- a/target/i386/kvm/tdx.c
|
|
+++ b/target/i386/kvm/tdx.c
|
|
@@ -20,6 +20,9 @@
|
|
#include "kvm_i386.h"
|
|
#include "tdx.h"
|
|
|
|
+#define TDX_MIN_TSC_FREQUENCY_KHZ (100 * 1000)
|
|
+#define TDX_MAX_TSC_FREQUENCY_KHZ (10 * 1000 * 1000)
|
|
+
|
|
#define TDX_TD_ATTRIBUTES_DEBUG BIT_ULL(0)
|
|
#define TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE BIT_ULL(28)
|
|
#define TDX_TD_ATTRIBUTES_PKS BIT_ULL(30)
|
|
@@ -267,6 +270,28 @@ int tdx_pre_create_vcpu(CPUState *cpu, Error **errp)
|
|
return r;
|
|
}
|
|
|
|
+ if (env->tsc_khz && (env->tsc_khz < TDX_MIN_TSC_FREQUENCY_KHZ ||
|
|
+ env->tsc_khz > TDX_MAX_TSC_FREQUENCY_KHZ)) {
|
|
+ error_setg(errp, "Invalid TSC %ld KHz, must specify cpu_frequency "
|
|
+ "between [%d, %d] kHz", env->tsc_khz,
|
|
+ TDX_MIN_TSC_FREQUENCY_KHZ, TDX_MAX_TSC_FREQUENCY_KHZ);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ if (env->tsc_khz % (25 * 1000)) {
|
|
+ error_setg(errp, "Invalid TSC %ld KHz, it must be multiple of 25MHz",
|
|
+ env->tsc_khz);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+ /* it's safe even env->tsc_khz is 0. KVM uses host's tsc_khz in this case */
|
|
+ r = kvm_vm_ioctl(kvm_state, KVM_SET_TSC_KHZ, env->tsc_khz);
|
|
+ if (r < 0) {
|
|
+ error_setg_errno(errp, -r, "Unable to set TSC frequency to %ld kHz",
|
|
+ env->tsc_khz);
|
|
+ return r;
|
|
+ }
|
|
+
|
|
if (tdx_guest->mrconfigid) {
|
|
g_autofree uint8_t *data = qbase64_decode(tdx_guest->mrconfigid,
|
|
strlen(tdx_guest->mrconfigid), &data_len, errp);
|
|
--
|
|
2.50.1
|
|
|