aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2013-01-14 04:01:26 -0500
committerGleb Natapov <gleb@redhat.com>2013-01-14 04:01:26 -0500
commitaa11e3a8a6d9f92c3fe4b91a9aca5d8c23d55d4d (patch)
tree17e13edc8e1b9998fed9660f55b2873246d4376b /arch
parentf79ed82da494bc2ea677c6fc28b5439eacf4f5cc (diff)
parent324b3e63167bce69e6622c2be182595790bf7e38 (diff)
Merge branch 'kvm-ppc-next' of https://github.com/agraf/linux-2.6 into queue
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/kvm_host.h2
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h10
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h6
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c30
-rw-r--r--arch/powerpc/kvm/book3s_pr.c5
-rw-r--r--arch/powerpc/kvm/booke.c40
-rw-r--r--arch/powerpc/kvm/booke_emulate.c3
-rw-r--r--arch/powerpc/kvm/emulate.c5
-rw-r--r--arch/powerpc/kvm/powerpc.c13
9 files changed, 106 insertions, 8 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index ab49c6cf891c..8a72d59467eb 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -520,6 +520,8 @@ struct kvm_vcpu_arch {
520 u8 sane; 520 u8 sane;
521 u8 cpu_type; 521 u8 cpu_type;
522 u8 hcall_needed; 522 u8 hcall_needed;
523 u8 epr_enabled;
524 u8 epr_needed;
523 525
524 u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */ 526 u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
525 527
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 572aa7530619..493630e209c8 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);
@@ -263,6 +264,15 @@ static inline void kvm_linear_init(void)
263{} 264{}
264#endif 265#endif
265 266
267static inline void kvmppc_set_epr(struct kvm_vcpu *vcpu, u32 epr)
268{
269#ifdef CONFIG_KVM_BOOKE_HV
270 mtspr(SPRN_GEPR, epr);
271#elif defined(CONFIG_BOOKE)
272 vcpu->arch.epr = epr;
273#endif
274}
275
266int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, 276int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
267 struct kvm_config_tlb *cfg); 277 struct kvm_config_tlb *cfg);
268int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, 278int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 2fba8a66fb10..16064d00adb9 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -114,7 +114,10 @@ struct kvm_regs {
114/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */ 114/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
115#define KVM_SREGS_E_SPE (1 << 9) 115#define KVM_SREGS_E_SPE (1 << 9)
116 116
117/* External Proxy (EXP) -- EPR */ 117/*
118 * DEPRECATED! USE ONE_REG FOR THIS ONE!
119 * External Proxy (EXP) -- EPR
120 */
118#define KVM_SREGS_EXP (1 << 10) 121#define KVM_SREGS_EXP (1 << 10)
119 122
120/* External PID (E.PD) -- EPSC/EPLC */ 123/* External PID (E.PD) -- EPSC/EPLC */
@@ -412,5 +415,6 @@ struct kvm_get_htab_header {
412#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84) 415#define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)
413 416
414#define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85) 417#define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
418#define KVM_REG_PPC_EPR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)
415 419
416#endif /* __LINUX_KVM_POWERPC_H */ 420#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index d31a716f7f2b..836c56975e21 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:
@@ -427,6 +455,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
427 case SPRN_PMC3_GEKKO: 455 case SPRN_PMC3_GEKKO:
428 case SPRN_PMC4_GEKKO: 456 case SPRN_PMC4_GEKKO:
429 case SPRN_WPAR_GEKKO: 457 case SPRN_WPAR_GEKKO:
458 case SPRN_MSSSR0:
430 break; 459 break;
431unprivileged: 460unprivileged:
432 default: 461 default:
@@ -523,6 +552,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
523 case SPRN_PMC3_GEKKO: 552 case SPRN_PMC3_GEKKO:
524 case SPRN_PMC4_GEKKO: 553 case SPRN_PMC4_GEKKO:
525 case SPRN_WPAR_GEKKO: 554 case SPRN_WPAR_GEKKO:
555 case SPRN_MSSSR0:
526 *spr_val = 0; 556 *spr_val = 0;
527 break; 557 break;
528 default: 558 default:
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 }
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 69f114015780..8779cd4c52d9 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -300,13 +300,22 @@ static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr)
300#endif 300#endif
301} 301}
302 302
303static unsigned long get_guest_epr(struct kvm_vcpu *vcpu)
304{
305#ifdef CONFIG_KVM_BOOKE_HV
306 return mfspr(SPRN_GEPR);
307#else
308 return vcpu->arch.epr;
309#endif
310}
311
303/* Deliver the interrupt of the corresponding priority, if possible. */ 312/* Deliver the interrupt of the corresponding priority, if possible. */
304static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, 313static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
305 unsigned int priority) 314 unsigned int priority)
306{ 315{
307 int allowed = 0; 316 int allowed = 0;
308 ulong msr_mask = 0; 317 ulong msr_mask = 0;
309 bool update_esr = false, update_dear = false; 318 bool update_esr = false, update_dear = false, update_epr = false;
310 ulong crit_raw = vcpu->arch.shared->critical; 319 ulong crit_raw = vcpu->arch.shared->critical;
311 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1); 320 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
312 bool crit; 321 bool crit;
@@ -330,6 +339,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
330 keep_irq = true; 339 keep_irq = true;
331 } 340 }
332 341
342 if ((priority == BOOKE_IRQPRIO_EXTERNAL) && vcpu->arch.epr_enabled)
343 update_epr = true;
344
333 switch (priority) { 345 switch (priority) {
334 case BOOKE_IRQPRIO_DTLB_MISS: 346 case BOOKE_IRQPRIO_DTLB_MISS:
335 case BOOKE_IRQPRIO_DATA_STORAGE: 347 case BOOKE_IRQPRIO_DATA_STORAGE:
@@ -408,6 +420,8 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
408 set_guest_esr(vcpu, vcpu->arch.queued_esr); 420 set_guest_esr(vcpu, vcpu->arch.queued_esr);
409 if (update_dear == true) 421 if (update_dear == true)
410 set_guest_dear(vcpu, vcpu->arch.queued_dear); 422 set_guest_dear(vcpu, vcpu->arch.queued_dear);
423 if (update_epr == true)
424 kvm_make_request(KVM_REQ_EPR_EXIT, vcpu);
411 425
412 new_msr &= msr_mask; 426 new_msr &= msr_mask;
413#if defined(CONFIG_64BIT) 427#if defined(CONFIG_64BIT)
@@ -581,6 +595,11 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
581 595
582 kvmppc_core_check_exceptions(vcpu); 596 kvmppc_core_check_exceptions(vcpu);
583 597
598 if (vcpu->requests) {
599 /* Exception delivery raised request; start over */
600 return 1;
601 }
602
584 if (vcpu->arch.shared->msr & MSR_WE) { 603 if (vcpu->arch.shared->msr & MSR_WE) {
585 local_irq_enable(); 604 local_irq_enable();
586 kvm_vcpu_block(vcpu); 605 kvm_vcpu_block(vcpu);
@@ -610,6 +629,13 @@ int kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
610 r = 0; 629 r = 0;
611 } 630 }
612 631
632 if (kvm_check_request(KVM_REQ_EPR_EXIT, vcpu)) {
633 vcpu->run->epr.epr = 0;
634 vcpu->arch.epr_needed = true;
635 vcpu->run->exit_reason = KVM_EXIT_EPR;
636 r = 0;
637 }
638
613 return r; 639 return r;
614} 640}
615 641
@@ -1388,6 +1414,11 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
1388 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64)); 1414 &vcpu->arch.dbg_reg.dac[dac], sizeof(u64));
1389 break; 1415 break;
1390 } 1416 }
1417 case KVM_REG_PPC_EPR: {
1418 u32 epr = get_guest_epr(vcpu);
1419 r = put_user(epr, (u32 __user *)(long)reg->addr);
1420 break;
1421 }
1391#if defined(CONFIG_64BIT) 1422#if defined(CONFIG_64BIT)
1392 case KVM_REG_PPC_EPCR: 1423 case KVM_REG_PPC_EPCR:
1393 r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr); 1424 r = put_user(vcpu->arch.epcr, (u32 __user *)(long)reg->addr);
@@ -1420,6 +1451,13 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
1420 (u64 __user *)(long)reg->addr, sizeof(u64)); 1451 (u64 __user *)(long)reg->addr, sizeof(u64));
1421 break; 1452 break;
1422 } 1453 }
1454 case KVM_REG_PPC_EPR: {
1455 u32 new_epr;
1456 r = get_user(new_epr, (u32 __user *)(long)reg->addr);
1457 if (!r)
1458 kvmppc_set_epr(vcpu, new_epr);
1459 break;
1460 }
1423#if defined(CONFIG_64BIT) 1461#if defined(CONFIG_64BIT)
1424 case KVM_REG_PPC_EPCR: { 1462 case KVM_REG_PPC_EPCR: {
1425 u32 new_epcr; 1463 u32 new_epcr;
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 4685b8cf2249..27a4b2877c10 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -269,6 +269,9 @@ int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
269 case SPRN_ESR: 269 case SPRN_ESR:
270 *spr_val = vcpu->arch.shared->esr; 270 *spr_val = vcpu->arch.shared->esr;
271 break; 271 break;
272 case SPRN_EPR:
273 *spr_val = vcpu->arch.epr;
274 break;
272 case SPRN_CSRR0: 275 case SPRN_CSRR0:
273 *spr_val = vcpu->arch.csrr0; 276 *spr_val = vcpu->arch.csrr0;
274 break; 277 break;
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index b0855e5d8905..71abcf4e2bda 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -149,8 +149,6 @@ static int kvmppc_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
149 case SPRN_TBWL: break; 149 case SPRN_TBWL: break;
150 case SPRN_TBWU: break; 150 case SPRN_TBWU: break;
151 151
152 case SPRN_MSSSR0: break;
153
154 case SPRN_DEC: 152 case SPRN_DEC:
155 vcpu->arch.dec = spr_val; 153 vcpu->arch.dec = spr_val;
156 kvmppc_emulate_dec(vcpu); 154 kvmppc_emulate_dec(vcpu);
@@ -201,9 +199,6 @@ static int kvmppc_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
201 case SPRN_PIR: 199 case SPRN_PIR:
202 spr_val = vcpu->vcpu_id; 200 spr_val = vcpu->vcpu_id;
203 break; 201 break;
204 case SPRN_MSSSR0:
205 spr_val = 0;
206 break;
207 202
208 /* Note: mftb and TBRL/TBWL are user-accessible, so 203 /* Note: mftb and TBRL/TBWL are user-accessible, so
209 * the guest can always access the real TB anyways. 204 * the guest can always access the real TB anyways.
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index be83fca2e8fd..934413cd3a1b 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -237,7 +237,8 @@ int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu)
237 r = RESUME_HOST; 237 r = RESUME_HOST;
238 break; 238 break;
239 default: 239 default:
240 BUG(); 240 WARN_ON(1);
241 r = RESUME_GUEST;
241 } 242 }
242 243
243 return r; 244 return r;
@@ -305,6 +306,7 @@ int kvm_dev_ioctl_check_extension(long ext)
305#ifdef CONFIG_BOOKE 306#ifdef CONFIG_BOOKE
306 case KVM_CAP_PPC_BOOKE_SREGS: 307 case KVM_CAP_PPC_BOOKE_SREGS:
307 case KVM_CAP_PPC_BOOKE_WATCHDOG: 308 case KVM_CAP_PPC_BOOKE_WATCHDOG:
309 case KVM_CAP_PPC_EPR:
308#else 310#else
309 case KVM_CAP_PPC_SEGSTATE: 311 case KVM_CAP_PPC_SEGSTATE:
310 case KVM_CAP_PPC_HIOR: 312 case KVM_CAP_PPC_HIOR:
@@ -720,6 +722,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
720 for (i = 0; i < 9; ++i) 722 for (i = 0; i < 9; ++i)
721 kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]); 723 kvmppc_set_gpr(vcpu, 4 + i, run->papr_hcall.args[i]);
722 vcpu->arch.hcall_needed = 0; 724 vcpu->arch.hcall_needed = 0;
725#ifdef CONFIG_BOOKE
726 } else if (vcpu->arch.epr_needed) {
727 kvmppc_set_epr(vcpu, run->epr.epr);
728 vcpu->arch.epr_needed = 0;
729#endif
723 } 730 }
724 731
725 r = kvmppc_vcpu_run(run, vcpu); 732 r = kvmppc_vcpu_run(run, vcpu);
@@ -761,6 +768,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
761 r = 0; 768 r = 0;
762 vcpu->arch.papr_enabled = true; 769 vcpu->arch.papr_enabled = true;
763 break; 770 break;
771 case KVM_CAP_PPC_EPR:
772 r = 0;
773 vcpu->arch.epr_enabled = cap->args[0];
774 break;
764#ifdef CONFIG_BOOKE 775#ifdef CONFIG_BOOKE
765 case KVM_CAP_PPC_BOOKE_WATCHDOG: 776 case KVM_CAP_PPC_BOOKE_WATCHDOG:
766 r = 0; 777 r = 0;