Skip to content

Commit d3a6b6c

Browse files
gaochaointelbonzini
authored andcommitted
KVM: x86: Allow to update cached values in kvm_user_return_msrs w/o wrmsr
Several MSRs are constant and only used in userspace(ring 3). But VMs may have different values. KVM uses kvm_set_user_return_msr() to switch to guest's values and leverages user return notifier to restore them when the kernel is to return to userspace. To eliminate unnecessary wrmsr, KVM also caches the value it wrote to an MSR last time. TDX module unconditionally resets some of these MSRs to architectural INIT state on TD exit. It makes the cached values in kvm_user_return_msrs are inconsistent with values in hardware. This inconsistency needs to be fixed. Otherwise, it may mislead kvm_on_user_return() to skip restoring some MSRs to the host's values. kvm_set_user_return_msr() can help correct this case, but it is not optimal as it always does a wrmsr. So, introduce a variation of kvm_set_user_return_msr() to update cached values and skip that wrmsr. Signed-off-by: Chao Gao <chao.gao@intel.com> 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-9-adrian.hunter@intel.com> Reviewed-by: Xiayao Li <xiaoyao.li@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 6bfa6d8 commit d3a6b6c

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,6 +2328,7 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
23282328
int kvm_add_user_return_msr(u32 msr);
23292329
int kvm_find_user_return_msr(u32 msr);
23302330
int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask);
2331+
void kvm_user_return_msr_update_cache(unsigned int index, u64 val);
23312332

23322333
static inline bool kvm_is_supported_user_return_msr(u32 msr)
23332334
{

arch/x86/kvm/x86.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,15 @@ static void kvm_user_return_msr_cpu_online(void)
636636
}
637637
}
638638

639+
static void kvm_user_return_register_notifier(struct kvm_user_return_msrs *msrs)
640+
{
641+
if (!msrs->registered) {
642+
msrs->urn.on_user_return = kvm_on_user_return;
643+
user_return_notifier_register(&msrs->urn);
644+
msrs->registered = true;
645+
}
646+
}
647+
639648
int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask)
640649
{
641650
struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs);
@@ -649,15 +658,20 @@ int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask)
649658
return 1;
650659

651660
msrs->values[slot].curr = value;
652-
if (!msrs->registered) {
653-
msrs->urn.on_user_return = kvm_on_user_return;
654-
user_return_notifier_register(&msrs->urn);
655-
msrs->registered = true;
656-
}
661+
kvm_user_return_register_notifier(msrs);
657662
return 0;
658663
}
659664
EXPORT_SYMBOL_GPL(kvm_set_user_return_msr);
660665

666+
void kvm_user_return_msr_update_cache(unsigned int slot, u64 value)
667+
{
668+
struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs);
669+
670+
msrs->values[slot].curr = value;
671+
kvm_user_return_register_notifier(msrs);
672+
}
673+
EXPORT_SYMBOL_GPL(kvm_user_return_msr_update_cache);
674+
661675
static void drop_user_return_notifiers(void)
662676
{
663677
struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs);

0 commit comments

Comments
 (0)