ia64/xen-unstable

changeset 904:90ae2bc0ebee

bitkeeper revision 1.572 (3fabca3boPogE8eX_8H6P5qlR4SCEQ)

memory.c, xi_save_linux.c, xi_restore_linux.c:
Moire fixes. Save/restore now works.
author kaf24@scramble.cl.cam.ac.uk
date Fri Nov 07 16:37:15 2003 +0000 (2003-11-07)
parents 099ae186d2cd
children f8e22c28741a 8d4b127849bd
files tools/internal/xi_restore_linux.c tools/internal/xi_save_linux.c xen/common/memory.c
line diff
     1.1 --- a/tools/internal/xi_restore_linux.c	Fri Nov 07 15:57:00 2003 +0000
     1.2 +++ b/tools/internal/xi_restore_linux.c	Fri Nov 07 16:37:15 2003 +0000
     1.3 @@ -15,6 +15,13 @@ static char *argv0 = "internal_restore_l
     1.4  /* A table mapping each PFN to its new MFN. */
     1.5  static unsigned long *pfn_to_mfn_table;
     1.6  
     1.7 +/* This may allow us to create a 'quiet' command-line option, if necessary. */
     1.8 +#define verbose_printf(_f, _a...) \
     1.9 +    do {                          \
    1.10 +        printf( _f , ## _a );     \
    1.11 +        fflush(stdout);           \
    1.12 +    } while ( 0 )
    1.13 +
    1.14  static int get_pfn_list(
    1.15      int domain_id, unsigned long *pfn_buf, unsigned long max_pfns)
    1.16  {
    1.17 @@ -126,6 +133,7 @@ int main(int argc, char **argv)
    1.18      dom0_op_t op;
    1.19      int rc = 1, i, j;
    1.20      unsigned long mfn, pfn, dom = 0;
    1.21 +    unsigned int prev_pc, this_pc;
    1.22      
    1.23      /* Number of page frames in use by this XenoLinux session. */
    1.24      unsigned long nr_pfns;
    1.25 @@ -256,12 +264,22 @@ int main(int argc, char **argv)
    1.26          goto out;
    1.27      }
    1.28  
    1.29 +    verbose_printf("Reloading memory pages:   0%%");
    1.30 +
    1.31      /*
    1.32       * Now simply read each saved frame into its new machine frame.
    1.33       * We uncanonicalise page tables as we go.
    1.34       */
    1.35 +    prev_pc = 0;
    1.36      for ( i = 0; i < nr_pfns; i++ )
    1.37      {
    1.38 +        this_pc = (i * 100) / nr_pfns;
    1.39 +        if ( (this_pc - prev_pc) >= 5 )
    1.40 +        {
    1.41 +            verbose_printf("\b\b\b\b%3d%%", this_pc);
    1.42 +            prev_pc = this_pc;
    1.43 +        }
    1.44 +
    1.45          mfn = pfn_to_mfn_table[i];
    1.46  
    1.47          if ( !checked_read(fd, page, PAGE_SIZE) )
    1.48 @@ -348,6 +366,8 @@ int main(int argc, char **argv)
    1.49      if ( flush_mmu_updates() )
    1.50          goto out;
    1.51  
    1.52 +    verbose_printf("\b\b\b\b100%%\nMemory reloaded.\n");
    1.53 +
    1.54      /* Uncanonicalise the suspend-record frame number and poke resume rec. */
    1.55      pfn = ctxt.i386_ctxt.esi;
    1.56      if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NONE) )
    1.57 @@ -446,13 +466,20 @@ int main(int argc, char **argv)
    1.58      rc = do_dom0_op(&op);
    1.59  
    1.60   out:
    1.61 -    /* If we experience an error then kill the half-constructed domain. */
    1.62 -    if ( (rc != 0) && (dom != 0) )
    1.63 +    if ( rc != 0 )
    1.64      {
    1.65 -        op.cmd = DOM0_DESTROYDOMAIN;
    1.66 -        op.u.destroydomain.domain = dom;
    1.67 -        op.u.destroydomain.force  = 1;
    1.68 -        (void)do_dom0_op(&op);
    1.69 +        if ( dom != 0 )
    1.70 +        {
    1.71 +            op.cmd = DOM0_DESTROYDOMAIN;
    1.72 +            op.u.destroydomain.domain = dom;
    1.73 +            op.u.destroydomain.force  = 1;
    1.74 +            (void)do_dom0_op(&op);
    1.75 +        }
    1.76 +    }
    1.77 +    else
    1.78 +    {
    1.79 +        /* Success: print the domain id. */
    1.80 +        printf("DOM=%ld\n", dom);
    1.81      }
    1.82  
    1.83      return !!rc;
     2.1 --- a/tools/internal/xi_save_linux.c	Fri Nov 07 15:57:00 2003 +0000
     2.2 +++ b/tools/internal/xi_save_linux.c	Fri Nov 07 16:37:15 2003 +0000
     2.3 @@ -17,6 +17,13 @@ static unsigned long *pfn_to_mfn_table;
     2.4  /* A table mapping each current MFN to its canonical PFN. */
     2.5  static unsigned long *mfn_to_pfn_table;
     2.6  
     2.7 +/* This may allow us to create a 'quiet' command-line option, if necessary. */
     2.8 +#define verbose_printf(_f, _a...) \
     2.9 +    do {                          \
    2.10 +        printf( _f , ## _a );     \
    2.11 +        fflush(stdout);           \
    2.12 +    } while ( 0 )
    2.13 +
    2.14  static int devmem_fd;
    2.15  
    2.16  static int init_pfn_mapper(void)
    2.17 @@ -100,6 +107,7 @@ int main(int argc, char **argv)
    2.18      dom0_op_t op;
    2.19      int rc = 1, i, j;
    2.20      unsigned long mfn, dom;
    2.21 +    unsigned int prev_pc, this_pc;
    2.22  
    2.23      /* Remember if we stopped the guest, so we can restart it on exit. */
    2.24      int we_stopped_it = 0;
    2.25 @@ -319,9 +327,19 @@ int main(int argc, char **argv)
    2.26      }
    2.27      unmap_pfn(ppage);
    2.28  
    2.29 +    verbose_printf("Saving memory pages:   0%%");
    2.30 +
    2.31      /* Now write out each data page, canonicalising page tables as we go... */
    2.32 +    prev_pc = 0;
    2.33      for ( i = 0; i < srec.nr_pfns; i++ )
    2.34      {
    2.35 +        this_pc = (i * 100) / srec.nr_pfns;
    2.36 +        if ( (this_pc - prev_pc) >= 5 )
    2.37 +        {
    2.38 +            verbose_printf("\b\b\b\b%3d%%", this_pc);
    2.39 +            prev_pc = this_pc;
    2.40 +        }
    2.41 +
    2.42          mfn = pfn_to_mfn_table[i];
    2.43  
    2.44          ppage = map_pfn(mfn);
    2.45 @@ -354,6 +372,8 @@ int main(int argc, char **argv)
    2.46          }
    2.47      }
    2.48  
    2.49 +    verbose_printf("\b\b\b\b100%%\nMemory saved.\n");
    2.50 +
    2.51      /* Success! */
    2.52      rc = 0;
    2.53  
     3.1 --- a/xen/common/memory.c	Fri Nov 07 15:57:00 2003 +0000
     3.2 +++ b/xen/common/memory.c	Fri Nov 07 16:37:15 2003 +0000
     3.3 @@ -138,7 +138,7 @@
     3.4  #include <asm/uaccess.h>
     3.5  #include <asm/domain_page.h>
     3.6  
     3.7 -#if 1
     3.8 +#if 0
     3.9  #define MEM_LOG(_f, _a...) printk("DOM%d: (file=memory.c, line=%d) " _f "\n", current->domain, __LINE__, ## _a )
    3.10  #else
    3.11  #define MEM_LOG(_f, _a...) ((void)0)
    3.12 @@ -395,6 +395,8 @@ static int get_twisted_l2_table(unsigned
    3.13  
    3.14  static int get_l2_table(unsigned long page_nr)
    3.15  {
    3.16 +    struct pfn_info *page;
    3.17 +    struct task_struct *p;
    3.18      l2_pgentry_t *p_l2_entry, l2_entry;
    3.19      int i, ret=0;
    3.20     
    3.21 @@ -424,13 +426,23 @@ static int get_l2_table(unsigned long pa
    3.22      memcpy(p_l2_entry, 
    3.23             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
    3.24             HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
    3.25 -    p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
    3.26 -              DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
    3.27 -        mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR);
    3.28      p_l2_entry[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT) -
    3.29                DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
    3.30          mk_l2_pgentry((page_nr << PAGE_SHIFT) | __PAGE_HYPERVISOR);
    3.31  
    3.32 +    /*
    3.33 +     * The per-domain PGD is slightly tricky, as we may not be executing
    3.34 +     * in the context of the correct domain (DOM0 builds pt's for others).
    3.35 +     */
    3.36 +    page = frame_table + page_nr;
    3.37 +    if ( (p = find_domain_by_id(page->flags & PG_domain_mask)) != NULL )
    3.38 +    {
    3.39 +        p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
    3.40 +                  DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
    3.41 +            mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR);
    3.42 +        put_task_struct(p);
    3.43 +    }
    3.44 +
    3.45   out:
    3.46      unmap_domain_mem(p_l2_entry);
    3.47      return ret;