direct-io.hg

changeset 8681:cc9bb3e0e348

Make some basic cases of grant tables work in shadow translate mode.
This is enough to get block devices to work.

Note that this involves assigning PFNs to the machine frames used for
the grant table structures. While I'm here, I also assigned a PFN to
the shared info frame.

Signed-off-by: Steven Smith, sos22@cam.ac.uk
author sos22@douglas.cl.cam.ac.uk
date Wed Jan 25 18:57:44 2006 +0100 (2006-01-25)
parents 407358daf389
children 1580009f137c
files tools/libxc/xc_linux_build.c tools/libxc/xc_private.c tools/libxc/xc_private.h xen/arch/x86/dom0_ops.c xen/common/grant_table.c xen/include/public/dom0_ops.h
line diff
     1.1 --- a/tools/libxc/xc_linux_build.c	Wed Jan 25 17:41:22 2006 +0100
     1.2 +++ b/tools/libxc/xc_linux_build.c	Wed Jan 25 18:57:44 2006 +0100
     1.3 @@ -3,6 +3,7 @@
     1.4   */
     1.5  
     1.6  #include "xg_private.h"
     1.7 +#include "xc_private.h"
     1.8  #include <xenctrl.h>
     1.9  
    1.10  #if defined(__i386__)
    1.11 @@ -32,6 +33,8 @@
    1.12  #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    1.13  #endif
    1.14  
    1.15 +#define NR_GRANT_FRAMES 4
    1.16 +
    1.17  #ifdef __ia64__
    1.18  #define get_tot_pages xc_get_max_pages
    1.19  #else
    1.20 @@ -504,6 +507,8 @@ static int setup_guest(int xc_handle,
    1.21          goto error_out;
    1.22      }
    1.23  
    1.24 +    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
    1.25 +                                   "SHADOW=translate");
    1.26      /*
    1.27       * Why do we need this? The number of page-table frames depends on the 
    1.28       * size of the bootstrap address space. But the size of the address space 
    1.29 @@ -587,7 +592,7 @@ static int setup_guest(int xc_handle,
    1.30          goto error_out;
    1.31      }
    1.32  
    1.33 -    if ( (page_array = malloc((nr_pages + 1) * sizeof(unsigned long))) == NULL )
    1.34 +    if ( (page_array = malloc((nr_pages + 1 + NR_GRANT_FRAMES) * sizeof(unsigned long))) == NULL )
    1.35      {
    1.36          PERROR("Could not allocate memory");
    1.37          goto error_out;
    1.38 @@ -622,19 +627,23 @@ static int setup_guest(int xc_handle,
    1.39      if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
    1.40          goto error_out;
    1.41  
    1.42 -    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
    1.43 -                                   "SHADOW=translate");
    1.44 -
    1.45      /* Write the phys->machine and machine->phys table entries. */
    1.46      physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
    1.47      physmap = physmap_e = xc_map_foreign_range(
    1.48          xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
    1.49          page_array[physmap_pfn++]);
    1.50  
    1.51 -    if (shadow_mode_enabled)
    1.52 -        page_array[nr_pages] = shared_info_frame;
    1.53 +    page_array[nr_pages] = shared_info_frame;
    1.54  
    1.55 -    for ( count = 0; count < nr_pages + shadow_mode_enabled; count++ )
    1.56 +    if ( xc_get_gnttab_frames(xc_handle,
    1.57 +                              dom,
    1.58 +                              page_array + 1 + nr_pages,
    1.59 +                              NR_GRANT_FRAMES) <= 0) {
    1.60 +        fprintf(stderr, "cannot get grant table frames\n");
    1.61 +        goto error_out;
    1.62 +    }
    1.63 +
    1.64 +    for ( count = 0; count < nr_pages + 1 + NR_GRANT_FRAMES; count++ )
    1.65      {
    1.66          if ( xc_add_mmu_update(
    1.67              xc_handle, mmu,
     2.1 --- a/tools/libxc/xc_private.c	Wed Jan 25 17:41:22 2006 +0100
     2.2 +++ b/tools/libxc/xc_private.c	Wed Jan 25 18:57:44 2006 +0100
     2.3 @@ -314,6 +314,35 @@ int xc_get_pfn_list(int xc_handle,
     2.4      return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
     2.5  }
     2.6  
     2.7 +int xc_get_gnttab_frames(int xc_handle,
     2.8 +                         uint32_t domid,
     2.9 +                         unsigned long *pfn_buf,
    2.10 +                         unsigned long max_pfns)
    2.11 +{
    2.12 +    DECLARE_DOM0_OP;
    2.13 +    int ret;
    2.14 +    op.cmd = DOM0_GETGNTTABLIST;
    2.15 +    op.u.getgnttablist.domain   = (domid_t)domid;
    2.16 +    op.u.getgnttablist.max_pfns = max_pfns;
    2.17 +    op.u.getgnttablist.buffer   = pfn_buf;
    2.18 +
    2.19 +#ifdef VALGRIND
    2.20 +    memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
    2.21 +#endif
    2.22 +
    2.23 +    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
    2.24 +    {
    2.25 +        PERROR("xc_get_pfn_list: pfn_buf mlock failed");
    2.26 +        return -1;
    2.27 +    }
    2.28 +
    2.29 +    ret = do_dom0_op(xc_handle, &op);
    2.30 +
    2.31 +    safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
    2.32 +
    2.33 +    return (ret < 0) ? -1 : op.u.getgnttablist.num_pfns;
    2.34 +}
    2.35 +
    2.36  long xc_get_tot_pages(int xc_handle, uint32_t domid)
    2.37  {
    2.38      DECLARE_DOM0_OP;
     3.1 --- a/tools/libxc/xc_private.h	Wed Jan 25 17:41:22 2006 +0100
     3.2 +++ b/tools/libxc/xc_private.h	Wed Jan 25 18:57:44 2006 +0100
     3.3 @@ -111,6 +111,9 @@ static inline int do_dom0_op(int xc_hand
     3.4      return ret;
     3.5  }
     3.6  
     3.7 +int xc_get_gnttab_frames(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
     3.8 +			 unsigned long max_pfns);
     3.9 +
    3.10  
    3.11  /*
    3.12   * ioctl-based mfn mapping interface
     4.1 --- a/xen/arch/x86/dom0_ops.c	Wed Jan 25 17:41:22 2006 +0100
     4.2 +++ b/xen/arch/x86/dom0_ops.c	Wed Jan 25 18:57:44 2006 +0100
     4.3 @@ -330,6 +330,38 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
     4.4      }
     4.5      break;
     4.6  
     4.7 +    case DOM0_GETGNTTABLIST:
     4.8 +    {
     4.9 +        int i;
    4.10 +        struct domain *d = find_domain_by_id(op->u.getgnttablist.domain);
    4.11 +        unsigned long max_pfns = op->u.getgnttablist.max_pfns;
    4.12 +        unsigned long pfn;
    4.13 +        unsigned long *buffer = op->u.getgnttablist.buffer;
    4.14 +
    4.15 +        ret = -EINVAL;
    4.16 +        if ( d != NULL )
    4.17 +        {
    4.18 +            ret = 0;
    4.19 +
    4.20 +            for ( i = 0; i < max_pfns && i < NR_GRANT_FRAMES; i++ )
    4.21 +            {
    4.22 +		pfn = gnttab_shared_mfn(d, d->grant_table, i);
    4.23 +                if ( put_user(pfn, buffer) )
    4.24 +                {
    4.25 +                    ret = -EFAULT;
    4.26 +                    break;
    4.27 +                }
    4.28 +                buffer++;
    4.29 +            }
    4.30 +
    4.31 +            op->u.getgnttablist.num_pfns = i;
    4.32 +            copy_to_user(u_dom0_op, op, sizeof(*op));
    4.33 +
    4.34 +            put_domain(d);
    4.35 +        }
    4.36 +    }
    4.37 +    break;
    4.38 +
    4.39      case DOM0_GETMEMLIST:
    4.40      {
    4.41          int i;
     5.1 --- a/xen/common/grant_table.c	Wed Jan 25 17:41:22 2006 +0100
     5.2 +++ b/xen/common/grant_table.c	Wed Jan 25 18:57:44 2006 +0100
     5.3 @@ -481,6 +481,7 @@ gnttab_setup_table(
     5.4      gnttab_setup_table_t  op;
     5.5      struct domain        *d;
     5.6      int                   i;
     5.7 +    unsigned long         mfn;
     5.8  
     5.9      if ( count != 1 )
    5.10          return -EINVAL;
    5.11 @@ -520,9 +521,12 @@ gnttab_setup_table(
    5.12      {
    5.13          ASSERT(d->grant_table != NULL);
    5.14          (void)put_user(GNTST_okay, &uop->status);
    5.15 -        for ( i = 0; i < op.nr_frames; i++ )
    5.16 -            (void)put_user(gnttab_shared_mfn(d, d->grant_table, i),
    5.17 -                           &op.frame_list[i]);
    5.18 +        for ( i = 0; i < op.nr_frames; i++ ) {
    5.19 +            mfn = gnttab_shared_mfn(d, d->grant_table, i);
    5.20 +            if (shadow_mode_translate(d))
    5.21 +                mfn = __mfn_to_gpfn(d, mfn);
    5.22 +            (void)put_user(mfn, &op.frame_list[i]);
    5.23 +        }
    5.24      }
    5.25  
    5.26      put_domain(d);
     6.1 --- a/xen/include/public/dom0_ops.h	Wed Jan 25 17:41:22 2006 +0100
     6.2 +++ b/xen/include/public/dom0_ops.h	Wed Jan 25 18:57:44 2006 +0100
     6.3 @@ -430,7 +430,17 @@ typedef struct {
     6.4      domid_t  domain;          /* domain to be affected */
     6.5      unsigned long mfn;        /* machine frame to be initialised */
     6.6  } dom0_hypercall_init_t;
     6.7 - 
     6.8 +
     6.9 +#define DOM0_GETGNTTABLIST    49
    6.10 +typedef struct {
    6.11 +    /* IN variables. */
    6.12 +    domid_t       domain;
    6.13 +    unsigned long max_pfns;
    6.14 +    void         *buffer;
    6.15 +    /* OUT variables. */
    6.16 +    unsigned long num_pfns;
    6.17 +} dom0_getgnttablist_t;
    6.18 +
    6.19  typedef struct {
    6.20      uint32_t cmd;
    6.21      uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
    6.22 @@ -472,6 +482,7 @@ typedef struct {
    6.23          dom0_irq_permission_t    irq_permission;
    6.24          dom0_iomem_permission_t  iomem_permission;
    6.25          dom0_hypercall_init_t    hypercall_init;
    6.26 +        dom0_getgnttablist_t     getgnttablist;
    6.27          uint8_t                  pad[128];
    6.28      } u;
    6.29  } dom0_op_t;