[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.