aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2013-07-02 01:45:16 -0400
committerAlexander Graf <agraf@suse.de>2013-07-08 10:19:58 -0400
commitfa61a4e376d2129690c82dfb05b31705a67d6e0b (patch)
tree549f4aaad63f0b18e60e059681144256a8cb2be7
parentf35320288c5306ddbcb5ecac046b73519837299c (diff)
powerpc/kvm: Contiguous memory allocator based hash page table allocation
Powerpc architecture uses a hash based page table mechanism for mapping virtual addresses to physical address. The architecture require this hash page table to be physically contiguous. With KVM on Powerpc currently we use early reservation mechanism for allocating guest hash page table. This implies that we need to reserve a big memory region to ensure we can create large number of guest simultaneously with KVM on Power. Another disadvantage is that the reserved memory is not available to rest of the subsystems and and that implies we limit the total available memory in the host. This patch series switch the guest hash page table allocation to use contiguous memory allocator. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_64.h1
-rw-r--r--arch/powerpc/include/asm/kvm_host.h2
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h8
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/powerpc/kvm/Kconfig1
-rw-r--r--arch/powerpc/kvm/Makefile1
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c37
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c91
-rw-r--r--arch/powerpc/kvm/book3s_hv_cma.c227
-rw-r--r--arch/powerpc/kvm/book3s_hv_cma.h22
10 files changed, 341 insertions, 51 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index 9c1ff330c805..f8355a902ac5 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -37,7 +37,6 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
37 37
38#ifdef CONFIG_KVM_BOOK3S_64_HV 38#ifdef CONFIG_KVM_BOOK3S_64_HV
39#define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ 39#define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */
40extern int kvm_hpt_order; /* order of preallocated HPTs */
41#endif 40#endif
42 41
43#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ 42#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index af326cde7cb6..0097dab3d601 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -259,7 +259,7 @@ struct kvm_arch {
259 spinlock_t slot_phys_lock; 259 spinlock_t slot_phys_lock;
260 cpumask_t need_tlb_flush; 260 cpumask_t need_tlb_flush;
261 struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; 261 struct kvmppc_vcore *vcores[KVM_MAX_VCORES];
262 struct kvmppc_linear_info *hpt_li; 262 int hpt_cma_alloc;
263#endif /* CONFIG_KVM_BOOK3S_64_HV */ 263#endif /* CONFIG_KVM_BOOK3S_64_HV */
264#ifdef CONFIG_PPC_BOOK3S_64 264#ifdef CONFIG_PPC_BOOK3S_64
265 struct list_head spapr_tce_tables; 265 struct list_head spapr_tce_tables;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index a5287fe03d77..b5ef7a3c606b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -139,8 +139,8 @@ extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm,
139 struct kvm_allocate_rma *rma); 139 struct kvm_allocate_rma *rma);
140extern struct kvmppc_linear_info *kvm_alloc_rma(void); 140extern struct kvmppc_linear_info *kvm_alloc_rma(void);
141extern void kvm_release_rma(struct kvmppc_linear_info *ri); 141extern void kvm_release_rma(struct kvmppc_linear_info *ri);
142extern struct kvmppc_linear_info *kvm_alloc_hpt(void); 142extern struct page *kvm_alloc_hpt(unsigned long nr_pages);
143extern void kvm_release_hpt(struct kvmppc_linear_info *li); 143extern void kvm_release_hpt(struct page *page, unsigned long nr_pages);
144extern int kvmppc_core_init_vm(struct kvm *kvm); 144extern int kvmppc_core_init_vm(struct kvm *kvm);
145extern void kvmppc_core_destroy_vm(struct kvm *kvm); 145extern void kvmppc_core_destroy_vm(struct kvm *kvm);
146extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free, 146extern void kvmppc_core_free_memslot(struct kvm_memory_slot *free,
@@ -261,6 +261,7 @@ void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
261struct openpic; 261struct openpic;
262 262
263#ifdef CONFIG_KVM_BOOK3S_64_HV 263#ifdef CONFIG_KVM_BOOK3S_64_HV
264extern void kvm_cma_reserve(void) __init;
264static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) 265static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
265{ 266{
266 paca[cpu].kvm_hstate.xics_phys = addr; 267 paca[cpu].kvm_hstate.xics_phys = addr;
@@ -284,6 +285,9 @@ extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu);
284extern void kvm_linear_init(void); 285extern void kvm_linear_init(void);
285 286
286#else 287#else
288static inline void __init kvm_cma_reserve(void)
289{}
290
287static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) 291static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
288{} 292{}
289 293
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e379d3fd1694..ee28d1f4b853 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -229,6 +229,8 @@ void __init early_setup(unsigned long dt_ptr)
229 /* Initialize the hash table or TLB handling */ 229 /* Initialize the hash table or TLB handling */
230 early_init_mmu(); 230 early_init_mmu();
231 231
232 kvm_cma_reserve();
233
232 /* 234 /*
233 * Reserve any gigantic pages requested on the command line. 235 * Reserve any gigantic pages requested on the command line.
234 * memblock needs to have been initialized by the time this is 236 * memblock needs to have been initialized by the time this is
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index eb643f862579..ffaef2cb101a 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -72,6 +72,7 @@ config KVM_BOOK3S_64_HV
72 bool "KVM support for POWER7 and PPC970 using hypervisor mode in host" 72 bool "KVM support for POWER7 and PPC970 using hypervisor mode in host"
73 depends on KVM_BOOK3S_64 73 depends on KVM_BOOK3S_64
74 select MMU_NOTIFIER 74 select MMU_NOTIFIER
75 select CMA
75 ---help--- 76 ---help---
76 Support running unmodified book3s_64 guest kernels in 77 Support running unmodified book3s_64 guest kernels in
77 virtual machines on POWER7 and PPC970 processors that have 78 virtual machines on POWER7 and PPC970 processors that have
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 008cd856c5b5..6646c952c5e3 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -81,6 +81,7 @@ kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \
81 book3s_64_vio_hv.o \ 81 book3s_64_vio_hv.o \
82 book3s_hv_ras.o \ 82 book3s_hv_ras.o \
83 book3s_hv_builtin.o \ 83 book3s_hv_builtin.o \
84 book3s_hv_cma.o \
84 $(kvm-book3s_64-builtin-xics-objs-y) 85 $(kvm-book3s_64-builtin-xics-objs-y)
85 86
86kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \ 87kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 5880dfb31074..354f4bb21f5c 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -52,8 +52,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
52{ 52{
53 unsigned long hpt; 53 unsigned long hpt;
54 struct revmap_entry *rev; 54 struct revmap_entry *rev;
55 struct kvmppc_linear_info *li; 55 struct page *page = NULL;
56 long order = kvm_hpt_order; 56 long order = KVM_DEFAULT_HPT_ORDER;
57 57
58 if (htab_orderp) { 58 if (htab_orderp) {
59 order = *htab_orderp; 59 order = *htab_orderp;
@@ -61,26 +61,22 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
61 order = PPC_MIN_HPT_ORDER; 61 order = PPC_MIN_HPT_ORDER;
62 } 62 }
63 63
64 kvm->arch.hpt_cma_alloc = 0;
64 /* 65 /*
65 * If the user wants a different size from default,
66 * try first to allocate it from the kernel page allocator. 66 * try first to allocate it from the kernel page allocator.
67 * We keep the CMA reserved for failed allocation.
67 */ 68 */
68 hpt = 0; 69 hpt = __get_free_pages(GFP_KERNEL | __GFP_ZERO | __GFP_REPEAT |
69 if (order != kvm_hpt_order) { 70 __GFP_NOWARN, order - PAGE_SHIFT);
70 hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|
71 __GFP_NOWARN, order - PAGE_SHIFT);
72 if (!hpt)
73 --order;
74 }
75 71
76 /* Next try to allocate from the preallocated pool */ 72 /* Next try to allocate from the preallocated pool */
77 if (!hpt) { 73 if (!hpt) {
78 li = kvm_alloc_hpt(); 74 page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT));
79 if (li) { 75 if (page) {
80 hpt = (ulong)li->base_virt; 76 hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
81 kvm->arch.hpt_li = li; 77 kvm->arch.hpt_cma_alloc = 1;
82 order = kvm_hpt_order; 78 } else
83 } 79 --order;
84 } 80 }
85 81
86 /* Lastly try successively smaller sizes from the page allocator */ 82 /* Lastly try successively smaller sizes from the page allocator */
@@ -118,8 +114,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
118 return 0; 114 return 0;
119 115
120 out_freehpt: 116 out_freehpt:
121 if (kvm->arch.hpt_li) 117 if (kvm->arch.hpt_cma_alloc)
122 kvm_release_hpt(kvm->arch.hpt_li); 118 kvm_release_hpt(page, 1 << (order - PAGE_SHIFT));
123 else 119 else
124 free_pages(hpt, order - PAGE_SHIFT); 120 free_pages(hpt, order - PAGE_SHIFT);
125 return -ENOMEM; 121 return -ENOMEM;
@@ -165,8 +161,9 @@ void kvmppc_free_hpt(struct kvm *kvm)
165{ 161{
166 kvmppc_free_lpid(kvm->arch.lpid); 162 kvmppc_free_lpid(kvm->arch.lpid);
167 vfree(kvm->arch.revmap); 163 vfree(kvm->arch.revmap);
168 if (kvm->arch.hpt_li) 164 if (kvm->arch.hpt_cma_alloc)
169 kvm_release_hpt(kvm->arch.hpt_li); 165 kvm_release_hpt(virt_to_page(kvm->arch.hpt_virt),
166 1 << (kvm->arch.hpt_order - PAGE_SHIFT));
170 else 167 else
171 free_pages(kvm->arch.hpt_virt, 168 free_pages(kvm->arch.hpt_virt,
172 kvm->arch.hpt_order - PAGE_SHIFT); 169 kvm->arch.hpt_order - PAGE_SHIFT);
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index ec0a9e5de100..4b865c553331 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -13,20 +13,30 @@
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/bootmem.h> 14#include <linux/bootmem.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/memblock.h>
17#include <linux/sizes.h>
16 18
17#include <asm/cputable.h> 19#include <asm/cputable.h>
18#include <asm/kvm_ppc.h> 20#include <asm/kvm_ppc.h>
19#include <asm/kvm_book3s.h> 21#include <asm/kvm_book3s.h>
20 22
23#include "book3s_hv_cma.h"
24
21#define KVM_LINEAR_RMA 0 25#define KVM_LINEAR_RMA 0
22#define KVM_LINEAR_HPT 1 26#define KVM_LINEAR_HPT 1
23 27
24static void __init kvm_linear_init_one(ulong size, int count, int type); 28static void __init kvm_linear_init_one(ulong size, int count, int type);
25static struct kvmppc_linear_info *kvm_alloc_linear(int type); 29static struct kvmppc_linear_info *kvm_alloc_linear(int type);
26static void kvm_release_linear(struct kvmppc_linear_info *ri); 30static void kvm_release_linear(struct kvmppc_linear_info *ri);
27 31/*
28int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; 32 * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
29EXPORT_SYMBOL_GPL(kvm_hpt_order); 33 * should be power of 2.
34 */
35#define HPT_ALIGN_PAGES ((1 << 18) >> PAGE_SHIFT) /* 256k */
36/*
37 * By default we reserve 5% of memory for hash pagetable allocation.
38 */
39static unsigned long kvm_cma_resv_ratio = 5;
30 40
31/*************** RMA *************/ 41/*************** RMA *************/
32 42
@@ -101,36 +111,29 @@ void kvm_release_rma(struct kvmppc_linear_info *ri)
101} 111}
102EXPORT_SYMBOL_GPL(kvm_release_rma); 112EXPORT_SYMBOL_GPL(kvm_release_rma);
103 113
104/*************** HPT *************/ 114static int __init early_parse_kvm_cma_resv(char *p)
105
106/*
107 * This maintains a list of big linear HPT tables that contain the GVA->HPA
108 * memory mappings. If we don't reserve those early on, we might not be able
109 * to get a big (usually 16MB) linear memory region from the kernel anymore.
110 */
111
112static unsigned long kvm_hpt_count;
113
114static int __init early_parse_hpt_count(char *p)
115{ 115{
116 pr_debug("%s(%s)\n", __func__, p);
116 if (!p) 117 if (!p)
117 return 1; 118 return -EINVAL;
118 119 return kstrtoul(p, 0, &kvm_cma_resv_ratio);
119 kvm_hpt_count = simple_strtoul(p, NULL, 0);
120
121 return 0;
122} 120}
123early_param("kvm_hpt_count", early_parse_hpt_count); 121early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv);
124 122
125struct kvmppc_linear_info *kvm_alloc_hpt(void) 123struct page *kvm_alloc_hpt(unsigned long nr_pages)
126{ 124{
127 return kvm_alloc_linear(KVM_LINEAR_HPT); 125 unsigned long align_pages = HPT_ALIGN_PAGES;
126
127 /* Old CPUs require HPT aligned on a multiple of its size */
128 if (!cpu_has_feature(CPU_FTR_ARCH_206))
129 align_pages = nr_pages;
130 return kvm_alloc_cma(nr_pages, align_pages);
128} 131}
129EXPORT_SYMBOL_GPL(kvm_alloc_hpt); 132EXPORT_SYMBOL_GPL(kvm_alloc_hpt);
130 133
131void kvm_release_hpt(struct kvmppc_linear_info *li) 134void kvm_release_hpt(struct page *page, unsigned long nr_pages)
132{ 135{
133 kvm_release_linear(li); 136 kvm_release_cma(page, nr_pages);
134} 137}
135EXPORT_SYMBOL_GPL(kvm_release_hpt); 138EXPORT_SYMBOL_GPL(kvm_release_hpt);
136 139
@@ -211,9 +214,6 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri)
211 */ 214 */
212void __init kvm_linear_init(void) 215void __init kvm_linear_init(void)
213{ 216{
214 /* HPT */
215 kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT);
216
217 /* RMA */ 217 /* RMA */
218 /* Only do this on PPC970 in HV mode */ 218 /* Only do this on PPC970 in HV mode */
219 if (!cpu_has_feature(CPU_FTR_HVMODE) || 219 if (!cpu_has_feature(CPU_FTR_HVMODE) ||
@@ -231,3 +231,40 @@ void __init kvm_linear_init(void)
231 231
232 kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA); 232 kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA);
233} 233}
234
235/**
236 * kvm_cma_reserve() - reserve area for kvm hash pagetable
237 *
238 * This function reserves memory from early allocator. It should be
239 * called by arch specific code once the early allocator (memblock or bootmem)
240 * has been activated and all other subsystems have already allocated/reserved
241 * memory.
242 */
243void __init kvm_cma_reserve(void)
244{
245 unsigned long align_size;
246 struct memblock_region *reg;
247 phys_addr_t selected_size = 0;
248 /*
249 * We cannot use memblock_phys_mem_size() here, because
250 * memblock_analyze() has not been called yet.
251 */
252 for_each_memblock(memory, reg)
253 selected_size += memblock_region_memory_end_pfn(reg) -
254 memblock_region_memory_base_pfn(reg);
255
256 selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT;
257 if (selected_size) {
258 pr_debug("%s: reserving %ld MiB for global area\n", __func__,
259 (unsigned long)selected_size / SZ_1M);
260 /*
261 * Old CPUs require HPT aligned on a multiple of its size. So for them
262 * make the alignment as max size we could request.
263 */
264 if (!cpu_has_feature(CPU_FTR_ARCH_206))
265 align_size = __rounddown_pow_of_two(selected_size);
266 else
267 align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
268 kvm_cma_declare_contiguous(selected_size, align_size);
269 }
270}
diff --git a/arch/powerpc/kvm/book3s_hv_cma.c b/arch/powerpc/kvm/book3s_hv_cma.c
new file mode 100644
index 000000000000..e04b269b9c5b
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_hv_cma.c
@@ -0,0 +1,227 @@
1/*
2 * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA
3 * for DMA mapping framework
4 *
5 * Copyright IBM Corporation, 2013
6 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License or (at your optional) any later version of the license.
12 *
13 */
14#define pr_fmt(fmt) "kvm_cma: " fmt
15
16#ifdef CONFIG_CMA_DEBUG
17#ifndef DEBUG
18# define DEBUG
19#endif
20#endif
21
22#include <linux/memblock.h>
23#include <linux/mutex.h>
24#include <linux/sizes.h>
25#include <linux/slab.h>
26
27struct kvm_cma {
28 unsigned long base_pfn;
29 unsigned long count;
30 unsigned long *bitmap;
31};
32
33static DEFINE_MUTEX(kvm_cma_mutex);
34static struct kvm_cma kvm_cma_area;
35
36/**
37 * kvm_cma_declare_contiguous() - reserve area for contiguous memory handling
38 * for kvm hash pagetable
39 * @size: Size of the reserved memory.
40 * @alignment: Alignment for the contiguous memory area
41 *
42 * This function reserves memory for kvm cma area. It should be
43 * called by arch code when early allocator (memblock or bootmem)
44 * is still activate.
45 */
46long __init kvm_cma_declare_contiguous(phys_addr_t size, phys_addr_t alignment)
47{
48 long base_pfn;
49 phys_addr_t addr;
50 struct kvm_cma *cma = &kvm_cma_area;
51
52 pr_debug("%s(size %lx)\n", __func__, (unsigned long)size);
53
54 if (!size)
55 return -EINVAL;
56 /*
57 * Sanitise input arguments.
58 * We should be pageblock aligned for CMA.
59 */
60 alignment = max(alignment, (phys_addr_t)(PAGE_SIZE << pageblock_order));
61 size = ALIGN(size, alignment);
62 /*
63 * Reserve memory
64 * Use __memblock_alloc_base() since
65 * memblock_alloc_base() panic()s.
66 */
67 addr = __memblock_alloc_base(size, alignment, 0);
68 if (!addr) {
69 base_pfn = -ENOMEM;
70 goto err;
71 } else
72 base_pfn = PFN_DOWN(addr);
73
74 /*
75 * Each reserved area must be initialised later, when more kernel
76 * subsystems (like slab allocator) are available.
77 */
78 cma->base_pfn = base_pfn;
79 cma->count = size >> PAGE_SHIFT;
80 pr_info("CMA: reserved %ld MiB\n", (unsigned long)size / SZ_1M);
81 return 0;
82err:
83 pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
84 return base_pfn;
85}
86
87/**
88 * kvm_alloc_cma() - allocate pages from contiguous area
89 * @nr_pages: Requested number of pages.
90 * @align_pages: Requested alignment in number of pages
91 *
92 * This function allocates memory buffer for hash pagetable.
93 */
94struct page *kvm_alloc_cma(unsigned long nr_pages, unsigned long align_pages)
95{
96 int ret;
97 struct page *page = NULL;
98 struct kvm_cma *cma = &kvm_cma_area;
99 unsigned long mask, pfn, pageno, start = 0;
100
101
102 if (!cma || !cma->count)
103 return NULL;
104
105 pr_debug("%s(cma %p, count %lu, align pages %lu)\n", __func__,
106 (void *)cma, nr_pages, align_pages);
107
108 if (!nr_pages)
109 return NULL;
110
111 VM_BUG_ON(!is_power_of_2(align_pages));
112 mask = align_pages - 1;
113
114 mutex_lock(&kvm_cma_mutex);
115 for (;;) {
116 pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
117 start, nr_pages, mask);
118 if (pageno >= cma->count)
119 break;
120
121 pfn = cma->base_pfn + pageno;
122 ret = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_CMA);
123 if (ret == 0) {
124 bitmap_set(cma->bitmap, pageno, nr_pages);
125 page = pfn_to_page(pfn);
126 memset(pfn_to_kaddr(pfn), 0, nr_pages << PAGE_SHIFT);
127 break;
128 } else if (ret != -EBUSY) {
129 break;
130 }
131 pr_debug("%s(): memory range at %p is busy, retrying\n",
132 __func__, pfn_to_page(pfn));
133 /* try again with a bit different memory target */
134 start = pageno + mask + 1;
135 }
136 mutex_unlock(&kvm_cma_mutex);
137 pr_debug("%s(): returned %p\n", __func__, page);
138 return page;
139}
140
141/**
142 * kvm_release_cma() - release allocated pages for hash pagetable
143 * @pages: Allocated pages.
144 * @nr_pages: Number of allocated pages.
145 *
146 * This function releases memory allocated by kvm_alloc_cma().
147 * It returns false when provided pages do not belong to contiguous area and
148 * true otherwise.
149 */
150bool kvm_release_cma(struct page *pages, unsigned long nr_pages)
151{
152 unsigned long pfn;
153 struct kvm_cma *cma = &kvm_cma_area;
154
155
156 if (!cma || !pages)
157 return false;
158
159 pr_debug("%s(page %p count %lu)\n", __func__, (void *)pages, nr_pages);
160
161 pfn = page_to_pfn(pages);
162
163 if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count)
164 return false;
165
166 VM_BUG_ON(pfn + nr_pages > cma->base_pfn + cma->count);
167
168 mutex_lock(&kvm_cma_mutex);
169 bitmap_clear(cma->bitmap, pfn - cma->base_pfn, nr_pages);
170 free_contig_range(pfn, nr_pages);
171 mutex_unlock(&kvm_cma_mutex);
172
173 return true;
174}
175
176static int __init kvm_cma_activate_area(unsigned long base_pfn,
177 unsigned long count)
178{
179 unsigned long pfn = base_pfn;
180 unsigned i = count >> pageblock_order;
181 struct zone *zone;
182
183 WARN_ON_ONCE(!pfn_valid(pfn));
184 zone = page_zone(pfn_to_page(pfn));
185 do {
186 unsigned j;
187 base_pfn = pfn;
188 for (j = pageblock_nr_pages; j; --j, pfn++) {
189 WARN_ON_ONCE(!pfn_valid(pfn));
190 /*
191 * alloc_contig_range requires the pfn range
192 * specified to be in the same zone. Make this
193 * simple by forcing the entire CMA resv range
194 * to be in the same zone.
195 */
196 if (page_zone(pfn_to_page(pfn)) != zone)
197 return -EINVAL;
198 }
199 init_cma_reserved_pageblock(pfn_to_page(base_pfn));
200 } while (--i);
201 return 0;
202}
203
204static int __init kvm_cma_init_reserved_areas(void)
205{
206 int bitmap_size, ret;
207 struct kvm_cma *cma = &kvm_cma_area;
208
209 pr_debug("%s()\n", __func__);
210 if (!cma->count)
211 return 0;
212
213 bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
214 cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
215 if (!cma->bitmap)
216 return -ENOMEM;
217
218 ret = kvm_cma_activate_area(cma->base_pfn, cma->count);
219 if (ret)
220 goto error;
221 return 0;
222
223error:
224 kfree(cma->bitmap);
225 return ret;
226}
227core_initcall(kvm_cma_init_reserved_areas);
diff --git a/arch/powerpc/kvm/book3s_hv_cma.h b/arch/powerpc/kvm/book3s_hv_cma.h
new file mode 100644
index 000000000000..788bc3b73104
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_hv_cma.h
@@ -0,0 +1,22 @@
1/*
2 * Contiguous Memory Allocator for ppc KVM hash pagetable based on CMA
3 * for DMA mapping framework
4 *
5 * Copyright IBM Corporation, 2013
6 * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License or (at your optional) any later version of the license.
12 *
13 */
14
15#ifndef __POWERPC_KVM_CMA_ALLOC_H__
16#define __POWERPC_KVM_CMA_ALLOC_H__
17extern struct page *kvm_alloc_cma(unsigned long nr_pages,
18 unsigned long align_pages);
19extern bool kvm_release_cma(struct page *pages, unsigned long nr_pages);
20extern long kvm_cma_declare_contiguous(phys_addr_t size,
21 phys_addr_t alignment) __init;
22#endif