[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-ia64-devel] [PATCH][resend] paravirtualize itc and support save/restore.
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |