aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2013-07-02 01:45:17 -0400
committerAlexander Graf <agraf@suse.de>2013-07-08 10:20:20 -0400
commit6c45b810989d1c04194499d666f695d3f811965f (patch)
tree31d9bf5d8411eb936a3377c5bfcef1c7b9f49ede
parentfa61a4e376d2129690c82dfb05b31705a67d6e0b (diff)
powerpc/kvm: Contiguous memory allocator based RMA allocation
Older version of power architecture use Real Mode Offset register and Real Mode Limit Selector for mapping guest Real Mode Area. The guest RMA should be physically contigous since we use the range when address translation is not enabled. This patch switch RMA allocation code to use contigous memory allocator. The patch also remove the the linear allocator which not used any more Acked-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> 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.h12
-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/book3s_hv.c27
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c167
6 files changed, 65 insertions, 152 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h
index f8355a902ac5..76ff0b5c9996 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -37,6 +37,7 @@ 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 unsigned long kvm_rma_pages;
40#endif 41#endif
41 42
42#define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ 43#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 0097dab3d601..33283532e9d8 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -183,13 +183,9 @@ struct kvmppc_spapr_tce_table {
183 struct page *pages[0]; 183 struct page *pages[0];
184}; 184};
185 185
186struct kvmppc_linear_info { 186struct kvm_rma_info {
187 void *base_virt; 187 atomic_t use_count;
188 unsigned long base_pfn; 188 unsigned long base_pfn;
189 unsigned long npages;
190 struct list_head list;
191 atomic_t use_count;
192 int type;
193}; 189};
194 190
195/* XICS components, defined in book3s_xics.c */ 191/* XICS components, defined in book3s_xics.c */
@@ -246,7 +242,7 @@ struct kvm_arch {
246 int tlbie_lock; 242 int tlbie_lock;
247 unsigned long lpcr; 243 unsigned long lpcr;
248 unsigned long rmor; 244 unsigned long rmor;
249 struct kvmppc_linear_info *rma; 245 struct kvm_rma_info *rma;
250 unsigned long vrma_slb_v; 246 unsigned long vrma_slb_v;
251 int rma_setup_done; 247 int rma_setup_done;
252 int using_mmu_notifiers; 248 int using_mmu_notifiers;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index b5ef7a3c606b..5a26bfcd0bbc 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -137,8 +137,8 @@ extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
137 unsigned long ioba, unsigned long tce); 137 unsigned long ioba, unsigned long tce);
138extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, 138extern 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 kvm_rma_info *kvm_alloc_rma(void);
141extern void kvm_release_rma(struct kvmppc_linear_info *ri); 141extern void kvm_release_rma(struct kvm_rma_info *ri);
142extern struct page *kvm_alloc_hpt(unsigned long nr_pages); 142extern struct page *kvm_alloc_hpt(unsigned long nr_pages);
143extern void kvm_release_hpt(struct page *page, unsigned long nr_pages); 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);
@@ -282,7 +282,6 @@ static inline void kvmppc_set_host_ipi(int cpu, u8 host_ipi)
282} 282}
283 283
284extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu); 284extern void kvmppc_fast_vcpu_kick(struct kvm_vcpu *vcpu);
285extern void kvm_linear_init(void);
286 285
287#else 286#else
288static inline void __init kvm_cma_reserve(void) 287static inline void __init kvm_cma_reserve(void)
@@ -291,9 +290,6 @@ static inline void __init kvm_cma_reserve(void)
291static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) 290static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr)
292{} 291{}
293 292
294static inline void kvm_linear_init(void)
295{}
296
297static inline u32 kvmppc_get_xics_latch(void) 293static inline u32 kvmppc_get_xics_latch(void)
298{ 294{
299 return 0; 295 return 0;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index ee28d1f4b853..8a022f5de0ef 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -611,8 +611,6 @@ void __init setup_arch(char **cmdline_p)
611 /* Initialize the MMU context management stuff */ 611 /* Initialize the MMU context management stuff */
612 mmu_context_init(); 612 mmu_context_init();
613 613
614 kvm_linear_init();
615
616 /* Interrupt code needs to be 64K-aligned */ 614 /* Interrupt code needs to be 64K-aligned */
617 if ((unsigned long)_stext & 0xffff) 615 if ((unsigned long)_stext & 0xffff)
618 panic("Kernelbase not 64K-aligned (0x%lx)!\n", 616 panic("Kernelbase not 64K-aligned (0x%lx)!\n",
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 2efa9dde741a..2b95c45e17d9 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1511,10 +1511,10 @@ static inline int lpcr_rmls(unsigned long rma_size)
1511 1511
1512static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 1512static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1513{ 1513{
1514 struct kvmppc_linear_info *ri = vma->vm_file->private_data;
1515 struct page *page; 1514 struct page *page;
1515 struct kvm_rma_info *ri = vma->vm_file->private_data;
1516 1516
1517 if (vmf->pgoff >= ri->npages) 1517 if (vmf->pgoff >= kvm_rma_pages)
1518 return VM_FAULT_SIGBUS; 1518 return VM_FAULT_SIGBUS;
1519 1519
1520 page = pfn_to_page(ri->base_pfn + vmf->pgoff); 1520 page = pfn_to_page(ri->base_pfn + vmf->pgoff);
@@ -1536,7 +1536,7 @@ static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma)
1536 1536
1537static int kvm_rma_release(struct inode *inode, struct file *filp) 1537static int kvm_rma_release(struct inode *inode, struct file *filp)
1538{ 1538{
1539 struct kvmppc_linear_info *ri = filp->private_data; 1539 struct kvm_rma_info *ri = filp->private_data;
1540 1540
1541 kvm_release_rma(ri); 1541 kvm_release_rma(ri);
1542 return 0; 1542 return 0;
@@ -1549,8 +1549,17 @@ static const struct file_operations kvm_rma_fops = {
1549 1549
1550long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) 1550long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret)
1551{ 1551{
1552 struct kvmppc_linear_info *ri;
1553 long fd; 1552 long fd;
1553 struct kvm_rma_info *ri;
1554 /*
1555 * Only do this on PPC970 in HV mode
1556 */
1557 if (!cpu_has_feature(CPU_FTR_HVMODE) ||
1558 !cpu_has_feature(CPU_FTR_ARCH_201))
1559 return -EINVAL;
1560
1561 if (!kvm_rma_pages)
1562 return -EINVAL;
1554 1563
1555 ri = kvm_alloc_rma(); 1564 ri = kvm_alloc_rma();
1556 if (!ri) 1565 if (!ri)
@@ -1560,7 +1569,7 @@ long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret)
1560 if (fd < 0) 1569 if (fd < 0)
1561 kvm_release_rma(ri); 1570 kvm_release_rma(ri);
1562 1571
1563 ret->rma_size = ri->npages << PAGE_SHIFT; 1572 ret->rma_size = kvm_rma_pages << PAGE_SHIFT;
1564 return fd; 1573 return fd;
1565} 1574}
1566 1575
@@ -1725,7 +1734,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
1725{ 1734{
1726 int err = 0; 1735 int err = 0;
1727 struct kvm *kvm = vcpu->kvm; 1736 struct kvm *kvm = vcpu->kvm;
1728 struct kvmppc_linear_info *ri = NULL; 1737 struct kvm_rma_info *ri = NULL;
1729 unsigned long hva; 1738 unsigned long hva;
1730 struct kvm_memory_slot *memslot; 1739 struct kvm_memory_slot *memslot;
1731 struct vm_area_struct *vma; 1740 struct vm_area_struct *vma;
@@ -1803,7 +1812,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
1803 1812
1804 } else { 1813 } else {
1805 /* Set up to use an RMO region */ 1814 /* Set up to use an RMO region */
1806 rma_size = ri->npages; 1815 rma_size = kvm_rma_pages;
1807 if (rma_size > memslot->npages) 1816 if (rma_size > memslot->npages)
1808 rma_size = memslot->npages; 1817 rma_size = memslot->npages;
1809 rma_size <<= PAGE_SHIFT; 1818 rma_size <<= PAGE_SHIFT;
@@ -1831,14 +1840,14 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu)
1831 /* POWER7 */ 1840 /* POWER7 */
1832 lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L); 1841 lpcr &= ~(LPCR_VPM0 | LPCR_VRMA_L);
1833 lpcr |= rmls << LPCR_RMLS_SH; 1842 lpcr |= rmls << LPCR_RMLS_SH;
1834 kvm->arch.rmor = kvm->arch.rma->base_pfn << PAGE_SHIFT; 1843 kvm->arch.rmor = ri->base_pfn << PAGE_SHIFT;
1835 } 1844 }
1836 kvm->arch.lpcr = lpcr; 1845 kvm->arch.lpcr = lpcr;
1837 pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n", 1846 pr_info("KVM: Using RMO at %lx size %lx (LPCR = %lx)\n",
1838 ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); 1847 ri->base_pfn << PAGE_SHIFT, rma_size, lpcr);
1839 1848
1840 /* Initialize phys addrs of pages in RMO */ 1849 /* Initialize phys addrs of pages in RMO */
1841 npages = ri->npages; 1850 npages = kvm_rma_pages;
1842 porder = __ilog2(npages); 1851 porder = __ilog2(npages);
1843 physp = memslot->arch.slot_phys; 1852 physp = memslot->arch.slot_phys;
1844 if (physp) { 1853 if (physp) {
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 4b865c553331..8cd0daebb82d 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -21,13 +21,6 @@
21#include <asm/kvm_book3s.h> 21#include <asm/kvm_book3s.h>
22 22
23#include "book3s_hv_cma.h" 23#include "book3s_hv_cma.h"
24
25#define KVM_LINEAR_RMA 0
26#define KVM_LINEAR_HPT 1
27
28static void __init kvm_linear_init_one(ulong size, int count, int type);
29static struct kvmppc_linear_info *kvm_alloc_linear(int type);
30static void kvm_release_linear(struct kvmppc_linear_info *ri);
31/* 24/*
32 * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) 25 * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
33 * should be power of 2. 26 * should be power of 2.
@@ -37,19 +30,17 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri);
37 * By default we reserve 5% of memory for hash pagetable allocation. 30 * By default we reserve 5% of memory for hash pagetable allocation.
38 */ 31 */
39static unsigned long kvm_cma_resv_ratio = 5; 32static unsigned long kvm_cma_resv_ratio = 5;
40
41/*************** RMA *************/
42
43/* 33/*
44 * This maintains a list of RMAs (real mode areas) for KVM guests to use. 34 * We allocate RMAs (real mode areas) for KVM guests from the KVM CMA area.
45 * Each RMA has to be physically contiguous and of a size that the 35 * Each RMA has to be physically contiguous and of a size that the
46 * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, 36 * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB,
47 * and other larger sizes. Since we are unlikely to be allocate that 37 * and other larger sizes. Since we are unlikely to be allocate that
48 * much physically contiguous memory after the system is up and running, 38 * much physically contiguous memory after the system is up and running,
49 * we preallocate a set of RMAs in early boot for KVM to use. 39 * we preallocate a set of RMAs in early boot using CMA.
40 * should be power of 2.
50 */ 41 */
51static unsigned long kvm_rma_size = 64 << 20; /* 64MB */ 42unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT; /* 128MB */
52static unsigned long kvm_rma_count; 43EXPORT_SYMBOL_GPL(kvm_rma_pages);
53 44
54/* Work out RMLS (real mode limit selector) field value for a given RMA size. 45/* Work out RMLS (real mode limit selector) field value for a given RMA size.
55 Assumes POWER7 or PPC970. */ 46 Assumes POWER7 or PPC970. */
@@ -79,35 +70,50 @@ static inline int lpcr_rmls(unsigned long rma_size)
79 70
80static int __init early_parse_rma_size(char *p) 71static int __init early_parse_rma_size(char *p)
81{ 72{
82 if (!p) 73 unsigned long kvm_rma_size;
83 return 1;
84 74
75 pr_debug("%s(%s)\n", __func__, p);
76 if (!p)
77 return -EINVAL;
85 kvm_rma_size = memparse(p, &p); 78 kvm_rma_size = memparse(p, &p);
86 79 /*
80 * Check that the requested size is one supported in hardware
81 */
82 if (lpcr_rmls(kvm_rma_size) < 0) {
83 pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size);
84 return -EINVAL;
85 }
86 kvm_rma_pages = kvm_rma_size >> PAGE_SHIFT;
87 return 0; 87 return 0;
88} 88}
89early_param("kvm_rma_size", early_parse_rma_size); 89early_param("kvm_rma_size", early_parse_rma_size);
90 90
91static int __init early_parse_rma_count(char *p) 91struct kvm_rma_info *kvm_alloc_rma()
92{ 92{
93 if (!p) 93 struct page *page;
94 return 1; 94 struct kvm_rma_info *ri;
95 95
96 kvm_rma_count = simple_strtoul(p, NULL, 0); 96 ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL);
97 97 if (!ri)
98 return 0; 98 return NULL;
99} 99 page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages);
100early_param("kvm_rma_count", early_parse_rma_count); 100 if (!page)
101 101 goto err_out;
102struct kvmppc_linear_info *kvm_alloc_rma(void) 102 atomic_set(&ri->use_count, 1);
103{ 103 ri->base_pfn = page_to_pfn(page);
104 return kvm_alloc_linear(KVM_LINEAR_RMA); 104 return ri;
105err_out:
106 kfree(ri);
107 return NULL;
105} 108}
106EXPORT_SYMBOL_GPL(kvm_alloc_rma); 109EXPORT_SYMBOL_GPL(kvm_alloc_rma);
107 110
108void kvm_release_rma(struct kvmppc_linear_info *ri) 111void kvm_release_rma(struct kvm_rma_info *ri)
109{ 112{
110 kvm_release_linear(ri); 113 if (atomic_dec_and_test(&ri->use_count)) {
114 kvm_release_cma(pfn_to_page(ri->base_pfn), kvm_rma_pages);
115 kfree(ri);
116 }
111} 117}
112EXPORT_SYMBOL_GPL(kvm_release_rma); 118EXPORT_SYMBOL_GPL(kvm_release_rma);
113 119
@@ -137,101 +143,6 @@ void kvm_release_hpt(struct page *page, unsigned long nr_pages)
137} 143}
138EXPORT_SYMBOL_GPL(kvm_release_hpt); 144EXPORT_SYMBOL_GPL(kvm_release_hpt);
139 145
140/*************** generic *************/
141
142static LIST_HEAD(free_linears);
143static DEFINE_SPINLOCK(linear_lock);
144
145static void __init kvm_linear_init_one(ulong size, int count, int type)
146{
147 unsigned long i;
148 unsigned long j, npages;
149 void *linear;
150 struct page *pg;
151 const char *typestr;
152 struct kvmppc_linear_info *linear_info;
153
154 if (!count)
155 return;
156
157 typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT";
158
159 npages = size >> PAGE_SHIFT;
160 linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info));
161 for (i = 0; i < count; ++i) {
162 linear = alloc_bootmem_align(size, size);
163 pr_debug("Allocated KVM %s at %p (%ld MB)\n", typestr, linear,
164 size >> 20);
165 linear_info[i].base_virt = linear;
166 linear_info[i].base_pfn = __pa(linear) >> PAGE_SHIFT;
167 linear_info[i].npages = npages;
168 linear_info[i].type = type;
169 list_add_tail(&linear_info[i].list, &free_linears);
170 atomic_set(&linear_info[i].use_count, 0);
171
172 pg = pfn_to_page(linear_info[i].base_pfn);
173 for (j = 0; j < npages; ++j) {
174 atomic_inc(&pg->_count);
175 ++pg;
176 }
177 }
178}
179
180static struct kvmppc_linear_info *kvm_alloc_linear(int type)
181{
182 struct kvmppc_linear_info *ri, *ret;
183
184 ret = NULL;
185 spin_lock(&linear_lock);
186 list_for_each_entry(ri, &free_linears, list) {
187 if (ri->type != type)
188 continue;
189
190 list_del(&ri->list);
191 atomic_inc(&ri->use_count);
192 memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT);
193 ret = ri;
194 break;
195 }
196 spin_unlock(&linear_lock);
197 return ret;
198}
199
200static void kvm_release_linear(struct kvmppc_linear_info *ri)
201{
202 if (atomic_dec_and_test(&ri->use_count)) {
203 spin_lock(&linear_lock);
204 list_add_tail(&ri->list, &free_linears);
205 spin_unlock(&linear_lock);
206
207 }
208}
209
210/*
211 * Called at boot time while the bootmem allocator is active,
212 * to allocate contiguous physical memory for the hash page
213 * tables for guests.
214 */
215void __init kvm_linear_init(void)
216{
217 /* RMA */
218 /* Only do this on PPC970 in HV mode */
219 if (!cpu_has_feature(CPU_FTR_HVMODE) ||
220 !cpu_has_feature(CPU_FTR_ARCH_201))
221 return;
222
223 if (!kvm_rma_size || !kvm_rma_count)
224 return;
225
226 /* Check that the requested size is one supported in hardware */
227 if (lpcr_rmls(kvm_rma_size) < 0) {
228 pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size);
229 return;
230 }
231
232 kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA);
233}
234
235/** 146/**
236 * kvm_cma_reserve() - reserve area for kvm hash pagetable 147 * kvm_cma_reserve() - reserve area for kvm hash pagetable
237 * 148 *
@@ -265,6 +176,8 @@ void __init kvm_cma_reserve(void)
265 align_size = __rounddown_pow_of_two(selected_size); 176 align_size = __rounddown_pow_of_two(selected_size);
266 else 177 else
267 align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; 178 align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
179
180 align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size);
268 kvm_cma_declare_contiguous(selected_size, align_size); 181 kvm_cma_declare_contiguous(selected_size, align_size);
269 } 182 }
270} 183}