Commit 1b3090da authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-mmu-7.1' of https://github.com/kvm-x86/linux into HEAD

KVM x86 MMU changes for 7.1

 - Fix an undefined behavior warning where a crafty userspace can read kvm.ko's
   nx_huge_pages before it's fully initialized.

 - Don't zero-allocate page tables that are used for splitting hugepages in the
   TDP MMU, as KVM is guaranteed to set all SPTEs in the page table and thus
   write all bytes.

 - Bail early when trying to unsync 4KiB mappings if the target gfn can be
   mapped with a 2MiB hugepage, to avoid the gfn hash lookup.
parents 7e7a6e2a b3ae3ceb
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -2940,6 +2940,15 @@ int mmu_try_to_unsync_pages(struct kvm *kvm, const struct kvm_memory_slot *slot,
	if (kvm_gfn_is_write_tracked(kvm, slot, gfn))
		return -EPERM;

	/*
	 * Only 4KiB mappings can become unsync, and KVM disallows hugepages
	 * when accounting 4KiB shadow pages.  Upper-level gPTEs are always
	 * write-protected (see above), thus if the gfn can be mapped with a
	 * hugepage and isn't write-tracked, it can't have a shadow page.
	 */
	if (!lpage_info_slot(gfn, slot, PG_LEVEL_2M)->disallow_lpage)
		return 0;

	/*
	 * The page is not write-tracked, mark existing shadow pages unsync
	 * unless KVM is synchronizing an unsync SP.  In that case, KVM must
@@ -7490,9 +7499,14 @@ static void kvm_wake_nx_recovery_thread(struct kvm *kvm)

static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp)
{
	int val = *(int *)kp->arg;

	if (nx_hugepage_mitigation_hard_disabled)
		return sysfs_emit(buffer, "never\n");

	if (val == -1)
		return sysfs_emit(buffer, "auto\n");

	return param_get_bool(buffer, kp);
}

+1 −1
Original line number Diff line number Diff line
@@ -1507,7 +1507,7 @@ static struct kvm_mmu_page *tdp_mmu_alloc_sp_for_split(void)
	if (!sp)
		return NULL;

	sp->spt = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
	sp->spt = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
	if (!sp->spt) {
		kmem_cache_free(mmu_page_header_cache, sp);
		return NULL;