[PATCH] KVM: PPC: Book3S PR: Do not fail emulation with mtspr/mfspr for unknown SPRs
Thomas Huth
thuth at redhat.com
Mon Apr 3 21:23:15 AEST 2017
According to the PowerISA 2.07, mtspr and mfspr should not generate
an illegal instruction exception when being used with an undefined SPR,
but rather treat the instruction as a NOP, inject a privilege exception
or an emulation assistance exception - depending on the SPR number.
Also turn the printk here into a ratelimited print statement, so that
the guest can not flood the dmesg log of the host by issueing lots of
illegal mtspr/mfspr instruction here.
Signed-off-by: Thomas Huth <thuth at redhat.com>
---
arch/powerpc/kvm/book3s.c | 1 +
arch/powerpc/kvm/book3s_emulate.c | 30 ++++++++++++++++++++++--------
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b6b5c18..9b007f9 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -137,6 +137,7 @@ void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec);
vcpu->arch.mmu.reset_msr(vcpu);
}
+EXPORT_SYMBOL_GPL(kvmppc_inject_interrupt);
static int kvmppc_book3s_vec2irqprio(unsigned int vec)
{
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 8359752..9c31e23 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -503,10 +503,16 @@ 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);
+ } else {
+ if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0)
+ kvmppc_inject_interrupt(vcpu,
+ BOOK3S_INTERRUPT_H_EMUL_ASSIST,
+ 0);
+ }
break;
}
@@ -648,10 +654,18 @@ 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);
+ } else {
+ if ((kvmppc_get_msr(vcpu) & MSR_PR) || sprn == 0 ||
+ sprn == 4 || sprn == 5 || sprn == 6)
+ kvmppc_inject_interrupt(vcpu,
+ BOOK3S_INTERRUPT_H_EMUL_ASSIST,
+ 0);
+ }
+
break;
}
--
1.8.3.1
More information about the Linuxppc-dev
mailing list