From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Wei Huang <w1.huang@samsung.com>, xen-devel@lists.xen.org
Cc: keir@xen.org, ian.campbell@citrix.com,
stefano.stabellini@eu.citrix.com, ian.jackson@eu.citrix.com,
julien.grall@linaro.org, tim@xen.org, jaeyong.yoo@samsung.com,
jbeulich@suse.com, yjhyun.yoo@samsung.com
Subject: Re: [RFC v3 2/6] xen/arm: Add save/restore support for ARM GIC V2
Date: Thu, 08 May 2014 23:47:56 +0100 [thread overview]
Message-ID: <536C099C.1090606@citrix.com> (raw)
In-Reply-To: <1399583908-21755-3-git-send-email-w1.huang@samsung.com>
On 08/05/2014 22:18, Wei Huang wrote:
> This patch implements a save/restore support for
> ARM guest GIC. Two types of GIC V2 states are saved seperately:
> 1) VGICD_* contains the GIC distributor state from
> guest VM's view; 2) GICH_* is the GIC virtual control
> state from hypervisor's persepctive.
>
> Signed-off-by: Evgeny Fedotov <e.fedotov@samsung.com>
> Signed-off-by: Wei Huang <w1.huang@samsung.com>
> ---
> xen/arch/arm/vgic.c | 171 ++++++++++++++++++++++++++++++++
> xen/include/public/arch-arm/hvm/save.h | 34 ++++++-
> 2 files changed, 204 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 4cf6470..505e944 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -24,6 +24,7 @@
> #include <xen/softirq.h>
> #include <xen/irq.h>
> #include <xen/sched.h>
> +#include <xen/hvm/save.h>
>
> #include <asm/current.h>
>
> @@ -73,6 +74,110 @@ static struct vgic_irq_rank *vgic_irq_rank(struct vcpu *v, int b, int n)
> return NULL;
> }
>
> +/* Save guest VM's distributor info into a context to support domains
Small nit, but Xen style would be:
/*
* start of comment
for multiline comments.
> + * save/restore. Such info represents guest VM's view of its GIC
> + * distributor (GICD_*).
> + */
> +static int hvm_vgicd_save(struct domain *d, hvm_domain_context_t *h)
> +{
> + struct hvm_arm_vgicd_v2 ctxt;
> + struct vcpu *v;
> + struct vgic_irq_rank *rank;
> + int rc = 0;
> +
> + /* Save the state for each VCPU */
> + for_each_vcpu( d, v )
> + {
> + rank = &v->arch.vgic.private_irqs;
> +
> + /* IENABLE, IACTIVE, IPEND, PENDSGI */
> + ctxt.ienable = rank->ienable;
> + ctxt.iactive = rank->iactive;
> + ctxt.ipend = rank->ipend;
> + ctxt.pendsgi = rank->pendsgi;
> +
> + /* ICFG */
> + ctxt.icfg[0] = rank->icfg[0];
> + ctxt.icfg[1] = rank->icfg[1];
> +
> + /* IPRIORITY */
> + BUILD_BUG_ON(sizeof(rank->ipriority) != sizeof (ctxt.ipriority));
> + memcpy(ctxt.ipriority, rank->ipriority, sizeof(rank->ipriority));
Can you be consistent with a space (or lack of) with the sizeof
operator. Eyeballing a grep of the codebase, Xen's prevaling style
would appear to be without the space.
> +
> + /* ITARGETS */
> + BUILD_BUG_ON(sizeof(rank->itargets) != sizeof (ctxt.itargets));
> + memcpy(ctxt.itargets, rank->itargets, sizeof(rank->itargets));
> +
> + if ( (rc = hvm_save_entry(VGICD_V2, v->vcpu_id, h, &ctxt)) != 0 )
> + return rc;
> + }
> +
> + return rc;
> +}
> +
> +/* Load guest VM's distributor info from a context to support domain
> + * save/restore. The info is loaded into vgic_irq_rank.
> + */
> +static int hvm_vgicd_load(struct domain *d, hvm_domain_context_t *h)
> +{
> + struct hvm_arm_vgicd_v2 ctxt;
> + struct vgic_irq_rank *rank;
> + struct vcpu *v;
> + int vcpuid;
unsigned int. (and later on as well)
Can be combined with the 'irq' declaration.
> + unsigned long enable_bits;
> + struct pending_irq *p;
> + unsigned int irq = 0;
> + int rc = 0;
> +
> + /* Which vcpu is this? */
> + vcpuid = hvm_load_instance(h);
> + if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
> + {
> + dprintk(XENLOG_ERR, "HVM restore: dom%u has no vcpu%u\n",
> + d->domain_id, vcpuid);
> + return -EINVAL;
> + }
> +
> + if ( (rc = hvm_load_entry(VGICD_V2, h, &ctxt)) != 0 )
> + return rc;
> +
> + /* Restore PPI states */
> + rank = &v->arch.vgic.private_irqs;
> +
> + /* IENABLE, IACTIVE, IPEND, PENDSGI */
> + rank->ienable = ctxt.ienable;
> + rank->iactive = ctxt.iactive;
> + rank->ipend = ctxt.ipend;
> + rank->pendsgi = ctxt.pendsgi;
> +
> + /* ICFG */
> + rank->icfg[0] = ctxt.icfg[0];
> + rank->icfg[1] = ctxt.icfg[1];
> +
> + /* IPRIORITY */
> + BUILD_BUG_ON(sizeof(rank->ipriority) != sizeof (ctxt.ipriority));
> + memcpy(rank->ipriority, ctxt.ipriority, sizeof(rank->ipriority));
> +
> + /* ITARGETS */
> + BUILD_BUG_ON(sizeof(rank->itargets) != sizeof (ctxt.itargets));
> + memcpy(rank->itargets, ctxt.itargets, sizeof(rank->itargets));
> +
> + /* Set IRQ status as enabled by iterating through rank->ienable register.
> + * This step is required otherwise events won't be received by the VM
> + * after restore. */
> + enable_bits = ctxt.ienable;
> + while ( (irq = find_next_bit(&enable_bits, 32, irq)) < 32 )
> + {
> + p = irq_to_pending(v, irq);
> + set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
> + irq++;
> + }
> +
> + return 0;
> +}
> +HVM_REGISTER_SAVE_RESTORE(VGICD_V2, hvm_vgicd_save, hvm_vgicd_load,
> + 1, HVMSR_PER_VCPU);
> +
> int domain_vgic_init(struct domain *d)
> {
> int i;
> @@ -759,6 +864,72 @@ out:
> smp_send_event_check_mask(cpumask_of(v->processor));
> }
>
> +/* Save GIC virtual control state into a context to support save/restore.
> + * The info reprsents most of GICH_* registers. */
> +static int hvm_gich_save(struct domain *d, hvm_domain_context_t *h)
> +{
> + struct hvm_arm_gich_v2 ctxt;
> + struct vcpu *v;
> + int rc = 0;
> +
> + /* Save the state of GICs */
> + for_each_vcpu( d, v )
> + {
> + ctxt.gic_hcr = v->arch.gic_hcr;
> + ctxt.gic_vmcr = v->arch.gic_vmcr;
> + ctxt.gic_apr = v->arch.gic_apr;
> +
> + /* Save list registers and masks */
> + BUILD_BUG_ON(sizeof(v->arch.gic_lr) > sizeof (ctxt.gic_lr));
> + memcpy(ctxt.gic_lr, v->arch.gic_lr, sizeof(v->arch.gic_lr));
> +
> + ctxt.lr_mask = v->arch.lr_mask;
> + ctxt.event_mask = v->arch.event_mask;
> +
> + if ( (rc = hvm_save_entry(GICH_V2, v->vcpu_id, h, &ctxt)) != 0 )
> + return rc;
> + }
> +
> + return rc;
> +}
> +
> +/* Restore GIC virtual control state from a context to support save/restore */
> +static int hvm_gich_load(struct domain *d, hvm_domain_context_t *h)
> +{
> + int vcpuid;
> + struct hvm_arm_gich_v2 ctxt;
> + struct vcpu *v;
> + int rc = 0;
> +
> + /* Which vcpu is this? */
> + vcpuid = hvm_load_instance(h);
> + if ( vcpuid >= d->max_vcpus || (v = d->vcpu[vcpuid]) == NULL )
> + {
> + dprintk(XENLOG_ERR, "HVM restore: dom%u has no vcpu%u\n", d->domain_id,
> + vcpuid);
> + return -EINVAL;
> + }
> +
> + if ( (rc = hvm_load_entry(GICH_V2, h, &ctxt)) != 0 )
> + return rc;
> +
> + v->arch.gic_hcr = ctxt.gic_hcr;
> + v->arch.gic_vmcr = ctxt.gic_vmcr;
> + v->arch.gic_apr = ctxt.gic_apr;
> +
> + /* Restore list registers and masks */
> + BUILD_BUG_ON(sizeof(v->arch.gic_lr) > sizeof (ctxt.gic_lr));
> + memcpy(v->arch.gic_lr, ctxt.gic_lr, sizeof(v->arch.gic_lr));
> +
> + v->arch.lr_mask = ctxt.lr_mask;
> + v->arch.event_mask = ctxt.event_mask;
> +
> + return rc;
> +}
> +
> +HVM_REGISTER_SAVE_RESTORE(GICH_V2, hvm_gich_save, hvm_gich_load, 1,
> + HVMSR_PER_VCPU);
> +
> /*
> * Local variables:
> * mode: C
> diff --git a/xen/include/public/arch-arm/hvm/save.h b/xen/include/public/arch-arm/hvm/save.h
> index 8312e7b..421a6f6 100644
> --- a/xen/include/public/arch-arm/hvm/save.h
> +++ b/xen/include/public/arch-arm/hvm/save.h
> @@ -40,10 +40,42 @@ struct hvm_save_header
> };
> DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
>
> +/* Guest's view of GIC distributor (per-vcpu)
> + * - Based on GICv2 (see "struct vgic_irq_rank")
> + * - Store guest's view of GIC distributor
> + * - Only support SGI and PPI for DomU (DomU doesn't handle SPI)
> + */
> +struct hvm_arm_vgicd_v2
> +{
> + uint32_t ienable;
> + uint32_t iactive;
> + uint32_t ipend;
> + uint32_t pendsgi;
> + uint32_t icfg[2];
> + uint32_t ipriority[8];
> + uint32_t itargets[8];
> +};
> +DECLARE_HVM_SAVE_TYPE(VGICD_V2, 2, struct hvm_arm_vgicd_v2);
> +
> +/* Info for hypervisor to manage guests (per-vcpu)
> + * - Based on GICv2
> + * - Mainly store registers of GICH_*
> + */
> +struct hvm_arm_gich_v2
> +{
> + uint32_t gic_hcr;
> + uint32_t gic_vmcr;
> + uint32_t gic_apr;
> + uint32_t gic_lr[64];
> + uint64_t event_mask;
> + uint64_t lr_mask;
This has an odd number of uint32_t. I suspect it will end up with a
different structure size between a 32 and 64 bit build of Xen.
> +};
> +DECLARE_HVM_SAVE_TYPE(GICH_V2, 3, struct hvm_arm_gich_v2);
> +
> /*
> * Largest type-code in use
> */
> -#define HVM_SAVE_CODE_MAX 1
> +#define HVM_SAVE_CODE_MAX 3
>
> #endif
>
On x86, we require that HVM save records only contain architectural
state. Not knowing arm myself, it is not clear from your comments
whether this is the case or not. Can you confirm whether it is or not?
~Andrew
next prev parent reply other threads:[~2014-05-08 22:47 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-08 21:18 [RFC v3 0/6] xen/arm: ARM save/restore/migration support Wei Huang
2014-05-08 21:18 ` [RFC v3 1/6] xen/arm: Add basic save/restore support for ARM Wei Huang
2014-05-08 22:11 ` Andrew Cooper
2014-05-08 22:20 ` Wei Huang
2014-05-09 8:56 ` Julien Grall
2014-05-14 10:27 ` Ian Campbell
2014-05-14 10:25 ` Ian Campbell
2014-05-14 10:46 ` Andrew Cooper
2014-05-14 13:22 ` Ian Campbell
2014-05-09 9:06 ` Julien Grall
2014-05-09 9:42 ` Jan Beulich
2014-05-14 10:37 ` Ian Campbell
2014-05-14 18:54 ` Wei Huang
2014-05-08 21:18 ` [RFC v3 2/6] xen/arm: Add save/restore support for ARM GIC V2 Wei Huang
2014-05-08 22:47 ` Andrew Cooper [this message]
2014-05-09 14:12 ` Wei Huang
2014-05-09 14:24 ` Ian Campbell
2014-05-11 16:15 ` Julien Grall
2014-05-13 14:53 ` Wei Huang
2014-05-09 9:17 ` Julien Grall
2014-05-14 11:07 ` Ian Campbell
2014-05-14 12:05 ` Julien Grall
2014-05-14 12:23 ` Tim Deegan
2014-05-14 13:24 ` Ian Campbell
2014-05-15 17:15 ` Julien Grall
2014-05-16 7:36 ` Ian Campbell
2014-05-08 21:18 ` [RFC v3 3/6] xen/arm: Add save/restore support for ARM arch timer Wei Huang
2014-05-08 23:02 ` Andrew Cooper
2014-05-11 9:01 ` Julien Grall
2014-05-11 8:58 ` Julien Grall
2014-05-12 8:35 ` Ian Campbell
2014-05-12 11:42 ` Julien Grall
2014-05-14 11:14 ` Ian Campbell
2014-05-14 12:13 ` Julien Grall
2014-05-14 13:23 ` Ian Campbell
2014-05-14 19:04 ` Wei Huang
2014-05-08 21:18 ` [RFC v3 4/6] xen/arm: Add save/restore support for guest core registers Wei Huang
2014-05-08 23:10 ` Andrew Cooper
2014-05-09 16:35 ` Wei Huang
2014-05-09 16:52 ` Ian Campbell
2014-05-11 9:06 ` Julien Grall
2014-05-14 11:16 ` Ian Campbell
2014-05-14 12:23 ` Julien Grall
2014-05-14 13:25 ` Ian Campbell
2014-05-14 13:31 ` Julien Grall
2014-05-14 11:37 ` Ian Campbell
2014-05-08 21:18 ` [RFC v3 5/6] xen/arm: Add log_dirty support for ARM Wei Huang
2014-05-08 23:46 ` Andrew Cooper
2014-05-14 11:51 ` Ian Campbell
2014-05-11 15:28 ` Julien Grall
2014-05-12 14:00 ` Wei Huang
2014-05-12 14:11 ` Julien Grall
2014-05-14 12:04 ` Ian Campbell
2014-05-14 11:57 ` Ian Campbell
2014-05-14 12:20 ` Julien Grall
2014-05-14 13:24 ` Ian Campbell
2014-05-14 13:18 ` Ian Campbell
2014-05-16 10:59 ` Julien Grall
2014-05-08 21:18 ` [RFC v3 6/6] xen/arm: Implement toolstack for xl restore/save/migration Wei Huang
2014-05-14 13:20 ` Ian Campbell
2014-05-14 13:24 ` Andrew Cooper
2014-05-11 9:23 ` [RFC v3 0/6] xen/arm: ARM save/restore/migration support Julien Grall
2014-05-12 14:37 ` Wei Huang
2014-05-13 14:41 ` Julien Grall
2014-05-12 14:17 ` Julien Grall
2014-05-12 14:52 ` Wei Huang
2014-05-12 15:01 ` Ian Campbell
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=536C099C.1090606@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jaeyong.yoo@samsung.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@linaro.org \
--cc=keir@xen.org \
--cc=stefano.stabellini@eu.citrix.com \
--cc=tim@xen.org \
--cc=w1.huang@samsung.com \
--cc=xen-devel@lists.xen.org \
--cc=yjhyun.yoo@samsung.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;
as well as URLs for NNTP newsgroup(s).