aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-12-14 17:42:05 -0500
committerAlexander Graf <agraf@suse.de>2013-01-10 07:15:08 -0500
commit50c7bb80b5bd5a9962905306dd2292eeb9857d46 (patch)
treee3cdb57befb40b314f2ccceece50d9ab2477f2f9 /arch/powerpc
parent5a33169ed29060df71627103e6968078b42de945 (diff)
KVM: PPC: Book3S: PR: Enable alternative instruction for SC 1
When running on top of pHyp, the hypercall instruction "sc 1" goes straight into pHyp without trapping in supervisor mode. So if we want to support PAPR guest in this configuration we need to add a second way of accessing PAPR hypercalls, preferably with the exact same semantics except for the instruction. So let's overlay an officially reserved instruction and emulate PAPR hypercalls whenever we hit that one. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h1
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c28
-rw-r--r--arch/powerpc/kvm/book3s_pr.c5
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
49extern int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); 50extern 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 }