diff options
-rw-r--r-- | arch/powerpc/include/asm/kvm_book3s.h | 38 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 2 |
2 files changed, 39 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 08891d07aeb6..fa19e2f1a874 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -334,6 +334,27 @@ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | |||
334 | return r; | 334 | return r; |
335 | } | 335 | } |
336 | 336 | ||
337 | /* | ||
338 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
339 | * Because the sc instruction sets SRR0 to point to the following | ||
340 | * instruction, we have to fetch from pc - 4. | ||
341 | */ | ||
342 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
343 | { | ||
344 | ulong pc = kvmppc_get_pc(vcpu) - 4; | ||
345 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | ||
346 | u32 r; | ||
347 | |||
348 | /* Load the instruction manually if it failed to do so in the | ||
349 | * exit path */ | ||
350 | if (svcpu->last_inst == KVM_INST_FETCH_FAILED) | ||
351 | kvmppc_ld(vcpu, &pc, sizeof(u32), &svcpu->last_inst, false); | ||
352 | |||
353 | r = svcpu->last_inst; | ||
354 | svcpu_put(svcpu); | ||
355 | return r; | ||
356 | } | ||
357 | |||
337 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 358 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
338 | { | 359 | { |
339 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); | 360 | struct kvmppc_book3s_shadow_vcpu *svcpu = svcpu_get(vcpu); |
@@ -446,6 +467,23 @@ static inline u32 kvmppc_get_last_inst(struct kvm_vcpu *vcpu) | |||
446 | return vcpu->arch.last_inst; | 467 | return vcpu->arch.last_inst; |
447 | } | 468 | } |
448 | 469 | ||
470 | /* | ||
471 | * Like kvmppc_get_last_inst(), but for fetching a sc instruction. | ||
472 | * Because the sc instruction sets SRR0 to point to the following | ||
473 | * instruction, we have to fetch from pc - 4. | ||
474 | */ | ||
475 | static inline u32 kvmppc_get_last_sc(struct kvm_vcpu *vcpu) | ||
476 | { | ||
477 | ulong pc = kvmppc_get_pc(vcpu) - 4; | ||
478 | |||
479 | /* Load the instruction manually if it failed to do so in the | ||
480 | * exit path */ | ||
481 | if (vcpu->arch.last_inst == KVM_INST_FETCH_FAILED) | ||
482 | kvmppc_ld(vcpu, &pc, sizeof(u32), &vcpu->arch.last_inst, false); | ||
483 | |||
484 | return vcpu->arch.last_inst; | ||
485 | } | ||
486 | |||
449 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) | 487 | static inline ulong kvmppc_get_fault_dar(struct kvm_vcpu *vcpu) |
450 | { | 488 | { |
451 | return vcpu->arch.fault_dar; | 489 | return vcpu->arch.fault_dar; |
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); |