aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-03-24 16:48:25 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:17:03 -0400
commitc04a695a4484467889d0c91c2e377c6abcecd5d5 (patch)
treef969b63d1064573407900150c7bca5081fbd8805 /arch/powerpc/kvm
parentc664876c6d88ff8c8e93ee05c0bbdc3e4c2af488 (diff)
KVM: PPC: Implement BAT reads
BATs can't only be written to, you can also read them out! So let's implement emulation for reading BAT values again. While at it, I also made BAT setting flush the segment cache, so we're absolutely sure there's no MMU state left when writing BATs. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r--arch/powerpc/kvm/book3s_64_emulate.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
index 8d7a78d87eff..39d5003e01f0 100644
--- a/arch/powerpc/kvm/book3s_64_emulate.c
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -239,6 +239,34 @@ void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
239 } 239 }
240} 240}
241 241
242static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn)
243{
244 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
245 struct kvmppc_bat *bat;
246
247 switch (sprn) {
248 case SPRN_IBAT0U ... SPRN_IBAT3L:
249 bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2];
250 break;
251 case SPRN_IBAT4U ... SPRN_IBAT7L:
252 bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)];
253 break;
254 case SPRN_DBAT0U ... SPRN_DBAT3L:
255 bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2];
256 break;
257 case SPRN_DBAT4U ... SPRN_DBAT7L:
258 bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)];
259 break;
260 default:
261 BUG();
262 }
263
264 if (sprn % 2)
265 return bat->raw >> 32;
266 else
267 return bat->raw;
268}
269
242static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) 270static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
243{ 271{
244 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); 272 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
@@ -290,6 +318,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
290 /* BAT writes happen so rarely that we're ok to flush 318 /* BAT writes happen so rarely that we're ok to flush
291 * everything here */ 319 * everything here */
292 kvmppc_mmu_pte_flush(vcpu, 0, 0); 320 kvmppc_mmu_pte_flush(vcpu, 0, 0);
321 kvmppc_mmu_flush_segments(vcpu);
293 break; 322 break;
294 case SPRN_HID0: 323 case SPRN_HID0:
295 to_book3s(vcpu)->hid[0] = spr_val; 324 to_book3s(vcpu)->hid[0] = spr_val;
@@ -373,6 +402,12 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
373 int emulated = EMULATE_DONE; 402 int emulated = EMULATE_DONE;
374 403
375 switch (sprn) { 404 switch (sprn) {
405 case SPRN_IBAT0U ... SPRN_IBAT3L:
406 case SPRN_IBAT4U ... SPRN_IBAT7L:
407 case SPRN_DBAT0U ... SPRN_DBAT3L:
408 case SPRN_DBAT4U ... SPRN_DBAT7L:
409 kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn));
410 break;
376 case SPRN_SDR1: 411 case SPRN_SDR1:
377 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); 412 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1);
378 break; 413 break;