summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2026-04-13 12:50:08 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2026-04-13 12:50:08 +0200
commit1b3090da8d25b1dd59744e32e6872c2831fed874 (patch)
tree074c496149a05b38b6fcc591831b57c04f85e442 /arch
parent7e7a6e2ad24b45b323a5c2e474847650e982b82a (diff)
parentb3ae3ceb556945724d0c046ddb4ea0cf492a0ce6 (diff)
downloadlinux-next-1b3090da8d25b1dd59744e32e6872c2831fed874.tar.gz
linux-next-1b3090da8d25b1dd59744e32e6872c2831fed874.zip
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.
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/mmu/mmu.c14
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.c2
2 files changed, 15 insertions, 1 deletions
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index dd06453d5b72..24fbc9ea502a 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2941,6 +2941,15 @@ int mmu_try_to_unsync_pages(struct kvm *kvm, const struct kvm_memory_slot *slot,
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
* complete emulation of the guest TLB flush before allowing shadow
@@ -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);
}
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 9c26038f6b77..7b1102d26f9c 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -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;