diff options
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv_builtin.c')
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 246 |
1 files changed, 98 insertions, 148 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index ec0a9e5de100..8cd0daebb82d 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -13,33 +13,34 @@ | |||
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 | ||
21 | #define KVM_LINEAR_RMA 0 | 23 | #include "book3s_hv_cma.h" |
22 | #define KVM_LINEAR_HPT 1 | 24 | /* |
23 | 25 | * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) | |
24 | static void __init kvm_linear_init_one(ulong size, int count, int type); | 26 | * should be power of 2. |
25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); | 27 | */ |
26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); | 28 | #define HPT_ALIGN_PAGES ((1 << 18) >> PAGE_SHIFT) /* 256k */ |
27 | 29 | /* | |
28 | int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; | 30 | * By default we reserve 5% of memory for hash pagetable allocation. |
29 | EXPORT_SYMBOL_GPL(kvm_hpt_order); | 31 | */ |
30 | 32 | static unsigned long kvm_cma_resv_ratio = 5; | |
31 | /*************** RMA *************/ | ||
32 | |||
33 | /* | 33 | /* |
34 | * 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. |
35 | * 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 |
36 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, | 36 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, |
37 | * 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 |
38 | * much physically contiguous memory after the system is up and running, | 38 | * much physically contiguous memory after the system is up and running, |
39 | * 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. | ||
40 | */ | 41 | */ |
41 | static unsigned long kvm_rma_size = 64 << 20; /* 64MB */ | 42 | unsigned long kvm_rma_pages = (1 << 27) >> PAGE_SHIFT; /* 128MB */ |
42 | static unsigned long kvm_rma_count; | 43 | EXPORT_SYMBOL_GPL(kvm_rma_pages); |
43 | 44 | ||
44 | /* 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. |
45 | Assumes POWER7 or PPC970. */ | 46 | Assumes POWER7 or PPC970. */ |
@@ -69,165 +70,114 @@ static inline int lpcr_rmls(unsigned long rma_size) | |||
69 | 70 | ||
70 | static int __init early_parse_rma_size(char *p) | 71 | static int __init early_parse_rma_size(char *p) |
71 | { | 72 | { |
72 | if (!p) | 73 | unsigned long kvm_rma_size; |
73 | return 1; | ||
74 | 74 | ||
75 | pr_debug("%s(%s)\n", __func__, p); | ||
76 | if (!p) | ||
77 | return -EINVAL; | ||
75 | kvm_rma_size = memparse(p, &p); | 78 | kvm_rma_size = memparse(p, &p); |
76 | 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; | ||
77 | return 0; | 87 | return 0; |
78 | } | 88 | } |
79 | early_param("kvm_rma_size", early_parse_rma_size); | 89 | early_param("kvm_rma_size", early_parse_rma_size); |
80 | 90 | ||
81 | static int __init early_parse_rma_count(char *p) | 91 | struct kvm_rma_info *kvm_alloc_rma() |
82 | { | 92 | { |
83 | if (!p) | 93 | struct page *page; |
84 | return 1; | 94 | struct kvm_rma_info *ri; |
85 | 95 | ||
86 | kvm_rma_count = simple_strtoul(p, NULL, 0); | 96 | ri = kmalloc(sizeof(struct kvm_rma_info), GFP_KERNEL); |
87 | 97 | if (!ri) | |
88 | return 0; | 98 | return NULL; |
89 | } | 99 | page = kvm_alloc_cma(kvm_rma_pages, kvm_rma_pages); |
90 | early_param("kvm_rma_count", early_parse_rma_count); | 100 | if (!page) |
91 | 101 | goto err_out; | |
92 | struct kvmppc_linear_info *kvm_alloc_rma(void) | 102 | atomic_set(&ri->use_count, 1); |
93 | { | 103 | ri->base_pfn = page_to_pfn(page); |
94 | return kvm_alloc_linear(KVM_LINEAR_RMA); | 104 | return ri; |
105 | err_out: | ||
106 | kfree(ri); | ||
107 | return NULL; | ||
95 | } | 108 | } |
96 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); | 109 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); |
97 | 110 | ||
98 | void kvm_release_rma(struct kvmppc_linear_info *ri) | 111 | void kvm_release_rma(struct kvm_rma_info *ri) |
99 | { | 112 | { |
100 | 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 | } | ||
101 | } | 117 | } |
102 | EXPORT_SYMBOL_GPL(kvm_release_rma); | 118 | EXPORT_SYMBOL_GPL(kvm_release_rma); |
103 | 119 | ||
104 | /*************** HPT *************/ | 120 | static 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 | |||
112 | static unsigned long kvm_hpt_count; | ||
113 | |||
114 | static int __init early_parse_hpt_count(char *p) | ||
115 | { | 121 | { |
122 | pr_debug("%s(%s)\n", __func__, p); | ||
116 | if (!p) | 123 | if (!p) |
117 | return 1; | 124 | return -EINVAL; |
118 | 125 | return kstrtoul(p, 0, &kvm_cma_resv_ratio); | |
119 | kvm_hpt_count = simple_strtoul(p, NULL, 0); | ||
120 | |||
121 | return 0; | ||
122 | } | 126 | } |
123 | early_param("kvm_hpt_count", early_parse_hpt_count); | 127 | early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv); |
124 | 128 | ||
125 | struct kvmppc_linear_info *kvm_alloc_hpt(void) | 129 | struct page *kvm_alloc_hpt(unsigned long nr_pages) |
126 | { | 130 | { |
127 | return kvm_alloc_linear(KVM_LINEAR_HPT); | 131 | unsigned long align_pages = HPT_ALIGN_PAGES; |
132 | |||
133 | /* Old CPUs require HPT aligned on a multiple of its size */ | ||
134 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
135 | align_pages = nr_pages; | ||
136 | return kvm_alloc_cma(nr_pages, align_pages); | ||
128 | } | 137 | } |
129 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); | 138 | EXPORT_SYMBOL_GPL(kvm_alloc_hpt); |
130 | 139 | ||
131 | void kvm_release_hpt(struct kvmppc_linear_info *li) | 140 | void kvm_release_hpt(struct page *page, unsigned long nr_pages) |
132 | { | 141 | { |
133 | kvm_release_linear(li); | 142 | kvm_release_cma(page, nr_pages); |
134 | } | 143 | } |
135 | EXPORT_SYMBOL_GPL(kvm_release_hpt); | 144 | EXPORT_SYMBOL_GPL(kvm_release_hpt); |
136 | 145 | ||
137 | /*************** generic *************/ | 146 | /** |
138 | 147 | * kvm_cma_reserve() - reserve area for kvm hash pagetable | |
139 | static LIST_HEAD(free_linears); | 148 | * |
140 | static DEFINE_SPINLOCK(linear_lock); | 149 | * This function reserves memory from early allocator. It should be |
141 | 150 | * called by arch specific code once the early allocator (memblock or bootmem) | |
142 | static void __init kvm_linear_init_one(ulong size, int count, int type) | 151 | * has been activated and all other subsystems have already allocated/reserved |
143 | { | 152 | * memory. |
144 | unsigned long i; | ||
145 | unsigned long j, npages; | ||
146 | void *linear; | ||
147 | struct page *pg; | ||
148 | const char *typestr; | ||
149 | struct kvmppc_linear_info *linear_info; | ||
150 | |||
151 | if (!count) | ||
152 | return; | ||
153 | |||
154 | typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT"; | ||
155 | |||
156 | npages = size >> PAGE_SHIFT; | ||
157 | linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info)); | ||
158 | for (i = 0; i < count; ++i) { | ||
159 | linear = alloc_bootmem_align(size, size); | ||
160 | pr_debug("Allocated KVM %s at %p (%ld MB)\n", typestr, linear, | ||
161 | size >> 20); | ||
162 | linear_info[i].base_virt = linear; | ||
163 | linear_info[i].base_pfn = __pa(linear) >> PAGE_SHIFT; | ||
164 | linear_info[i].npages = npages; | ||
165 | linear_info[i].type = type; | ||
166 | list_add_tail(&linear_info[i].list, &free_linears); | ||
167 | atomic_set(&linear_info[i].use_count, 0); | ||
168 | |||
169 | pg = pfn_to_page(linear_info[i].base_pfn); | ||
170 | for (j = 0; j < npages; ++j) { | ||
171 | atomic_inc(&pg->_count); | ||
172 | ++pg; | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static struct kvmppc_linear_info *kvm_alloc_linear(int type) | ||
178 | { | ||
179 | struct kvmppc_linear_info *ri, *ret; | ||
180 | |||
181 | ret = NULL; | ||
182 | spin_lock(&linear_lock); | ||
183 | list_for_each_entry(ri, &free_linears, list) { | ||
184 | if (ri->type != type) | ||
185 | continue; | ||
186 | |||
187 | list_del(&ri->list); | ||
188 | atomic_inc(&ri->use_count); | ||
189 | memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT); | ||
190 | ret = ri; | ||
191 | break; | ||
192 | } | ||
193 | spin_unlock(&linear_lock); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static void kvm_release_linear(struct kvmppc_linear_info *ri) | ||
198 | { | ||
199 | if (atomic_dec_and_test(&ri->use_count)) { | ||
200 | spin_lock(&linear_lock); | ||
201 | list_add_tail(&ri->list, &free_linears); | ||
202 | spin_unlock(&linear_lock); | ||
203 | |||
204 | } | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Called at boot time while the bootmem allocator is active, | ||
209 | * to allocate contiguous physical memory for the hash page | ||
210 | * tables for guests. | ||
211 | */ | 153 | */ |
212 | void __init kvm_linear_init(void) | 154 | void __init kvm_cma_reserve(void) |
213 | { | 155 | { |
214 | /* HPT */ | 156 | unsigned long align_size; |
215 | kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); | 157 | struct memblock_region *reg; |
216 | 158 | phys_addr_t selected_size = 0; | |
217 | /* RMA */ | 159 | /* |
218 | /* Only do this on PPC970 in HV mode */ | 160 | * We cannot use memblock_phys_mem_size() here, because |
219 | if (!cpu_has_feature(CPU_FTR_HVMODE) || | 161 | * memblock_analyze() has not been called yet. |
220 | !cpu_has_feature(CPU_FTR_ARCH_201)) | 162 | */ |
221 | return; | 163 | for_each_memblock(memory, reg) |
222 | 164 | selected_size += memblock_region_memory_end_pfn(reg) - | |
223 | if (!kvm_rma_size || !kvm_rma_count) | 165 | memblock_region_memory_base_pfn(reg); |
224 | return; | 166 | |
225 | 167 | selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; | |
226 | /* Check that the requested size is one supported in hardware */ | 168 | if (selected_size) { |
227 | if (lpcr_rmls(kvm_rma_size) < 0) { | 169 | pr_debug("%s: reserving %ld MiB for global area\n", __func__, |
228 | pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); | 170 | (unsigned long)selected_size / SZ_1M); |
229 | return; | 171 | /* |
172 | * Old CPUs require HPT aligned on a multiple of its size. So for them | ||
173 | * make the alignment as max size we could request. | ||
174 | */ | ||
175 | if (!cpu_has_feature(CPU_FTR_ARCH_206)) | ||
176 | align_size = __rounddown_pow_of_two(selected_size); | ||
177 | else | ||
178 | align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; | ||
179 | |||
180 | align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size); | ||
181 | kvm_cma_declare_contiguous(selected_size, align_size); | ||
230 | } | 182 | } |
231 | |||
232 | kvm_linear_init_one(kvm_rma_size, kvm_rma_count, KVM_LINEAR_RMA); | ||
233 | } | 183 | } |