summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_64_mmu_hv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s_64_mmu_hv.c')
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index c615617..efd5a6b 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -81,7 +81,7 @@ struct kvm_resize_hpt {
int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order)
{
unsigned long hpt = 0;
- int cma = 0;
+ int resv = 0, cma = 0;
struct page *page = NULL;
struct revmap_entry *rev;
unsigned long npte;
@@ -89,11 +89,17 @@ int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order)
if ((order < PPC_MIN_HPT_ORDER) || (order > PPC_MAX_HPT_ORDER))
return -EINVAL;
- page = kvm_alloc_hpt_cma(1ul << (order - PAGE_SHIFT));
- if (page) {
- hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+ hpt = kvmhv_alloc_resv_hpt(order);
+ if (hpt) {
memset((void *)hpt, 0, (1ul << order));
- cma = 1;
+ resv = 1;
+ } else {
+ page = kvm_alloc_hpt_cma(1ul << (order - PAGE_SHIFT));
+ if (page) {
+ hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+ memset((void *)hpt, 0, (1ul << order));
+ cma = 1;
+ }
}
if (!hpt)
@@ -109,7 +115,9 @@ int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order)
/* Allocate reverse map array */
rev = vmalloc(array_size(npte, sizeof(struct revmap_entry)));
if (!rev) {
- if (cma)
+ if (resv)
+ kvmhv_release_resv_hpt(hpt, order);
+ else if (cma)
kvm_free_hpt_cma(page, 1 << (order - PAGE_SHIFT));
else
free_pages(hpt, order - PAGE_SHIFT);
@@ -118,6 +126,7 @@ int kvmppc_allocate_hpt(struct kvm_hpt_info *info, u32 order)
info->order = order;
info->virt = hpt;
+ info->resv = resv;
info->cma = cma;
info->rev = rev;
@@ -191,7 +200,9 @@ void kvmppc_free_hpt(struct kvm_hpt_info *info)
{
vfree(info->rev);
info->rev = NULL;
- if (info->cma)
+ if (info->resv)
+ kvmhv_release_resv_hpt(info->virt, info->order);
+ else if (info->cma)
kvm_free_hpt_cma(virt_to_page(info->virt),
1 << (info->order - PAGE_SHIFT));
else if (info->virt)
OpenPOWER on IntegriCloud