mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
bitkeeper revision 1.572 (3fabca3boPogE8eX_8H6P5qlR4SCEQ)
memory.c, xi_save_linux.c, xi_restore_linux.c: Moire fixes. Save/restore now works.
This commit is contained in:
1 parent
4ab922b1a7
commit
5162084504
3 files changed
+69
-10
No files matched your search
@@ -15,6 +15,13 @@ static char *argv0 = "internal_restore_linux";
|
||||
/* A table mapping each PFN to its new MFN. */
|
||||
static unsigned long *pfn_to_mfn_table;
|
||||
|
||||
/* This may allow us to create a 'quiet' command-line option, if necessary. */
|
||||
#define verbose_printf(_f, _a...) \
|
||||
do { \
|
||||
printf( _f , ## _a ); \
|
||||
fflush(stdout); \
|
||||
} while ( 0 )
|
||||
|
||||
static int get_pfn_list(
|
||||
int domain_id, unsigned long *pfn_buf, unsigned long max_pfns)
|
||||
{
|
||||
@@ -126,6 +133,7 @@ int main(int argc, char **argv)
|
||||
dom0_op_t op;
|
||||
int rc = 1, i, j;
|
||||
unsigned long mfn, pfn, dom = 0;
|
||||
unsigned int prev_pc, this_pc;
|
||||
|
||||
/* Number of page frames in use by this XenoLinux session. */
|
||||
unsigned long nr_pfns;
|
||||
@@ -256,12 +264,22 @@ int main(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
verbose_printf("Reloading memory pages: 0%%");
|
||||
|
||||
/*
|
||||
* Now simply read each saved frame into its new machine frame.
|
||||
* We uncanonicalise page tables as we go.
|
||||
*/
|
||||
prev_pc = 0;
|
||||
for ( i = 0; i < nr_pfns; i++ )
|
||||
{
|
||||
this_pc = (i * 100) / nr_pfns;
|
||||
if ( (this_pc - prev_pc) >= 5 )
|
||||
{
|
||||
verbose_printf("\b\b\b\b%3d%%", this_pc);
|
||||
prev_pc = this_pc;
|
||||
}
|
||||
|
||||
mfn = pfn_to_mfn_table[i];
|
||||
|
||||
if ( !checked_read(fd, page, PAGE_SIZE) )
|
||||
@@ -348,6 +366,8 @@ int main(int argc, char **argv)
|
||||
if ( flush_mmu_updates() )
|
||||
goto out;
|
||||
|
||||
verbose_printf("\b\b\b\b100%%\nMemory reloaded.\n");
|
||||
|
||||
/* Uncanonicalise the suspend-record frame number and poke resume rec. */
|
||||
pfn = ctxt.i386_ctxt.esi;
|
||||
if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NONE) )
|
||||
@@ -446,13 +466,20 @@ int main(int argc, char **argv)
|
||||
rc = do_dom0_op(&op);
|
||||
|
||||
out:
|
||||
/* If we experience an error then kill the half-constructed domain. */
|
||||
if ( (rc != 0) && (dom != 0) )
|
||||
if ( rc != 0 )
|
||||
{
|
||||
op.cmd = DOM0_DESTROYDOMAIN;
|
||||
op.u.destroydomain.domain = dom;
|
||||
op.u.destroydomain.force = 1;
|
||||
(void)do_dom0_op(&op);
|
||||
if ( dom != 0 )
|
||||
{
|
||||
op.cmd = DOM0_DESTROYDOMAIN;
|
||||
op.u.destroydomain.domain = dom;
|
||||
op.u.destroydomain.force = 1;
|
||||
(void)do_dom0_op(&op);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Success: print the domain id. */
|
||||
printf("DOM=%ld\n", dom);
|
||||
}
|
||||
|
||||
return !!rc;
|
||||
|
||||
@@ -17,6 +17,13 @@ static unsigned long *pfn_to_mfn_table;
|
||||
/* A table mapping each current MFN to its canonical PFN. */
|
||||
static unsigned long *mfn_to_pfn_table;
|
||||
|
||||
/* This may allow us to create a 'quiet' command-line option, if necessary. */
|
||||
#define verbose_printf(_f, _a...) \
|
||||
do { \
|
||||
printf( _f , ## _a ); \
|
||||
fflush(stdout); \
|
||||
} while ( 0 )
|
||||
|
||||
static int devmem_fd;
|
||||
|
||||
static int init_pfn_mapper(void)
|
||||
@@ -100,6 +107,7 @@ int main(int argc, char **argv)
|
||||
dom0_op_t op;
|
||||
int rc = 1, i, j;
|
||||
unsigned long mfn, dom;
|
||||
unsigned int prev_pc, this_pc;
|
||||
|
||||
/* Remember if we stopped the guest, so we can restart it on exit. */
|
||||
int we_stopped_it = 0;
|
||||
@@ -319,9 +327,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
unmap_pfn(ppage);
|
||||
|
||||
verbose_printf("Saving memory pages: 0%%");
|
||||
|
||||
/* Now write out each data page, canonicalising page tables as we go... */
|
||||
prev_pc = 0;
|
||||
for ( i = 0; i < srec.nr_pfns; i++ )
|
||||
{
|
||||
this_pc = (i * 100) / srec.nr_pfns;
|
||||
if ( (this_pc - prev_pc) >= 5 )
|
||||
{
|
||||
verbose_printf("\b\b\b\b%3d%%", this_pc);
|
||||
prev_pc = this_pc;
|
||||
}
|
||||
|
||||
mfn = pfn_to_mfn_table[i];
|
||||
|
||||
ppage = map_pfn(mfn);
|
||||
@@ -354,6 +372,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
verbose_printf("\b\b\b\b100%%\nMemory saved.\n");
|
||||
|
||||
/* Success! */
|
||||
rc = 0;
|
||||
|
||||
|
||||
+16
-4
@@ -138,7 +138,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/domain_page.h>
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
#define MEM_LOG(_f, _a...) printk("DOM%d: (file=memory.c, line=%d) " _f "\n", current->domain, __LINE__, ## _a )
|
||||
#else
|
||||
#define MEM_LOG(_f, _a...) ((void)0)
|
||||
@@ -395,6 +395,8 @@ static int get_twisted_l2_table(unsigned long entry_pfn, l2_pgentry_t l2e)
|
||||
|
||||
static int get_l2_table(unsigned long page_nr)
|
||||
{
|
||||
struct pfn_info *page;
|
||||
struct task_struct *p;
|
||||
l2_pgentry_t *p_l2_entry, l2_entry;
|
||||
int i, ret=0;
|
||||
|
||||
@@ -424,13 +426,23 @@ static int get_l2_table(unsigned long page_nr)
|
||||
memcpy(p_l2_entry,
|
||||
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
|
||||
HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
|
||||
p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
|
||||
DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
|
||||
mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR);
|
||||
p_l2_entry[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT) -
|
||||
DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
|
||||
mk_l2_pgentry((page_nr << PAGE_SHIFT) | __PAGE_HYPERVISOR);
|
||||
|
||||
/*
|
||||
* The per-domain PGD is slightly tricky, as we may not be executing
|
||||
* in the context of the correct domain (DOM0 builds pt's for others).
|
||||
*/
|
||||
page = frame_table + page_nr;
|
||||
if ( (p = find_domain_by_id(page->flags & PG_domain_mask)) != NULL )
|
||||
{
|
||||
p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
|
||||
DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
|
||||
mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR);
|
||||
put_task_struct(p);
|
||||
}
|
||||
|
||||
out:
|
||||
unmap_domain_mem(p_l2_entry);
|
||||
return ret;
|
||||
|
||||