[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] paravirtualize itc and support save/restore.
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1231125898 -32400 # Node ID 4422219acd938d8a7b6bdd14c604c215a6aace20 # Parent ecdc570407ecfa1264c043eecc4a14ffb175579f [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> --- tools/libxc/ia64/xc_ia64_linux_restore.c | 3 + xen/arch/ia64/xen/domain.c | 50 +++++++++++++++++++++++++++++++ xen/include/public/arch-ia64.h | 10 ++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff -r ecdc570407ec -r 4422219acd93 tools/libxc/ia64/xc_ia64_linux_restore.c --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Mon Jan 05 12:24:58 2009 +0900 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Mon Jan 05 12:24:58 2009 +0900 @@ -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 -r ecdc570407ec -r 4422219acd93 xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Mon Jan 05 12:24:58 2009 +0900 +++ b/xen/arch/ia64/xen/domain.c Mon Jan 05 12:24:58 2009 +0900 @@ -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 -r ecdc570407ec -r 4422219acd93 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Mon Jan 05 12:24:58 2009 +0900 +++ b/xen/include/public/arch-ia64.h Mon Jan 05 12:24:58 2009 +0900 @@ -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; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |