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;
        }
 
                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;
        }
 
 
 
                case OP_31_XOP_MFSPR:
                        emulated = kvmppc_emulate_mfspr(vcpu, sprn, rt);
+                       if (emulated == EMULATE_AGAIN) {
+                               emulated = EMULATE_DONE;
+                               advance = 0;
+                       }
                        break;
 
                case OP_31_XOP_MTSPR:
                        emulated = kvmppc_emulate_mtspr(vcpu, sprn, rs);
+                       if (emulated == EMULATE_AGAIN) {
+                               emulated = EMULATE_DONE;
+                               advance = 0;
+                       }
                        break;
 
                case OP_31_XOP_TLBSYNC: