On Mon, 18 Feb 2013, Stefano Stabellini wrote:> Trap guest WFI, block the guest VCPU unless it has pending interrupts.
> Awake the guest vcpu when a new interrupt for it arrrives.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
I have an updated version of this patch, that I sent separately to the
list.
> xen/arch/arm/domain_build.c | 2 +-
> xen/arch/arm/traps.c | 7 +++++++
> xen/arch/arm/vgic.c | 4 +++-
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 1e9776d..aa0f191 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -331,7 +331,7 @@ int construct_dom0(struct domain *d)
>
> WRITE_CP32(SCTLR_BASE, SCTLR);
>
> - WRITE_CP32(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM, HCR);
> + WRITE_CP32(HCR_PTW|HCR_BSU_OUTER|HCR_AMO|HCR_IMO|HCR_VM|HCR_TWI, HCR);
> isb();
>
> local_abort_enable();
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 5347dce..b313e7a 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -29,6 +29,7 @@
> #include <xen/hypercall.h>
> #include <xen/softirq.h>
> #include <xen/domain_page.h>
> +#include <public/sched.h>
> #include <public/xen.h>
> #include <asm/regs.h>
> #include <asm/cpregs.h>
> @@ -781,6 +782,12 @@ asmlinkage void do_trap_hypervisor(struct
cpu_user_regs *regs)
> case HSR_EC_DATA_ABORT_GUEST:
> do_trap_data_abort_guest(regs, hsr.dabt);
> break;
> + /* at the moment we only trap WFI */
> + case HSR_EC_WFI_WFE:
> + if ( list_empty(¤t->arch.vgic.inflight_irqs) )
> + do_sched_op_compat(SCHEDOP_block, 0);
> + regs->pc += hsr.len ? 4 : 2;
> + break;
> default:
> printk("Hypervisor Trap. HSR=0x%x EC=0x%x IL=%x
Syndrome=%"PRIx32"\n",
> hsr.bits, hsr.ec, hsr.len, hsr.iss);
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 39b9775..8495384 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -608,12 +608,14 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned
int irq, int virtual)
> {
> list_add_tail(&n->inflight, &iter->inflight);
> spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
> - return;
> + goto out;
> }
> }
> list_add_tail(&n->inflight,
&v->arch.vgic.inflight_irqs);
> spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
> /* we have a new higher priority irq, inject it into the guest */
> +out:
> + vcpu_unblock(v);
> }
>
> /*
> --
> 1.7.2.5
>