KVM: PPC: Book3S PR: Do not fail emulation with mtspr/mfspr for unknown SPRs
According to the PowerISA 2.07, mtspr and mfspr should not always generate an illegal instruction exception when being used with an undefined SPR, but rather treat the instruction as a NOP or inject a privilege exception in some cases, too - 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@redhat.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This commit is contained in:
Родитель
121f80ba68
Коммит
feafd13c96
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,10 +259,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
|
|||
|
||||
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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче