diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index e726d76..7a35c64 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2253,6 +2253,32 @@ The possible hypercalls are defined in the Power Architecture Platform
 Requirements (PAPR) document available from www.power.org (free
 developer registration required to access it).
 
+		/* KVM_EXIT_SPR */
+		struct {
+			__u64 sprn;
+			__u64 data;
+			__u64 msr;
+			__u8  is_write;
+#define SPR_STATUS_OK   0
+#define SPR_STATUS_FAIL 1
+			__u8  status;
+		} spr;
+
+This is used on PowerPC for Special Purpose Register emulation that
+the kernel can not deal with.
+
+It occurs when the guest triggers an mtspr or mfspr instruction on
+an SPR that is not handled by kvm's SPR emulation code. In these
+cases, 'sprn' contains the SPR ID. That ID is target CPU specific.
+'data' contains the value to write to the SPR when 'is_write'==1 (mtspr)
+or is used as result buffer for 'is_write'==0 (mfspr). Status is used
+to tell the kernel that an SPR read/write was successful. It is set to
+SPR_STATUS_OK by default. If user space fails to emulate an SPR access,
+it should set it to SPR_STATUS_FAIL, so that the kernel can inject
+an exception into the guest context. The field 'msr' contains the MSR
+register state at the point of time the SPR read/write occured. It can
+be used by user space for permission checks.
+
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -2374,3 +2400,14 @@ For mmu types KVM_MMU_FSL_BOOKE_NOHV and KVM_MMU_FSL_BOOKE_HV:
    where "num_sets" is the tlb_sizes[] value divided by the tlb_ways[] value.
  - The tsize field of mas1 shall be set to 4K on TLB0, even though the
    hardware ignores this value for TLB0.
+
+6.4 KVM_CAP_PPC_SPR_EXIT
+
+Architectures: ppc
+Parameters: none
+Returns: 0 on success; -1 on error
+
+With this CAP enabled, KVM returns KVM_EXIT_SPR exits to have user space emulate
+SPRs that it can not handle itself.
+
+When this capability is enabled, KVM_EXIT_SPR can occur.
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 68f5a30..d72ea96 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -510,6 +510,9 @@ struct kvm_vcpu_arch {
 	u8 osi_enabled;
 	u8 papr_enabled;
 	u8 watchdog_enabled;
+	u8 spr_needed;
+	u8 spr_is_write;
+	u8 spr_exit_enabled;
 	u8 sane;
 	u8 cpu_type;
 	u8 hcall_needed;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 609cca3..f9cdd42 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -42,6 +42,7 @@ enum emulation_result {
 	EMULATE_DONE,         /* no further processing */
 	EMULATE_DO_MMIO,      /* kvm_run filled with MMIO request */
 	EMULATE_DO_DCR,       /* kvm_run filled with DCR request */
+	EMULATE_DO_SPR,       /* kvm_run filled with SPR request */
 	EMULATE_FAIL,         /* can't emulate this instruction */
 	EMULATE_AGAIN,        /* something went wrong. go again */
 };
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index b853696..8d4dbc8 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -748,6 +748,10 @@ program_interrupt:
 			run->exit_reason = KVM_EXIT_MMIO;
 			r = RESUME_HOST_NV;
 			break;
+		case EMULATE_DO_SPR:
+			run->exit_reason = KVM_EXIT_SPR;
+			r = RESUME_HOST_NV;
+			break;
 		default:
 			BUG();
 		}
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 3d1f35d..07fff68 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -694,6 +694,10 @@ static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		run->exit_reason = KVM_EXIT_DCR;
 		return RESUME_HOST;
 
+	case EMULATE_DO_SPR:
+		run->exit_reason = KVM_EXIT_SPR;
+		return RESUME_HOST;
+
 	case EMULATE_FAIL:
 		printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
 		       __func__, vcpu->arch.pc, vcpu->arch.last_inst);
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index b0855e5..c35cec5 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -172,9 +172,23 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 	default:
 		emulated = kvmppc_core_emulate_mtspr(vcpu, sprn,
 						     spr_val);
-		if (emulated == EMULATE_FAIL)
-			printk(KERN_INFO "mtspr: unknown spr "
-				"0x%x\n", sprn);
+		if (unlikely(emulated == EMULATE_FAIL)) {
+			if (vcpu->arch.spr_exit_enabled) {
+				/* In-kernel code can't handle this SPR.
+				   Forward it on to user space */
+				vcpu->run->spr.sprn = sprn;
+				vcpu->run->spr.data =  spr_val;
+				vcpu->run->spr.is_write = 1;
+				vcpu->run->spr.status = SPR_STATUS_OK;
+				vcpu->run->spr.msr = vcpu->arch.shared->msr;
+				vcpu->arch.spr_is_write = 1;
+				vcpu->arch.spr_needed = 1;
+				emulated = EMULATE_DO_SPR;
+			} else {
+				printk(KERN_INFO "mfspr: unknown spr "
+					"0x%x\n", sprn);
+			}
+		}
 		break;
 	}
 
@@ -237,8 +251,22 @@ static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 		emulated = kvmppc_core_emulate_mfspr(vcpu, sprn,
 						     &spr_val);
 		if (unlikely(emulated == EMULATE_FAIL)) {
-			printk(KERN_INFO "mfspr: unknown spr "
-				"0x%x\n", sprn);
+			if (vcpu->arch.spr_exit_enabled) {
+				/* In-kernel code can't handle this SPR.
+				   Forward it on to user space */
+				vcpu->run->spr.sprn = sprn;
+				vcpu->run->spr.data = 0;
+				vcpu->run->spr.is_write = 0;
+				vcpu->run->spr.status = SPR_STATUS_OK;
+				vcpu->run->spr.msr = vcpu->arch.shared->msr;
+				vcpu->arch.spr_is_write = 0;
+				vcpu->arch.io_gpr = rt;
+				vcpu->arch.spr_needed = 1;
+				emulated = EMULATE_DO_SPR;
+			} else {
+				printk(KERN_INFO "mfspr: unknown spr "
+					"0x%x\n", sprn);
+			}
 		}
 		break;
 	}
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index deb0d59..7d120dc 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -530,6 +530,12 @@ static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
 	kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->dcr.data);
 }
 
+static void kvmppc_complete_spr_load(struct kvm_vcpu *vcpu,
+                                     struct kvm_run *run)
+{
+	kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, run->spr.data);
+}
+
 static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
                                       struct kvm_run *run)
 {
@@ -680,6 +686,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (!vcpu->arch.dcr_is_write)
 			kvmppc_complete_dcr_load(vcpu, run);
 		vcpu->arch.dcr_needed = 0;
+	} else if (vcpu->arch.spr_needed) {
+		int flags = 0;
+		if (!vcpu->arch.spr_is_write)
+			kvmppc_complete_spr_load(vcpu, run);
+#if !defined(CONFIG_PPC_BOOK3S)
+		/* Indicate an illegal instruction for BookE */
+		flags = ESR_PIL;
+#endif
+		kvmppc_core_queue_program(vcpu, flags);
+		vcpu->arch.spr_needed = 0;
 	} else if (vcpu->arch.osi_needed) {
 		u64 *gprs = run->osi.gprs;
 		int i;
@@ -735,6 +751,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
 		r = 0;
 		vcpu->arch.papr_enabled = true;
 		break;
+	case KVM_CAP_PPC_SPR_EXIT:
+		r = 0;
+		vcpu->arch.spr_exit_enabled = true;
+		break;
 #ifdef CONFIG_BOOKE
 	case KVM_CAP_PPC_BOOKE_WATCHDOG:
 		r = 0;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 65ad5c6..2e8f536 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -168,6 +168,7 @@ struct kvm_pit_config {
 #define KVM_EXIT_PAPR_HCALL	  19
 #define KVM_EXIT_S390_UCONTROL	  20
 #define KVM_EXIT_WATCHDOG         21
+#define KVM_EXIT_SPR              22
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 #define KVM_INTERNAL_ERROR_EMULATION 1
@@ -281,6 +282,16 @@ struct kvm_run {
 			__u64 ret;
 			__u64 args[9];
 		} papr_hcall;
+		/* KVM_EXIT_SPR */
+		struct {
+			__u64 sprn;
+			__u64 data;
+			__u64 msr;
+			__u8  is_write;
+#define SPR_STATUS_OK   0
+#define SPR_STATUS_FAIL 1
+			__u8  status;
+		} spr;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -630,6 +641,7 @@ struct kvm_ppc_smmu_info {
 #endif
 #define KVM_CAP_IRQFD_RESAMPLE 82
 #define KVM_CAP_PPC_BOOKE_WATCHDOG 83
+#define KVM_CAP_PPC_SPR_EXIT 84
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
