ia64/xen-unstable

changeset 16171:e7d7a4adf357

[IA64] vti domain save/restore: implement hvm_save/load. work in progress.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Sun Oct 21 14:39:07 2007 -0600 (2007-10-21)
parents ff1f49f62204
children d251f99b55e7
files xen/arch/ia64/Rules.mk xen/arch/ia64/vmx/Makefile xen/arch/ia64/vmx/save.c xen/arch/ia64/vmx/vacpi.c xen/arch/ia64/vmx/viosapic.c xen/arch/ia64/vmx/vlsapic.c xen/arch/ia64/vmx/vmx_vcpu_save.c xen/common/Makefile xen/include/asm-ia64/hvm/support.h xen/include/asm-ia64/hvm/vacpi.h xen/include/asm-ia64/viosapic.h xen/include/public/arch-ia64/hvm/save.h xen/include/public/hvm/save.h
line diff
     1.1 --- a/xen/arch/ia64/Rules.mk	Sun Oct 21 13:38:57 2007 -0600
     1.2 +++ b/xen/arch/ia64/Rules.mk	Sun Oct 21 14:39:07 2007 -0600
     1.3 @@ -1,6 +1,7 @@
     1.4  ########################################
     1.5  # ia64-specific definitions
     1.6  
     1.7 +ia64 := y
     1.8  HAS_ACPI := y
     1.9  HAS_VGA  := y
    1.10  xenoprof := y
     2.1 --- a/xen/arch/ia64/vmx/Makefile	Sun Oct 21 13:38:57 2007 -0600
     2.2 +++ b/xen/arch/ia64/vmx/Makefile	Sun Oct 21 14:39:07 2007 -0600
     2.3 @@ -20,3 +20,4 @@ obj-y += vtlb.o
     2.4  obj-y += optvfault.o
     2.5  obj-y += vacpi.o
     2.6  obj-y += vmx_vcpu_save.o
     2.7 +obj-y += save.o
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/ia64/vmx/save.c	Sun Oct 21 14:39:07 2007 -0600
     3.3 @@ -0,0 +1,71 @@
     3.4 +/*
     3.5 + * hvm/save.c: Save and restore HVM guest's emulated hardware state.
     3.6 + *
     3.7 + * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
     3.8 + *                     VA Linux Systems Japan K.K.
     3.9 + *                     IA64 support
    3.10 + *
    3.11 + * This program is free software; you can redistribute it and/or modify
    3.12 + * it under the terms of the GNU General Public License as published by
    3.13 + * the Free Software Foundation; either version 2 of the License, or
    3.14 + * (at your option) any later version.
    3.15 + *
    3.16 + * This program is distributed in the hope that it will be useful,
    3.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.19 + * GNU General Public License for more details.
    3.20 + *
    3.21 + * You should have received a copy of the GNU General Public License
    3.22 + * along with this program; if not, write to the Free Software
    3.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.24 + */
    3.25 +
    3.26 +#include <xen/types.h>
    3.27 +#include <xen/hvm/save.h>
    3.28 +
    3.29 +void
    3.30 +arch_hvm_save(struct hvm_save_header *hdr)
    3.31 +{
    3.32 +    unsigned int i;
    3.33 +    
    3.34 +    for (i = 0; i < 5; ++i)
    3.35 +        hdr->cpuid[i] = ia64_get_cpuid(i);
    3.36 +}
    3.37 +
    3.38 +int
    3.39 +arch_hvm_load(struct hvm_save_header *hdr)
    3.40 +{
    3.41 +    unsigned int i;
    3.42 +    if (hdr->magic != HVM_FILE_MAGIC) {
    3.43 +        gdprintk(XENLOG_ERR, 
    3.44 +                 "HVM restore: bad magic number %#"PRIx64"\n", hdr->magic);
    3.45 +        return -1;
    3.46 +    }
    3.47 +
    3.48 +    if (hdr->version != HVM_FILE_VERSION) {
    3.49 +        gdprintk(XENLOG_ERR, 
    3.50 +                 "HVM restore: unsupported version %"PRIx64"\n", hdr->version);
    3.51 +        return -1;
    3.52 +    }
    3.53 +
    3.54 +    for (i = 0; i < 5; ++i) {
    3.55 +        unsigned long cpuid = ia64_get_cpuid(i);
    3.56 +        /* TODO: need to define how big a difference is acceptable */
    3.57 +        if (hdr->cpuid[i] != cpuid)
    3.58 +            gdprintk(XENLOG_WARNING,
    3.59 +                     "HVM restore: saved CPUID[%d] (%#lx) "
    3.60 +                     "does not match host (%#lx).\n", i, hdr->cpuid[i], cpuid);
    3.61 +    }
    3.62 +
    3.63 +    return 0;
    3.64 +}
    3.65 +
    3.66 +/*
    3.67 + * Local variables:
    3.68 + * mode: C
    3.69 + * c-set-style: "BSD"
    3.70 + * c-basic-offset: 4
    3.71 + * tab-width: 4
    3.72 + * indent-tabs-mode: nil
    3.73 + * End:
    3.74 + */
     4.1 --- a/xen/arch/ia64/vmx/vacpi.c	Sun Oct 21 13:38:57 2007 -0600
     4.2 +++ b/xen/arch/ia64/vmx/vacpi.c	Sun Oct 21 14:39:07 2007 -0600
     4.3 @@ -7,6 +7,7 @@
     4.4   * Copyright (c) 2007 VA Linux Systems Japan K.K
     4.5   *      Isaku Yamahata <yamahata at valinux co jp>
     4.6   *      SMP support
     4.7 + *      save/restore support
     4.8   *
     4.9   * Copyright (c) 2007, XenSource inc.
    4.10   * Copyright (c) 2006, Intel Corporation.
    4.11 @@ -28,6 +29,8 @@
    4.12  #include <asm/vmx_vcpu.h>
    4.13  #include <asm/vmx.h>
    4.14  #include <asm/hvm/vacpi.h>
    4.15 +#include <asm/hvm/support.h>
    4.16 +#include <public/hvm/save.h>
    4.17  
    4.18  /* The interesting bits of the PM1a_STS register */
    4.19  #define TMR_STS    (1 << 0)
    4.20 @@ -197,3 +200,69 @@ void vacpi_relinquish_resources(struct d
    4.21  	struct vacpi *s = &d->arch.hvm_domain.vacpi;
    4.22  	kill_timer(&s->timer);
    4.23  }
    4.24 +
    4.25 +// stolen from xen/arch/x86/hvm/pmtimer.c
    4.26 +static int vacpi_save(struct domain *d, hvm_domain_context_t *h)
    4.27 +{
    4.28 +	struct vacpi *s = &d->arch.hvm_domain.vacpi;
    4.29 +	unsigned long delta;
    4.30 +	uint32_t msb = s->regs.tmr_val & TMR_VAL_MSB;
    4.31 +	struct hvm_hw_ia64_vacpi vacpi_save;
    4.32 +	int rc;
    4.33 +
    4.34 +	stop_timer(&s->timer); //XXX
    4.35 +	
    4.36 +	spin_lock(&s->lock);
    4.37 +
    4.38 +	/* Update the counter to the guest's current time.  We always save
    4.39 +	 * with the domain paused, so the saved time should be after the
    4.40 +	 * last_gtime, but just in case, make sure we only go forwards */
    4.41 +
    4.42 +	//XXX NOW() should be the time that domais paused
    4.43 +	delta = NOW() - s->last_gtime; 
    4.44 +	delta = ((delta >> 8) * ((FREQUENCE_PMTIMER << 32) / SECONDS(1))) >> 24;
    4.45 +	if ( delta < 1UL<<31 )
    4.46 +		s->regs.tmr_val += delta;
    4.47 +	if ( (s->regs.tmr_val & TMR_VAL_MSB) != msb )
    4.48 +		s->regs.pm1a_sts |= TMR_STS;
    4.49 +	/* No point in setting the SCI here because we'll already have saved the 
    4.50 +	 * IRQ and *PIC state; we'll fix it up when we restore the domain */
    4.51 +
    4.52 +	vacpi_save.regs = s->regs;
    4.53 +	rc = hvm_save_entry(VACPI, 0, h, &vacpi_save);
    4.54 +	
    4.55 +	spin_unlock(&s->lock);
    4.56 +
    4.57 +	pmt_timer_callback(d);//XXX This might change the domain state.
    4.58 +	return 0;
    4.59 +}
    4.60 +
    4.61 +static int vacpi_load(struct domain *d, hvm_domain_context_t *h)
    4.62 +{
    4.63 +	struct vacpi *s = &d->arch.hvm_domain.vacpi;
    4.64 +	struct hvm_hw_ia64_vacpi vacpi_load;
    4.65 +
    4.66 +	/* Reload the registers */
    4.67 +	if ( hvm_load_entry(VACPI, h, &vacpi_load) )
    4.68 +		return -EINVAL;
    4.69 +
    4.70 +	stop_timer(&s->timer);//XXX
    4.71 +
    4.72 +	spin_lock(&s->lock);
    4.73 +
    4.74 +	s->regs = vacpi_load.regs;
    4.75 +
    4.76 +	/* Calculate future counter values from now. */
    4.77 +	//XXX NOW(); last_gtime should be set when domain is unpaused
    4.78 +	s->last_gtime = NOW(); 
    4.79 +
    4.80 +	/* Set the SCI state from the registers */ 
    4.81 +	pmt_update_sci(d, s);
    4.82 +
    4.83 +	spin_unlock(&s->lock);
    4.84 +
    4.85 +	pmt_timer_callback(d);//XXX
    4.86 +	return 0;
    4.87 +}
    4.88 +
    4.89 +HVM_REGISTER_SAVE_RESTORE(VACPI, vacpi_save, vacpi_load, 1, HVMSR_PER_DOM);
     5.1 --- a/xen/arch/ia64/vmx/viosapic.c	Sun Oct 21 13:38:57 2007 -0600
     5.2 +++ b/xen/arch/ia64/vmx/viosapic.c	Sun Oct 21 14:39:07 2007 -0600
     5.3 @@ -27,6 +27,7 @@
     5.4   *  Copyright (C) 2007 VA Linux Systems Japan K.K.
     5.5   *  Isaku Yamahata <yamahata at valinux co jp>
     5.6   *  SMP support
     5.7 + *  xen save/restore support
     5.8   */
     5.9  
    5.10  #include <xen/config.h>
    5.11 @@ -40,6 +41,8 @@
    5.12  #include <asm/viosapic.h>
    5.13  #include <asm/current.h>
    5.14  #include <asm/event.h>
    5.15 +#include <asm/hvm/support.h>
    5.16 +#include <public/hvm/save.h>
    5.17  
    5.18  static void viosapic_deliver(struct viosapic *viosapic, int irq)
    5.19  {
    5.20 @@ -356,3 +359,69 @@ void viosapic_init(struct domain *d)
    5.21      
    5.22      viosapic->base_address = VIOSAPIC_DEFAULT_BASE_ADDRESS;
    5.23  }
    5.24 +
    5.25 +#define VIOSAPIC_INVALID_VCPU_ID (-1UL)
    5.26 +static int viosapic_save(struct domain *d, hvm_domain_context_t *h)
    5.27 +{
    5.28 +    struct viosapic *viosapic = domain_viosapic(d);
    5.29 +    struct hvm_hw_ia64_viosapic viosapic_save;
    5.30 +    int i;
    5.31 +
    5.32 +    memset(&viosapic_save, 0, sizeof(viosapic_save));
    5.33 +    
    5.34 +    spin_lock(&viosapic->lock);
    5.35 +    viosapic_save.irr = viosapic->irr;
    5.36 +    viosapic_save.isr = viosapic->isr;
    5.37 +    viosapic_save.ioregsel = viosapic->ioregsel;
    5.38 +    if (viosapic->lowest_vcpu != NULL)
    5.39 +        viosapic_save.lowest_vcpu_id = viosapic->lowest_vcpu->vcpu_id;
    5.40 +    else
    5.41 +        viosapic_save.lowest_vcpu_id = VIOSAPIC_INVALID_VCPU_ID;
    5.42 +    viosapic_save.base_address = viosapic->base_address;
    5.43 +
    5.44 +    for (i = 0; i < VIOSAPIC_NUM_PINS; i++)
    5.45 +        viosapic_save.redirtbl[i] = viosapic->redirtbl[i];
    5.46 +    spin_unlock(&viosapic->lock);
    5.47 +
    5.48 +    return hvm_save_entry(VIOSAPIC, 0, h, &viosapic_save);
    5.49 +}
    5.50 +
    5.51 +static int viosapic_load(struct domain *d, hvm_domain_context_t *h)
    5.52 +{
    5.53 +    struct viosapic *viosapic = domain_viosapic(d);
    5.54 +    struct hvm_hw_ia64_viosapic viosapic_load;
    5.55 +    struct vcpu *lowest_vcpu;
    5.56 +    int i;
    5.57 +
    5.58 +    if (hvm_load_entry(VIOSAPIC, h, &viosapic_load))
    5.59 +        return -EINVAL;
    5.60 +
    5.61 +    lowest_vcpu = NULL;
    5.62 +    if (viosapic_load.lowest_vcpu_id < MAX_VIRT_CPUS)
    5.63 +        lowest_vcpu = d->vcpu[viosapic_load.lowest_vcpu_id];
    5.64 +    else if (viosapic_load.lowest_vcpu_id != VIOSAPIC_INVALID_VCPU_ID)
    5.65 +        return -EINVAL;
    5.66 +
    5.67 +    if (viosapic_load.base_address != VIOSAPIC_DEFAULT_BASE_ADDRESS)
    5.68 +        return -EINVAL;
    5.69 +
    5.70 +    spin_lock(&viosapic->lock);
    5.71 +    viosapic->irr = viosapic_load.irr;
    5.72 +    viosapic->isr = viosapic_load.isr;
    5.73 +    viosapic->ioregsel = viosapic_load.ioregsel;
    5.74 +
    5.75 +    viosapic->lowest_vcpu = lowest_vcpu;
    5.76 +
    5.77 +    viosapic->base_address = viosapic_load.base_address;
    5.78 +
    5.79 +    for (i = 0; i < VIOSAPIC_NUM_PINS; i++)
    5.80 +        viosapic->redirtbl[i] = viosapic_load.redirtbl[i];
    5.81 +
    5.82 +    service_iosapic(viosapic);//XXX
    5.83 +    spin_unlock(&viosapic->lock);
    5.84 +
    5.85 +    return 0;
    5.86 +}
    5.87 +
    5.88 +HVM_REGISTER_SAVE_RESTORE(VIOSAPIC, viosapic_save, viosapic_load,
    5.89 +                          1, HVMSR_PER_DOM);
     6.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Sun Oct 21 13:38:57 2007 -0600
     6.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Sun Oct 21 14:39:07 2007 -0600
     6.3 @@ -4,6 +4,10 @@
     6.4   * vlsapic.c: virtual lsapic model including ITC timer.
     6.5   * Copyright (c) 2005, Intel Corporation.
     6.6   *
     6.7 + * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
     6.8 + *                     VA Linux Systems Japan K.K.
     6.9 + *                     save/restore support
    6.10 + *
    6.11   * This program is free software; you can redistribute it and/or modify it
    6.12   * under the terms and conditions of the GNU General Public License,
    6.13   * version 2, as published by the Free Software Foundation.
    6.14 @@ -40,6 +44,8 @@
    6.15  #include <asm/vlsapic.h>
    6.16  #include <asm/linux/jiffies.h>
    6.17  #include <xen/domain.h>
    6.18 +#include <asm/hvm/support.h>
    6.19 +#include <public/hvm/save.h>
    6.20  
    6.21  #ifdef IPI_DEBUG
    6.22  #define IPI_DPRINTK(x...) printk(x)
    6.23 @@ -820,3 +826,122 @@ void vlsapic_write(struct vcpu *v,
    6.24      }
    6.25  }
    6.26  
    6.27 +static int vlsapic_save(struct domain *d, hvm_domain_context_t *h)
    6.28 +{
    6.29 +    struct vcpu *v;
    6.30 +
    6.31 +    for_each_vcpu(d, v) {
    6.32 +        struct hvm_hw_ia64_vlsapic vlsapic;
    6.33 +        int i;
    6.34 +
    6.35 +        if (test_bit(_VPF_down, &v->pause_flags))
    6.36 +            continue;
    6.37 +
    6.38 +        memset(&vlsapic, 0, sizeof(vlsapic));
    6.39 +        for (i = 0; i < 4; i++)
    6.40 +            vlsapic.insvc[i] = VLSAPIC_INSVC(v,i);
    6.41 +
    6.42 +        vlsapic.vhpi = VCPU(v, vhpi);
    6.43 +        vlsapic.xtp = VLSAPIC_XTP(v);
    6.44 +        vlsapic.pal_init_pending = v->arch.arch_vmx.pal_init_pending;
    6.45 +
    6.46 +        if (hvm_save_entry(VLSAPIC, v->vcpu_id, h, &vlsapic))
    6.47 +            return -EINVAL;
    6.48 +    }
    6.49 +
    6.50 +    return 0;
    6.51 +}
    6.52 +
    6.53 +static int vlsapic_load(struct domain *d, hvm_domain_context_t *h)
    6.54 +{
    6.55 +    uint16_t vcpuid;
    6.56 +    struct vcpu *v;
    6.57 +    struct hvm_hw_ia64_vlsapic vlsapic;
    6.58 +    int i;
    6.59 +
    6.60 +    vcpuid = hvm_load_instance(h);
    6.61 +    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
    6.62 +        gdprintk(XENLOG_ERR,
    6.63 +                 "%s: domain has no vlsapic %u\n", __func__, vcpuid);
    6.64 +        return -EINVAL;
    6.65 +    }
    6.66 +
    6.67 +    if (hvm_load_entry(VLSAPIC, h, &vlsapic) != 0) 
    6.68 +        return -EINVAL;
    6.69 +
    6.70 +    for (i = 0; i < 4; i++)
    6.71 +        VLSAPIC_INSVC(v,i) = vlsapic.insvc[i];
    6.72 +
    6.73 +    VCPU(v, vhpi) = vlsapic.vhpi;
    6.74 +    VLSAPIC_XTP(v) = vlsapic.xtp;
    6.75 +    v->arch.arch_vmx.pal_init_pending = vlsapic.pal_init_pending;
    6.76 +    v->arch.irq_new_pending = 1; /* to force checking irq */
    6.77 +
    6.78 +    return 0;
    6.79 +}
    6.80 +
    6.81 +HVM_REGISTER_SAVE_RESTORE(VLSAPIC, vlsapic_save, vlsapic_load,
    6.82 +                          1, HVMSR_PER_VCPU);
    6.83 +
    6.84 +static int vtime_save(struct domain *d, hvm_domain_context_t *h)
    6.85 +{
    6.86 +    struct vcpu *v;
    6.87 +
    6.88 +    for_each_vcpu(d, v) {
    6.89 +        vtime_t *vtm = &VMX(v, vtm);
    6.90 +        struct hvm_hw_ia64_vtime vtime;
    6.91 +
    6.92 +        if (test_bit(_VPF_down, &v->pause_flags))
    6.93 +            continue;
    6.94 +
    6.95 +        stop_timer(&vtm->vtm_timer);//XXX should wait for callback not running.
    6.96 +
    6.97 +        memset(&vtime, 0, sizeof(vtime));
    6.98 +        vtime.itc = now_itc(vtm);
    6.99 +        vtime.itm = VCPU(v, itm);
   6.100 +        vtime.last_itc = vtm->last_itc;
   6.101 +        vtime.pending = vtm->pending;
   6.102 +
   6.103 +        vtm_set_itm(v, vtime.itm);// this may start timer.
   6.104 +
   6.105 +        if (hvm_save_entry(VTIME, v->vcpu_id, h, &vtime))
   6.106 +            return -EINVAL;
   6.107 +    }
   6.108 +
   6.109 +    return 0;
   6.110 +}
   6.111 +
   6.112 +static int vtime_load(struct domain *d, hvm_domain_context_t *h)
   6.113 +{
   6.114 +    uint16_t vcpuid;
   6.115 +    struct vcpu *v;
   6.116 +    struct hvm_hw_ia64_vtime vtime;
   6.117 +    vtime_t *vtm;
   6.118 +
   6.119 +    vcpuid = hvm_load_instance(h);
   6.120 +    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
   6.121 +        gdprintk(XENLOG_ERR,
   6.122 +                 "%s: domain has no vtime %u\n", __func__, vcpuid);
   6.123 +        return -EINVAL;
   6.124 +    }
   6.125 +
   6.126 +    if (hvm_load_entry(VTIME, h, &vtime) != 0)
   6.127 +        return -EINVAL;
   6.128 +
   6.129 +    vtm = &VMX(v, vtm);
   6.130 +    stop_timer(&vtm->vtm_timer); //XXX should wait for callback not running.
   6.131 +
   6.132 +    vtm->last_itc = vtime.last_itc;
   6.133 +    vtm->pending = vtime.pending;
   6.134 +
   6.135 +    migrate_timer(&vtm->vtm_timer, v->processor);
   6.136 +    vtm_set_itm(v, vtime.itm);
   6.137 +    vtm_set_itc(v, vtime.itc); // This may start timer.
   6.138 +
   6.139 +    if (test_and_clear_bit(_VPF_down, &v->pause_flags))
   6.140 +        vcpu_wake(v);
   6.141 +
   6.142 +    return 0;
   6.143 +}
   6.144 +
   6.145 +HVM_REGISTER_SAVE_RESTORE(VTIME, vtime_save, vtime_load, 1, HVMSR_PER_VCPU);
     7.1 --- a/xen/arch/ia64/vmx/vmx_vcpu_save.c	Sun Oct 21 13:38:57 2007 -0600
     7.2 +++ b/xen/arch/ia64/vmx/vmx_vcpu_save.c	Sun Oct 21 14:39:07 2007 -0600
     7.3 @@ -22,6 +22,8 @@
     7.4  
     7.5  #include <asm/vmx_vcpu.h>
     7.6  #include <asm/vmx_vcpu_save.h>
     7.7 +#include <asm/hvm/support.h>
     7.8 +#include <public/hvm/save.h>
     7.9  
    7.10  void
    7.11  vmx_arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
    7.12 @@ -192,6 +194,166 @@ vmx_arch_set_info_guest(struct vcpu *v, 
    7.13      return 0;
    7.14  }
    7.15  
    7.16 +
    7.17 +static int vmx_cpu_save(struct domain *d, hvm_domain_context_t *h)
    7.18 +{
    7.19 +    struct vcpu *v;
    7.20 +
    7.21 +    for_each_vcpu(d, v) {
    7.22 +        struct pt_regs *regs = vcpu_regs(v);
    7.23 +        struct hvm_hw_ia64_cpu ia64_cpu;
    7.24 +
    7.25 +        if (test_bit(_VPF_down, &v->pause_flags))
    7.26 +            continue;
    7.27 +
    7.28 +        memset(&ia64_cpu, 0, sizeof(ia64_cpu));
    7.29 +
    7.30 +        ia64_cpu.ipsr = regs->cr_ipsr;
    7.31 +
    7.32 +        if (hvm_save_entry(CPU, v->vcpu_id, h, &ia64_cpu))
    7.33 +            return -EINVAL;
    7.34 +    }
    7.35 +
    7.36 +    return 0;
    7.37 +}
    7.38 +
    7.39 +static int vmx_cpu_load(struct domain *d, hvm_domain_context_t *h)
    7.40 +{
    7.41 +    int rc = 0;
    7.42 +    uint16_t vcpuid;
    7.43 +    struct vcpu *v;
    7.44 +    struct hvm_hw_ia64_cpu ia64_cpu;
    7.45 +    struct pt_regs *regs;
    7.46 +
    7.47 +    vcpuid = hvm_load_instance(h);
    7.48 +    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
    7.49 +        gdprintk(XENLOG_ERR,
    7.50 +                 "%s: domain has no vcpu %u\n", __func__, vcpuid);
    7.51 +        rc = -EINVAL;
    7.52 +        goto out;
    7.53 +    }
    7.54 +
    7.55 +    if (hvm_load_entry(CPU, h, &ia64_cpu) != 0) {
    7.56 +        rc = -EINVAL;
    7.57 +        goto out;
    7.58 +    }
    7.59 +
    7.60 +    regs = vcpu_regs(v);
    7.61 +    regs->cr_ipsr = ia64_cpu.ipsr | IA64_PSR_VM;
    7.62 +
    7.63 + out:
    7.64 +    return rc;
    7.65 +}
    7.66 +
    7.67 +HVM_REGISTER_SAVE_RESTORE(CPU, vmx_cpu_save, vmx_cpu_load, 1, HVMSR_PER_VCPU);
    7.68 +
    7.69 +static int vmx_vpd_save(struct domain *d, hvm_domain_context_t *h)
    7.70 +{
    7.71 +    struct vcpu *v;
    7.72 +
    7.73 +    for_each_vcpu(d, v) {
    7.74 +        vpd_t *vpd = (void *)v->arch.privregs;
    7.75 +
    7.76 +        if (test_bit(_VPF_down, &v->pause_flags))
    7.77 +            continue;
    7.78 +        
    7.79 +        // currently struct hvm_hw_ia64_vpd = struct vpd
    7.80 +        // if it is changed, this must be revised.
    7.81 +        if (hvm_save_entry(VPD, v->vcpu_id, h, (struct hvm_hw_ia64_vpd*)vpd))
    7.82 +            return -EINVAL;
    7.83 +    }
    7.84 +
    7.85 +    return 0;
    7.86 +}
    7.87 +
    7.88 +static int vmx_vpd_load(struct domain *d, hvm_domain_context_t *h)
    7.89 +{
    7.90 +    int rc = 0;
    7.91 +    uint16_t vcpuid;
    7.92 +    struct vcpu *v;
    7.93 +    vpd_t *vpd;
    7.94 +    struct hvm_hw_ia64_vpd *ia64_vpd = NULL;
    7.95 +    int i;
    7.96 +
    7.97 +    vcpuid = hvm_load_instance(h);
    7.98 +    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
    7.99 +        gdprintk(XENLOG_ERR,
   7.100 +                 "%s: domain has no vcpu %u\n", __func__, vcpuid);
   7.101 +        rc = -EINVAL;
   7.102 +        goto out;
   7.103 +    }
   7.104 +
   7.105 +    ia64_vpd = xmalloc(struct hvm_hw_ia64_vpd);
   7.106 +    if (ia64_vpd == NULL) {
   7.107 +        gdprintk(XENLOG_ERR,
   7.108 +                 "%s: can't allocate memory %d\n", __func__, vcpuid);
   7.109 +        rc = -ENOMEM;
   7.110 +        goto out;
   7.111 +    }
   7.112 +
   7.113 +    if (hvm_load_entry(VPD, h, ia64_vpd) != 0) {
   7.114 +        rc = -EINVAL;
   7.115 +        goto out;
   7.116 +    }
   7.117 +
   7.118 +    vpd = (void *)v->arch.privregs;
   7.119 +#define VPD_COPY(x)    vpd->vpd_low.x = ia64_vpd->vpd.vpd_low.x
   7.120 +
   7.121 +    for (i = 0; i < 16; i++)
   7.122 +        VPD_COPY(vgr[i]);
   7.123 +    for (i = 0; i < 16; i++)
   7.124 +        VPD_COPY(vbgr[i]);
   7.125 +    VPD_COPY(vnat);
   7.126 +    VPD_COPY(vbnat);
   7.127 +    for (i = 0; i < 5; i++)
   7.128 +        VPD_COPY(vcpuid[i]);
   7.129 +    VPD_COPY(vpsr);
   7.130 +    VPD_COPY(vpr);
   7.131 +
   7.132 +    // cr
   7.133 +#if 0
   7.134 +    VPD_COPY(dcr);
   7.135 +    VPD_COPY(itm);
   7.136 +    VPD_COPY(iva);
   7.137 +    VPD_COPY(pta);
   7.138 +    VPD_COPY(ipsr);
   7.139 +    VPD_COPY(isr);
   7.140 +    VPD_COPY(iip);
   7.141 +    VPD_COPY(ifa);
   7.142 +    VPD_COPY(itir);
   7.143 +    VPD_COPY(iipa);
   7.144 +    VPD_COPY(ifs);
   7.145 +    VPD_COPY(iim);
   7.146 +    VPD_COPY(iha);
   7.147 +    VPD_COPY(lid);
   7.148 +    VPD_COPY(ivr);
   7.149 +    VPD_COPY(tpr);
   7.150 +    VPD_COPY(eoi);
   7.151 +    VPD_COPY(irr[0]);
   7.152 +    VPD_COPY(irr[1]);
   7.153 +    VPD_COPY(irr[2]);
   7.154 +    VPD_COPY(irr[3]);
   7.155 +    VPD_COPY(itv);
   7.156 +    VPD_COPY(pmv);
   7.157 +    VPD_COPY(cmcv);
   7.158 +    VPD_COPY(lrr0);
   7.159 +    VPD_COPY(lrr1);
   7.160 +#else
   7.161 +    memcpy(&vpd->vpd_low.vcr[0], &ia64_vpd->vpd.vpd_low.vcr[0],
   7.162 +           sizeof(vpd->vpd_low.vcr));
   7.163 +#endif
   7.164 +#undef VPD_COPY
   7.165 +
   7.166 +    v->arch.irq_new_condition = 1;
   7.167 +
   7.168 + out:
   7.169 +    if (ia64_vpd != NULL)
   7.170 +        xfree(ia64_vpd);
   7.171 +    return rc;
   7.172 +}
   7.173 +
   7.174 +HVM_REGISTER_SAVE_RESTORE(VPD, vmx_vpd_save, vmx_vpd_load, 1, HVMSR_PER_VCPU);
   7.175 +
   7.176  /*
   7.177   * Local variables:
   7.178   * mode: C
     8.1 --- a/xen/common/Makefile	Sun Oct 21 13:38:57 2007 -0600
     8.2 +++ b/xen/common/Makefile	Sun Oct 21 14:39:07 2007 -0600
     8.3 @@ -37,6 +37,7 @@ subdir-$(CONFIG_COMPAT) += compat
     8.4  
     8.5  subdir-$(x86_32) += hvm
     8.6  subdir-$(x86_64) += hvm
     8.7 +subdir-$(ia64) += hvm
     8.8  
     8.9  subdir-y += libelf
    8.10  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/include/asm-ia64/hvm/support.h	Sun Oct 21 14:39:07 2007 -0600
     9.3 @@ -0,0 +1,28 @@
     9.4 +/*
     9.5 + * xen/include/asm-ia64/hvm/save.h
     9.6 + *
     9.7 + * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
     9.8 + *                     VA Linux Systems Japan K.K.
     9.9 + *                     IA64 support
    9.10 + *
    9.11 + * This program is free software; you can redistribute it and/or modify
    9.12 + * it under the terms of the GNU General Public License as published by
    9.13 + * the Free Software Foundation; either version 2 of the License, or
    9.14 + * (at your option) any later version.
    9.15 + *
    9.16 + * This program is distributed in the hope that it will be useful,
    9.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.19 + * GNU General Public License for more details.
    9.20 + *
    9.21 + * You should have received a copy of the GNU General Public License
    9.22 + * along with this program; if not, write to the Free Software
    9.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.24 + */
    9.25 +
    9.26 +#ifndef __ASM_IA64_HVM_SUPPORT_H__
    9.27 +#define __ASM_IA64_HVM_SUPPORT_H__
    9.28 +
    9.29 +#include <xen/hvm/save.h>
    9.30 +
    9.31 +#endif /* __ASM_IA64_HVM_SUPPORT_H__ */
    10.1 --- a/xen/include/asm-ia64/hvm/vacpi.h	Sun Oct 21 13:38:57 2007 -0600
    10.2 +++ b/xen/include/asm-ia64/hvm/vacpi.h	Sun Oct 21 14:39:07 2007 -0600
    10.3 @@ -21,6 +21,7 @@
    10.4  #ifndef __ASM_IA64_HVM_VACPI_H__
    10.5  #define __ASM_IA64_HVM_VACPI_H__
    10.6  
    10.7 +#include <public/arch-ia64/hvm/save.h> /* for struct vacpi_regs */
    10.8  #include <public/hvm/ioreq.h>
    10.9  
   10.10  #define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40
   10.11 @@ -31,17 +32,6 @@
   10.12  
   10.13  #define FREQUENCE_PMTIMER  3579545UL	/* Timer should run at 3.579545 MHz */
   10.14  
   10.15 -struct vacpi_regs {
   10.16 -	union {
   10.17 -		struct {
   10.18 -			uint32_t pm1a_sts:16;
   10.19 -			uint32_t pm1a_en:16;
   10.20 -		};
   10.21 -		uint32_t evt_blk;
   10.22 -	};
   10.23 -	uint32_t tmr_val;
   10.24 -};
   10.25 -
   10.26  struct vacpi {
   10.27  	struct vacpi_regs regs;
   10.28  	s_time_t last_gtime;
    11.1 --- a/xen/include/asm-ia64/viosapic.h	Sun Oct 21 13:38:57 2007 -0600
    11.2 +++ b/xen/include/asm-ia64/viosapic.h	Sun Oct 21 14:39:07 2007 -0600
    11.3 @@ -29,6 +29,8 @@
    11.4  #include <xen/config.h>
    11.5  #include <xen/types.h>
    11.6  #include <xen/smp.h>
    11.7 +#include <public/arch-ia64/hvm/save.h> /* for VIOSAPIC_NUM_PINS and
    11.8 +                                          union viosapic_rte */
    11.9  
   11.10  /* Direct registers. */
   11.11  #define VIOSAPIC_REG_SELECT   0x00
   11.12 @@ -42,8 +44,6 @@
   11.13  
   11.14  #define VIOSAPIC_VERSION_ID   0x21 /* IOSAPIC version */
   11.15  
   11.16 -#define VIOSAPIC_NUM_PINS     48
   11.17 -
   11.18  #define VIOSAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
   11.19  #define VIOSAPIC_MEM_LENGTH            0x100
   11.20  
   11.21 @@ -52,27 +52,6 @@
   11.22                                          arch.hvm_domain.viosapic))
   11.23  #define vcpu_viosapic(v) (&(v)->domain->arch.hvm_domain.viosapic)
   11.24  
   11.25 -union viosapic_rte
   11.26 -{
   11.27 -    uint64_t bits;
   11.28 -    struct {
   11.29 -        uint8_t vector;
   11.30 -
   11.31 -        uint8_t delivery_mode  : 3;
   11.32 -        uint8_t reserve1       : 1;
   11.33 -        uint8_t delivery_status: 1;
   11.34 -        uint8_t polarity       : 1;
   11.35 -        uint8_t reserve2       : 1;
   11.36 -        uint8_t trig_mode      : 1;
   11.37 -
   11.38 -        uint8_t mask           : 1;
   11.39 -        uint8_t reserve3       : 7;
   11.40 -
   11.41 -        uint8_t reserved[3];
   11.42 -        uint16_t dest_id;
   11.43 -    }; 
   11.44 -};
   11.45 -
   11.46  struct viosapic {
   11.47      uint64_t irr;
   11.48      uint64_t isr;     /* This is used for level trigger */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/xen/include/public/arch-ia64/hvm/save.h	Sun Oct 21 14:39:07 2007 -0600
    12.3 @@ -0,0 +1,195 @@
    12.4 +/******************************************************************************
    12.5 + * save_types.h
    12.6 + *
    12.7 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
    12.8 + *                    VA Linux Systems Japan K.K.
    12.9 + *
   12.10 + * This program is free software; you can redistribute it and/or modify
   12.11 + * it under the terms of the GNU General Public License as published by
   12.12 + * the Free Software Foundation; either version 2 of the License, or
   12.13 + * (at your option) any later version.
   12.14 + *
   12.15 + * This program is distributed in the hope that it will be useful,
   12.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.18 + * GNU General Public License for more details.
   12.19 + *
   12.20 + * You should have received a copy of the GNU General Public License
   12.21 + * along with this program; if not, write to the Free Software
   12.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   12.23 + *
   12.24 + */
   12.25 +
   12.26 +#ifndef __XEN_PUBLIC_HVM_SAVE_IA64_H__
   12.27 +#define __XEN_PUBLIC_HVM_SAVE_IA64_H__
   12.28 +
   12.29 +#include <public/hvm/save.h>
   12.30 +#include <public/arch-ia64.h>
   12.31 +
   12.32 +/* 
   12.33 + * Save/restore header: general info about the save file. 
   12.34 + */
   12.35 +
   12.36 +/* x86 uses 0x54381286 */
   12.37 +#define HVM_FILE_MAGIC   0x343641492f6e6558UL   /* "Xen/IA64" */
   12.38 +#define HVM_FILE_VERSION 0x0000000000000001UL
   12.39 +
   12.40 +struct hvm_save_header {
   12.41 +    uint64_t magic;             /* Must be HVM_FILE_MAGIC */
   12.42 +    uint64_t version;           /* File format version */
   12.43 +    uint64_t changeset;         /* Version of Xen that saved this file */
   12.44 +    uint64_t cpuid[5];          /* CPUID[0x01][%eax] on the saving machine */
   12.45 +};
   12.46 +
   12.47 +DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
   12.48 +
   12.49 +/*
   12.50 + * CPU
   12.51 + */
   12.52 +struct hvm_hw_ia64_cpu {
   12.53 +    uint64_t    ipsr;
   12.54 +};
   12.55 +DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_ia64_cpu);
   12.56 +
   12.57 +/*
   12.58 + * CPU
   12.59 + */
   12.60 +struct hvm_hw_ia64_vpd {
   12.61 +    struct vpd      vpd;
   12.62 +};
   12.63 +DECLARE_HVM_SAVE_TYPE(VPD, 3, struct hvm_hw_ia64_vpd);
   12.64 +
   12.65 +/*
   12.66 + * device dependency
   12.67 + * vacpi => viosapic => vlsapic
   12.68 + */
   12.69 +/*
   12.70 + * vlsapic
   12.71 + */
   12.72 +struct hvm_hw_ia64_vlsapic {
   12.73 +    uint64_t insvc[4];
   12.74 +    uint64_t vhpi; // ??? should this be saved in vpd
   12.75 +    uint8_t xtp;
   12.76 +    uint8_t pal_init_pending;
   12.77 +    uint8_t pad[2];
   12.78 +};
   12.79 +DECLARE_HVM_SAVE_TYPE(VLSAPIC, 4, struct hvm_hw_ia64_vlsapic);
   12.80 +// unconditionaly set v->arch.irq_new_peding = 1 
   12.81 +// unconditionaly set v->arch.irq_new_condition = 0
   12.82 +
   12.83 +/*
   12.84 + * vtime
   12.85 + */
   12.86 +// itc, itm, itv are saved by arch vcpu context
   12.87 +struct hvm_hw_ia64_vtime {
   12.88 +    uint64_t itc;
   12.89 +    uint64_t itm;
   12.90 +
   12.91 +    uint64_t last_itc;
   12.92 +    uint64_t pending;
   12.93 +};
   12.94 +DECLARE_HVM_SAVE_TYPE(VTIME, 5, struct hvm_hw_ia64_vtime);
   12.95 +// calculate v->vtm.vtm_offset
   12.96 +// ??? Or should vtm_offset be set by leave_hypervisor_tail()?
   12.97 +// start vtm_timer if necessary by vtm_set_itm().
   12.98 +// ??? Or should vtm_timer be set by leave_hypervisor_tail()?
   12.99 +//
  12.100 +// ??? or should be done by schedule_tail()
  12.101 +//        => schedule_tail() should do.
  12.102 +
  12.103 +/*
  12.104 + * viosapic
  12.105 + */
  12.106 +#define VIOSAPIC_NUM_PINS     48
  12.107 +
  12.108 +union viosapic_rte
  12.109 +{
  12.110 +    uint64_t bits;
  12.111 +    struct {
  12.112 +        uint8_t vector;
  12.113 +
  12.114 +        uint8_t delivery_mode  : 3;
  12.115 +        uint8_t reserve1       : 1;
  12.116 +        uint8_t delivery_status: 1;
  12.117 +        uint8_t polarity       : 1;
  12.118 +        uint8_t reserve2       : 1;
  12.119 +        uint8_t trig_mode      : 1;
  12.120 +
  12.121 +        uint8_t mask           : 1;
  12.122 +        uint8_t reserve3       : 7;
  12.123 +
  12.124 +        uint8_t reserved[3];
  12.125 +        uint16_t dest_id;
  12.126 +    }; 
  12.127 +};
  12.128 +
  12.129 +struct hvm_hw_ia64_viosapic {
  12.130 +    uint64_t    irr;
  12.131 +    uint64_t    isr;
  12.132 +    uint32_t    ioregsel;
  12.133 +    uint32_t    pad;
  12.134 +    uint64_t    lowest_vcpu_id;
  12.135 +    uint64_t    base_address;
  12.136 +    union viosapic_rte  redirtbl[VIOSAPIC_NUM_PINS];
  12.137 +};
  12.138 +DECLARE_HVM_SAVE_TYPE(VIOSAPIC, 6, struct hvm_hw_ia64_viosapic);
  12.139 +  
  12.140 +/*
  12.141 + * vacpi
  12.142 + * PM timer
  12.143 + */
  12.144 +#if 0
  12.145 +struct hvm_hw_ia64_pmtimer {
  12.146 +    uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
  12.147 +    uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
  12.148 +    uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
  12.149 +};
  12.150 +DECLARE_HVM_SAVE_TYPE(PMTIMER, 7, struct hvm_hw_ia64_pmtimer);
  12.151 +#else
  12.152 +struct vacpi_regs {
  12.153 +	union {
  12.154 +		struct {
  12.155 +			uint32_t pm1a_sts:16;
  12.156 +			uint32_t pm1a_en:16;
  12.157 +		};
  12.158 +		uint32_t evt_blk;
  12.159 +	};
  12.160 +	uint32_t tmr_val;
  12.161 +};
  12.162 +
  12.163 +struct hvm_hw_ia64_vacpi {
  12.164 +    struct vacpi_regs   regs;
  12.165 +};
  12.166 +DECLARE_HVM_SAVE_TYPE(VACPI, 7, struct hvm_hw_ia64_vacpi);
  12.167 +// update last_gtime and setup timer of struct vacpi
  12.168 +#endif
  12.169 +
  12.170 +#if 0
  12.171 +/*
  12.172 + * guest os type
  12.173 + * XXX Xen guest os specific optimization
  12.174 + *     This isn't hvm specific so this should be addressed genericly
  12.175 + *     including paravirtualized domain.
  12.176 + */
  12.177 +struct hvm_hw_ia64_gos {
  12.178 +    uint64_t	gos_type;
  12.179 +};
  12.180 +DECLARE_HVM_SAVE_TYPE(GOS_TYPE, 8, struct hvm_hw_ia64_gos);
  12.181 +#endif
  12.182 +
  12.183 +/* 
  12.184 + * Largest type-code in use
  12.185 + */
  12.186 +#define HVM_SAVE_CODE_MAX       7
  12.187 +
  12.188 +#endif /* __XEN_PUBLIC_HVM_SAVE_IA64_H__ */
  12.189 +
  12.190 +/*
  12.191 + * Local variables:
  12.192 + * mode: C
  12.193 + * c-set-style: "BSD"
  12.194 + * c-basic-offset: 4
  12.195 + * tab-width: 4
  12.196 + * indent-tabs-mode: nil
  12.197 + * End:
  12.198 + */
    13.1 --- a/xen/include/public/hvm/save.h	Sun Oct 21 13:38:57 2007 -0600
    13.2 +++ b/xen/include/public/hvm/save.h	Sun Oct 21 14:39:07 2007 -0600
    13.3 @@ -75,6 +75,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm
    13.4  
    13.5  #if defined(__i386__) || defined(__x86_64__)
    13.6  #include "../arch-x86/hvm/save.h"
    13.7 +#elif defined(__ia64__)
    13.8 +#include "../arch-ia64/hvm/save.h"
    13.9  #else
   13.10  #error "unsupported architecture"
   13.11  #endif