ia64/xen-unstable

changeset 4419:d1b9f9da04c2

bitkeeper revision 1.1236.1.183 (424d1ccaDlUUQZ1KrVHubRYFS5AKQA)

Batch p.t. pin requests during guest restore (after being suspended, or
after migration). Allow L1 tables to be pinned even after their va
backptr is fixed (no longer mutable).
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Apr 01 10:04:58 2005 +0000 (2005-04-01)
parents 941598a91ed0
children 09485b0bafad 6f22a415c2bc
files tools/libxc/xc_linux_restore.c tools/libxc/xc_private.c tools/libxc/xc_private.h xen/arch/x86/mm.c
line diff
     1.1 --- a/tools/libxc/xc_linux_restore.c	Fri Apr 01 09:40:25 2005 +0000
     1.2 +++ b/tools/libxc/xc_linux_restore.c	Fri Apr 01 10:04:58 2005 +0000
     1.3 @@ -106,6 +106,10 @@ int xc_linux_restore(int xc_handle, XcIO
     1.4      /* used by debug verify code */
     1.5      unsigned long buf[PAGE_SIZE/sizeof(unsigned long)];
     1.6  
     1.7 +#define MAX_PIN_BATCH 1024
     1.8 +    struct mmuext_op pin[MAX_PIN_BATCH];
     1.9 +    unsigned int nr_pins = 0;
    1.10 +
    1.11      xcio_info(ioctxt, "xc_linux_restore start\n");
    1.12  
    1.13      if ( mlock(&ctxt, sizeof(ctxt) ) )
    1.14 @@ -414,38 +418,33 @@ int xc_linux_restore(int xc_handle, XcIO
    1.15  
    1.16      xcio_info(ioctxt, "Received all pages\n");
    1.17  
    1.18 +    if ( finish_mmu_updates(xc_handle, mmu) )
    1.19 +        goto out;
    1.20 +
    1.21      /*
    1.22       * Pin page tables. Do this after writing to them as otherwise Xen
    1.23       * will barf when doing the type-checking.
    1.24       */
    1.25      for ( i = 0; i < nr_pfns; i++ )
    1.26      {
    1.27 +        if ( (pfn_type[i] & LPINTAB) == 0 )
    1.28 +            continue;
    1.29          if ( pfn_type[i] == (L1TAB|LPINTAB) )
    1.30 +            pin[nr_pins].cmd = MMUEXT_PIN_L1_TABLE;
    1.31 +        else /* pfn_type[i] == (L2TAB|LPINTAB) */
    1.32 +            pin[nr_pins].cmd = MMUEXT_PIN_L2_TABLE;
    1.33 +        pin[nr_pins].mfn = pfn_to_mfn_table[i];
    1.34 +        if ( ++nr_pins == MAX_PIN_BATCH )
    1.35          {
    1.36 -            if ( pin_table(xc_handle, MMUEXT_PIN_L1_TABLE,
    1.37 -                           pfn_to_mfn_table[i], dom) ) {
    1.38 -                printf("ERR pin L1 pfn=%lx mfn=%lx\n",
    1.39 -                       (unsigned long)i, pfn_to_mfn_table[i]);
    1.40 +            if ( do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 )
    1.41                  goto out;
    1.42 -            }
    1.43 +            nr_pins = 0;
    1.44          }
    1.45      }
    1.46  
    1.47 -    /* must pin all L1's before L2's (need consistent va back ptr) */
    1.48 -    for ( i = 0; i < nr_pfns; i++ )
    1.49 -    {
    1.50 -        if ( pfn_type[i] == (L2TAB|LPINTAB) )
    1.51 -        {
    1.52 -            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
    1.53 -                           pfn_to_mfn_table[i], dom) ) {
    1.54 -                printf("ERR pin L2 pfn=%lx mfn=%lx\n",
    1.55 -                       (unsigned long)i, pfn_to_mfn_table[i]);
    1.56 -                goto out;
    1.57 -            }
    1.58 -        }
    1.59 -    }
    1.60 -
    1.61 -    if ( finish_mmu_updates(xc_handle, mmu) ) goto out;
    1.62 +    if ( (nr_pins != 0) &&
    1.63 +         (do_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
    1.64 +        goto out;
    1.65  
    1.66      xcio_info(ioctxt, "\b\b\b\b100%%\n");
    1.67      xcio_info(ioctxt, "Memory reloaded.\n");
     2.1 --- a/tools/libxc/xc_private.c	Fri Apr 01 09:40:25 2005 +0000
     2.2 +++ b/tools/libxc/xc_private.c	Fri Apr 01 10:04:58 2005 +0000
     2.3 @@ -95,36 +95,15 @@ unsigned int get_pfn_type(int xc_handle,
     2.4  int pin_table(
     2.5      int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
     2.6  {
     2.7 -    int err = 0;
     2.8      struct mmuext_op op;
     2.9 -    privcmd_hypercall_t hypercall;
    2.10  
    2.11      op.cmd = type;
    2.12      op.mfn = mfn;
    2.13  
    2.14 -    hypercall.op     = __HYPERVISOR_mmuext_op;
    2.15 -    hypercall.arg[0] = (unsigned long)&op;
    2.16 -    hypercall.arg[1] = 1;
    2.17 -    hypercall.arg[2] = 0;
    2.18 -    hypercall.arg[3] = dom;
    2.19 +    if ( do_mmuext_op(xc_handle, &op, 1, dom) < 0 )
    2.20 +        return 1;
    2.21  
    2.22 -    if ( mlock(&op, sizeof(op)) != 0 )
    2.23 -    {
    2.24 -        PERROR("Could not lock mmuext_op");
    2.25 -        err = 1;
    2.26 -        goto out;
    2.27 -    }
    2.28 -
    2.29 -    if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
    2.30 -    {
    2.31 -        ERROR("Failure when submitting mmu updates");
    2.32 -        err = 1;
    2.33 -    }
    2.34 -
    2.35 -    (void)munlock(&op, sizeof(op));
    2.36 -
    2.37 - out:
    2.38 -    return err;
    2.39 +    return 0;
    2.40  }
    2.41  
    2.42  static int flush_mmu_updates(int xc_handle, mmu_t *mmu)
     3.1 --- a/tools/libxc/xc_private.h	Fri Apr 01 09:40:25 2005 +0000
     3.2 +++ b/tools/libxc/xc_private.h	Fri Apr 01 10:04:58 2005 +0000
     3.3 @@ -142,6 +142,38 @@ static inline int do_dom_mem_op(int     
     3.4   out1: return ret;
     3.5  }    
     3.6  
     3.7 +static inline int do_mmuext_op(
     3.8 +    int xc_handle,
     3.9 +    struct mmuext_op *op,
    3.10 +    unsigned int nr_ops,
    3.11 +    domid_t dom)
    3.12 +{
    3.13 +    privcmd_hypercall_t hypercall;
    3.14 +    long ret = -EINVAL;
    3.15 +	
    3.16 +    hypercall.op     = __HYPERVISOR_mmuext_op;
    3.17 +    hypercall.arg[0] = (unsigned long)op;
    3.18 +    hypercall.arg[1] = (unsigned long)nr_ops;
    3.19 +    hypercall.arg[2] = (unsigned long)0;
    3.20 +    hypercall.arg[3] = (unsigned long)dom;
    3.21 +
    3.22 +    if ( mlock(op, nr_ops*sizeof(*op)) != 0 )
    3.23 +    {
    3.24 +        PERROR("Could not lock memory for Xen hypercall");
    3.25 +        goto out1;
    3.26 +    }
    3.27 +
    3.28 +    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
    3.29 +    {
    3.30 +	fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to"
    3.31 +                    " rebuild the user-space tool set?\n",ret,errno);
    3.32 +        goto out2;
    3.33 +    }
    3.34 +
    3.35 + out2: (void)munlock(op, nr_ops*sizeof(*op));
    3.36 + out1: return ret;
    3.37 +}    
    3.38 +
    3.39  
    3.40  /*
    3.41   * PFN mapping.
     4.1 --- a/xen/arch/x86/mm.c	Fri Apr 01 09:40:25 2005 +0000
     4.2 +++ b/xen/arch/x86/mm.c	Fri Apr 01 10:04:58 2005 +0000
     4.3 @@ -1186,7 +1186,8 @@ int get_page_type(struct pfn_info *page,
     4.4                  nx &= ~PGT_va_mask;
     4.5                  nx |= type; /* we know the actual type is correct */
     4.6              }
     4.7 -            else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) )
     4.8 +            else if ( ((type & PGT_va_mask) != PGT_va_mutable) &&
     4.9 +                      ((type & PGT_va_mask) != (x & PGT_va_mask)) )
    4.10              {
    4.11                  /* This table is potentially mapped at multiple locations. */
    4.12                  nx &= ~PGT_va_mask;
    4.13 @@ -1388,11 +1389,6 @@ int do_mmuext_op(
    4.14          switch ( op.cmd )
    4.15          {
    4.16          case MMUEXT_PIN_L1_TABLE:
    4.17 -            /*
    4.18 -             * We insist that, if you pin an L1 page, it's the first thing that
    4.19 -             * you do to it. This is because we require the backptr to still be
    4.20 -             * mutable. This assumption seems safe.
    4.21 -             */
    4.22              type = PGT_l1_page_table | PGT_va_mutable;
    4.23  
    4.24          pin_page: