]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/kvm/book3s_emulate.c
Merge tag 'dmaengine-4.12-rc1' of git://git.infradead.org/users/vkoul/slave-dma
[karo-tx-linux.git] / arch / powerpc / kvm / book3s_emulate.c
index 8359752b3efcc616aa2509ee1bc0ae68f58deb44..68d68983948e13813221627e0dcfe743d1c91037 100644 (file)
@@ -503,10 +503,18 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
                break;
 unprivileged:
        default:
-               printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
-#ifndef DEBUG_SPR
-               emulated = EMULATE_FAIL;
-#endif
+               pr_info_ratelimited("KVM: invalid SPR write: %d\n", sprn);
+               if (sprn & 0x10) {
+                       if (kvmppc_get_msr(vcpu) & MSR_PR) {
+                               kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
+                               emulated = EMULATE_AGAIN;
+                       }
+               } else {
+                       if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0) {
+                               kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
+                               emulated = EMULATE_AGAIN;
+                       }
+               }
                break;
        }
 
@@ -648,10 +656,20 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
                break;
        default:
 unprivileged:
-               printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
-#ifndef DEBUG_SPR
-               emulated = EMULATE_FAIL;
-#endif
+               pr_info_ratelimited("KVM: invalid SPR read: %d\n", sprn);
+               if (sprn & 0x10) {
+                       if (kvmppc_get_msr(vcpu) & MSR_PR) {
+                               kvmppc_core_queue_program(vcpu, SRR1_PROGPRIV);
+                               emulated = EMULATE_AGAIN;
+                       }
+               } else {
+                       if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0 ||
+                           sprn == 4 || sprn == 5 || sprn == 6) {
+                               kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
+                               emulated = EMULATE_AGAIN;
+                       }
+               }
+
                break;
        }