[v8,08/14] KVM: x86/tdp_mmu: Allocate private page table for large page split
Commit Message
From: Isaku Yamahata <isaku.yamahata@intel.com>
Make tdp_mmu_alloc_sp_split() aware of private page table.
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
---
arch/x86/kvm/mmu/mmu_internal.h | 9 +++++++++
arch/x86/kvm/mmu/tdp_mmu.c | 8 ++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
@@ -201,6 +201,15 @@ static inline void kvm_mmu_alloc_private_spt(struct kvm_vcpu *vcpu, struct kvm_m
}
}
+static inline int kvm_alloc_private_spt_for_split(struct kvm_mmu_page *sp, gfp_t gfp)
+{
+ gfp &= ~__GFP_ZERO;
+ sp->private_spt = (void *)__get_free_page(gfp);
+ if (!sp->private_spt)
+ return -ENOMEM;
+ return 0;
+}
+
static inline void kvm_mmu_free_private_spt(struct kvm_mmu_page *sp)
{
if (sp->private_spt)
@@ -1593,8 +1593,12 @@ static struct kvm_mmu_page *__tdp_mmu_alloc_sp_for_split(gfp_t gfp, union kvm_mm
sp->role = role;
sp->spt = (void *)__get_free_page(gfp);
- /* TODO: large page support for private GPA. */
- WARN_ON_ONCE(kvm_mmu_page_role_is_private(role));
+ if (kvm_mmu_page_role_is_private(role)) {
+ if (kvm_alloc_private_spt_for_split(sp, gfp)) {
+ free_page((unsigned long)sp->spt);
+ sp->spt = NULL;
+ }
+ }
if (!sp->spt) {
kmem_cache_free(mmu_page_header_cache, sp);
return NULL;