diff options
-rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_emulate.c | 28 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 5 |
3 files changed, 34 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 572aa7530619..5f5f69abd281 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -44,6 +44,7 @@ enum emulation_result { | |||
44 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ | 44 | EMULATE_DO_DCR, /* kvm_run filled with DCR request */ |
45 | EMULATE_FAIL, /* can't emulate this instruction */ | 45 | EMULATE_FAIL, /* can't emulate this instruction */ |
46 | EMULATE_AGAIN, /* something went wrong. go again */ | 46 | EMULATE_AGAIN, /* something went wrong. go again */ |
47 | EMULATE_DO_PAPR, /* kvm_run filled with PAPR request */ | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | 50 | extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); |
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index d31a716f7f2b..c88161bed8df 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #define OP_31_XOP_MTSRIN 242 | 34 | #define OP_31_XOP_MTSRIN 242 |
35 | #define OP_31_XOP_TLBIEL 274 | 35 | #define OP_31_XOP_TLBIEL 274 |
36 | #define OP_31_XOP_TLBIE 306 | 36 | #define OP_31_XOP_TLBIE 306 |
37 | /* Opcode is officially reserved, reuse it as sc 1 when sc 1 doesn't trap */ | ||
38 | #define OP_31_XOP_FAKE_SC1 308 | ||
37 | #define OP_31_XOP_SLBMTE 402 | 39 | #define OP_31_XOP_SLBMTE 402 |
38 | #define OP_31_XOP_SLBIE 434 | 40 | #define OP_31_XOP_SLBIE 434 |
39 | #define OP_31_XOP_SLBIA 498 | 41 | #define OP_31_XOP_SLBIA 498 |
@@ -170,6 +172,32 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
170 | vcpu->arch.mmu.tlbie(vcpu, addr, large); | 172 | vcpu->arch.mmu.tlbie(vcpu, addr, large); |
171 | break; | 173 | break; |
172 | } | 174 | } |
175 | #ifdef CONFIG_KVM_BOOK3S_64_PR | ||
176 | case OP_31_XOP_FAKE_SC1: | ||
177 | { | ||
178 | /* SC 1 papr hypercalls */ | ||
179 | ulong cmd = kvmppc_get_gpr(vcpu, 3); | ||
180 | int i; | ||
181 | |||
182 | if ((vcpu->arch.shared->msr & MSR_PR) || | ||
183 | !vcpu->arch.papr_enabled) { | ||
184 | emulated = EMULATE_FAIL; | ||
185 | break; | ||
186 | } | ||
187 | |||
188 | if (kvmppc_h_pr(vcpu, cmd) == EMULATE_DONE) | ||
189 | break; | ||
190 | |||
191 | run->papr_hcall.nr = cmd; | ||
192 | for (i = 0; i < 9; ++i) { | ||
193 | ulong gpr = kvmppc_get_gpr(vcpu, 4 + i); | ||
194 | run->papr_hcall.args[i] = gpr; | ||
195 | } | ||
196 | |||
197 | emulated = EMULATE_DO_PAPR; | ||
198 | break; | ||
199 | } | ||
200 | #endif | ||
173 | case OP_31_XOP_EIOIO: | 201 | case OP_31_XOP_EIOIO: |
174 | break; | 202 | break; |
175 | case OP_31_XOP_SLBMTE: | 203 | case OP_31_XOP_SLBMTE: |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 28d38adeca73..73ed11c41bac 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -760,6 +760,11 @@ program_interrupt: | |||
760 | run->exit_reason = KVM_EXIT_MMIO; | 760 | run->exit_reason = KVM_EXIT_MMIO; |
761 | r = RESUME_HOST_NV; | 761 | r = RESUME_HOST_NV; |
762 | break; | 762 | break; |
763 | case EMULATE_DO_PAPR: | ||
764 | run->exit_reason = KVM_EXIT_PAPR_HCALL; | ||
765 | vcpu->arch.hcall_needed = 1; | ||
766 | r = RESUME_HOST_NV; | ||
767 | break; | ||
763 | default: | 768 | default: |
764 | BUG(); | 769 | BUG(); |
765 | } | 770 | } |