diff options
author | Paul Mackerras <paulus@samba.org> | 2013-08-06 00:15:19 -0400 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-08-28 10:47:49 -0400 |
commit | 8b23de29489fd63fce753db9d53055e4bbf8f616 (patch) | |
tree | 94e266d8d7029bbb411568454d0c4df56b52d5fd /arch/powerpc/kvm | |
parent | 9d1ffdd8f34b1f89264effd10e75ea4d6272690e (diff) |
KVM: PPC: Book3S PR: Make instruction fetch fallback work for system calls
It turns out that if we exit the guest due to a hcall instruction (sc 1),
and the loading of the instruction in the guest exit path fails for any
reason, the call to kvmppc_ld() in kvmppc_get_last_inst() fetches the
instruction after the hcall instruction rather than the hcall itself.
This in turn means that the instruction doesn't get recognized as an
hcall in kvmppc_handle_exit_pr() but gets passed to the guest kernel
as a sc instruction. That usually results in the guest kernel getting
a return code of 38 (ENOSYS) from an hcall, which often triggers a
BUG_ON() or other failure.
This fixes the problem by adding a new variant of kvmppc_get_last_inst()
called kvmppc_get_last_sc(), which fetches the instruction if necessary
from pc - 4 rather than pc.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm')
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 983e5eda892f..27db1e665959 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -792,7 +792,7 @@ program_interrupt: | |||
792 | } | 792 | } |
793 | case BOOK3S_INTERRUPT_SYSCALL: | 793 | case BOOK3S_INTERRUPT_SYSCALL: |
794 | if (vcpu->arch.papr_enabled && | 794 | if (vcpu->arch.papr_enabled && |
795 | (kvmppc_get_last_inst(vcpu) == 0x44000022) && | 795 | (kvmppc_get_last_sc(vcpu) == 0x44000022) && |
796 | !(vcpu->arch.shared->msr & MSR_PR)) { | 796 | !(vcpu->arch.shared->msr & MSR_PR)) { |
797 | /* SC 1 papr hypercalls */ | 797 | /* SC 1 papr hypercalls */ |
798 | ulong cmd = kvmppc_get_gpr(vcpu, 3); | 798 | ulong cmd = kvmppc_get_gpr(vcpu, 3); |