diff options
author | Alexander Graf <agraf@suse.de> | 2010-03-24 16:48:25 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:17:03 -0400 |
commit | c04a695a4484467889d0c91c2e377c6abcecd5d5 (patch) | |
tree | f969b63d1064573407900150c7bca5081fbd8805 /arch/powerpc/kvm | |
parent | c664876c6d88ff8c8e93ee05c0bbdc3e4c2af488 (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.c | 35 |
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 | ||
242 | static 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 | |||
242 | static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) | 270 | static 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; |