The Linux upstream merge window is comming and
there has been no comment on save/restore so far.
So I expect the abi won't change and I'd like to commit
this patch.
Any comment? I will commit it if no objections.
On Thu, Nov 27, 2008 at 10:58:58AM +0900, Isaku Yamahata wrote:
> This patch is necessary for save/restore support of ia64 pv_ops
> domU linux.
> I posted this patch before, but didn't commit it because
> it wasn't clear how the save/restore support was integrated.
> I'm posting this patch again for those who want to try
> ia64 pv_ops domU Linux save/restore.
>
>
> [IA64] paravirtualize itc and support save/restore.
>
> ia64 linux 2.6.18 only use ar.itc for local ticks so that
> ar.itc didn't need paravirtualization and it can be work arounded
> when save/restore.
> However recent ia64 linux uses ar.itc for sched_clock() and
> CONFIG_VIRT_CPU_ACCOUNTING and other issues. So ar.itc needs
> paravirtualization. Although Most part is done in guest OS,
> save/restore needs hypervisor support.
>
> Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
>
> diff --git a/tools/libxc/ia64/xc_ia64_linux_restore.c
> b/tools/libxc/ia64/xc_ia64_linux_restore.c
> --- a/tools/libxc/ia64/xc_ia64_linux_restore.c
> +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c
> @@ -128,7 +128,8 @@ xc_ia64_recv_vcpu_context(int xc_handle,
> fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip,
> ctxt->regs.b[0]);
>
> /* Initialize and set registers. */
> - ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online;
> + ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online |
> + VGCF_SET_AR_ITC;
> if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt_any) != 0) {
> ERROR("Couldn't set vcpu context");
> return -1;
> diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c
> --- a/xen/arch/ia64/xen/domain.c
> +++ b/xen/arch/ia64/xen/domain.c
> @@ -719,6 +719,48 @@ nats_update(unsigned int* nats, unsigned
> *nats &= ~(1UL << reg);
> }
>
> +static unsigned long
> +__vcpu_get_itc(struct vcpu *v)
> +{
> + unsigned long itc_last;
> + unsigned long itc_offset;
> + unsigned long itc;
> +
> + if (unlikely(v->arch.privregs == NULL))
> + return ia64_get_itc();
> +
> + itc_last = v->arch.privregs->itc_last;
> + itc_offset = v->arch.privregs->itc_offset;
> + itc = ia64_get_itc();
> + itc += itc_offset;
> + if (itc_last >= itc)
> + itc = itc_last;
> + return itc;
> +}
> +
> +static void
> +__vcpu_set_itc(struct vcpu *v, u64 val)
> +{
> + unsigned long itc;
> + unsigned long itc_offset;
> + unsigned long itc_last;
> +
> + BUG_ON(v->arch.privregs == NULL);
> +
> + if (v != current)
> + vcpu_pause(v);
> +
> + itc = ia64_get_itc();
> + itc_offset = val - itc;
> + itc_last = val;
> +
> + v->arch.privregs->itc_offset = itc_offset;
> + v->arch.privregs->itc_last = itc_last;
> +
> + if (v != current)
> + vcpu_unpause(v);
> +}
> +
> void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
> {
> int i;
> @@ -757,6 +799,10 @@ void arch_get_info_guest(struct vcpu *v,
> unw_get_ar(&info, UNW_AR_LC, &c.nat->regs.ar.lc);
> unw_get_ar(&info, UNW_AR_EC, &c.nat->regs.ar.ec);
> }
> +
> + if (!is_hvm)
> + c.nat->regs.ar.itc = __vcpu_get_itc(v);
> +
> c.nat->regs.ar.csd = uregs->ar_csd;
> c.nat->regs.ar.ssd = uregs->ar_ssd;
>
> @@ -1244,6 +1290,10 @@ int arch_set_info_guest(struct vcpu *v,
> unw_set_ar(&info, UNW_AR_LC, c.nat->regs.ar.lc);
> unw_set_ar(&info, UNW_AR_EC, c.nat->regs.ar.ec);
> }
> +
> + if (!is_hvm_domain(d) && (c.nat->flags & VGCF_SET_AR_ITC))
> + __vcpu_set_itc(v, c.nat->regs.ar.itc);
> +
> uregs->ar_csd = c.nat->regs.ar.csd;
> uregs->ar_ssd = c.nat->regs.ar.ssd;
>
> diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h
> --- a/xen/include/public/arch-ia64.h
> +++ b/xen/include/public/arch-ia64.h
> @@ -198,6 +198,15 @@ struct mapped_regs {
> unsigned long rrs[8]; // region registers
> unsigned long krs[8]; // kernel registers
> unsigned long tmp[16]; // temp registers (e.g. for hyperprivops)
> +
> + /* itc paravirtualization
> + * vAR.ITC = mAR.ITC + itc_offset
> + * itc_last is one which was lastly passed to
> + * the guest OS in order to prevent it from
> + * going backwords.
> + */
> + unsigned long itc_offset;
> + unsigned long itc_last;
> };
> };
> };
> @@ -392,6 +401,7 @@ struct vcpu_guest_context {
> #define VGCF_EXTRA_REGS (1UL << 1) /* Set extra regs. */
> #define VGCF_SET_CR_IRR (1UL << 2) /* Set cr_irr[0:3]. */
> #define VGCF_online (1UL << 3) /* make this vcpu online */
> +#define VGCF_SET_AR_ITC (1UL << 4) /* set pv ar.itc. itc_offset, itc_last */
> unsigned long flags; /* VGCF_* flags */
>
> struct vcpu_guest_context_regs regs;
>
>
--
yamahata
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|