Skip to content

Commit 81bf40d

Browse files
yamahatabonzini
authored andcommitted
KVM: TDX: vcpu_run: save/restore host state(host kernel gs)
On entering/exiting TDX vcpu, preserved or clobbered CPU state is different from the VMX case. Add TDX hooks to save/restore host/guest CPU state. Save/restore kernel GS base MSR. Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20250129095902.16391-7-adrian.hunter@intel.com> Reviewed-by: Xiayao Li <xiaoyao.li@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 81bf912 commit 81bf40d

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

arch/x86/kvm/vmx/main.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,26 @@ static void vt_update_cpu_dirty_logging(struct kvm_vcpu *vcpu)
145145
vmx_update_cpu_dirty_logging(vcpu);
146146
}
147147

148+
static void vt_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
149+
{
150+
if (is_td_vcpu(vcpu)) {
151+
tdx_prepare_switch_to_guest(vcpu);
152+
return;
153+
}
154+
155+
vmx_prepare_switch_to_guest(vcpu);
156+
}
157+
158+
static void vt_vcpu_put(struct kvm_vcpu *vcpu)
159+
{
160+
if (is_td_vcpu(vcpu)) {
161+
tdx_vcpu_put(vcpu);
162+
return;
163+
}
164+
165+
vmx_vcpu_put(vcpu);
166+
}
167+
148168
static int vt_vcpu_pre_run(struct kvm_vcpu *vcpu)
149169
{
150170
if (is_td_vcpu(vcpu))
@@ -265,9 +285,9 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
265285
.vcpu_free = vt_vcpu_free,
266286
.vcpu_reset = vt_vcpu_reset,
267287

268-
.prepare_switch_to_guest = vmx_prepare_switch_to_guest,
288+
.prepare_switch_to_guest = vt_prepare_switch_to_guest,
269289
.vcpu_load = vt_vcpu_load,
270-
.vcpu_put = vmx_vcpu_put,
290+
.vcpu_put = vt_vcpu_put,
271291

272292
.update_exception_bitmap = vmx_update_exception_bitmap,
273293
.get_feature_msr = vmx_get_feature_msr,

arch/x86/kvm/vmx/tdx.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/cpu.h>
44
#include <asm/cpufeature.h>
55
#include <linux/misc_cgroup.h>
6+
#include <linux/mmu_context.h>
67
#include <asm/tdx.h>
78
#include "capabilities.h"
89
#include "mmu.h"
@@ -12,6 +13,7 @@
1213
#include "vmx.h"
1314
#include "mmu/spte.h"
1415
#include "common.h"
16+
#include "posted_intr.h"
1517
#include <trace/events/kvm.h>
1618
#include "trace.h"
1719

@@ -629,6 +631,44 @@ void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
629631
local_irq_enable();
630632
}
631633

634+
/*
635+
* Compared to vmx_prepare_switch_to_guest(), there is not much to do
636+
* as SEAMCALL/SEAMRET calls take care of most of save and restore.
637+
*/
638+
void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
639+
{
640+
struct vcpu_vt *vt = to_vt(vcpu);
641+
642+
if (vt->guest_state_loaded)
643+
return;
644+
645+
if (likely(is_64bit_mm(current->mm)))
646+
vt->msr_host_kernel_gs_base = current->thread.gsbase;
647+
else
648+
vt->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
649+
650+
vt->guest_state_loaded = true;
651+
}
652+
653+
static void tdx_prepare_switch_to_host(struct kvm_vcpu *vcpu)
654+
{
655+
struct vcpu_vt *vt = to_vt(vcpu);
656+
657+
if (!vt->guest_state_loaded)
658+
return;
659+
660+
++vcpu->stat.host_state_reload;
661+
wrmsrl(MSR_KERNEL_GS_BASE, vt->msr_host_kernel_gs_base);
662+
663+
vt->guest_state_loaded = false;
664+
}
665+
666+
void tdx_vcpu_put(struct kvm_vcpu *vcpu)
667+
{
668+
vmx_vcpu_pi_put(vcpu);
669+
tdx_prepare_switch_to_host(vcpu);
670+
}
671+
632672
void tdx_vcpu_free(struct kvm_vcpu *vcpu)
633673
{
634674
struct kvm_tdx *kvm_tdx = to_kvm_tdx(vcpu->kvm);

arch/x86/kvm/vmx/x86_ops.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ void tdx_vcpu_free(struct kvm_vcpu *vcpu);
133133
void tdx_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
134134
int tdx_vcpu_pre_run(struct kvm_vcpu *vcpu);
135135
fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit);
136+
void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
137+
void tdx_vcpu_put(struct kvm_vcpu *vcpu);
136138

137139
int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp);
138140

@@ -164,6 +166,8 @@ static inline fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediat
164166
{
165167
return EXIT_FASTPATH_NONE;
166168
}
169+
static inline void tdx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) {}
170+
static inline void tdx_vcpu_put(struct kvm_vcpu *vcpu) {}
167171

168172
static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; }
169173

0 commit comments

Comments
 (0)