ia64/xen-unstable

changeset 8686:c0a0f4db5ab1

Create a block of reserved PFNs in shadow translate mode guests, and
move the shared info and grant table pfns into that block. This
allows us to remove the get_gnttablist dom0 op, and simplifies the
domain creation code slightly. Having the reserved block managed by
Xen may also make it slightly easier to handle the case where the
grant table needs to be extended at run time.

Suggested-by: kaf24
Signed-off-by: Steven Smith, sos22@cam.ac.uk
author sos22@douglas.cl.cam.ac.uk
date Thu Jan 26 19:40:13 2006 +0100 (2006-01-26)
parents edf1fab86618
children 05a1340bc1e7
files tools/libxc/xc_linux_build.c tools/libxc/xc_misc.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xenctrl.h xen/arch/x86/dom0_ops.c xen/arch/x86/mm.c xen/include/asm-x86/config.h xen/include/public/dom0_ops.h xen/include/public/xen.h xen/include/xen/sched.h
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Thu Jan 26 18:02:21 2006 +0100
     1.2 +++ b/tools/libxc/xc_linux_build.c	Thu Jan 26 19:40:13 2006 +0100
     1.3 @@ -610,7 +610,7 @@ static int setup_guest(int xc_handle,
     1.4          goto error_out;
     1.5      }
     1.6  
     1.7 -    if ( (page_array = malloc((nr_pages + 1 + NR_GRANT_FRAMES) * sizeof(unsigned long))) == NULL )
     1.8 +    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
     1.9      {
    1.10          PERROR("Could not allocate memory");
    1.11          goto error_out;
    1.12 @@ -651,17 +651,7 @@ static int setup_guest(int xc_handle,
    1.13          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
    1.14          page_array[physmap_pfn++]);
    1.15  
    1.16 -    page_array[nr_pages] = shared_info_frame;
    1.17 -
    1.18 -    if ( xc_get_gnttab_frames(xc_handle,
    1.19 -                              dom,
    1.20 -                              page_array + 1 + nr_pages,
    1.21 -                              NR_GRANT_FRAMES) <= 0) {
    1.22 -        fprintf(stderr, "cannot get grant table frames\n");
    1.23 -        goto error_out;
    1.24 -    }
    1.25 -
    1.26 -    for ( count = 0; count < nr_pages + 1 + NR_GRANT_FRAMES; count++ )
    1.27 +    for ( count = 0; count < nr_pages; count++ )
    1.28      {
    1.29          if ( xc_add_mmu_update(
    1.30              xc_handle, mmu,
    1.31 @@ -696,6 +686,16 @@ static int setup_guest(int xc_handle,
    1.32              PERROR("Could not enable translation mode");
    1.33              goto error_out;
    1.34          }
    1.35 +
    1.36 +        /* Find the shared info frame.  It's guaranteed to be at the
    1.37 +           start of the PFN hole. */
    1.38 +        guest_shared_info_mfn = xc_get_pfn_hole_start(xc_handle, dom);
    1.39 +        if (guest_shared_info_mfn <= 0) {
    1.40 +            PERROR("Cannot find shared info pfn");
    1.41 +            goto error_out;
    1.42 +        }
    1.43 +    } else {
    1.44 +        guest_shared_info_mfn = shared_info_frame;
    1.45      }
    1.46  
    1.47      /* setup page tables */
    1.48 @@ -756,11 +756,9 @@ static int setup_guest(int xc_handle,
    1.49      if (shadow_mode_enabled) {
    1.50          guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
    1.51          guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
    1.52 -        guest_shared_info_mfn = nr_pages;
    1.53      } else {
    1.54          guest_store_mfn = *store_mfn;
    1.55          guest_console_mfn = *console_mfn;
    1.56 -        guest_shared_info_mfn = shared_info_frame;
    1.57      }
    1.58  
    1.59      start_info = xc_map_foreign_range(
     2.1 --- a/tools/libxc/xc_misc.c	Thu Jan 26 18:02:21 2006 +0100
     2.2 +++ b/tools/libxc/xc_misc.c	Thu Jan 26 19:40:13 2006 +0100
     2.3 @@ -131,6 +131,14 @@ int xc_msr_write(int xc_handle, int cpu_
     2.4      return rc;
     2.5  }
     2.6  
     2.7 +int xc_get_pfn_hole_start(int xc_handle, domid_t dom)
     2.8 +{
     2.9 +    struct mmuext_op op = {0};
    2.10 +    op.cmd = MMUEXT_PFN_HOLE_BASE;
    2.11 +    return xc_mmuext_op(xc_handle, &op, 1, dom);
    2.12 +}
    2.13 +
    2.14 +
    2.15  /*
    2.16   * Local variables:
    2.17   * mode: C
     3.1 --- a/tools/libxc/xc_private.c	Thu Jan 26 18:02:21 2006 +0100
     3.2 +++ b/tools/libxc/xc_private.c	Thu Jan 26 19:40:13 2006 +0100
     3.3 @@ -314,35 +314,6 @@ int xc_get_pfn_list(int xc_handle,
     3.4      return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
     3.5  }
     3.6  
     3.7 -int xc_get_gnttab_frames(int xc_handle,
     3.8 -                         uint32_t domid,
     3.9 -                         unsigned long *pfn_buf,
    3.10 -                         unsigned long max_pfns)
    3.11 -{
    3.12 -    DECLARE_DOM0_OP;
    3.13 -    int ret;
    3.14 -    op.cmd = DOM0_GETGNTTABLIST;
    3.15 -    op.u.getgnttablist.domain   = (domid_t)domid;
    3.16 -    op.u.getgnttablist.max_pfns = max_pfns;
    3.17 -    op.u.getgnttablist.buffer   = pfn_buf;
    3.18 -
    3.19 -#ifdef VALGRIND
    3.20 -    memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
    3.21 -#endif
    3.22 -
    3.23 -    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
    3.24 -    {
    3.25 -        PERROR("xc_get_pfn_list: pfn_buf mlock failed");
    3.26 -        return -1;
    3.27 -    }
    3.28 -
    3.29 -    ret = do_dom0_op(xc_handle, &op);
    3.30 -
    3.31 -    safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
    3.32 -
    3.33 -    return (ret < 0) ? -1 : op.u.getgnttablist.num_pfns;
    3.34 -}
    3.35 -
    3.36  long xc_get_tot_pages(int xc_handle, uint32_t domid)
    3.37  {
    3.38      DECLARE_DOM0_OP;
     4.1 --- a/tools/libxc/xc_private.h	Thu Jan 26 18:02:21 2006 +0100
     4.2 +++ b/tools/libxc/xc_private.h	Thu Jan 26 19:40:13 2006 +0100
     4.3 @@ -111,9 +111,6 @@ static inline int do_dom0_op(int xc_hand
     4.4      return ret;
     4.5  }
     4.6  
     4.7 -int xc_get_gnttab_frames(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
     4.8 -			 unsigned long max_pfns);
     4.9 -
    4.10  
    4.11  /*
    4.12   * ioctl-based mfn mapping interface
     5.1 --- a/tools/libxc/xenctrl.h	Thu Jan 26 18:02:21 2006 +0100
     5.2 +++ b/tools/libxc/xenctrl.h	Thu Jan 26 19:40:13 2006 +0100
     5.3 @@ -528,4 +528,6 @@ int xc_add_mmu_update(int xc_handle, xc_
     5.4                     unsigned long long ptr, unsigned long long val);
     5.5  int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);
     5.6  
     5.7 +int xc_get_pfn_hole_start(int xc_handle, domid_t dom);
     5.8 +
     5.9  #endif
     6.1 --- a/xen/arch/x86/dom0_ops.c	Thu Jan 26 18:02:21 2006 +0100
     6.2 +++ b/xen/arch/x86/dom0_ops.c	Thu Jan 26 19:40:13 2006 +0100
     6.3 @@ -330,38 +330,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
     6.4      }
     6.5      break;
     6.6  
     6.7 -    case DOM0_GETGNTTABLIST:
     6.8 -    {
     6.9 -        int i;
    6.10 -        struct domain *d = find_domain_by_id(op->u.getgnttablist.domain);
    6.11 -        unsigned long max_pfns = op->u.getgnttablist.max_pfns;
    6.12 -        unsigned long pfn;
    6.13 -        unsigned long *buffer = op->u.getgnttablist.buffer;
    6.14 -
    6.15 -        ret = -EINVAL;
    6.16 -        if ( d != NULL )
    6.17 -        {
    6.18 -            ret = 0;
    6.19 -
    6.20 -            for ( i = 0; i < max_pfns && i < NR_GRANT_FRAMES; i++ )
    6.21 -            {
    6.22 -		pfn = gnttab_shared_mfn(d, d->grant_table, i);
    6.23 -                if ( put_user(pfn, buffer) )
    6.24 -                {
    6.25 -                    ret = -EFAULT;
    6.26 -                    break;
    6.27 -                }
    6.28 -                buffer++;
    6.29 -            }
    6.30 -
    6.31 -            op->u.getgnttablist.num_pfns = i;
    6.32 -            copy_to_user(u_dom0_op, op, sizeof(*op));
    6.33 -
    6.34 -            put_domain(d);
    6.35 -        }
    6.36 -    }
    6.37 -    break;
    6.38 -
    6.39      case DOM0_GETMEMLIST:
    6.40      {
    6.41          int i;
     7.1 --- a/xen/arch/x86/mm.c	Thu Jan 26 18:02:21 2006 +0100
     7.2 +++ b/xen/arch/x86/mm.c	Thu Jan 26 19:40:13 2006 +0100
     7.3 @@ -1929,7 +1929,57 @@ int do_mmuext_op(
     7.4              }
     7.5              break;
     7.6          }
     7.7 -            
     7.8 +
     7.9 +        case MMUEXT_PFN_HOLE_BASE:
    7.10 +        {
    7.11 +            if (FOREIGNDOM->start_pfn_hole) {
    7.12 +                rc = FOREIGNDOM->start_pfn_hole;
    7.13 +                okay = 1;
    7.14 +            } else {
    7.15 +                rc = FOREIGNDOM->start_pfn_hole =
    7.16 +                    FOREIGNDOM->max_pages;
    7.17 +                okay = 1;
    7.18 +                if (shadow_mode_translate(FOREIGNDOM)) {
    7.19 +                    /* Fill in a few entries in the hole.  At the
    7.20 +                       moment, this means the shared info page and the
    7.21 +                       grant table pages. */
    7.22 +                    struct domain_mmap_cache c1, c2;
    7.23 +                    unsigned long pfn, mfn, x;
    7.24 +                    domain_mmap_cache_init(&c1);
    7.25 +                    domain_mmap_cache_init(&c2);
    7.26 +                    shadow_lock(FOREIGNDOM);
    7.27 +                    pfn = FOREIGNDOM->start_pfn_hole;
    7.28 +                    mfn = virt_to_phys(FOREIGNDOM->shared_info) >> PAGE_SHIFT;
    7.29 +                    set_p2m_entry(FOREIGNDOM, pfn, mfn, &c1, &c2);
    7.30 +                    set_pfn_from_mfn(mfn, pfn);
    7.31 +                    pfn++;
    7.32 +                    for (x = 0; x < NR_GRANT_FRAMES; x++) {
    7.33 +                        mfn = gnttab_shared_mfn(FOREIGNDOM,
    7.34 +                                                FOREIGNDOM->grant_table,
    7.35 +                                                x);
    7.36 +                        set_p2m_entry(FOREIGNDOM, pfn, mfn, &c1, &c2);
    7.37 +                        set_pfn_from_mfn(mfn, pfn);
    7.38 +                        pfn++;
    7.39 +                    }
    7.40 +                    shadow_unlock(FOREIGNDOM);
    7.41 +                    domain_mmap_cache_destroy(&c1);
    7.42 +                    domain_mmap_cache_destroy(&c2);
    7.43 +                }
    7.44 +            }
    7.45 +            break;
    7.46 +        }
    7.47 +
    7.48 +        case MMUEXT_PFN_HOLE_SIZE:
    7.49 +        {
    7.50 +            if (shadow_mode_translate(FOREIGNDOM)) {
    7.51 +                rc = PFN_HOLE_SIZE;
    7.52 +            } else {
    7.53 +                rc = 0;
    7.54 +            }
    7.55 +            okay = 1;
    7.56 +            break;
    7.57 +        }
    7.58 +
    7.59          default:
    7.60              MEM_LOG("Invalid extended pt command 0x%x", op.cmd);
    7.61              okay = 0;
    7.62 @@ -2663,7 +2713,7 @@ long set_gdt(struct vcpu *v,
    7.63  
    7.64  long do_set_gdt(unsigned long *frame_list, unsigned int entries)
    7.65  {
    7.66 -    int i, nr_pages = (entries + 511) / 512;
    7.67 +    int nr_pages = (entries + 511) / 512;
    7.68      unsigned long frames[16];
    7.69      long ret;
    7.70  
     8.1 --- a/xen/include/asm-x86/config.h	Thu Jan 26 18:02:21 2006 +0100
     8.2 +++ b/xen/include/asm-x86/config.h	Thu Jan 26 19:40:13 2006 +0100
     8.3 @@ -60,6 +60,9 @@
     8.4  #endif
     8.5  #endif
     8.6  
     8.7 +/* How large is the PFN reserved area, when we have one? */
     8.8 +#define PFN_HOLE_SIZE 32
     8.9 +
    8.10  #ifndef STACK_ORDER
    8.11  #define STACK_ORDER 1
    8.12  #endif
     9.1 --- a/xen/include/public/dom0_ops.h	Thu Jan 26 18:02:21 2006 +0100
     9.2 +++ b/xen/include/public/dom0_ops.h	Thu Jan 26 19:40:13 2006 +0100
     9.3 @@ -431,16 +431,6 @@ typedef struct {
     9.4      unsigned long mfn;        /* machine frame to be initialised */
     9.5  } dom0_hypercall_init_t;
     9.6  
     9.7 -#define DOM0_GETGNTTABLIST    49
     9.8 -typedef struct {
     9.9 -    /* IN variables. */
    9.10 -    domid_t       domain;
    9.11 -    unsigned long max_pfns;
    9.12 -    void         *buffer;
    9.13 -    /* OUT variables. */
    9.14 -    unsigned long num_pfns;
    9.15 -} dom0_getgnttablist_t;
    9.16 -
    9.17  typedef struct {
    9.18      uint32_t cmd;
    9.19      uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
    9.20 @@ -482,7 +472,6 @@ typedef struct {
    9.21          dom0_irq_permission_t    irq_permission;
    9.22          dom0_iomem_permission_t  iomem_permission;
    9.23          dom0_hypercall_init_t    hypercall_init;
    9.24 -        dom0_getgnttablist_t     getgnttablist;
    9.25          uint8_t                  pad[128];
    9.26      } u;
    9.27  } dom0_op_t;
    10.1 --- a/xen/include/public/xen.h	Thu Jan 26 18:02:21 2006 +0100
    10.2 +++ b/xen/include/public/xen.h	Thu Jan 26 19:40:13 2006 +0100
    10.3 @@ -144,6 +144,15 @@
    10.4   * cmd: MMUEXT_SET_LDT
    10.5   * linear_addr: Linear address of LDT base (NB. must be page-aligned).
    10.6   * nr_ents: Number of entries in LDT.
    10.7 + *
    10.8 + * cmd: MMUEXT_PFN_HOLE_BASE
    10.9 + * No additional arguments.  Returns the first pfn in the Xen-reserved
   10.10 + * pfn hole.  Note that we delay allocating the hole until the first
   10.11 + * time this is called.
   10.12 + *
   10.13 + * cmd: MMUEXT_PFN_HOLE_SIZE
   10.14 + * No additional arguments.  Returns the number of pfns in the
   10.15 + * Xen-reserved pfn hole.
   10.16   */
   10.17  #define MMUEXT_PIN_L1_TABLE      0
   10.18  #define MMUEXT_PIN_L2_TABLE      1
   10.19 @@ -160,6 +169,8 @@
   10.20  #define MMUEXT_FLUSH_CACHE      12
   10.21  #define MMUEXT_SET_LDT          13
   10.22  #define MMUEXT_NEW_USER_BASEPTR 15
   10.23 +#define MMUEXT_PFN_HOLE_BASE    16
   10.24 +#define MMUEXT_PFN_HOLE_SIZE    17
   10.25  
   10.26  #ifndef __ASSEMBLY__
   10.27  struct mmuext_op {
    11.1 --- a/xen/include/xen/sched.h	Thu Jan 26 18:02:21 2006 +0100
    11.2 +++ b/xen/include/xen/sched.h	Thu Jan 26 19:40:13 2006 +0100
    11.3 @@ -153,6 +153,9 @@ struct domain
    11.4  
    11.5      /* Control-plane tools handle for this domain. */
    11.6      xen_domain_handle_t handle;
    11.7 +
    11.8 +    /* Start of the PFN hole */
    11.9 +    unsigned long start_pfn_hole;
   11.10  };
   11.11  
   11.12  struct domain_setup_info