ia64/xen-unstable

changeset 16067:9f9f9b68cd08

Allow iomem permissions to be set up through grant table ops.
Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 04 10:26:21 2007 +0100 (2007-10-04)
parents 48d42d659a04
children 062fe1c7b09f
files xen/arch/x86/mm.c xen/common/grant_table.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Thu Oct 04 10:25:35 2007 +0100
     1.2 +++ b/xen/arch/x86/mm.c	Thu Oct 04 10:26:21 2007 +0100
     1.3 @@ -597,6 +597,14 @@ get_##level##_linear_pagetable(         
     1.4      return 1;                                                               \
     1.5  }
     1.6  
     1.7 +
     1.8 +int iomem_page_test(unsigned long mfn, struct page_info *page)
     1.9 +{
    1.10 +    return unlikely(!mfn_valid(mfn)) ||
    1.11 +        unlikely(page_get_owner(page) == dom_io);
    1.12 +}
    1.13 +
    1.14 +
    1.15  int
    1.16  get_page_from_l1e(
    1.17      l1_pgentry_t l1e, struct domain *d)
    1.18 @@ -614,8 +622,7 @@ get_page_from_l1e(
    1.19          return 0;
    1.20      }
    1.21  
    1.22 -    if ( unlikely(!mfn_valid(mfn)) ||
    1.23 -         unlikely(page_get_owner(page) == dom_io) )
    1.24 +    if ( iomem_page_test(mfn, page) )
    1.25      {
    1.26          /* DOMID_IO reverts to caller for privilege checks. */
    1.27          if ( d == dom_io )
     2.1 --- a/xen/common/grant_table.c	Thu Oct 04 10:25:35 2007 +0100
     2.2 +++ b/xen/common/grant_table.c	Thu Oct 04 10:26:21 2007 +0100
     2.3 @@ -198,6 +198,7 @@ static void
     2.4      int            handle;
     2.5      unsigned long  frame = 0;
     2.6      int            rc = GNTST_okay;
     2.7 +    int            is_iomem = 0;
     2.8      struct active_grant_entry *act;
     2.9      struct grant_mapping *mt;
    2.10      grant_entry_t *sha;
    2.11 @@ -328,34 +329,52 @@ static void
    2.12  
    2.13      spin_unlock(&rd->grant_table->lock);
    2.14  
    2.15 -    if ( unlikely(!mfn_valid(frame)) ||
    2.16 -         unlikely(!((op->flags & GNTMAP_readonly) ?
    2.17 -                    get_page(mfn_to_page(frame), rd) :
    2.18 -                    get_page_and_type(mfn_to_page(frame), rd,
    2.19 -                                      PGT_writable_page))) )
    2.20 +    if ( op->flags & GNTMAP_host_map ) 
    2.21      {
    2.22 -        if ( !rd->is_dying )
    2.23 -            gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame);
    2.24 -        rc = GNTST_general_error;
    2.25 -        goto undo_out;
    2.26 -    }
    2.27 +        /* Could be an iomem page for setting up permission */
    2.28 +        if( iomem_page_test(frame, mfn_to_page(frame)) ) {
    2.29 +            is_iomem = 1;
    2.30 +            if ( iomem_permit_access(ld, frame, frame) ) {
    2.31 +                gdprintk(XENLOG_WARNING, 
    2.32 +                         "Could not permit access to grant frame %lx as iomem\n",
    2.33 +                         frame);
    2.34 +                rc = GNTST_general_error;
    2.35 +                goto undo_out;
    2.36 +            }
    2.37 +        }
    2.38 +    } 
    2.39  
    2.40 -    if ( op->flags & GNTMAP_host_map )
    2.41 +    if (!is_iomem ) 
    2.42      {
    2.43 -        rc = create_grant_host_mapping(op->host_addr, frame, op->flags);
    2.44 -        if ( rc != GNTST_okay )
    2.45 +        if ( unlikely(!mfn_valid(frame)) ||
    2.46 +             unlikely(!((op->flags & GNTMAP_readonly) ?
    2.47 +                        get_page(mfn_to_page(frame), rd) :
    2.48 +                        get_page_and_type(mfn_to_page(frame), rd,
    2.49 +                                          PGT_writable_page))))
    2.50          {
    2.51 -            if ( !(op->flags & GNTMAP_readonly) )
    2.52 -                put_page_type(mfn_to_page(frame));
    2.53 -            put_page(mfn_to_page(frame));
    2.54 +            if ( !rd->is_dying )
    2.55 +                gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n", frame);
    2.56 +            rc = GNTST_general_error;
    2.57              goto undo_out;
    2.58          }
    2.59 -
    2.60 -        if ( op->flags & GNTMAP_device_map )
    2.61 +        
    2.62 +        if ( op->flags & GNTMAP_host_map )
    2.63          {
    2.64 -            (void)get_page(mfn_to_page(frame), rd);
    2.65 -            if ( !(op->flags & GNTMAP_readonly) )
    2.66 -                get_page_type(mfn_to_page(frame), PGT_writable_page);
    2.67 +            rc = create_grant_host_mapping(op->host_addr, frame, op->flags);
    2.68 +            if ( rc != GNTST_okay )
    2.69 +            {
    2.70 +                if ( !(op->flags & GNTMAP_readonly) )
    2.71 +                    put_page_type(mfn_to_page(frame));
    2.72 +                put_page(mfn_to_page(frame));
    2.73 +                goto undo_out;
    2.74 +            }
    2.75 +
    2.76 +            if ( op->flags & GNTMAP_device_map )
    2.77 +            {
    2.78 +                (void)get_page(mfn_to_page(frame), rd);
    2.79 +                if ( !(op->flags & GNTMAP_readonly) )
    2.80 +                    get_page_type(mfn_to_page(frame), PGT_writable_page);
    2.81 +            }
    2.82          }
    2.83      }
    2.84  
    2.85 @@ -483,7 +502,8 @@ static void
    2.86      {
    2.87          if ( unlikely(op->frame != act->frame) )
    2.88              PIN_FAIL(unmap_out, GNTST_general_error,
    2.89 -                     "Bad frame number doesn't match gntref.\n");
    2.90 +                     "Bad frame number doesn't match gntref. (%lx != %lx)\n",
    2.91 +                     op->frame, act->frame);
    2.92          if ( op->flags & GNTMAP_device_map )
    2.93          {
    2.94              ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
    2.95 @@ -495,12 +515,21 @@ static void
    2.96          }
    2.97      }
    2.98  
    2.99 -    if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) )
   2.100 +    if ( op->flags & GNTMAP_host_map )
   2.101      {
   2.102 -        if ( (rc = replace_grant_host_mapping(op->host_addr,
   2.103 -                                              op->frame, op->new_addr, 
   2.104 -                                              op->flags)) < 0 )
   2.105 -            goto unmap_out;
   2.106 +        if ( (op->host_addr != 0) )
   2.107 +        {
   2.108 +            if ( (rc = replace_grant_host_mapping(op->host_addr,
   2.109 +                                                  op->frame, op->new_addr, 
   2.110 +                                                  op->flags)) < 0 )
   2.111 +                goto unmap_out;
   2.112 +        }
   2.113 +        else if ( iomem_page_test(op->frame, mfn_to_page(op->frame)) &&
   2.114 +                  iomem_access_permitted(ld, op->frame, op->frame) )
   2.115 +        {
   2.116 +            if ( (rc = iomem_deny_access(ld, op->frame, op->frame)) < 0 )
   2.117 +                goto unmap_out;
   2.118 +        }
   2.119  
   2.120          ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
   2.121          op->map->flags &= ~GNTMAP_host_map;
   2.122 @@ -508,7 +537,7 @@ static void
   2.123              act->pin -= GNTPIN_hstr_inc;
   2.124          else
   2.125              act->pin -= GNTPIN_hstw_inc;
   2.126 -    }
   2.127 +    } 
   2.128  
   2.129      /* If just unmapped a writable mapping, mark as dirtied */
   2.130      if ( !(op->flags & GNTMAP_readonly) )
   2.131 @@ -1577,6 +1606,7 @@ gnttab_release_mappings(
   2.132      struct domain        *rd;
   2.133      struct active_grant_entry *act;
   2.134      struct grant_entry   *sha;
   2.135 +    int rc;
   2.136  
   2.137      BUG_ON(!d->is_dying);
   2.138  
   2.139 @@ -1634,7 +1664,12 @@ gnttab_release_mappings(
   2.140              {
   2.141                  BUG_ON(!(act->pin & GNTPIN_hstw_mask));
   2.142                  act->pin -= GNTPIN_hstw_inc;
   2.143 -                gnttab_release_put_page_and_type(mfn_to_page(act->frame));
   2.144 +
   2.145 +                if ( iomem_page_test(act->frame, mfn_to_page(act->frame)) &&
   2.146 +                     iomem_access_permitted(rd, act->frame, act->frame) )
   2.147 +                    rc = iomem_deny_access(rd, act->frame, act->frame);
   2.148 +                else 
   2.149 +                    gnttab_release_put_page_and_type(mfn_to_page(act->frame));
   2.150              }
   2.151  
   2.152              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
     3.1 --- a/xen/include/asm-x86/mm.h	Thu Oct 04 10:25:35 2007 +0100
     3.2 +++ b/xen/include/asm-x86/mm.h	Thu Oct 04 10:26:21 2007 +0100
     3.3 @@ -197,6 +197,9 @@ static inline int get_page(struct page_i
     3.4      return 1;
     3.5  }
     3.6  
     3.7 +/* Decide whether this page looks like iomem or real memory */
     3.8 +int iomem_page_test(unsigned long mfn, struct page_info *page);
     3.9 +
    3.10  void put_page_type(struct page_info *page);
    3.11  int  get_page_type(struct page_info *page, unsigned long type);
    3.12  int  get_page_from_l1e(l1_pgentry_t l1e, struct domain *d);