From: Isaku Yamahata <[email protected]>
Make tdp_mmu_alloc_sp_split() aware of private page table.
Signed-off-by: Isaku Yamahata <[email protected]>
---
arch/x86/kvm/mmu/mmu_internal.h | 14 ++++++++++++++
arch/x86/kvm/mmu/tdp_mmu.c | 8 ++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index 0ed802dc8627..e51fc5a5cabc 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -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)
@@ -229,6 +238,11 @@ 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)
+{
+ return -ENOMEM;
+}
+
static inline void kvm_mmu_free_private_spt(struct kvm_mmu_page *sp)
{
}
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 5c2c7e8ea62e..1a71aad62bd3 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1690,8 +1690,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;
--
2.25.1