lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1321526148.3664.263.camel@zakaz.uk.xensource.com>
Date:	Thu, 17 Nov 2011 10:35:48 +0000
From:	Ian Campbell <Ian.Campbell@...rix.com>
To:	"annie.li@...cle.com" <annie.li@...cle.com>
CC:	"xen-devel@...ts.xensource.com" <xen-devel@...ts.xensource.com>,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"konrad.wilk@...cle.com" <konrad.wilk@...cle.com>,
	"jeremy@...p.org" <jeremy@...p.org>,
	"kurt.hackel@...cle.com" <kurt.hackel@...cle.com>,
	Paul Durrant <Paul.Durrant@...rix.com>
Subject: Re: [PATCH 1/3] xen/granttable: Introducing grant table V2 stucture

On Wed, 2011-11-16 at 13:48 +0000, annie.li@...cle.com wrote:
> From: Annie Li <annie.li@...cle.com>
> 
> This patch introduces new structures of grant table V2, grant table V2 is an
> extension from V1. Grant table is shared between guest and Xen, and Xen is
> responsible to do corresponding work for grant operations, such as: figure
> out guest's grant table version, perform different actions based on
> different grant table version, etc. Although full-page structure of V2
> is different from V1, it play the same role as V1.
> 
> Signed-off-by: Annie Li <annie.li@...cle.com>
> ---
>  arch/x86/xen/grant-table.c          |    7 +-
>  drivers/xen/grant-table.c           |  181 +++++++++++++++++++++++++++--------
>  include/xen/grant_table.h           |    4 +-
>  include/xen/interface/grant_table.h |  167 +++++++++++++++++++++++++++++++-
>  include/xen/interface/xen.h         |    2 +
>  5 files changed, 311 insertions(+), 50 deletions(-)
> 
> diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
> index 6bbfd7a..c6ab2e7 100644
> --- a/arch/x86/xen/grant-table.c
> +++ b/arch/x86/xen/grant-table.c
> @@ -64,10 +64,10 @@ static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
> 
>  int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
>                            unsigned long max_nr_gframes,
> -                          struct grant_entry **__shared)
> +                          void **__shared)
>  {
>         int rc;
> -       struct grant_entry *shared = *__shared;
> +       void *shared = *__shared;
> 
>         if (shared == NULL) {
>                 struct vm_struct *area =
> @@ -83,8 +83,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
>         return rc;
>  }
> 
> -void arch_gnttab_unmap_shared(struct grant_entry *shared,
> -                             unsigned long nr_gframes)
> +void arch_gnttab_unmap_shared(void *shared, unsigned long nr_gframes)
>  {
>         apply_to_page_range(&init_mm, (unsigned long)shared,
>                             PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
> diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
> index bf1c094..1bd9d5f 100644
> --- a/drivers/xen/grant-table.c
> +++ b/drivers/xen/grant-table.c
> @@ -53,7 +53,7 @@
>  /* External tools reserve first few grant table entries. */
>  #define NR_RESERVED_ENTRIES 8
>  #define GNTTAB_LIST_END 0xffffffff
> -#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry))
> +#define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry_v1))
> 
>  static grant_ref_t **gnttab_list;
>  static unsigned int nr_grant_frames;
> @@ -64,7 +64,61 @@ static DEFINE_SPINLOCK(gnttab_list_lock);
>  unsigned long xen_hvm_resume_frames;
>  EXPORT_SYMBOL_GPL(xen_hvm_resume_frames);
> 
> -static struct grant_entry *shared;
> +static union {
> +       struct grant_entry_v1 *v1;
> +       void *addr;
> +} gnttab_shared;
> +
> +/*This is a structure of function pointers for grant table*/
> +static struct {
> +       /*
> +        * Mapping a list of frames for storing grant entries. First input
> +        * parameter is used to storing grant table address when grant table
> +        * being setup, second parameter is the number of frames to map grant
> +        * table. Returning GNTST_okay means success and negative value means
> +        * failure.
> +        */
> +       int (*map_frames)(unsigned long *, unsigned int);
> +       /*
> +        * Release a list of frames which are mapped in map_frames for grant
> +        * entry status.
> +        */
> +       void (*unmap_frames)(void);
> +       /*
> +        * Introducing a valid entry into the grant table, granting the frame
> +        * of this grant entry to domain for accessing, or transfering, or
> +        * transitively accessing. First input parameter is reference of this
> +        * introduced grant entry, second one is domid of granted domain, third
> +        * one is the frame to be granted, and the last one is status of the
> +        * grant entry to be updated.
> +        */
> +       void (*update_entry)(grant_ref_t, domid_t, unsigned long, unsigned);
> +       /*
> +        * Stop granting a grant entry to domain for accessing. First input
> +        * parameter is reference of a grant entry whose grant access will be
> +        * stopped, second one is not in use now. If the grant entry is
> +        * currently mapped for reading or writing, just return failure(==0)
> +        * directly and don't tear down the grant access. Otherwise, stop grant
> +        * access for this entry and return success(==1).
> +        */
> +       int (*end_foreign_access_ref)(grant_ref_t, int);
> +       /*
> +        * Stop granting a grant entry to domain for transfer. If tranfer has
> +        * not started, just reclaim the grant entry and return failure(==0).
> +        * Otherwise, wait for the transfer to complete and then return the
> +        * frame.
> +        */
> +       unsigned long (*end_foreign_transfer_ref)(grant_ref_t);
> +       /*
> +        * Query the status of a grant entry. Input parameter is reference of
> +        * queried grant entry, return value is the status of queried entry.
> +        * Detailed status(writing/reading) can be gotten from the return value
> +        * by bit operations.
> +        */
> +       int (*query_foreign_access)(grant_ref_t);
> +} gnttab_interface;
> +
> +static int grant_table_version;
> 
>  static struct gnttab_free_callback *gnttab_free_callback_list;
> 
> @@ -142,23 +196,23 @@ static void put_free_entry(grant_ref_t ref)
>         spin_unlock_irqrestore(&gnttab_list_lock, flags);
>  }
> 
> -static void update_grant_entry(grant_ref_t ref, domid_t domid,
> -                              unsigned long frame, unsigned flags)
> +/*
> + * Introducing a valid entry into the grant table:
> + *  1. Write ent->domid.
> + *  2. Write ent->frame:
> + *      GTF_permit_access:   Frame to which access is permitted.
> + *      GTF_accept_transfer: Pseudo-phys frame slot being filled by new
> + *                           frame, or zero if none.
> + *  3. Write memory barrier (WMB).
> + *  4. Write ent->flags, inc. valid type.
> + */
> +static void update_grant_entry_v1(grant_ref_t ref, domid_t domid,
> +                                 unsigned long frame, unsigned flags)
>  {
> -       /*
> -        * Introducing a valid entry into the grant table:
> -        *  1. Write ent->domid.
> -        *  2. Write ent->frame:
> -        *      GTF_permit_access:   Frame to which access is permitted.
> -        *      GTF_accept_transfer: Pseudo-phys frame slot being filled by new
> -        *                           frame, or zero if none.
> -        *  3. Write memory barrier (WMB).
> -        *  4. Write ent->flags, inc. valid type.
> -        */
> -       shared[ref].frame = frame;
> -       shared[ref].domid = domid;
> +       gnttab_shared.v1[ref].domid = domid;
> +       gnttab_shared.v1[ref].frame = frame;
>         wmb();
> -       shared[ref].flags = flags;
> +       gnttab_shared.v1[ref].flags = flags;
>  }
> 
>  /*
> @@ -167,7 +221,7 @@ static void update_grant_entry(grant_ref_t ref, domid_t domid,
>  void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
>                                      unsigned long frame, int readonly)
>  {
> -       update_grant_entry(ref, domid, frame,
> +       gnttab_interface.update_entry(ref, domid, frame,
>                            GTF_permit_access | (readonly ? GTF_readonly : 0));
>  }
>  EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
> @@ -187,31 +241,40 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
>  }
>  EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access);
> 
> -int gnttab_query_foreign_access(grant_ref_t ref)
> +static int gnttab_query_foreign_access_v1(grant_ref_t ref)
>  {
> -       u16 nflags;
> -
> -       nflags = shared[ref].flags;
> +       return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing);
> +}
> -       return nflags & (GTF_reading|GTF_writing);
> +int gnttab_query_foreign_access(grant_ref_t ref)
> +{
> +       return gnttab_interface.query_foreign_access(ref);
>  }
>  EXPORT_SYMBOL_GPL(gnttab_query_foreign_access);
> 
> -int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
> +static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly)
>  {
>         u16 flags, nflags;
> +       u16 *pflags;
> 
> -       nflags = shared[ref].flags;
> +       pflags = &gnttab_shared.v1[ref].flags;
> +       nflags = *pflags;
>         do {
>                 flags = nflags;
>                 if (flags & (GTF_reading|GTF_writing)) {
>                         printk(KERN_ALERT "WARNING: g.e. still in use!\n");
>                         return 0;
>                 }
> -       } while ((nflags = sync_cmpxchg(&shared[ref].flags, flags, 0)) != flags);
> +       } while ((nflags = sync_cmpxchg(&gnttab_shared.v1[ref].flags, flags, 0))
> +                       != flags);

I think this is one of those cases where strictly adhering to an
80-column rule hurts the readability of the code.

If you had left the static global as "shared" rather than
"gnttab_shared" you wouldn't have this issue. If you want a more
descriptive name why not just call it "gnttab"?

> 
>         return 1;
>  }
> +
> +int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
> +{
> +       return gnttab_interface.end_foreign_access_ref(ref, readonly);
> +}
>  EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
> 
>  void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
> @@ -246,37 +309,45 @@ EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer);
>  void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
>                                        unsigned long pfn)
>  {
> -       update_grant_entry(ref, domid, pfn, GTF_accept_transfer);
> +       gnttab_interface.update_entry(ref, domid, pfn, GTF_accept_transfer);
>  }
>  EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref);
> 
> -unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)
> +static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref)
>  {
>         unsigned long frame;
>         u16           flags;
> +       u16          *pflags;
> +
> +       pflags = &gnttab_shared.v1[ref].flags;

It would be nice if these refactoring bits could be separated out from
the more mechanical renaming and abstracting to fn pointer aspects of
the patch.
> 
>         /*
>          * If a transfer is not even yet started, try to reclaim the grant
>          * reference and return failure (== 0).
>          */
> -       while (!((flags = shared[ref].flags) & GTF_transfer_committed)) {
> -               if (sync_cmpxchg(&shared[ref].flags, flags, 0) == flags)
> +       while (!((flags = *pflags) & GTF_transfer_committed)) {
> +               if (sync_cmpxchg(pflags, flags, 0) == flags)
>                         return 0;
>                 cpu_relax();
>         }
> 
>         /* If a transfer is in progress then wait until it is completed. */
>         while (!(flags & GTF_transfer_completed)) {
> -               flags = shared[ref].flags;
> +               flags = *pflags;
>                 cpu_relax();
>         }
> 
>         rmb();  /* Read the frame number /after/ reading completion status. */
> -       frame = shared[ref].frame;
> +       frame = gnttab_shared.v1[ref].frame;
>         BUG_ON(frame == 0);
> 
>         return frame;
>  }
> +
> +unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)
> +{
> +       return gnttab_interface.end_foreign_transfer_ref(ref);
> +}
>  EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref);
> 
>  unsigned long gnttab_end_foreign_transfer(grant_ref_t ref)
> @@ -520,6 +591,23 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
>  }
>  EXPORT_SYMBOL_GPL(gnttab_unmap_refs);
> 
> +static int gnttab_map_frames_v1(unsigned long *frames, unsigned int nr_gframes)
> +{
> +       int rc;
> +
> +       rc = arch_gnttab_map_shared(frames, nr_gframes,
> +                                   gnttab_max_grant_frames(),
> +                                   &gnttab_shared.addr);
> +       BUG_ON(rc);
> +
> +       return 0;
> +}
> +
> +static void gnttab_unmap_frames_v1(void)
> +{
> +       arch_gnttab_unmap_shared(gnttab_shared.addr, nr_grant_frames);
> +}
> +
>  static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
>  {
>         struct gnttab_setup_table setup;
> @@ -567,19 +655,33 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
> 
>         BUG_ON(rc || setup.status);
> 
> -       rc = arch_gnttab_map_shared(frames, nr_gframes, gnttab_max_grant_frames(),
> -                                   &shared);
> -       BUG_ON(rc);
> +       rc = gnttab_interface.map_frames(frames, nr_gframes);

Nothing checks rc here now?

In fact the gnttab_map_frames_v1 function has its own BUG_ON(rc) and
always returns 0 if it returns at all so perhaps that hook should be
returning void?

> 
>         kfree(frames);
> 
>         return 0;
>  }
> 
> +static void gnttab_request_version(void)
> +{
> +       grant_table_version = 1;
> +       gnttab_interface.map_frames = gnttab_map_frames_v1;
> +       gnttab_interface.unmap_frames = gnttab_unmap_frames_v1;
> +       gnttab_interface.update_entry = update_grant_entry_v1;
> +       gnttab_interface.end_foreign_access_ref =
> +                                       gnttab_end_foreign_access_ref_v1;
> +       gnttab_interface.end_foreign_transfer_ref =
> +                                       gnttab_end_foreign_transfer_ref_v1;
> +       gnttab_interface.query_foreign_access = gnttab_query_foreign_access_v1;

The more normal way to do this would be to make gnttab_interface a
pointer, define gnttab_v1_ops and do:
	gnttab_interface = &gnttab_v1_ops;
or if the pointer overhead is significant remove that and just do a
struct assignment:
	gnttab_interface = gnttab_v1_ops;

> +       printk(KERN_INFO "Grant tables using version %d layout.\n",
> +               grant_table_version);
> +}
> +
>  int gnttab_resume(void)
>  {
>         unsigned int max_nr_gframes;
> 
> +       gnttab_request_version();
>         max_nr_gframes = gnttab_max_grant_frames();
>         if (max_nr_gframes < nr_grant_frames)
>                 return -ENOSYS;
> @@ -587,9 +689,10 @@ int gnttab_resume(void)
>         if (xen_pv_domain())
>                 return gnttab_map(0, nr_grant_frames - 1);
> 
> -       if (!shared) {
> -               shared = ioremap(xen_hvm_resume_frames, PAGE_SIZE * max_nr_gframes);
> -               if (shared == NULL) {
> +       if (gnttab_shared.addr == NULL) {
> +               gnttab_shared.addr = ioremap(xen_hvm_resume_frames,
> +                                               PAGE_SIZE * max_nr_gframes);
> +               if (gnttab_shared.addr == NULL) {
>                         printk(KERN_WARNING
>                                         "Failed to ioremap gnttab share frames!");
>                         return -ENOMEM;
> @@ -603,7 +706,7 @@ int gnttab_resume(void)
> 
>  int gnttab_suspend(void)
>  {
> -       arch_gnttab_unmap_shared(shared, nr_grant_frames);
> +       gnttab_interface.unmap_frames();
>         return 0;
>  }
> 
> diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
> index 11e2dfc..c7a40f8 100644
> --- a/include/xen/grant_table.h
> +++ b/include/xen/grant_table.h
> @@ -145,8 +145,8 @@ gnttab_set_unmap_op(struct gnttab_unmap_grant_ref *unmap, phys_addr_t addr,
> 
>  int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
>                            unsigned long max_nr_gframes,
> -                          struct grant_entry **__shared);
> -void arch_gnttab_unmap_shared(struct grant_entry *shared,
> +                          void **__shared);
> +void arch_gnttab_unmap_shared(void *shared,
>                               unsigned long nr_gframes);
> 
>  extern unsigned long xen_hvm_resume_frames;
> diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
> index 39e5717..a17d844 100644
> --- a/include/xen/interface/grant_table.h
> +++ b/include/xen/interface/grant_table.h
> @@ -85,12 +85,22 @@
>   */
> 
>  /*
> + * Reference to a grant entry in a specified domain's grant table.
> + */
> +typedef uint32_t grant_ref_t;
> +
> +/*
>   * A grant table comprises a packed array of grant entries in one or more
>   * page frames shared between Xen and a guest.
>   * [XEN]: This field is written by Xen and read by the sharing guest.
>   * [GST]: This field is written by the guest and read by Xen.
>   */
> -struct grant_entry {
> +
> +/*
> + * Version 1 of the grant table entry structure is maintained purely
> + * for backwards compatibility.  New guests should use version 2.
> + */
> +struct grant_entry_v1 {
>      /* GTF_xxx: various type and flag information.  [XEN,GST] */
>      uint16_t flags;
>      /* The domain being granted foreign privileges. [GST] */
> @@ -108,10 +118,13 @@ struct grant_entry {
>   *  GTF_permit_access: Allow @domid to map/access @frame.
>   *  GTF_accept_transfer: Allow @domid to transfer ownership of one page frame
>   *                       to this guest. Xen writes the page number to @frame.
> + *  GTF_transitive: Allow @domid to transitively access a subrange of
> + *                  @trans_grant in @trans_domid.  No mappings are allowed.
>   */
>  #define GTF_invalid         (0U<<0)
>  #define GTF_permit_access   (1U<<0)
>  #define GTF_accept_transfer (2U<<0)
> +#define GTF_transitive      (3U<<0)
>  #define GTF_type_mask       (3U<<0)
> 
>  /*
> @@ -119,6 +132,9 @@ struct grant_entry {
>   *  GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
>   *  GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
>   *  GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
> + *  GTF_sub_page: Grant access to only a subrange of the page.  @domid
> + *                will only be allowed to copy from the grant, and not
> + *                map it. [GST]
>   */
>  #define _GTF_readonly       (2)
>  #define GTF_readonly        (1U<<_GTF_readonly)
> @@ -126,6 +142,8 @@ struct grant_entry {
>  #define GTF_reading         (1U<<_GTF_reading)
>  #define _GTF_writing        (4)
>  #define GTF_writing         (1U<<_GTF_writing)
> +#define _GTF_sub_page       (8)
> +#define GTF_sub_page        (1U<<_GTF_sub_page)
> 
>  /*
>   * Subflags for GTF_accept_transfer:
> @@ -142,15 +160,81 @@ struct grant_entry {
>  #define _GTF_transfer_completed (3)
>  #define GTF_transfer_completed  (1U<<_GTF_transfer_completed)
> 
> +/*
> + * Version 2 grant table entries.  These fulfil the same role as
> + * version 1 entries, but can represent more complicated operations.
> + * Any given domain will have either a version 1 or a version 2 table,
> + * and every entry in the table will be the same version.
> + *
> + * The interface by which domains use grant references does not depend
> + * on the grant table version in use by the other domain.
> + */
> 
> -/***********************************
> - * GRANT TABLE QUERIES AND USES
> +/*
> + * Version 1 and version 2 grant entries share a common prefix.  The
> + * fields of the prefix are documented as part of struct
> + * grant_entry_v1.
>   */
> +struct grant_entry_header {
> +    uint16_t flags;
> +    domid_t  domid;
> +};
> 
>  /*
> - * Reference to a grant entry in a specified domain's grant table.
> + * Version 2 of the grant entry structure, here is an union because three
> + * different types are suppotted: full_page, sub_page and transitive.
> + */
> +union grant_entry_v2 {
> +    struct grant_entry_header hdr;
> +
> +    /*
> +     * This member is used for V1-style full page grants, where either:
> +     *
> +     * -- hdr.type is GTF_accept_transfer, or
> +     * -- hdr.type is GTF_permit_access and GTF_sub_page is not set.
> +     *
> +     * In that case, the frame field has the same semantics as the
> +     * field of the same name in the V1 entry structure.
> +     */
> +    struct {
> +       struct grant_entry_header hdr;
> +       uint32_t pad0;
> +       uint64_t frame;
> +    } full_page;
> +
> +    /*
> +     * If the grant type is GTF_grant_access and GTF_sub_page is set,
> +     * @domid is allowed to access bytes [@page_off,@page_off+@...gth)
> +     * in frame @frame.
> +     */
> +    struct {
> +       struct grant_entry_header hdr;
> +       uint16_t page_off;
> +       uint16_t length;
> +       uint64_t frame;
> +    } sub_page;
> +
> +    /*
> +     * If the grant is GTF_transitive, @domid is allowed to use the
> +     * grant @gref in domain @trans_domid, as if it was the local
> +     * domain.  Obviously, the transitive access must be compatible
> +     * with the original grant.
> +     */
> +    struct {
> +       struct grant_entry_header hdr;
> +       domid_t trans_domid;
> +       uint16_t pad0;
> +       grant_ref_t gref;
> +    } transitive;
> +
> +    uint32_t __spacer[4]; /* Pad to a power of two */
> +};
> +
> +typedef uint16_t grant_status_t;
> +
> +/***********************************
> + * GRANT TABLE QUERIES AND USES
>   */
> -typedef uint32_t grant_ref_t;
> 
>  /*
>   * Handle to track a mapping created via a grant reference.
> @@ -322,6 +406,79 @@ struct gnttab_query_size {
>  DEFINE_GUEST_HANDLE_STRUCT(gnttab_query_size);
> 
>  /*
> + * GNTTABOP_unmap_and_replace: Destroy one or more grant-reference mappings
> + * tracked by <handle> but atomically replace the page table entry with one
> + * pointing to the machine address under <new_addr>.  <new_addr> will be
> + * redirected to the null entry.
> + * NOTES:
> + *  1. The call may fail in an undefined manner if either mapping is not
> + *     tracked by <handle>.
> + *  2. After executing a batch of unmaps, it is guaranteed that no stale
> + *     mappings will remain in the device or host TLBs.
> + */
> +#define GNTTABOP_unmap_and_replace    7
> +struct gnttab_unmap_and_replace {
> +    /* IN parameters. */
> +    uint64_t host_addr;
> +    uint64_t new_addr;
> +    grant_handle_t handle;
> +    /* OUT parameters. */
> +    int16_t  status;              /* GNTST_* */
> +};
> +DEFINE_GUEST_HANDLE_STRUCT(gnttab_unmap_and_replace);
> +
> +/*
> + * GNTTABOP_set_version: Request a particular version of the grant
> + * table shared table structure.  This operation can only be performed
> + * once in any given domain.  It must be performed before any grants
> + * are activated; otherwise, the domain will be stuck with version 1.
> + * The only defined versions are 1 and 2.
> + */
> +#define GNTTABOP_set_version          8
> +struct gnttab_set_version {
> +    /* IN parameters */
> +    uint32_t version;
> +};
> +DEFINE_GUEST_HANDLE_STRUCT(gnttab_set_version);
> +
> +/*
> + * GNTTABOP_get_status_frames: Get the list of frames used to store grant
> + * status for <dom>. In grant format version 2, the status is separated
> + * from the other shared grant fields to allow more efficient synchronization
> + * using barriers instead of atomic cmpexch operations.
> + * <nr_frames> specify the size of vector <frame_list>.
> + * The frame addresses are returned in the <frame_list>.
> + * Only <nr_frames> addresses are returned, even if the table is larger.
> + * NOTES:
> + *  1. <dom> may be specified as DOMID_SELF.
> + *  2. Only a sufficiently-privileged domain may specify <dom> != DOMID_SELF.
> + */
> +#define GNTTABOP_get_status_frames     9
> +struct gnttab_get_status_frames {
> +    /* IN parameters. */
> +    uint32_t nr_frames;
> +    domid_t  dom;
> +    /* OUT parameters. */
> +    int16_t  status;              /* GNTST_* */
> +    GUEST_HANDLE(uint64_t) frame_list;
> +};
> +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_status_frames);
> +
> +/*
> + * GNTTABOP_get_version: Get the grant table version which is in
> + * effect for domain <dom>.
> + */
> +#define GNTTABOP_get_version          10
> +struct gnttab_get_version {
> +    /* IN parameters */
> +    domid_t dom;
> +    uint16_t pad;
> +    /* OUT parameters */
> +    uint32_t version;
> +};
> +DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);
> +
> +/*
>   * Bitfield values for update_pin_status.flags.
>   */
>   /* Map the grant entry for access by I/O devices. */
> diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
> index 6a6e914..710afe0 100644
> --- a/include/xen/interface/xen.h
> +++ b/include/xen/interface/xen.h
> @@ -523,6 +523,8 @@ struct tmem_op {
>         } u;
>  };
> 
> +DEFINE_GUEST_HANDLE(uint64_t);

The kernel uses uN style types rather than the uintN_t style ones,
although include/xen/interface/grant_table.h seems not to adhere to that
at the moment. It might be worth cleaning that up as you go passed.

> +
>  #else /* __ASSEMBLY__ */
> 
>  /* In assembly code we cannot use C numeric constant suffixes. */
> --
> 1.7.6.4
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ