diff options
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r-- | arch/powerpc/kvm/book3s_emulate.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index f333cb445349..466846557089 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
@@ -264,7 +264,7 @@ void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper, | |||
264 | } | 264 | } |
265 | } | 265 | } |
266 | 266 | ||
267 | static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) | 267 | static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn) |
268 | { | 268 | { |
269 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); | 269 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); |
270 | struct kvmppc_bat *bat; | 270 | struct kvmppc_bat *bat; |
@@ -286,35 +286,7 @@ static u32 kvmppc_read_bat(struct kvm_vcpu *vcpu, int sprn) | |||
286 | BUG(); | 286 | BUG(); |
287 | } | 287 | } |
288 | 288 | ||
289 | if (sprn % 2) | 289 | return bat; |
290 | return bat->raw >> 32; | ||
291 | else | ||
292 | return bat->raw; | ||
293 | } | ||
294 | |||
295 | static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val) | ||
296 | { | ||
297 | struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); | ||
298 | struct kvmppc_bat *bat; | ||
299 | |||
300 | switch (sprn) { | ||
301 | case SPRN_IBAT0U ... SPRN_IBAT3L: | ||
302 | bat = &vcpu_book3s->ibat[(sprn - SPRN_IBAT0U) / 2]; | ||
303 | break; | ||
304 | case SPRN_IBAT4U ... SPRN_IBAT7L: | ||
305 | bat = &vcpu_book3s->ibat[4 + ((sprn - SPRN_IBAT4U) / 2)]; | ||
306 | break; | ||
307 | case SPRN_DBAT0U ... SPRN_DBAT3L: | ||
308 | bat = &vcpu_book3s->dbat[(sprn - SPRN_DBAT0U) / 2]; | ||
309 | break; | ||
310 | case SPRN_DBAT4U ... SPRN_DBAT7L: | ||
311 | bat = &vcpu_book3s->dbat[4 + ((sprn - SPRN_DBAT4U) / 2)]; | ||
312 | break; | ||
313 | default: | ||
314 | BUG(); | ||
315 | } | ||
316 | |||
317 | kvmppc_set_bat(vcpu, bat, !(sprn % 2), val); | ||
318 | } | 290 | } |
319 | 291 | ||
320 | int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | 292 | int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) |
@@ -339,12 +311,16 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
339 | case SPRN_IBAT4U ... SPRN_IBAT7L: | 311 | case SPRN_IBAT4U ... SPRN_IBAT7L: |
340 | case SPRN_DBAT0U ... SPRN_DBAT3L: | 312 | case SPRN_DBAT0U ... SPRN_DBAT3L: |
341 | case SPRN_DBAT4U ... SPRN_DBAT7L: | 313 | case SPRN_DBAT4U ... SPRN_DBAT7L: |
342 | kvmppc_write_bat(vcpu, sprn, (u32)spr_val); | 314 | { |
315 | struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn); | ||
316 | |||
317 | kvmppc_set_bat(vcpu, bat, !(sprn % 2), (u32)spr_val); | ||
343 | /* BAT writes happen so rarely that we're ok to flush | 318 | /* BAT writes happen so rarely that we're ok to flush |
344 | * everything here */ | 319 | * everything here */ |
345 | kvmppc_mmu_pte_flush(vcpu, 0, 0); | 320 | kvmppc_mmu_pte_flush(vcpu, 0, 0); |
346 | kvmppc_mmu_flush_segments(vcpu); | 321 | kvmppc_mmu_flush_segments(vcpu); |
347 | break; | 322 | break; |
323 | } | ||
348 | case SPRN_HID0: | 324 | case SPRN_HID0: |
349 | to_book3s(vcpu)->hid[0] = spr_val; | 325 | to_book3s(vcpu)->hid[0] = spr_val; |
350 | break; | 326 | break; |
@@ -434,8 +410,16 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) | |||
434 | case SPRN_IBAT4U ... SPRN_IBAT7L: | 410 | case SPRN_IBAT4U ... SPRN_IBAT7L: |
435 | case SPRN_DBAT0U ... SPRN_DBAT3L: | 411 | case SPRN_DBAT0U ... SPRN_DBAT3L: |
436 | case SPRN_DBAT4U ... SPRN_DBAT7L: | 412 | case SPRN_DBAT4U ... SPRN_DBAT7L: |
437 | kvmppc_set_gpr(vcpu, rt, kvmppc_read_bat(vcpu, sprn)); | 413 | { |
414 | struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn); | ||
415 | |||
416 | if (sprn % 2) | ||
417 | kvmppc_set_gpr(vcpu, rt, bat->raw >> 32); | ||
418 | else | ||
419 | kvmppc_set_gpr(vcpu, rt, bat->raw); | ||
420 | |||
438 | break; | 421 | break; |
422 | } | ||
439 | case SPRN_SDR1: | 423 | case SPRN_SDR1: |
440 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); | 424 | kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); |
441 | break; | 425 | break; |