blob: 4b865c553331b595676b90eb37e24d3326839573 [file] [log] [blame]
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +00001/*
2 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2, as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kvm_host.h>
10#include <linux/preempt.h>
Paul Gortmaker66b15db2011-05-27 10:46:24 -040011#include <linux/export.h>
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000012#include <linux/sched.h>
13#include <linux/spinlock.h>
14#include <linux/bootmem.h>
15#include <linux/init.h>
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +053016#include <linux/memblock.h>
17#include <linux/sizes.h>
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000018
19#include <asm/cputable.h>
20#include <asm/kvm_ppc.h>
21#include <asm/kvm_book3s.h>
22
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +053023#include "book3s_hv_cma.h"
24
Alexander Grafb4e70612012-01-16 16:50:10 +010025#define KVM_LINEAR_RMA 0
Alexander Grafd2a1b482012-01-16 19:12:11 +010026#define KVM_LINEAR_HPT 1
Alexander Grafb4e70612012-01-16 16:50:10 +010027
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);
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +053031/*
32 * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
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;
Paul Mackerras32fad282012-05-04 02:32:53 +000040
Alexander Grafb4e70612012-01-16 16:50:10 +010041/*************** RMA *************/
42
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000043/*
44 * This maintains a list of RMAs (real mode areas) for KVM guests to use.
45 * Each RMA has to be physically contiguous and of a size that the
46 * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB,
47 * and other larger sizes. Since we are unlikely to be allocate that
48 * 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.
50 */
51static unsigned long kvm_rma_size = 64 << 20; /* 64MB */
52static unsigned long kvm_rma_count;
53
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000054/* Work out RMLS (real mode limit selector) field value for a given RMA size.
Paul Mackerras9e368f22011-06-29 00:40:08 +000055 Assumes POWER7 or PPC970. */
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000056static inline int lpcr_rmls(unsigned long rma_size)
57{
58 switch (rma_size) {
59 case 32ul << 20: /* 32 MB */
Paul Mackerras9e368f22011-06-29 00:40:08 +000060 if (cpu_has_feature(CPU_FTR_ARCH_206))
61 return 8; /* only supported on POWER7 */
62 return -1;
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +000063 case 64ul << 20: /* 64 MB */
64 return 3;
65 case 128ul << 20: /* 128 MB */
66 return 7;
67 case 256ul << 20: /* 256 MB */
68 return 4;
69 case 1ul << 30: /* 1 GB */
70 return 2;
71 case 16ul << 30: /* 16 GB */
72 return 1;
73 case 256ul << 30: /* 256 GB */
74 return 0;
75 default:
76 return -1;
77 }
78}
79
Alexander Grafb4e70612012-01-16 16:50:10 +010080static int __init early_parse_rma_size(char *p)
81{
82 if (!p)
83 return 1;
84
85 kvm_rma_size = memparse(p, &p);
86
87 return 0;
88}
89early_param("kvm_rma_size", early_parse_rma_size);
90
91static int __init early_parse_rma_count(char *p)
92{
93 if (!p)
94 return 1;
95
96 kvm_rma_count = simple_strtoul(p, NULL, 0);
97
98 return 0;
99}
100early_param("kvm_rma_count", early_parse_rma_count);
101
102struct kvmppc_linear_info *kvm_alloc_rma(void)
103{
104 return kvm_alloc_linear(KVM_LINEAR_RMA);
105}
106EXPORT_SYMBOL_GPL(kvm_alloc_rma);
107
108void kvm_release_rma(struct kvmppc_linear_info *ri)
109{
110 kvm_release_linear(ri);
111}
112EXPORT_SYMBOL_GPL(kvm_release_rma);
113
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530114static int __init early_parse_kvm_cma_resv(char *p)
Alexander Grafd2a1b482012-01-16 19:12:11 +0100115{
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530116 pr_debug("%s(%s)\n", __func__, p);
Alexander Grafd2a1b482012-01-16 19:12:11 +0100117 if (!p)
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530118 return -EINVAL;
119 return kstrtoul(p, 0, &kvm_cma_resv_ratio);
Alexander Grafd2a1b482012-01-16 19:12:11 +0100120}
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530121early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv);
Alexander Grafd2a1b482012-01-16 19:12:11 +0100122
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530123struct page *kvm_alloc_hpt(unsigned long nr_pages)
Alexander Grafd2a1b482012-01-16 19:12:11 +0100124{
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530125 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);
Alexander Grafd2a1b482012-01-16 19:12:11 +0100131}
132EXPORT_SYMBOL_GPL(kvm_alloc_hpt);
133
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530134void kvm_release_hpt(struct page *page, unsigned long nr_pages)
Alexander Grafd2a1b482012-01-16 19:12:11 +0100135{
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530136 kvm_release_cma(page, nr_pages);
Alexander Grafd2a1b482012-01-16 19:12:11 +0100137}
138EXPORT_SYMBOL_GPL(kvm_release_hpt);
139
Alexander Grafb4e70612012-01-16 16:50:10 +0100140/*************** 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)
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +0000146{
147 unsigned long i;
148 unsigned long j, npages;
Alexander Grafb4e70612012-01-16 16:50:10 +0100149 void *linear;
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +0000150 struct page *pg;
Alexander Grafb4e70612012-01-16 16:50:10 +0100151 const char *typestr;
152 struct kvmppc_linear_info *linear_info;
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +0000153
Alexander Grafb4e70612012-01-16 16:50:10 +0100154 if (!count)
155 return;
156
Alexander Grafd2a1b482012-01-16 19:12:11 +0100157 typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT";
Alexander Grafb4e70612012-01-16 16:50:10 +0100158
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);
Paul Mackerras1340f3e82012-08-06 00:04:14 +0000163 pr_debug("Allocated KVM %s at %p (%ld MB)\n", typestr, linear,
164 size >> 20);
Alexander Grafb4e70612012-01-16 16:50:10 +0100165 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{
Paul Mackerrasb4e512292012-02-03 00:45:02 +0000182 struct kvmppc_linear_info *ri, *ret;
Alexander Grafb4e70612012-01-16 16:50:10 +0100183
Paul Mackerrasb4e512292012-02-03 00:45:02 +0000184 ret = NULL;
Alexander Grafb4e70612012-01-16 16:50:10 +0100185 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);
Paul Mackerrasb4e512292012-02-03 00:45:02 +0000192 memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT);
193 ret = ri;
Alexander Grafb4e70612012-01-16 16:50:10 +0100194 break;
195 }
196 spin_unlock(&linear_lock);
Paul Mackerrasb4e512292012-02-03 00:45:02 +0000197 return ret;
Alexander Grafb4e70612012-01-16 16:50:10 +0100198}
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 */
Paul Mackerras9e368f22011-06-29 00:40:08 +0000218 /* Only do this on PPC970 in HV mode */
219 if (!cpu_has_feature(CPU_FTR_HVMODE) ||
220 !cpu_has_feature(CPU_FTR_ARCH_201))
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +0000221 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
Alexander Grafb4e70612012-01-16 16:50:10 +0100232 kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA);
Paul Mackerrasaa04b4c2011-06-29 00:25:44 +0000233}
Aneesh Kumar K.Vfa61a4e32013-07-02 11:15:16 +0530234
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}