Skip to content

Commit 34f4335

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: - syzkaller NULL pointer dereference - TDP MMU performance issue with disabling dirty logging - 5.14 regression with SVM TSC scaling - indefinite stall on applying live patches - unstable selftest - memory leak from wrong copy-and-paste - missed PV TLB flush when racing with emulation * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86: do not report a vCPU as preempted outside instruction boundaries KVM: x86: do not set st->preempted when going back to user space KVM: SVM: fix tsc scaling cache logic KVM: selftests: Make hyperv_clock selftest more stable KVM: x86/MMU: Zap non-leaf SPTEs when disabling dirty logging x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm() KVM: x86/mmu: Check every prev_roots in __kvm_mmu_free_obsolete_roots() entry/kvm: Exit to user mode when TIF_NOTIFY_SIGNAL is set KVM: Don't null dereference ops->destroy
2 parents 32d380a + 6cd8824 commit 34f4335

File tree

15 files changed

+124
-47
lines changed

15 files changed

+124
-47
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ struct kvm_vcpu_arch {
653653
u64 ia32_misc_enable_msr;
654654
u64 smbase;
655655
u64 smi_count;
656+
bool at_instruction_boundary;
656657
bool tpr_access_reporting;
657658
bool xsaves_enabled;
658659
bool xfd_no_write_intercept;
@@ -1300,6 +1301,8 @@ struct kvm_vcpu_stat {
13001301
u64 nested_run;
13011302
u64 directed_yield_attempted;
13021303
u64 directed_yield_successful;
1304+
u64 preemption_reported;
1305+
u64 preemption_other;
13031306
u64 guest_mode;
13041307
};
13051308

arch/x86/include/asm/uaccess.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ do { \
439439
[ptr] "+m" (*_ptr), \
440440
[old] "+a" (__old) \
441441
: [new] ltype (__new) \
442-
: "memory", "cc"); \
442+
: "memory"); \
443443
if (unlikely(__err)) \
444444
goto label; \
445445
if (unlikely(!success)) \

arch/x86/kvm/mmu/mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5179,7 +5179,7 @@ static void __kvm_mmu_free_obsolete_roots(struct kvm *kvm, struct kvm_mmu *mmu)
51795179
roots_to_free |= KVM_MMU_ROOT_CURRENT;
51805180

51815181
for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) {
5182-
if (is_obsolete_root(kvm, mmu->root.hpa))
5182+
if (is_obsolete_root(kvm, mmu->prev_roots[i].hpa))
51835183
roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);
51845184
}
51855185

arch/x86/kvm/mmu/tdp_iter.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ static bool try_step_up(struct tdp_iter *iter)
145145
return true;
146146
}
147147

148+
/*
149+
* Step the iterator back up a level in the paging structure. Should only be
150+
* used when the iterator is below the root level.
151+
*/
152+
void tdp_iter_step_up(struct tdp_iter *iter)
153+
{
154+
WARN_ON(!try_step_up(iter));
155+
}
156+
148157
/*
149158
* Step to the next SPTE in a pre-order traversal of the paging structure.
150159
* To get to the next SPTE, the iterator either steps down towards the goal

arch/x86/kvm/mmu/tdp_iter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,6 @@ void tdp_iter_start(struct tdp_iter *iter, struct kvm_mmu_page *root,
114114
int min_level, gfn_t next_last_level_gfn);
115115
void tdp_iter_next(struct tdp_iter *iter);
116116
void tdp_iter_restart(struct tdp_iter *iter);
117+
void tdp_iter_step_up(struct tdp_iter *iter);
117118

118119
#endif /* __KVM_X86_MMU_TDP_ITER_H */

arch/x86/kvm/mmu/tdp_mmu.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,28 +1742,54 @@ static void zap_collapsible_spte_range(struct kvm *kvm,
17421742
gfn_t start = slot->base_gfn;
17431743
gfn_t end = start + slot->npages;
17441744
struct tdp_iter iter;
1745+
int max_mapping_level;
17451746
kvm_pfn_t pfn;
17461747

17471748
rcu_read_lock();
17481749

17491750
tdp_root_for_each_pte(iter, root, start, end) {
1750-
retry:
17511751
if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true))
17521752
continue;
17531753

17541754
if (!is_shadow_present_pte(iter.old_spte) ||
17551755
!is_last_spte(iter.old_spte, iter.level))
17561756
continue;
17571757

1758+
/*
1759+
* This is a leaf SPTE. Check if the PFN it maps can
1760+
* be mapped at a higher level.
1761+
*/
17581762
pfn = spte_to_pfn(iter.old_spte);
1759-
if (kvm_is_reserved_pfn(pfn) ||
1760-
iter.level >= kvm_mmu_max_mapping_level(kvm, slot, iter.gfn,
1761-
pfn, PG_LEVEL_NUM))
1763+
1764+
if (kvm_is_reserved_pfn(pfn))
17621765
continue;
17631766

1767+
max_mapping_level = kvm_mmu_max_mapping_level(kvm, slot,
1768+
iter.gfn, pfn, PG_LEVEL_NUM);
1769+
1770+
WARN_ON(max_mapping_level < iter.level);
1771+
1772+
/*
1773+
* If this page is already mapped at the highest
1774+
* viable level, there's nothing more to do.
1775+
*/
1776+
if (max_mapping_level == iter.level)
1777+
continue;
1778+
1779+
/*
1780+
* The page can be remapped at a higher level, so step
1781+
* up to zap the parent SPTE.
1782+
*/
1783+
while (max_mapping_level > iter.level)
1784+
tdp_iter_step_up(&iter);
1785+
17641786
/* Note, a successful atomic zap also does a remote TLB flush. */
1765-
if (tdp_mmu_zap_spte_atomic(kvm, &iter))
1766-
goto retry;
1787+
tdp_mmu_zap_spte_atomic(kvm, &iter);
1788+
1789+
/*
1790+
* If the atomic zap fails, the iter will recurse back into
1791+
* the same subtree to retry.
1792+
*/
17671793
}
17681794

17691795
rcu_read_unlock();

arch/x86/kvm/svm/nested.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,7 @@ int nested_svm_vmexit(struct vcpu_svm *svm)
982982
if (svm->tsc_ratio_msr != kvm_default_tsc_scaling_ratio) {
983983
WARN_ON(!svm->tsc_scaling_enabled);
984984
vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio;
985-
svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio);
985+
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
986986
}
987987

988988
svm->nested.ctl.nested_cr3 = 0;
@@ -1387,7 +1387,7 @@ void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu)
13871387
vcpu->arch.tsc_scaling_ratio =
13881388
kvm_calc_nested_tsc_multiplier(vcpu->arch.l1_tsc_scaling_ratio,
13891389
svm->tsc_ratio_msr);
1390-
svm_write_tsc_multiplier(vcpu, vcpu->arch.tsc_scaling_ratio);
1390+
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
13911391
}
13921392

13931393
/* Inverse operation of nested_copy_vmcb_control_to_cache(). asid is copied too. */

arch/x86/kvm/svm/svm.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -465,11 +465,24 @@ static int has_svm(void)
465465
return 1;
466466
}
467467

468+
void __svm_write_tsc_multiplier(u64 multiplier)
469+
{
470+
preempt_disable();
471+
472+
if (multiplier == __this_cpu_read(current_tsc_ratio))
473+
goto out;
474+
475+
wrmsrl(MSR_AMD64_TSC_RATIO, multiplier);
476+
__this_cpu_write(current_tsc_ratio, multiplier);
477+
out:
478+
preempt_enable();
479+
}
480+
468481
static void svm_hardware_disable(void)
469482
{
470483
/* Make sure we clean up behind us */
471484
if (tsc_scaling)
472-
wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT);
485+
__svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);
473486

474487
cpu_svm_disable();
475488

@@ -515,8 +528,7 @@ static int svm_hardware_enable(void)
515528
* Set the default value, even if we don't use TSC scaling
516529
* to avoid having stale value in the msr
517530
*/
518-
wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT);
519-
__this_cpu_write(current_tsc_ratio, SVM_TSC_RATIO_DEFAULT);
531+
__svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);
520532
}
521533

522534

@@ -999,11 +1011,12 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
9991011
vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
10001012
}
10011013

1002-
void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier)
1014+
static void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier)
10031015
{
1004-
wrmsrl(MSR_AMD64_TSC_RATIO, multiplier);
1016+
__svm_write_tsc_multiplier(multiplier);
10051017
}
10061018

1019+
10071020
/* Evaluate instruction intercepts that depend on guest CPUID features. */
10081021
static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu,
10091022
struct vcpu_svm *svm)
@@ -1363,13 +1376,8 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
13631376
sev_es_prepare_switch_to_guest(hostsa);
13641377
}
13651378

1366-
if (tsc_scaling) {
1367-
u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio;
1368-
if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) {
1369-
__this_cpu_write(current_tsc_ratio, tsc_ratio);
1370-
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
1371-
}
1372-
}
1379+
if (tsc_scaling)
1380+
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
13731381

13741382
if (likely(tsc_aux_uret_slot >= 0))
13751383
kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
@@ -4255,6 +4263,8 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
42554263

42564264
static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)
42574265
{
4266+
if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR)
4267+
vcpu->arch.at_instruction_boundary = true;
42584268
}
42594269

42604270
static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
590590
bool has_error_code, u32 error_code);
591591
int nested_svm_exit_special(struct vcpu_svm *svm);
592592
void nested_svm_update_tsc_ratio_msr(struct kvm_vcpu *vcpu);
593-
void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier);
593+
void __svm_write_tsc_multiplier(u64 multiplier);
594594
void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm,
595595
struct vmcb_control_area *control);
596596
void nested_copy_vmcb_save_to_cache(struct vcpu_svm *svm,

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6547,6 +6547,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
65476547
return;
65486548

65496549
handle_interrupt_nmi_irqoff(vcpu, gate_offset(desc));
6550+
vcpu->arch.at_instruction_boundary = true;
65506551
}
65516552

65526553
static void vmx_handle_exit_irqoff(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)