aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h2
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c19
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c39
4 files changed, 57 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 8221e717bbce..1843d5d2a3be 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -235,6 +235,7 @@ struct kvm_arch {
235 int slot_npages[KVM_MEM_SLOTS_NUM]; 235 int slot_npages[KVM_MEM_SLOTS_NUM];
236 unsigned short last_vcpu[NR_CPUS]; 236 unsigned short last_vcpu[NR_CPUS];
237 struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; 237 struct kvmppc_vcore *vcores[KVM_MAX_VCORES];
238 struct kvmppc_linear_info *hpt_li;
238#endif /* CONFIG_KVM_BOOK3S_64_HV */ 239#endif /* CONFIG_KVM_BOOK3S_64_HV */
239}; 240};
240 241
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 1c37a2f8d0f4..9d6dee0f7d48 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -130,6 +130,8 @@ extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm,
130 struct kvm_allocate_rma *rma); 130 struct kvm_allocate_rma *rma);
131extern struct kvmppc_linear_info *kvm_alloc_rma(void); 131extern struct kvmppc_linear_info *kvm_alloc_rma(void);
132extern void kvm_release_rma(struct kvmppc_linear_info *ri); 132extern void kvm_release_rma(struct kvmppc_linear_info *ri);
133extern struct kvmppc_linear_info *kvm_alloc_hpt(void);
134extern void kvm_release_hpt(struct kvmppc_linear_info *li);
133extern int kvmppc_core_init_vm(struct kvm *kvm); 135extern int kvmppc_core_init_vm(struct kvm *kvm);
134extern void kvmppc_core_destroy_vm(struct kvm *kvm); 136extern void kvmppc_core_destroy_vm(struct kvm *kvm);
135extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, 137extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index 783cd3510c93..ddc485a529f2 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -44,10 +44,20 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
44 unsigned long hpt; 44 unsigned long hpt;
45 unsigned long lpid; 45 unsigned long lpid;
46 struct revmap_entry *rev; 46 struct revmap_entry *rev;
47 struct kvmppc_linear_info *li;
47 48
48 /* Allocate guest's hashed page table */ 49 /* Allocate guest's hashed page table */
49 hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|__GFP_NOWARN, 50 li = kvm_alloc_hpt();
50 HPT_ORDER - PAGE_SHIFT); 51 if (li) {
52 /* using preallocated memory */
53 hpt = (ulong)li->base_virt;
54 kvm->arch.hpt_li = li;
55 } else {
56 /* using dynamic memory */
57 hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT|
58 __GFP_NOWARN, HPT_ORDER - PAGE_SHIFT);
59 }
60
51 if (!hpt) { 61 if (!hpt) {
52 pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n"); 62 pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n");
53 return -ENOMEM; 63 return -ENOMEM;
@@ -88,7 +98,10 @@ void kvmppc_free_hpt(struct kvm *kvm)
88{ 98{
89 clear_bit(kvm->arch.lpid, lpid_inuse); 99 clear_bit(kvm->arch.lpid, lpid_inuse);
90 vfree(kvm->arch.revmap); 100 vfree(kvm->arch.revmap);
91 free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); 101 if (kvm->arch.hpt_li)
102 kvm_release_hpt(kvm->arch.hpt_li);
103 else
104 free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT);
92} 105}
93 106
94/* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ 107/* Bits in first HPTE dword for pagesize 4k, 64k or 16M */
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 7caed1dfd7a4..bed1279aa6a8 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -19,6 +19,7 @@
19#include <asm/kvm_book3s.h> 19#include <asm/kvm_book3s.h>
20 20
21#define KVM_LINEAR_RMA 0 21#define KVM_LINEAR_RMA 0
22#define KVM_LINEAR_HPT 1
22 23
23static void __init kvm_linear_init_one(ulong size, int count, int type); 24static void __init kvm_linear_init_one(ulong size, int count, int type);
24static struct kvmppc_linear_info *kvm_alloc_linear(int type); 25static struct kvmppc_linear_info *kvm_alloc_linear(int type);
@@ -97,6 +98,39 @@ void kvm_release_rma(struct kvmppc_linear_info *ri)
97} 98}
98EXPORT_SYMBOL_GPL(kvm_release_rma); 99EXPORT_SYMBOL_GPL(kvm_release_rma);
99 100
101/*************** HPT *************/
102
103/*
104 * This maintains a list of big linear HPT tables that contain the GVA->HPA
105 * memory mappings. If we don't reserve those early on, we might not be able
106 * to get a big (usually 16MB) linear memory region from the kernel anymore.
107 */
108
109static unsigned long kvm_hpt_count;
110
111static int __init early_parse_hpt_count(char *p)
112{
113 if (!p)
114 return 1;
115
116 kvm_hpt_count = simple_strtoul(p, NULL, 0);
117
118 return 0;
119}
120early_param("kvm_hpt_count", early_parse_hpt_count);
121
122struct kvmppc_linear_info *kvm_alloc_hpt(void)
123{
124 return kvm_alloc_linear(KVM_LINEAR_HPT);
125}
126EXPORT_SYMBOL_GPL(kvm_alloc_hpt);
127
128void kvm_release_hpt(struct kvmppc_linear_info *li)
129{
130 kvm_release_linear(li);
131}
132EXPORT_SYMBOL_GPL(kvm_release_hpt);
133
100/*************** generic *************/ 134/*************** generic *************/
101 135
102static LIST_HEAD(free_linears); 136static LIST_HEAD(free_linears);
@@ -114,7 +148,7 @@ static void __init kvm_linear_init_one(ulong size, int count, int type)
114 if (!count) 148 if (!count)
115 return; 149 return;
116 150
117 typestr = (type == KVM_LINEAR_RMA) ? "RMA" : ""; 151 typestr = (type == KVM_LINEAR_RMA) ? "RMA" : "HPT";
118 152
119 npages = size >> PAGE_SHIFT; 153 npages = size >> PAGE_SHIFT;
120 linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info)); 154 linear_info = alloc_bootmem(count * sizeof(struct kvmppc_linear_info));
@@ -173,6 +207,9 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri)
173 */ 207 */
174void __init kvm_linear_init(void) 208void __init kvm_linear_init(void)
175{ 209{
210 /* HPT */
211 kvm_linear_init_one(1 << HPT_ORDER, kvm_hpt_count, KVM_LINEAR_HPT);
212
176 /* RMA */ 213 /* RMA */
177 /* Only do this on PPC970 in HV mode */ 214 /* Only do this on PPC970 in HV mode */
178 if (!cpu_has_feature(CPU_FTR_HVMODE) || 215 if (!cpu_has_feature(CPU_FTR_HVMODE) ||