aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-04-14 19:52:26 +1000
committerWang Sen <wangsen@linux.vnet.ibm.com>2014-04-16 11:15:21 +0800
commita758d7ee38f23bfb828f7e0abf470ca68191fe5c (patch)
tree0fb3eb03e532caeff1530478d30fd57df22bb6e1
parent6c71c41f52f9b763f52c333b781d939e9fbdba5f (diff)
downloadpowerkvm-a758d7ee38f23bfb828f7e0abf470ca68191fe5c.tar.gz
KVM: PPC: Book3S PR: Unimplemented SPRs in supervisor mode don't cause trap
The Power ISA states that an mtspr or mfspr to/from an unimplemented SPR should be a no-op in privileged mode, rather than causing an program interrupt (0x700 vector), with the exception of mtspr to SPR 0 and mfspr from SPRs 0, 4, 5 or 6. Currently our SPR emulation code doesn't follow this rule. This modifies the code in kvmppc_core_emulate_m[ft]spr_pr() to check the PR bit in the MSR when we detect an unknown SPR number, and only return EMULATE_FAIL (which results in a program interrupt) if PR is 0 or the SPR number is one of the ones which are specifically defined to cause a program interrupt. Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index f2f63c2304ff8..1829c0da44538 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -455,16 +455,18 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
case SPRN_WPAR_GEKKO:
case SPRN_MSSSR0:
break;
-unprivileged:
default:
- printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
-#ifndef DEBUG_SPR
- emulated = EMULATE_FAIL;
-#endif
+ if ((vcpu->arch.shared->msr & MSR_PR) || !sprn)
+ goto unprivileged;
break;
}
return emulated;
+
+unprivileged:
+ /* really want to do priv vs. illegal program interrupt */
+ printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
+ return EMULATE_FAIL;
}
int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
@@ -554,15 +556,18 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
*spr_val = 0;
break;
default:
-unprivileged:
- printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
-#ifndef DEBUG_SPR
- emulated = EMULATE_FAIL;
-#endif
+ if ((vcpu->arch.shared->msr & MSR_PR) || sprn == 0 ||
+ sprn == 4 || sprn == 5 || sprn == 6)
+ goto unprivileged;
break;
}
return emulated;
+
+unprivileged:
+ /* really want to do priv vs. illegal program interrupt */
+ printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
+ return EMULATE_FAIL;
}
u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)