Message ID | 1407235175-30994-3-git-send-email-mihai.caraman@freescale.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 05.08.14 12:39, Mihai Caraman wrote: > Add KVM Book3e AltiVec support. KVM Book3e FPU support gracefully reuse host > infrastructure so follow the same approach for AltiVec. > > Keep SPE/AltiVec exception handlers distinct using CONFIG_KVM_E500V2. > > Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> > --- > v3: > - use distinct SPE/AltiVec exception handlers > > v2: > - integrate Paul's FP/VMX/VSX changes > > arch/powerpc/kvm/booke.c | 73 +++++++++++++++++++++++++++++++++++ > arch/powerpc/kvm/booke.h | 5 +++ > arch/powerpc/kvm/bookehv_interrupts.S | 10 +++-- > arch/powerpc/kvm/e500_emulate.c | 18 +++++++++ > 4 files changed, 102 insertions(+), 4 deletions(-) > > diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c > index 0c6f616..c5cca09 100644 > --- a/arch/powerpc/kvm/booke.c > +++ b/arch/powerpc/kvm/booke.c > @@ -168,6 +168,40 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) > #endif > } > > +/* > + * Simulate AltiVec unavailable fault to load guest state > + * from thread to AltiVec unit. > + * It requires to be called with preemption disabled. > + */ > +static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu) > +{ > +#ifdef CONFIG_ALTIVEC > + if (cpu_has_feature(CPU_FTR_ALTIVEC)) { > + if (!(current->thread.regs->msr & MSR_VEC)) { > + enable_kernel_altivec(); > + load_vr_state(&vcpu->arch.vr); > + current->thread.vr_save_area = &vcpu->arch.vr; > + current->thread.regs->msr |= MSR_VEC; > + } > + } > +#endif > +} > + > +/* > + * Save guest vcpu AltiVec state into thread. > + * It requires to be called with preemption disabled. > + */ > +static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu) > +{ > +#ifdef CONFIG_ALTIVEC > + if (cpu_has_feature(CPU_FTR_ALTIVEC)) { > + if (current->thread.regs->msr & MSR_VEC) > + giveup_altivec(current); > + current->thread.vr_save_area = NULL; > + } > +#endif > +} > + > static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) > { > /* Synchronize guest's desire to get debug interrupts into shadow MSR */ > @@ -375,9 +409,14 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, > case BOOKE_IRQPRIO_ITLB_MISS: > case BOOKE_IRQPRIO_SYSCALL: > case BOOKE_IRQPRIO_FP_UNAVAIL: > +#ifdef CONFIG_KVM_E500V2 Why not use your new SPE_POSSIBLE define? > case BOOKE_IRQPRIO_SPE_UNAVAIL: > case BOOKE_IRQPRIO_SPE_FP_DATA: > case BOOKE_IRQPRIO_SPE_FP_ROUND: > +#else We only ever support altivec capable CPUs with CONFIG_ALTIVEC, no? So just make this a new #ifdef CONFIG_ALTIVEC > + case BOOKE_IRQPRIO_ALTIVEC_UNAVAIL: > + case BOOKE_IRQPRIO_ALTIVEC_ASSIST: > +#endif > case BOOKE_IRQPRIO_AP_UNAVAIL: > allowed = 1; > msr_mask = MSR_CE | MSR_ME | MSR_DE; > @@ -693,6 +732,17 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) > kvmppc_load_guest_fp(vcpu); > #endif > > +#ifdef CONFIG_ALTIVEC > + /* Save userspace AltiVec state in stack */ > + if (cpu_has_feature(CPU_FTR_ALTIVEC)) > + enable_kernel_altivec(); > + /* > + * Since we can't trap on MSR_VEC in GS-mode, we consider the guest > + * as always using the AltiVec. > + */ > + kvmppc_load_guest_altivec(vcpu); > +#endif > + > /* Switch to guest debug context */ > debug = vcpu->arch.shadow_dbg_reg; > switch_booke_debug_regs(&debug); > @@ -715,6 +765,10 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) > kvmppc_save_guest_fp(vcpu); > #endif > > +#ifdef CONFIG_ALTIVEC > + kvmppc_save_guest_altivec(vcpu); > +#endif > + > out: > vcpu->mode = OUTSIDE_GUEST_MODE; > return ret; > @@ -999,6 +1053,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, > r = RESUME_GUEST; > break; > > +#ifdef CONFIG_KVM_E500V2 Why? We're already guarded by CONFIG_SPE > #ifdef CONFIG_SPE > case BOOKE_INTERRUPT_SPE_UNAVAIL: { > if (vcpu->arch.shared->msr & MSR_SPE) > @@ -1040,7 +1095,24 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, > run->hw.hardware_exit_reason = exit_nr; > r = RESUME_HOST; > break; > +#endif /* !CONFIG_SPE */ > +#else > +/* > + * On cores with Vector category, KVM is loaded only if CONFIG_ALTIVEC, > + * see kvmppc_core_check_processor_compat(). > + */ > +#ifdef CONFIG_ALTIVEC ... and 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); > + r = RESUME_GUEST; > + break; > #endif > +#endif /* !CONFIG_KVM_E500V2 */ > > case BOOKE_INTERRUPT_DATA_STORAGE: > kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear, > @@ -1217,6 +1289,7 @@ out: > /* interrupts now hard-disabled */ > kvmppc_fix_ee_before_entry(); > kvmppc_load_guest_fp(vcpu); > + kvmppc_load_guest_altivec(vcpu); > } > } > > diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h > index e73d513..ce5b543 100644 > --- a/arch/powerpc/kvm/booke.h > +++ b/arch/powerpc/kvm/booke.h > @@ -32,9 +32,14 @@ > #define BOOKE_IRQPRIO_ALIGNMENT 2 > #define BOOKE_IRQPRIO_PROGRAM 3 > #define BOOKE_IRQPRIO_FP_UNAVAIL 4 > +#ifdef CONFIG_KVM_E500V2 Same comments as above > #define BOOKE_IRQPRIO_SPE_UNAVAIL 5 > #define BOOKE_IRQPRIO_SPE_FP_DATA 6 > #define BOOKE_IRQPRIO_SPE_FP_ROUND 7 > +#else > +#define BOOKE_IRQPRIO_ALTIVEC_UNAVAIL 5 > +#define BOOKE_IRQPRIO_ALTIVEC_ASSIST 6 > +#endif > #define BOOKE_IRQPRIO_SYSCALL 8 > #define BOOKE_IRQPRIO_AP_UNAVAIL 9 > #define BOOKE_IRQPRIO_DTLB_MISS 10 > diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S > index e9fa56a..1d7c4d6 100644 > --- a/arch/powerpc/kvm/bookehv_interrupts.S > +++ b/arch/powerpc/kvm/bookehv_interrupts.S > @@ -256,11 +256,9 @@ 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), \ > +kvm_handler BOOKE_INTERRUPT_ALTIVEC_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_FP_ROUND, EX_PARAMS(GEN), \ > +kvm_handler BOOKE_INTERRUPT_ALTIVEC_ASSIST, EX_PARAMS(GEN), \ > SPRN_SRR0, SPRN_SRR1, 0 > kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, EX_PARAMS(GEN), \ > SPRN_SRR0, SPRN_SRR1, 0 > @@ -361,6 +359,10 @@ 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 > +/* > + * TODO: SPE handlers should be available only for e500v2 cores. > + * HV does not target e500v2 so remove them after kernel cleanup. > + */ Let's do the cleanup first, then apply these patches. > 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_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0 > diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c > index c99c40e..e6e0429 100644 > --- a/arch/powerpc/kvm/e500_emulate.c > +++ b/arch/powerpc/kvm/e500_emulate.c > @@ -259,6 +259,7 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va > break; > > /* extra exceptions */ > +#ifdef CONFIG_KVM_E500V2 Same comments as above > case SPRN_IVOR32: > vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; > break; > @@ -268,6 +269,14 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va > case SPRN_IVOR34: > vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val; > break; > +#else > + case SPRN_IVOR32: > + vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val; > + break; > + case SPRN_IVOR33: > + vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST] = spr_val; > + break; > +#endif > case SPRN_IVOR35: > vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; > break; > @@ -381,6 +390,7 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v > break; > > /* extra exceptions */ > +#ifdef CONFIG_KVM_E500V2 Here too. Alex > case SPRN_IVOR32: > *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; > break; > @@ -390,6 +400,14 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v > case SPRN_IVOR34: > *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; > break; > +#else > + case SPRN_IVOR32: > + *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL]; > + break; > + case SPRN_IVOR33: > + *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST]; > + break; > +#endif > case SPRN_IVOR35: > *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; > break; -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 0c6f616..c5cca09 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -168,6 +168,40 @@ static void kvmppc_vcpu_sync_fpu(struct kvm_vcpu *vcpu) #endif } +/* + * Simulate AltiVec unavailable fault to load guest state + * from thread to AltiVec unit. + * It requires to be called with preemption disabled. + */ +static inline void kvmppc_load_guest_altivec(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) { + if (!(current->thread.regs->msr & MSR_VEC)) { + enable_kernel_altivec(); + load_vr_state(&vcpu->arch.vr); + current->thread.vr_save_area = &vcpu->arch.vr; + current->thread.regs->msr |= MSR_VEC; + } + } +#endif +} + +/* + * Save guest vcpu AltiVec state into thread. + * It requires to be called with preemption disabled. + */ +static inline void kvmppc_save_guest_altivec(struct kvm_vcpu *vcpu) +{ +#ifdef CONFIG_ALTIVEC + if (cpu_has_feature(CPU_FTR_ALTIVEC)) { + if (current->thread.regs->msr & MSR_VEC) + giveup_altivec(current); + current->thread.vr_save_area = NULL; + } +#endif +} + static void kvmppc_vcpu_sync_debug(struct kvm_vcpu *vcpu) { /* Synchronize guest's desire to get debug interrupts into shadow MSR */ @@ -375,9 +409,14 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, case BOOKE_IRQPRIO_ITLB_MISS: case BOOKE_IRQPRIO_SYSCALL: case BOOKE_IRQPRIO_FP_UNAVAIL: +#ifdef CONFIG_KVM_E500V2 case BOOKE_IRQPRIO_SPE_UNAVAIL: case BOOKE_IRQPRIO_SPE_FP_DATA: case BOOKE_IRQPRIO_SPE_FP_ROUND: +#else + case BOOKE_IRQPRIO_ALTIVEC_UNAVAIL: + case BOOKE_IRQPRIO_ALTIVEC_ASSIST: +#endif case BOOKE_IRQPRIO_AP_UNAVAIL: allowed = 1; msr_mask = MSR_CE | MSR_ME | MSR_DE; @@ -693,6 +732,17 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_load_guest_fp(vcpu); #endif +#ifdef CONFIG_ALTIVEC + /* Save userspace AltiVec state in stack */ + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + enable_kernel_altivec(); + /* + * Since we can't trap on MSR_VEC in GS-mode, we consider the guest + * as always using the AltiVec. + */ + kvmppc_load_guest_altivec(vcpu); +#endif + /* Switch to guest debug context */ debug = vcpu->arch.shadow_dbg_reg; switch_booke_debug_regs(&debug); @@ -715,6 +765,10 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) kvmppc_save_guest_fp(vcpu); #endif +#ifdef CONFIG_ALTIVEC + kvmppc_save_guest_altivec(vcpu); +#endif + out: vcpu->mode = OUTSIDE_GUEST_MODE; return ret; @@ -999,6 +1053,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, r = RESUME_GUEST; break; +#ifdef CONFIG_KVM_E500V2 #ifdef CONFIG_SPE case BOOKE_INTERRUPT_SPE_UNAVAIL: { if (vcpu->arch.shared->msr & MSR_SPE) @@ -1040,7 +1095,24 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run->hw.hardware_exit_reason = exit_nr; r = RESUME_HOST; break; +#endif /* !CONFIG_SPE */ +#else +/* + * On cores with Vector category, KVM is loaded only if CONFIG_ALTIVEC, + * see kvmppc_core_check_processor_compat(). + */ +#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); + r = RESUME_GUEST; + break; #endif +#endif /* !CONFIG_KVM_E500V2 */ case BOOKE_INTERRUPT_DATA_STORAGE: kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear, @@ -1217,6 +1289,7 @@ out: /* interrupts now hard-disabled */ kvmppc_fix_ee_before_entry(); kvmppc_load_guest_fp(vcpu); + kvmppc_load_guest_altivec(vcpu); } } diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h index e73d513..ce5b543 100644 --- a/arch/powerpc/kvm/booke.h +++ b/arch/powerpc/kvm/booke.h @@ -32,9 +32,14 @@ #define BOOKE_IRQPRIO_ALIGNMENT 2 #define BOOKE_IRQPRIO_PROGRAM 3 #define BOOKE_IRQPRIO_FP_UNAVAIL 4 +#ifdef CONFIG_KVM_E500V2 #define BOOKE_IRQPRIO_SPE_UNAVAIL 5 #define BOOKE_IRQPRIO_SPE_FP_DATA 6 #define BOOKE_IRQPRIO_SPE_FP_ROUND 7 +#else +#define BOOKE_IRQPRIO_ALTIVEC_UNAVAIL 5 +#define BOOKE_IRQPRIO_ALTIVEC_ASSIST 6 +#endif #define BOOKE_IRQPRIO_SYSCALL 8 #define BOOKE_IRQPRIO_AP_UNAVAIL 9 #define BOOKE_IRQPRIO_DTLB_MISS 10 diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S index e9fa56a..1d7c4d6 100644 --- a/arch/powerpc/kvm/bookehv_interrupts.S +++ b/arch/powerpc/kvm/bookehv_interrupts.S @@ -256,11 +256,9 @@ 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), \ +kvm_handler BOOKE_INTERRUPT_ALTIVEC_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_FP_ROUND, EX_PARAMS(GEN), \ +kvm_handler BOOKE_INTERRUPT_ALTIVEC_ASSIST, EX_PARAMS(GEN), \ SPRN_SRR0, SPRN_SRR1, 0 kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, EX_PARAMS(GEN), \ SPRN_SRR0, SPRN_SRR1, 0 @@ -361,6 +359,10 @@ 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 +/* + * TODO: SPE handlers should be available only for e500v2 cores. + * HV does not target e500v2 so remove them after kernel cleanup. + */ 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_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0 diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index c99c40e..e6e0429 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c @@ -259,6 +259,7 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va break; /* extra exceptions */ +#ifdef CONFIG_KVM_E500V2 case SPRN_IVOR32: vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = spr_val; break; @@ -268,6 +269,14 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va case SPRN_IVOR34: vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = spr_val; break; +#else + case SPRN_IVOR32: + vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL] = spr_val; + break; + case SPRN_IVOR33: + vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST] = spr_val; + break; +#endif case SPRN_IVOR35: vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; break; @@ -381,6 +390,7 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v break; /* extra exceptions */ +#ifdef CONFIG_KVM_E500V2 case SPRN_IVOR32: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; break; @@ -390,6 +400,14 @@ int kvmppc_core_emulate_mfspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong *spr_v case SPRN_IVOR34: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; break; +#else + case SPRN_IVOR32: + *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_UNAVAIL]; + break; + case SPRN_IVOR33: + *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALTIVEC_ASSIST]; + break; +#endif case SPRN_IVOR35: *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; break;
Add KVM Book3e AltiVec support. KVM Book3e FPU support gracefully reuse host infrastructure so follow the same approach for AltiVec. Keep SPE/AltiVec exception handlers distinct using CONFIG_KVM_E500V2. Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com> --- v3: - use distinct SPE/AltiVec exception handlers v2: - integrate Paul's FP/VMX/VSX changes arch/powerpc/kvm/booke.c | 73 +++++++++++++++++++++++++++++++++++ arch/powerpc/kvm/booke.h | 5 +++ arch/powerpc/kvm/bookehv_interrupts.S | 10 +++-- arch/powerpc/kvm/e500_emulate.c | 18 +++++++++ 4 files changed, 102 insertions(+), 4 deletions(-)