aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2013-09-20 00:52:49 -0400
committerAlexander Graf <agraf@suse.de>2013-10-17 08:45:05 -0400
commit3ff955024d186c512ee91263df9c850d6ae34a12 (patch)
treea76e934a4a82fa68e47bcca8c09fbc32aeae4169
parent9308ab8e2da933d895ebbb903bf459e33ed94dec (diff)
KVM: PPC: Book3S PR: Allocate kvm_vcpu structs from kvm_vcpu_cache
This makes PR KVM allocate its kvm_vcpu structs from the kvm_vcpu_cache rather than having them embedded in the kvmppc_vcpu_book3s struct, which is allocated with vzalloc. The reason is to reduce the differences between PR and HV KVM in order to make is easier to have them coexist in one kernel binary. With this, the kvm_vcpu struct has a pointer to the kvmppc_vcpu_book3s struct. The pointer to the kvmppc_book3s_shadow_vcpu struct has moved from the kvmppc_vcpu_book3s struct to the kvm_vcpu struct, and is only present for 32-bit, since it is only used for 32-bit. Signed-off-by: Paul Mackerras <paulus@samba.org> [agraf: squash in compile fix from Aneesh] Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h4
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_32.h2
-rw-r--r--arch/powerpc/include/asm/kvm_host.h7
-rw-r--r--arch/powerpc/kvm/book3s_32_mmu.c8
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu.c11
-rw-r--r--arch/powerpc/kvm/book3s_pr.c33
6 files changed, 39 insertions, 26 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index 6bf20b4a2841..603fba494a0b 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -70,8 +70,6 @@ struct hpte_cache {
70}; 70};
71 71
72struct kvmppc_vcpu_book3s { 72struct kvmppc_vcpu_book3s {
73 struct kvm_vcpu vcpu;
74 struct kvmppc_book3s_shadow_vcpu *shadow_vcpu;
75 struct kvmppc_sid_map sid_map[SID_MAP_NUM]; 73 struct kvmppc_sid_map sid_map[SID_MAP_NUM];
76 struct { 74 struct {
77 u64 esid; 75 u64 esid;
@@ -194,7 +192,7 @@ extern int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd);
194 192
195static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) 193static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu)
196{ 194{
197 return container_of(vcpu, struct kvmppc_vcpu_book3s, vcpu); 195 return vcpu->arch.book3s;
198} 196}
199 197
200extern void kvm_return_point(void); 198extern void kvm_return_point(void);
diff --git a/arch/powerpc/include/asm/kvm_book3s_32.h b/arch/powerpc/include/asm/kvm_book3s_32.h
index ce0ef6ce8f86..c720e0b3238d 100644
--- a/arch/powerpc/include/asm/kvm_book3s_32.h
+++ b/arch/powerpc/include/asm/kvm_book3s_32.h
@@ -22,7 +22,7 @@
22 22
23static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu) 23static inline struct kvmppc_book3s_shadow_vcpu *svcpu_get(struct kvm_vcpu *vcpu)
24{ 24{
25 return to_book3s(vcpu)->shadow_vcpu; 25 return vcpu->arch.shadow_vcpu;
26} 26}
27 27
28static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) 28static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 0fe48729d07d..404dbc81434d 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -86,6 +86,9 @@ struct lppaca;
86struct slb_shadow; 86struct slb_shadow;
87struct dtl_entry; 87struct dtl_entry;
88 88
89struct kvmppc_vcpu_book3s;
90struct kvmppc_book3s_shadow_vcpu;
91
89struct kvm_vm_stat { 92struct kvm_vm_stat {
90 u32 remote_tlb_flush; 93 u32 remote_tlb_flush;
91}; 94};
@@ -408,6 +411,10 @@ struct kvm_vcpu_arch {
408 int slb_max; /* 1 + index of last valid entry in slb[] */ 411 int slb_max; /* 1 + index of last valid entry in slb[] */
409 int slb_nr; /* total number of entries in SLB */ 412 int slb_nr; /* total number of entries in SLB */
410 struct kvmppc_mmu mmu; 413 struct kvmppc_mmu mmu;
414 struct kvmppc_vcpu_book3s *book3s;
415#endif
416#ifdef CONFIG_PPC_BOOK3S_32
417 struct kvmppc_book3s_shadow_vcpu *shadow_vcpu;
411#endif 418#endif
412 419
413 ulong gpr[32]; 420 ulong gpr[32];
diff --git a/arch/powerpc/kvm/book3s_32_mmu.c b/arch/powerpc/kvm/book3s_32_mmu.c
index 856af988ad59..b14af6d09347 100644
--- a/arch/powerpc/kvm/book3s_32_mmu.c
+++ b/arch/powerpc/kvm/book3s_32_mmu.c
@@ -111,10 +111,11 @@ static void kvmppc_mmu_book3s_32_reset_msr(struct kvm_vcpu *vcpu)
111 kvmppc_set_msr(vcpu, 0); 111 kvmppc_set_msr(vcpu, 0);
112} 112}
113 113
114static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3s, 114static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvm_vcpu *vcpu,
115 u32 sre, gva_t eaddr, 115 u32 sre, gva_t eaddr,
116 bool primary) 116 bool primary)
117{ 117{
118 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
118 u32 page, hash, pteg, htabmask; 119 u32 page, hash, pteg, htabmask;
119 hva_t r; 120 hva_t r;
120 121
@@ -132,7 +133,7 @@ static hva_t kvmppc_mmu_book3s_32_get_pteg(struct kvmppc_vcpu_book3s *vcpu_book3
132 kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg, 133 kvmppc_get_pc(&vcpu_book3s->vcpu), eaddr, vcpu_book3s->sdr1, pteg,
133 sr_vsid(sre)); 134 sr_vsid(sre));
134 135
135 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT); 136 r = gfn_to_hva(vcpu->kvm, pteg >> PAGE_SHIFT);
136 if (kvm_is_error_hva(r)) 137 if (kvm_is_error_hva(r))
137 return r; 138 return r;
138 return r | (pteg & ~PAGE_MASK); 139 return r | (pteg & ~PAGE_MASK);
@@ -203,7 +204,6 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
203 struct kvmppc_pte *pte, bool data, 204 struct kvmppc_pte *pte, bool data,
204 bool primary) 205 bool primary)
205{ 206{
206 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
207 u32 sre; 207 u32 sre;
208 hva_t ptegp; 208 hva_t ptegp;
209 u32 pteg[16]; 209 u32 pteg[16];
@@ -218,7 +218,7 @@ static int kvmppc_mmu_book3s_32_xlate_pte(struct kvm_vcpu *vcpu, gva_t eaddr,
218 218
219 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data); 219 pte->vpage = kvmppc_mmu_book3s_32_ea_to_vp(vcpu, eaddr, data);
220 220
221 ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu_book3s, sre, eaddr, primary); 221 ptegp = kvmppc_mmu_book3s_32_get_pteg(vcpu, sre, eaddr, primary);
222 if (kvm_is_error_hva(ptegp)) { 222 if (kvm_is_error_hva(ptegp)) {
223 printk(KERN_INFO "KVM: Invalid PTEG!\n"); 223 printk(KERN_INFO "KVM: Invalid PTEG!\n");
224 goto no_page_found; 224 goto no_page_found;
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index ad9ecfd29c4c..c110145522e6 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -130,11 +130,11 @@ static u32 kvmppc_mmu_book3s_64_get_page(struct kvmppc_slb *slbe, gva_t eaddr)
130 return ((eaddr & kvmppc_slb_offset_mask(slbe)) >> p); 130 return ((eaddr & kvmppc_slb_offset_mask(slbe)) >> p);
131} 131}
132 132
133static hva_t kvmppc_mmu_book3s_64_get_pteg( 133static hva_t kvmppc_mmu_book3s_64_get_pteg(struct kvm_vcpu *vcpu,
134 struct kvmppc_vcpu_book3s *vcpu_book3s,
135 struct kvmppc_slb *slbe, gva_t eaddr, 134 struct kvmppc_slb *slbe, gva_t eaddr,
136 bool second) 135 bool second)
137{ 136{
137 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
138 u64 hash, pteg, htabsize; 138 u64 hash, pteg, htabsize;
139 u32 ssize; 139 u32 ssize;
140 hva_t r; 140 hva_t r;
@@ -159,10 +159,10 @@ static hva_t kvmppc_mmu_book3s_64_get_pteg(
159 159
160 /* When running a PAPR guest, SDR1 contains a HVA address instead 160 /* When running a PAPR guest, SDR1 contains a HVA address instead
161 of a GPA */ 161 of a GPA */
162 if (vcpu_book3s->vcpu.arch.papr_enabled) 162 if (vcpu->arch.papr_enabled)
163 r = pteg; 163 r = pteg;
164 else 164 else
165 r = gfn_to_hva(vcpu_book3s->vcpu.kvm, pteg >> PAGE_SHIFT); 165 r = gfn_to_hva(vcpu->kvm, pteg >> PAGE_SHIFT);
166 166
167 if (kvm_is_error_hva(r)) 167 if (kvm_is_error_hva(r))
168 return r; 168 return r;
@@ -208,7 +208,6 @@ static int decode_pagesize(struct kvmppc_slb *slbe, u64 r)
208static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, 208static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
209 struct kvmppc_pte *gpte, bool data) 209 struct kvmppc_pte *gpte, bool data)
210{ 210{
211 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
212 struct kvmppc_slb *slbe; 211 struct kvmppc_slb *slbe;
213 hva_t ptegp; 212 hva_t ptegp;
214 u64 pteg[16]; 213 u64 pteg[16];
@@ -260,7 +259,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
260 mutex_lock(&vcpu->kvm->arch.hpt_mutex); 259 mutex_lock(&vcpu->kvm->arch.hpt_mutex);
261 260
262do_second: 261do_second:
263 ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu_book3s, slbe, eaddr, second); 262 ptegp = kvmppc_mmu_book3s_64_get_pteg(vcpu, slbe, eaddr, second);
264 if (kvm_is_error_hva(ptegp)) 263 if (kvm_is_error_hva(ptegp))
265 goto no_page_found; 264 goto no_page_found;
266 265
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 4fa73c3f5713..677d7e33b1ff 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -66,7 +66,7 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
66#endif 66#endif
67 vcpu->cpu = smp_processor_id(); 67 vcpu->cpu = smp_processor_id();
68#ifdef CONFIG_PPC_BOOK3S_32 68#ifdef CONFIG_PPC_BOOK3S_32
69 current->thread.kvm_shadow_vcpu = to_book3s(vcpu)->shadow_vcpu; 69 current->thread.kvm_shadow_vcpu = vcpu->arch.shadow_vcpu;
70#endif 70#endif
71} 71}
72 72
@@ -1125,17 +1125,22 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1125 int err = -ENOMEM; 1125 int err = -ENOMEM;
1126 unsigned long p; 1126 unsigned long p;
1127 1127
1128 vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
1129 if (!vcpu)
1130 goto out;
1131
1128 vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s)); 1132 vcpu_book3s = vzalloc(sizeof(struct kvmppc_vcpu_book3s));
1129 if (!vcpu_book3s) 1133 if (!vcpu_book3s)
1130 goto out; 1134 goto free_vcpu;
1135 vcpu->arch.book3s = vcpu_book3s;
1131 1136
1132#ifdef CONFIG_KVM_BOOK3S_32 1137#ifdef CONFIG_KVM_BOOK3S_32
1133 vcpu_book3s->shadow_vcpu = 1138 vcpu->arch.shadow_vcpu =
1134 kzalloc(sizeof(*vcpu_book3s->shadow_vcpu), GFP_KERNEL); 1139 kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL);
1135 if (!vcpu_book3s->shadow_vcpu) 1140 if (!vcpu->arch.shadow_vcpu)
1136 goto free_vcpu; 1141 goto free_vcpu3s;
1137#endif 1142#endif
1138 vcpu = &vcpu_book3s->vcpu; 1143
1139 err = kvm_vcpu_init(vcpu, kvm, id); 1144 err = kvm_vcpu_init(vcpu, kvm, id);
1140 if (err) 1145 if (err)
1141 goto free_shadow_vcpu; 1146 goto free_shadow_vcpu;
@@ -1175,10 +1180,12 @@ uninit_vcpu:
1175 kvm_vcpu_uninit(vcpu); 1180 kvm_vcpu_uninit(vcpu);
1176free_shadow_vcpu: 1181free_shadow_vcpu:
1177#ifdef CONFIG_KVM_BOOK3S_32 1182#ifdef CONFIG_KVM_BOOK3S_32
1178 kfree(vcpu_book3s->shadow_vcpu); 1183 kfree(vcpu->arch.shadow_vcpu);
1179free_vcpu: 1184free_vcpu3s:
1180#endif 1185#endif
1181 vfree(vcpu_book3s); 1186 vfree(vcpu_book3s);
1187free_vcpu:
1188 kmem_cache_free(kvm_vcpu_cache, vcpu);
1182out: 1189out:
1183 return ERR_PTR(err); 1190 return ERR_PTR(err);
1184} 1191}
@@ -1189,8 +1196,11 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
1189 1196
1190 free_page((unsigned long)vcpu->arch.shared & PAGE_MASK); 1197 free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
1191 kvm_vcpu_uninit(vcpu); 1198 kvm_vcpu_uninit(vcpu);
1192 kfree(vcpu_book3s->shadow_vcpu); 1199#ifdef CONFIG_KVM_BOOK3S_32
1200 kfree(vcpu->arch.shadow_vcpu);
1201#endif
1193 vfree(vcpu_book3s); 1202 vfree(vcpu_book3s);
1203 kmem_cache_free(kvm_vcpu_cache, vcpu);
1194} 1204}
1195 1205
1196int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) 1206int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
@@ -1452,8 +1462,7 @@ static int kvmppc_book3s_init(void)
1452{ 1462{
1453 int r; 1463 int r;
1454 1464
1455 r = kvm_init(NULL, sizeof(struct kvmppc_vcpu_book3s), 0, 1465 r = kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE);
1456 THIS_MODULE);
1457 1466
1458 if (r) 1467 if (r)
1459 return r; 1468 return r;