From: Alexander Graf <agraf@suse.de>
To: Mihai Caraman <mihai.caraman@freescale.com>, kvm-ppc@vger.kernel.org
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v3 2/5] KVM: PPC: Book3e: Add AltiVec support
Date: Tue, 12 Aug 2014 13:45:07 +0200 [thread overview]
Message-ID: <53E9FE43.80201@suse.de> (raw)
In-Reply-To: <1407235175-30994-3-git-send-email-mihai.caraman@freescale.com>
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;
next prev parent reply other threads:[~2014-08-12 11:45 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-05 10:39 [PATCH v3 0/5] KVM: PPC: Book3e: AltiVec support Mihai Caraman
2014-08-05 10:39 ` [PATCH v3 1/5] KVM: PPC: Book3e: Increase FPU laziness Mihai Caraman
2014-08-05 10:39 ` [PATCH v3 2/5] KVM: PPC: Book3e: Add AltiVec support Mihai Caraman
2014-08-12 11:45 ` Alexander Graf [this message]
2014-08-05 10:39 ` [PATCH v3 3/5] KVM: PPC: Move ONE_REG AltiVec support to powerpc Mihai Caraman
2014-08-12 11:47 ` Alexander Graf
2014-08-05 10:39 ` [PATCH v3 4/5] KVM: PPC: Booke: Add ONE_REG IVORs support Mihai Caraman
2014-08-12 11:48 ` Alexander Graf
2014-08-05 10:39 ` [PATCH v3 5/5] KVM: PPC: Book3E: Enable e6500 core Mihai Caraman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53E9FE43.80201@suse.de \
--to=agraf@suse.de \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=mihai.caraman@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox