WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ia64-devel

[Xen-ia64-devel] [PATCH 21/23] [RFC] vti domain save/restore: implement

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [PATCH 21/23] [RFC] vti domain save/restore: implement hvm_save/load. work in progress.
From: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Date: Fri, 12 Oct 2007 12:51:36 +0900
Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Delivery-date: Thu, 11 Oct 2007 20:54:10 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.2.1i
# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Date 1192101030 -32400
# Node ID 9009a8f49f11378d562a4aed005b17f136a773c0
# Parent  57c32f36b569df0b24edd1d90b0d45035cce55d5
implement IA64 VTi domain save/restore. work in progress
PATCHNAME: implement_vti_domain_save_restore

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

diff -r 57c32f36b569 -r 9009a8f49f11 config/ia64.mk
--- a/config/ia64.mk    Thu Oct 11 19:04:53 2007 +0900
+++ b/config/ia64.mk    Thu Oct 11 20:10:30 2007 +0900
@@ -1,6 +1,7 @@ CONFIG_IA64 := y
 CONFIG_IA64 := y
 CONFIG_IA64_$(XEN_OS) := y
 
+CONFIG_HVM_SAVE := y
 CONFIG_IOEMU := y
 CONFIG_XCUTILS := y
 CONFIG_XENCOMM := y
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/Makefile
--- a/xen/arch/ia64/vmx/Makefile        Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/arch/ia64/vmx/Makefile        Thu Oct 11 20:10:30 2007 +0900
@@ -20,3 +20,4 @@ obj-y += optvfault.o
 obj-y += optvfault.o
 obj-y += vacpi.o
 obj-y += vmx_vcpu_save.o
+obj-y += save.o
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/save.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ia64/vmx/save.c  Thu Oct 11 20:10:30 2007 +0900
@@ -0,0 +1,72 @@
+/*
+ * hvm/save.c: Save and restore HVM guest's emulated hardware state.
+ *
+ * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
+ *                     VA Linux Systems Japan K.K.
+ *                     IA64 support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <xen/types.h>
+#include <public/hvm/save.h>
+#include <xen/hvm/support.h>
+
+void
+arch_hvm_save(struct hvm_save_header *hdr)
+{
+    unsigned int i;
+    
+    for (i = 0; i < 5; ++i)
+        hdr->cpuid[i] = ia64_get_cpuid(i);
+}
+
+int
+arch_hvm_load(struct hvm_save_header *hdr)
+{
+    unsigned int i;
+    if (hdr->magic != HVM_FILE_MAGIC) {
+        gdprintk(XENLOG_ERR, 
+                 "HVM restore: bad magic number %#"PRIx64"\n", hdr->magic);
+        return -1;
+    }
+
+    if (hdr->version != HVM_FILE_VERSION) {
+        gdprintk(XENLOG_ERR, 
+                 "HVM restore: unsupported version %"PRIx64"\n", hdr->version);
+        return -1;
+    }
+
+    for (i = 0; i < 5; ++i) {
+        unsigned long cpuid = ia64_get_cpuid(i);
+        /*TODO: need to define how big a difference is acceptable */
+        if (hdr->cpuid[i] != cpuid)
+            gdprintk(XENLOG_WARNING,
+                     "HVM restore: saved CPUID[%d] (%#lx) "
+                     "does not match host (%#lx).\n", i, hdr->cpuid[i], cpuid);
+    }
+
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vacpi.c
--- a/xen/arch/ia64/vmx/vacpi.c Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/arch/ia64/vmx/vacpi.c Thu Oct 11 20:10:30 2007 +0900
@@ -7,6 +7,7 @@
  * Copyright (c) 2007 VA Linux Systems Japan K.K
  *      Isaku Yamahata <yamahata at valinux co jp>
  *      SMP support
+ *      save/restore support
  *
  * Copyright (c) 2007, XenSource inc.
  * Copyright (c) 2006, Intel Corporation.
@@ -28,6 +29,8 @@
 #include <asm/vmx_vcpu.h>
 #include <asm/vmx.h>
 #include <asm/hvm/vacpi.h>
+#include <asm/hvm/support.h>
+#include <public/hvm/save.h>
 
 /* The interesting bits of the PM1a_STS register */
 #define TMR_STS    (1 << 0)
@@ -197,3 +200,69 @@ void vacpi_relinquish_resources(struct d
        struct vacpi *s = &d->arch.hvm_domain.vacpi;
        kill_timer(&s->timer);
 }
+
+// stolen from xen/arch/x86/hvm/pmtimer.c
+static int vacpi_save(struct domain *d, hvm_domain_context_t *h)
+{
+       struct vacpi *s = &d->arch.hvm_domain.vacpi;
+       unsigned long delta;
+       uint32_t msb = s->regs.tmr_val & TMR_VAL_MSB;
+       struct hvm_hw_ia64_vacpi vacpi_save;
+       int rc;
+
+       stop_timer(&s->timer); //XXX
+       
+       spin_lock(&s->lock);
+
+       /* Update the counter to the guest's current time.  We always save
+        * with the domain paused, so the saved time should be after the
+        * last_gtime, but just in case, make sure we only go forwards */
+
+       //XXX NOW() should be the time that domais paused
+       delta = NOW() - s->last_gtime; 
+       delta = ((delta >> 8) * ((FREQUENCE_PMTIMER << 32) / SECONDS(1))) >> 24;
+       if ( delta < 1UL<<31 )
+               s->regs.tmr_val += delta;
+       if ( (s->regs.tmr_val & TMR_VAL_MSB) != msb )
+               s->regs.pm1a_sts |= TMR_STS;
+       /* No point in setting the SCI here because we'll already have saved 
the 
+        * IRQ and *PIC state; we'll fix it up when we restore the domain */
+
+       vacpi_save.regs = s->regs;
+       rc = hvm_save_entry(VACPI, 0, h, &vacpi_save);
+       
+       spin_unlock(&s->lock);
+
+       pmt_timer_callback(d);//XXX This might change the domain state.
+       return 0;
+}
+
+static int vacpi_load(struct domain *d, hvm_domain_context_t *h)
+{
+       struct vacpi *s = &d->arch.hvm_domain.vacpi;
+       struct hvm_hw_ia64_vacpi vacpi_load;
+
+       /* Reload the registers */
+       if ( hvm_load_entry(VACPI, h, &vacpi_load) )
+               return -EINVAL;
+
+       stop_timer(&s->timer);//XXX
+
+       spin_lock(&s->lock);
+
+       s->regs = vacpi_load.regs;
+
+       /* Calculate future counter values from now. */
+       //XXX NOW(); last_gtime should be set when domain is unpaused
+       s->last_gtime = NOW(); 
+
+       /* Set the SCI state from the registers */ 
+       pmt_update_sci(d, s);
+
+       spin_unlock(&s->lock);
+
+       pmt_timer_callback(d);//XXX
+       return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VACPI, vacpi_save, vacpi_load, 1, HVMSR_PER_DOM);
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/viosapic.c
--- a/xen/arch/ia64/vmx/viosapic.c      Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/arch/ia64/vmx/viosapic.c      Thu Oct 11 20:10:30 2007 +0900
@@ -27,6 +27,7 @@
  *  Copyright (C) 2007 VA Linux Systems Japan K.K.
  *  Isaku Yamahata <yamahata at valinux co jp>
  *  SMP support
+ *  xen save/restore support
  */
 
 #include <xen/config.h>
@@ -40,6 +41,8 @@
 #include <asm/viosapic.h>
 #include <asm/current.h>
 #include <asm/event.h>
+#include <asm/hvm/support.h>
+#include <public/hvm/save.h>
 
 static void viosapic_deliver(struct viosapic *viosapic, int irq)
 {
@@ -355,3 +358,69 @@ void viosapic_init(struct domain *d)
     
     viosapic->base_address = VIOSAPIC_DEFAULT_BASE_ADDRESS;
 }
+
+#define VIOSAPIC_INVALID_VCPU_ID (-1UL)
+static int viosapic_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct viosapic *viosapic = domain_viosapic(d);
+    struct hvm_hw_ia64_viosapic viosapic_save;
+    int i;
+
+    memset(&viosapic_save, 0, sizeof(viosapic_save));
+    
+    spin_lock(&viosapic->lock);
+    viosapic_save.irr = viosapic->irr;
+    viosapic_save.isr = viosapic->isr;
+    viosapic_save.ioregsel = viosapic->ioregsel;
+    if (viosapic->lowest_vcpu != NULL)
+        viosapic_save.lowest_vcpu_id = viosapic->lowest_vcpu->vcpu_id;
+    else
+        viosapic_save.lowest_vcpu_id = VIOSAPIC_INVALID_VCPU_ID;
+    viosapic_save.base_address = viosapic->base_address;
+
+    for (i = 0; i < VIOSAPIC_NUM_PINS; i++)
+        viosapic_save.redirtbl[i] = viosapic->redirtbl[i];
+    spin_unlock(&viosapic->lock);
+
+    return hvm_save_entry(VIOSAPIC, 0, h, &viosapic_save);
+}
+
+static int viosapic_load(struct domain *d, hvm_domain_context_t *h)
+{
+    struct viosapic *viosapic = domain_viosapic(d);
+    struct hvm_hw_ia64_viosapic viosapic_load;
+    struct vcpu *lowest_vcpu;
+    int i;
+
+    if (hvm_load_entry(VIOSAPIC, h, &viosapic_load))
+        return -EINVAL;
+
+    lowest_vcpu = NULL;
+    if (viosapic_load.lowest_vcpu_id < MAX_VIRT_CPUS)
+        lowest_vcpu = d->vcpu[viosapic_load.lowest_vcpu_id];
+    else if (viosapic_load.lowest_vcpu_id != VIOSAPIC_INVALID_VCPU_ID)
+        return -EINVAL;
+
+    if (viosapic_load.base_address != VIOSAPIC_DEFAULT_BASE_ADDRESS)
+        return -EINVAL;
+
+    spin_lock(&viosapic->lock);
+    viosapic->irr = viosapic_load.irr;
+    viosapic->isr = viosapic_load.isr;
+    viosapic->ioregsel = viosapic_load.ioregsel;
+
+    viosapic->lowest_vcpu = lowest_vcpu;
+
+    viosapic->base_address = viosapic_load.base_address;
+
+    for (i = 0; i < VIOSAPIC_NUM_PINS; i++)
+        viosapic->redirtbl[i] = viosapic_load.redirtbl[i];
+
+    service_iosapic(viosapic);//XXX
+    spin_unlock(&viosapic->lock);
+
+    return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VIOSAPIC, viosapic_save, viosapic_load,
+                          1, HVMSR_PER_DOM);
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vlsapic.c
--- a/xen/arch/ia64/vmx/vlsapic.c       Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/arch/ia64/vmx/vlsapic.c       Thu Oct 11 20:10:30 2007 +0900
@@ -3,6 +3,10 @@
 /*
  * vlsapic.c: virtual lsapic model including ITC timer.
  * Copyright (c) 2005, Intel Corporation.
+ *
+ * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
+ *                     VA Linux Systems Japan K.K.
+ *                     save/restore support
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -40,6 +44,8 @@
 #include <asm/vlsapic.h>
 #include <asm/linux/jiffies.h>
 #include <xen/domain.h>
+#include <asm/hvm/support.h>
+#include <public/hvm/save.h>
 
 #ifdef IPI_DEBUG
 #define IPI_DPRINTK(x...) printk(x)
@@ -820,3 +826,122 @@ void vlsapic_write(struct vcpu *v,
     }
 }
 
+static int vlsapic_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct vcpu *v;
+
+    for_each_vcpu(d, v) {
+        struct hvm_hw_ia64_vlsapic vlsapic;
+        int i;
+
+        if (test_bit(_VPF_down, &v->pause_flags))
+            continue;
+
+        memset(&vlsapic, 0, sizeof(vlsapic));
+        for (i = 0; i < 4; i++)
+            vlsapic.insvc[i] = VLSAPIC_INSVC(v,i);
+
+        vlsapic.vhpi = VCPU(v, vhpi);
+        vlsapic.xtp = VLSAPIC_XTP(v);
+        vlsapic.pal_init_pending = v->arch.arch_vmx.pal_init_pending;
+
+        if (hvm_save_entry(VLSAPIC, v->vcpu_id, h, &vlsapic))
+            return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int vlsapic_load(struct domain *d, hvm_domain_context_t *h)
+{
+    uint16_t vcpuid;
+    struct vcpu *v;
+    struct hvm_hw_ia64_vlsapic vlsapic;
+    int i;
+
+    vcpuid = hvm_load_instance(h);
+    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
+        gdprintk(XENLOG_ERR,
+                 "%s: domain has no vlsapic %u\n", __func__, vcpuid);
+        return -EINVAL;
+    }
+
+    if (hvm_load_entry(VLSAPIC, h, &vlsapic) != 0) 
+        return -EINVAL;
+
+    for (i = 0; i < 4; i++)
+        VLSAPIC_INSVC(v,i) = vlsapic.insvc[i];
+
+    VCPU(v, vhpi) = vlsapic.vhpi;
+    VLSAPIC_XTP(v) = vlsapic.xtp;
+    v->arch.arch_vmx.pal_init_pending = vlsapic.pal_init_pending;
+    v->arch.irq_new_pending = 1; /* to force checking irq */
+
+    return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VLSAPIC, vlsapic_save, vlsapic_load,
+                          1, HVMSR_PER_VCPU);
+
+static int vtime_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct vcpu *v;
+
+    for_each_vcpu(d, v) {
+        vtime_t *vtm = &VMX(v, vtm);
+        struct hvm_hw_ia64_vtime vtime;
+
+        if (test_bit(_VPF_down, &v->pause_flags))
+            continue;
+
+        stop_timer(&vtm->vtm_timer);//XXX should wait for callback not running.
+
+        memset(&vtime, 0, sizeof(vtime));
+        vtime.itc = now_itc(vtm);
+        vtime.itm = VCPU(v, itm);
+        vtime.last_itc = vtm->last_itc;
+        vtime.pending = vtm->pending;
+
+        vtm_set_itm(v, vtime.itm);// this may start timer.
+
+        if (hvm_save_entry(VTIME, v->vcpu_id, h, &vtime))
+            return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int vtime_load(struct domain *d, hvm_domain_context_t *h)
+{
+    uint16_t vcpuid;
+    struct vcpu *v;
+    struct hvm_hw_ia64_vtime vtime;
+    vtime_t *vtm;
+
+    vcpuid = hvm_load_instance(h);
+    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
+        gdprintk(XENLOG_ERR,
+                 "%s: domain has no vtime %u\n", __func__, vcpuid);
+        return -EINVAL;
+    }
+
+    if (hvm_load_entry(VTIME, h, &vtime) != 0)
+        return -EINVAL;
+
+    vtm = &VMX(v, vtm);
+    stop_timer(&vtm->vtm_timer); //XXX should wait for callback not running.
+
+    vtm->last_itc = vtime.last_itc;
+    vtm->pending = vtime.pending;
+
+    migrate_timer(&vtm->vtm_timer, v->processor);
+    vtm_set_itm(v, vtime.itm);
+    vtm_set_itc(v, vtime.itc); // This may start timer.
+
+    if (test_and_clear_bit(_VPF_down, &v->pause_flags))
+        vcpu_wake(v);
+
+    return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VTIME, vtime_save, vtime_load, 1, HVMSR_PER_VCPU);
diff -r 57c32f36b569 -r 9009a8f49f11 xen/arch/ia64/vmx/vmx_vcpu_save.c
--- a/xen/arch/ia64/vmx/vmx_vcpu_save.c Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/arch/ia64/vmx/vmx_vcpu_save.c Thu Oct 11 20:10:30 2007 +0900
@@ -22,6 +22,8 @@
 
 #include <asm/vmx_vcpu.h>
 #include <asm/vmx_vcpu_save.h>
+#include <asm/hvm/support.h>
+#include <public/hvm/save.h>
 
 void
 vmx_arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
@@ -192,6 +194,166 @@ vmx_arch_set_info_guest(struct vcpu *v, 
     return 0;
 }
 
+
+static int vmx_cpu_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct vcpu *v;
+
+    for_each_vcpu(d, v) {
+        struct pt_regs *regs = vcpu_regs(v);
+        struct hvm_hw_ia64_cpu ia64_cpu;
+
+        if (test_bit(_VPF_down, &v->pause_flags))
+            continue;
+
+        memset(&ia64_cpu, 0, sizeof(ia64_cpu));
+
+        ia64_cpu.ipsr = regs->cr_ipsr;
+
+        if (hvm_save_entry(CPU, v->vcpu_id, h, &ia64_cpu))
+            return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int vmx_cpu_load(struct domain *d, hvm_domain_context_t *h)
+{
+    int rc = 0;
+    uint16_t vcpuid;
+    struct vcpu *v;
+    struct hvm_hw_ia64_cpu ia64_cpu;
+    struct pt_regs *regs;
+
+    vcpuid = hvm_load_instance(h);
+    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
+        gdprintk(XENLOG_ERR,
+                 "%s: domain has no vcpu %u\n", __func__, vcpuid);
+        rc = -EINVAL;
+        goto out;
+    }
+
+    if (hvm_load_entry(CPU, h, &ia64_cpu) != 0) {
+        rc = -EINVAL;
+        goto out;
+    }
+
+    regs = vcpu_regs(v);
+    regs->cr_ipsr = ia64_cpu.ipsr | IA64_PSR_VM;
+
+ out:
+    return rc;
+}
+
+HVM_REGISTER_SAVE_RESTORE(CPU, vmx_cpu_save, vmx_cpu_load, 1, HVMSR_PER_VCPU);
+
+static int vmx_vpd_save(struct domain *d, hvm_domain_context_t *h)
+{
+    struct vcpu *v;
+
+    for_each_vcpu(d, v) {
+        vpd_t *vpd = (void *)v->arch.privregs;
+
+        if (test_bit(_VPF_down, &v->pause_flags))
+            continue;
+        
+        // currently struct hvm_hw_ia64_vpd = struct vpd
+        // if it is changed, this must be revised.
+        if (hvm_save_entry(VPD, v->vcpu_id, h, (struct hvm_hw_ia64_vpd*)vpd))
+            return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int vmx_vpd_load(struct domain *d, hvm_domain_context_t *h)
+{
+    int rc = 0;
+    uint16_t vcpuid;
+    struct vcpu *v;
+    vpd_t *vpd;
+    struct hvm_hw_ia64_vpd *ia64_vpd = NULL;
+    int i;
+
+    vcpuid = hvm_load_instance(h);
+    if (vcpuid > MAX_VIRT_CPUS || (v = d->vcpu[vcpuid]) == NULL) {
+        gdprintk(XENLOG_ERR,
+                 "%s: domain has no vcpu %u\n", __func__, vcpuid);
+        rc = -EINVAL;
+        goto out;
+    }
+
+    ia64_vpd = xmalloc(struct hvm_hw_ia64_vpd);
+    if (ia64_vpd == NULL) {
+        gdprintk(XENLOG_ERR,
+                 "%s: can't allocate memory %d\n", __func__, vcpuid);
+        rc = -ENOMEM;
+        goto out;
+    }
+
+    if (hvm_load_entry(VPD, h, ia64_vpd) != 0) {
+        rc = -EINVAL;
+        goto out;
+    }
+
+    vpd = (void *)v->arch.privregs;
+#define VPD_COPY(x)    vpd->vpd_low.x = ia64_vpd->vpd.vpd_low.x
+
+    for (i = 0; i < 16; i++)
+        VPD_COPY(vgr[i]);
+    for (i = 0; i < 16; i++)
+        VPD_COPY(vbgr[i]);
+    VPD_COPY(vnat);
+    VPD_COPY(vbnat);
+    for (i = 0; i < 5; i++)
+        VPD_COPY(vcpuid[i]);
+    VPD_COPY(vpsr);
+    VPD_COPY(vpr);
+
+    // cr
+#if 0
+    VPD_COPY(dcr);
+    VPD_COPY(itm);
+    VPD_COPY(iva);
+    VPD_COPY(pta);
+    VPD_COPY(ipsr);
+    VPD_COPY(isr);
+    VPD_COPY(iip);
+    VPD_COPY(ifa);
+    VPD_COPY(itir);
+    VPD_COPY(iipa);
+    VPD_COPY(ifs);
+    VPD_COPY(iim);
+    VPD_COPY(iha);
+    VPD_COPY(lid);
+    VPD_COPY(ivr);
+    VPD_COPY(tpr);
+    VPD_COPY(eoi);
+    VPD_COPY(irr[0]);
+    VPD_COPY(irr[1]);
+    VPD_COPY(irr[2]);
+    VPD_COPY(irr[3]);
+    VPD_COPY(itv);
+    VPD_COPY(pmv);
+    VPD_COPY(cmcv);
+    VPD_COPY(lrr0);
+    VPD_COPY(lrr1);
+#else
+    memcpy(&vpd->vpd_low.vcr[0], &ia64_vpd->vpd.vpd_low.vcr[0],
+           sizeof(vpd->vpd_low.vcr));
+#endif
+#undef VPD_COPY
+
+    v->arch.irq_new_condition = 1;
+
+ out:
+    if (ia64_vpd != NULL)
+        xfree(ia64_vpd);
+    return rc;
+}
+
+HVM_REGISTER_SAVE_RESTORE(VPD, vmx_vpd_save, vmx_vpd_load, 1, HVMSR_PER_VCPU);
+
 /*
  * Local variables:
  * mode: C
diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/hvm/support.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-ia64/hvm/support.h        Thu Oct 11 20:10:30 2007 +0900
@@ -0,0 +1,28 @@
+/*
+ * xen/include/asm-ia64/hvm/support.h
+ *
+ * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
+ *                     VA Linux Systems Japan K.K.
+ *                     IA64 support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_IA64_HVM_SUPPORT_H__
+#define __ASM_IA64_HVM_SUPPORT_H__
+
+#include <xen/hvm/support.h>
+
+#endif /* __ASM_IA64_HVM_SUPPORT_H__ */
diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/hvm/vacpi.h
--- a/xen/include/asm-ia64/hvm/vacpi.h  Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/include/asm-ia64/hvm/vacpi.h  Thu Oct 11 20:10:30 2007 +0900
@@ -21,6 +21,7 @@
 #ifndef __ASM_IA64_HVM_VACPI_H__
 #define __ASM_IA64_HVM_VACPI_H__
 
+#include <public/hvm/save-ia64.h> /* for struct vacpi_regs */
 #include <public/hvm/ioreq.h>
 
 #define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40
@@ -30,17 +31,6 @@
 #define IS_ACPI_ADDR(X)  ((unsigned long)((X)-ACPI_PM1A_EVT_BLK_ADDRESS)<12)
 
 #define FREQUENCE_PMTIMER  3579545UL   /* Timer should run at 3.579545 MHz */
-
-struct vacpi_regs {
-       union {
-               struct {
-                       uint32_t pm1a_sts:16;
-                       uint32_t pm1a_en:16;
-               };
-               uint32_t evt_blk;
-       };
-       uint32_t tmr_val;
-};
 
 struct vacpi {
        struct vacpi_regs regs;
diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/asm-ia64/viosapic.h
--- a/xen/include/asm-ia64/viosapic.h   Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/include/asm-ia64/viosapic.h   Thu Oct 11 20:10:30 2007 +0900
@@ -29,6 +29,8 @@
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/smp.h>
+#include <public/hvm/save-ia64.h> /* for VIOSAPIC_NUM_PINS and
+                                    union viosapic_rte */
 
 /* Direct registers. */
 #define VIOSAPIC_REG_SELECT   0x00
@@ -42,8 +44,6 @@
 
 #define VIOSAPIC_VERSION_ID   0x21 /* IOSAPIC version */
 
-#define VIOSAPIC_NUM_PINS     48
-
 #define VIOSAPIC_DEFAULT_BASE_ADDRESS  0xfec00000
 #define VIOSAPIC_MEM_LENGTH            0x100
 
@@ -51,27 +51,6 @@
 #define viosapic_domain(v) (container_of((v), struct domain, \
                                         arch.hvm_domain.viosapic))
 #define vcpu_viosapic(v) (&(v)->domain->arch.hvm_domain.viosapic)
-
-union viosapic_rte
-{
-    uint64_t bits;
-    struct {
-        uint8_t vector;
-
-        uint8_t delivery_mode  : 3;
-        uint8_t reserve1       : 1;
-        uint8_t delivery_status: 1;
-        uint8_t polarity       : 1;
-        uint8_t reserve2       : 1;
-        uint8_t trig_mode      : 1;
-
-        uint8_t mask           : 1;
-        uint8_t reserve3       : 7;
-
-        uint8_t reserved[3];
-        uint16_t dest_id;
-    }; 
-};
 
 struct viosapic {
     uint64_t irr;
diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/public/hvm/save-ia64.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/public/hvm/save-ia64.h        Thu Oct 11 20:10:30 2007 +0900
@@ -0,0 +1,195 @@
+/******************************************************************************
+ * save_types.h
+ *
+ * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
+ *                    VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ASM_IA64_HVM_SAVE_TYPES_H__
+#define __ASM_IA64_HVM_SAVE_TYPES_H__
+
+#include <public/hvm/save.h>
+#include <public/arch-ia64.h>
+
+/* 
+ * Save/restore header: general info about the save file. 
+ */
+
+/* x86 uses 0x54381286 */
+#define HVM_FILE_MAGIC   0x343641492f6e6558UL   /* "Xen/IA64" */
+#define HVM_FILE_VERSION 0x0000000000000001UL
+
+struct hvm_save_header {
+    uint64_t magic;             /* Must be HVM_FILE_MAGIC */
+    uint64_t version;           /* File format version */
+    uint64_t changeset;         /* Version of Xen that saved this file */
+    uint64_t cpuid[5];          /* CPUID[0x01][%eax] on the saving machine */
+};
+
+DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
+
+/*
+ * CPU
+ */
+struct hvm_hw_ia64_cpu {
+    uint64_t    ipsr;
+};
+DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_ia64_cpu);
+
+/*
+ * CPU
+ */
+struct hvm_hw_ia64_vpd {
+    struct vpd      vpd;
+};
+DECLARE_HVM_SAVE_TYPE(VPD, 3, struct hvm_hw_ia64_vpd);
+
+/*
+ * device dependency
+ * vacpi => viosapic => vlsapic
+ */
+/*
+ * vlsapic
+ */
+struct hvm_hw_ia64_vlsapic {
+    uint64_t insvc[4];
+    uint64_t vhpi; // ??? should this be saved in vpd
+    uint8_t xtp;
+    uint8_t pal_init_pending;
+    uint8_t pad[2];
+};
+DECLARE_HVM_SAVE_TYPE(VLSAPIC, 4, struct hvm_hw_ia64_vlsapic);
+// unconditionaly set v->arch.irq_new_peding = 1 
+// unconditionaly set v->arch.irq_new_condition = 0
+
+/*
+ * vtime
+ */
+// itc, itm, itv are saved by arch vcpu context
+struct hvm_hw_ia64_vtime {
+    uint64_t itc;
+    uint64_t itm;
+
+    uint64_t last_itc;
+    uint64_t pending;
+};
+DECLARE_HVM_SAVE_TYPE(VTIME, 5, struct hvm_hw_ia64_vtime);
+// calculate v->vtm.vtm_offset
+// ??? Or should vtm_offset be set by leave_hypervisor_tail()?
+// start vtm_timer if necessary by vtm_set_itm().
+// ??? Or should vtm_timer be set by leave_hypervisor_tail()?
+//
+// ??? or should be done by schedule_tail()
+//        => schedule_tail() should do.
+
+/*
+ * viosapic
+ */
+#define VIOSAPIC_NUM_PINS     48
+
+union viosapic_rte
+{
+    uint64_t bits;
+    struct {
+        uint8_t vector;
+
+        uint8_t delivery_mode  : 3;
+        uint8_t reserve1       : 1;
+        uint8_t delivery_status: 1;
+        uint8_t polarity       : 1;
+        uint8_t reserve2       : 1;
+        uint8_t trig_mode      : 1;
+
+        uint8_t mask           : 1;
+        uint8_t reserve3       : 7;
+
+        uint8_t reserved[3];
+        uint16_t dest_id;
+    }; 
+};
+
+struct hvm_hw_ia64_viosapic {
+    uint64_t    irr;
+    uint64_t    isr;
+    uint32_t    ioregsel;
+    uint32_t    pad;
+    uint64_t    lowest_vcpu_id;
+    uint64_t    base_address;
+    union viosapic_rte  redirtbl[VIOSAPIC_NUM_PINS];
+};
+DECLARE_HVM_SAVE_TYPE(VIOSAPIC, 6, struct hvm_hw_ia64_viosapic);
+  
+/*
+ * vacpi
+ * PM timer
+ */
+#if 0
+struct hvm_hw_ia64_pmtimer {
+    uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
+    uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
+    uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
+};
+DECLARE_HVM_SAVE_TYPE(PMTIMER, 7, struct hvm_hw_ia64_pmtimer);
+#else
+struct vacpi_regs {
+       union {
+               struct {
+                       uint32_t pm1a_sts:16;
+                       uint32_t pm1a_en:16;
+               };
+               uint32_t evt_blk;
+       };
+       uint32_t tmr_val;
+};
+
+struct hvm_hw_ia64_vacpi {
+    struct vacpi_regs   regs;
+};
+DECLARE_HVM_SAVE_TYPE(VACPI, 7, struct hvm_hw_ia64_vacpi);
+// update last_gtime and setup timer of struct vacpi
+#endif
+
+#if 0
+/*
+ * guest os type
+ * XXX Xen guest os specific optimization
+ *     This isn't hvm specific so this should be addressed genericly
+ *     including paravirtualized domain.
+ */
+struct hvm_hw_ia64_gos {
+    uint64_t   gos_type;
+};
+DECLARE_HVM_SAVE_TYPE(GOS_TYPE, 8, struct hvm_hw_ia64_gos);
+#endif
+
+/* 
+ * Largest type-code in use
+ */
+#define HVM_SAVE_CODE_MAX       7
+
+#endif /* __ASM_IA64_HVM_SAVE_TYPES_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r 57c32f36b569 -r 9009a8f49f11 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Thu Oct 11 19:04:53 2007 +0900
+++ b/xen/include/public/hvm/save.h     Thu Oct 11 20:10:30 2007 +0900
@@ -76,6 +76,8 @@ DECLARE_HVM_SAVE_TYPE(END, 0, struct hvm
 
 #if defined(__i386__) || defined(__x86_64__)
 #include "save-x86.h"
+#elif defined(__ia64__)
+#include "save-ia64.h"
 #else
 #error "unsupported architecture"
 #endif

Attachment: 16068_9009a8f49f11_implement_vti_domain_save_restore.patch
Description: Text Data

_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-ia64-devel] [PATCH 21/23] [RFC] vti domain save/restore: implement hvm_save/load. work in progress., Isaku Yamahata <=