diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kvm_asm.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 69 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.h | 38 | ||||
-rw-r--r-- | arch/powerpc/kvm/bookehv_interrupts.S | 16 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 16 |
6 files changed, 60 insertions, 93 deletions
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 6e9f858..851bac7 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -75,10 +75,6 @@ #define BOOKE_INTERRUPT_HV_SYSCALL 40 #define BOOKE_INTERRUPT_HV_PRIV 41 -/* altivec */ -#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42 -#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43 - /* book3s */ #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index d2579d8..9328ee6 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -386,12 +386,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, case BOOKE_IRQPRIO_ITLB_MISS: case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_FP_UNAVAIL: - case BOOKE_IRQPRIO_SPE_UNAVAIL: - case BOOKE_IRQPRIO_SPE_FP_DATA: + case BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL: + case BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST: case BOOKE_IRQPRIO_SPE_FP_ROUND: case BOOKE_IRQPRIO_AP_UNAVAIL: - case BOOKE_IRQPRIO_ALTIVEC_UNAVAIL: - case BOOKE_IRQPRIO_ALTIVEC_ASSIST: allowed = 1; msr_mask = MSR_CE | MSR_ME | MSR_DE; int_class = INT_CLASS_NONCRIT; @@ -1099,70 +1097,51 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, r = RESUME_GUEST; break; + case BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL: #ifdef CONFIG_SPE - case BOOKE_INTERRUPT_SPE_UNAVAIL: { if (vcpu->arch.shared->msr & MSR_SPE) kvmppc_vcpu_enable_spe(vcpu); else kvmppc_booke_queue_irqprio(vcpu, - BOOKE_IRQPRIO_SPE_UNAVAIL); - r = RESUME_GUEST; - break; - } - - case BOOKE_INTERRUPT_SPE_FP_DATA: - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA); - r = RESUME_GUEST; - break; - - case BOOKE_INTERRUPT_SPE_FP_ROUND: - kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND); - r = RESUME_GUEST; - break; + BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL); +#elif defined(CONFIG_ALTIVEC) + kvmppc_booke_queue_irqprio(vcpu, + BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL); #else - case BOOKE_INTERRUPT_SPE_UNAVAIL: /* - * Guest wants SPE, but host kernel doesn't support it. Send - * an "unimplemented operation" program check to the guest. + * Guest wants SPE/Altivec, but host kernel doesn't support + * it. Send an "unimplemented operation" program check to + * the guest. */ kvmppc_core_queue_program(vcpu, ESR_PUO | ESR_SPV); +#endif r = RESUME_GUEST; break; - /* - * These really should never happen without CONFIG_SPE, - * as we should never enable the real MSR[SPE] in the guest. - */ - case BOOKE_INTERRUPT_SPE_FP_DATA: - case BOOKE_INTERRUPT_SPE_FP_ROUND: - printk(KERN_CRIT "%s: unexpected SPE interrupt %u at %08lx\n", + case BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST: +#if defined(CONFIG_SPE) || defined(CONFIG_ALTIVEC) + kvmppc_booke_queue_irqprio(vcpu, + BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST); + r = RESUME_GUEST; +#else + printk(KERN_CRIT "%s: unexpected SPE/Altivec interrupt %u at %08lx\n", __func__, exit_nr, vcpu->arch.pc); run->hw.hardware_exit_reason = exit_nr; r = RESUME_HOST; - break; #endif - -#ifdef CONFIG_ALTIVEC - case BOOKE_INTERRUPT_ALTIVEC_UNAVAIL: - kvmppc_booke_queue_irqprio(vcpu, - BOOKE_IRQPRIO_ALTIVEC_UNAVAIL); - r = RESUME_GUEST; break; - case BOOKE_INTERRUPT_ALTIVEC_ASSIST: - kvmppc_booke_queue_irqprio(vcpu, - BOOKE_IRQPRIO_ALTIVEC_ASSIST); + case BOOKE_INTERRUPT_SPE_FP_ROUND: +#ifdef CONFIG_SPE + kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND); r = RESUME_GUEST; - break; #else - case BOOKE_INTERRUPT_ALTIVEC_UNAVAIL: - case BOOKE_INTERRUPT_ALTIVEC_ASSIST: - printk(KERN_CRIT "%s: unexpected AltiVec interrupt %u \ - at %08lx\n", __func__, exit_nr, vcpu->arch.pc); + printk(KERN_CRIT "%s: unexpected SPE interrupt %u at %08lx\n", + __func__, exit_nr, vcpu->arch.pc); run->hw.hardware_exit_reason = exit_nr; r = RESUME_HOST; - break; #endif + break; case BOOKE_INTERRUPT_DATA_STORAGE: kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear, diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index 59d1d4e..8b0861c 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h @@ -32,28 +32,26 @@ #define BOOKE_IRQPRIO_ALIGNMENT 2 #define BOOKE_IRQPRIO_PROGRAM 3 #define BOOKE_IRQPRIO_FP_UNAVAIL 4 -#define BOOKE_IRQPRIO_SPE_UNAVAIL 5 -#define BOOKE_IRQPRIO_SPE_FP_DATA 6 +#define BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL 5 +#define BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST 6 #define BOOKE_IRQPRIO_SPE_FP_ROUND 7 -#define BOOKE_IRQPRIO_ALTIVEC_UNAVAIL 8 -#define BOOKE_IRQPRIO_ALTIVEC_ASSIST 9 -#define BOOKE_IRQPRIO_SYSCALL 10 -#define BOOKE_IRQPRIO_AP_UNAVAIL 11 -#define BOOKE_IRQPRIO_DTLB_MISS 12 -#define BOOKE_IRQPRIO_ITLB_MISS 13 -#define BOOKE_IRQPRIO_MACHINE_CHECK 14 -#define BOOKE_IRQPRIO_DEBUG 15 -#define BOOKE_IRQPRIO_CRITICAL 16 -#define BOOKE_IRQPRIO_WATCHDOG 17 -#define BOOKE_IRQPRIO_EXTERNAL 18 -#define BOOKE_IRQPRIO_FIT 19 -#define BOOKE_IRQPRIO_DECREMENTER 20 -#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 21 +#define BOOKE_IRQPRIO_SYSCALL 8 +#define BOOKE_IRQPRIO_AP_UNAVAIL 9 +#define BOOKE_IRQPRIO_DTLB_MISS 10 +#define BOOKE_IRQPRIO_ITLB_MISS 11 +#define BOOKE_IRQPRIO_MACHINE_CHECK 12 +#define BOOKE_IRQPRIO_DEBUG 13 +#define BOOKE_IRQPRIO_CRITICAL 14 +#define BOOKE_IRQPRIO_WATCHDOG 15 +#define BOOKE_IRQPRIO_EXTERNAL 16 +#define BOOKE_IRQPRIO_FIT 17 +#define BOOKE_IRQPRIO_DECREMENTER 18 +#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19 /* Internal pseudo-irqprio for level triggered externals */ -#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 22 -#define BOOKE_IRQPRIO_DBELL 23 -#define BOOKE_IRQPRIO_DBELL_CRIT 24 -#define BOOKE_IRQPRIO_MAX 25 +#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20 +#define BOOKE_IRQPRIO_DBELL 21 +#define BOOKE_IRQPRIO_DBELL_CRIT 22 +#define BOOKE_IRQPRIO_MAX 23 #define BOOKE_IRQMASK_EE ((1 << BOOKE_IRQPRIO_EXTERNAL_LEVEL) | \ (1 << BOOKE_IRQPRIO_PERFORMANCE_MONITOR) | \ diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index 6a10ee7..63ce811 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S @@ -253,10 +253,10 @@ kvm_handler BOOKE_INTERRUPT_DTLB_MISS, EX_PARAMS_TLB, \ SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) kvm_handler BOOKE_INTERRUPT_ITLB_MISS, EX_PARAMS_TLB, \ SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, EX_PARAMS(GEN), \ - SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, EX_PARAMS(GEN), \ - SPRN_SRR0, SPRN_SRR1, 0 +kvm_handler BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL, EX_PARAMS(GEN), \ + SPRN_SRR0, SPRN_SRR1, NEED_ESR +kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST, EX_PARAMS(GEN), \ + SPRN_SRR0, SPRN_SRR1, NEED_ESR kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, EX_PARAMS(GEN), \ SPRN_SRR0, SPRN_SRR1, 0 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, EX_PARAMS(GEN), \ @@ -277,10 +277,6 @@ kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(DBG), \ SPRN_DSRR0, SPRN_DSRR1, 0 kvm_handler BOOKE_INTERRUPT_DEBUG, EX_PARAMS(CRIT), \ SPRN_CSRR0, SPRN_CSRR1, 0 -kvm_handler BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, EX_PARAMS(GEN), \ - SPRN_SRR0, SPRN_SRR1, NEED_ESR -kvm_handler BOOKE_INTERRUPT_ALTIVEC_ASSIST, EX_PARAMS(GEN), \ - SPRN_SRR0, SPRN_SRR1, NEED_ESR #else /* * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h @@ -360,8 +356,8 @@ kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \ kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \ SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR) kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 -kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, SPRN_SRR0, SPRN_SRR1, 0 +kvm_handler BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0 +kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST, SPRN_SRR0, SPRN_SRR1, 0 kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, SPRN_SRR1, 0 kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0 diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index c82a89f..ed19bdd 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -380,8 +380,10 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0; sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar; - sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; - sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; + sregs->u.e.ivor_high[0] = + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL]; + sregs->u.e.ivor_high[1] = + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST]; sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; sregs->u.e.ivor_high[3] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; @@ -409,9 +411,9 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) return 0; if (sregs->u.e.features & KVM_SREGS_E_SPE) { - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL] = sregs->u.e.ivor_high[0]; - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST] = sregs->u.e.ivor_high[1]; vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = sregs->u.e.ivor_high[2]; diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 1e29aa8..31b1a63 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -234,12 +234,11 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) /* extra exceptions */ case SPRN_IVOR32: - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; - vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val; + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL] = spr_val; break; case SPRN_IVOR33: - vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = spr_val; - vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST] = spr_val; + vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST] = + spr_val; break; case SPRN_IVOR34: vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val; @@ -358,14 +357,11 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) /* extra exceptions */ case SPRN_IVOR32: - WARN_ON_ONCE(vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] != - vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL]); - *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; + *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_ALTIVEC_UNAVAIL]; break; case SPRN_IVOR33: - WARN_ON_ONCE(vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] != - vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST]); - *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; + *spr_val = vcpu->arch.ivor[ + BOOKE_IRQPRIO_SPE_FP_DATA_ALTIVEC_ASSIST]; break; case SPRN_IVOR34: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; |