diff options
-rw-r--r-- | arch/powerpc/include/asm/kvm_asm.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 19 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_emulate.c | 5 |
3 files changed, 24 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 7238c048e5bb..c5ea4cda34b3 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h | |||
@@ -89,6 +89,7 @@ | |||
89 | #define BOOK3S_HFLAG_DCBZ32 0x1 | 89 | #define BOOK3S_HFLAG_DCBZ32 0x1 |
90 | #define BOOK3S_HFLAG_SLB 0x2 | 90 | #define BOOK3S_HFLAG_SLB 0x2 |
91 | #define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 | 91 | #define BOOK3S_HFLAG_PAIRED_SINGLE 0x4 |
92 | #define BOOK3S_HFLAG_NATIVE_PS 0x8 | ||
92 | 93 | ||
93 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ | 94 | #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ |
94 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ | 95 | #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ |
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 397701d39ae7..9f97dbe25e4e 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -345,6 +345,8 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) | |||
345 | 345 | ||
346 | void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) | 346 | void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) |
347 | { | 347 | { |
348 | u32 host_pvr; | ||
349 | |||
348 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB; | 350 | vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB; |
349 | vcpu->arch.pvr = pvr; | 351 | vcpu->arch.pvr = pvr; |
350 | #ifdef CONFIG_PPC_BOOK3S_64 | 352 | #ifdef CONFIG_PPC_BOOK3S_64 |
@@ -376,6 +378,23 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr) | |||
376 | /* 32 bit Book3S always has 32 byte dcbz */ | 378 | /* 32 bit Book3S always has 32 byte dcbz */ |
377 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; | 379 | vcpu->arch.hflags |= BOOK3S_HFLAG_DCBZ32; |
378 | #endif | 380 | #endif |
381 | |||
382 | /* On some CPUs we can execute paired single operations natively */ | ||
383 | asm ( "mfpvr %0" : "=r"(host_pvr)); | ||
384 | switch (host_pvr) { | ||
385 | case 0x00080200: /* lonestar 2.0 */ | ||
386 | case 0x00088202: /* lonestar 2.2 */ | ||
387 | case 0x70000100: /* gekko 1.0 */ | ||
388 | case 0x00080100: /* gekko 2.0 */ | ||
389 | case 0x00083203: /* gekko 2.3a */ | ||
390 | case 0x00083213: /* gekko 2.3b */ | ||
391 | case 0x00083204: /* gekko 2.4 */ | ||
392 | case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ | ||
393 | case 0x00087200: /* broadway */ | ||
394 | vcpu->arch.hflags |= BOOK3S_HFLAG_NATIVE_PS; | ||
395 | /* Enable HID2.PSE - in case we need it later */ | ||
396 | mtspr(SPRN_HID2_GEKKO, mfspr(SPRN_HID2_GEKKO) | (1 << 29)); | ||
397 | } | ||
379 | } | 398 | } |
380 | 399 | ||
381 | /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To | 400 | /* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To |
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3f7afb5f3483..c85f906038ce 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
@@ -365,7 +365,10 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) | |||
365 | case 0x00083213: /* gekko 2.3b */ | 365 | case 0x00083213: /* gekko 2.3b */ |
366 | case 0x00083204: /* gekko 2.4 */ | 366 | case 0x00083204: /* gekko 2.4 */ |
367 | case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ | 367 | case 0x00083214: /* gekko 2.4e (8SE) - retail HW2 */ |
368 | if (spr_val & (1 << 29)) { /* HID2.PSE */ | 368 | case 0x00087200: /* broadway */ |
369 | if (vcpu->arch.hflags & BOOK3S_HFLAG_NATIVE_PS) { | ||
370 | /* Native paired singles */ | ||
371 | } else if (spr_val & (1 << 29)) { /* HID2.PSE */ | ||
369 | vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; | 372 | vcpu->arch.hflags |= BOOK3S_HFLAG_PAIRED_SINGLE; |
370 | kvmppc_giveup_ext(vcpu, MSR_FP); | 373 | kvmppc_giveup_ext(vcpu, MSR_FP); |
371 | } else { | 374 | } else { |