Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
Allow iomem permissions to be set up through grant table ops
diff -r 749b60ccc177 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/arch/x86/mm.c Wed Jul 25 14:03:12 2007 +0100
@@ -594,6 +594,14 @@ get_##level##_linear_pagetable(
return 1;
\
}
+
+int iomem_page_test(unsigned long mfn, struct page_info *page)
+{
+ return unlikely(!mfn_valid(mfn)) ||
+ unlikely(page_get_owner(page) == dom_io);
+}
+
+
int
get_page_from_l1e(
l1_pgentry_t l1e, struct domain *d)
@@ -611,8 +619,7 @@ get_page_from_l1e(
return 0;
}
- if ( unlikely(!mfn_valid(mfn)) ||
- unlikely(page_get_owner(page) == dom_io) )
+ if ( iomem_page_test(mfn, page) )
{
/* DOMID_IO reverts to caller for privilege checks. */
if ( d == dom_io )
diff -r 749b60ccc177 xen/common/grant_table.c
--- a/xen/common/grant_table.c Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/common/grant_table.c Mon Jul 30 10:28:27 2007 +0100
@@ -199,6 +199,7 @@ __gnttab_map_grant_ref(
int handle;
unsigned long frame = 0;
int rc = GNTST_okay;
+ int is_iomem = 0;
struct active_grant_entry *act;
struct grant_mapping *mt;
grant_entry_t *sha;
@@ -327,34 +328,52 @@ __gnttab_map_grant_ref(
spin_unlock(&rd->grant_table->lock);
- if ( unlikely(!mfn_valid(frame)) ||
- unlikely(!((op->flags & GNTMAP_readonly) ?
- get_page(mfn_to_page(frame), rd) :
- get_page_and_type(mfn_to_page(frame), rd,
- PGT_writable_page))) )
- {
- if ( !rd->is_dying )
- gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx\n",
frame);
- rc = GNTST_general_error;
- goto undo_out;
- }
-
- if ( op->flags & GNTMAP_host_map )
- {
- rc = create_grant_host_mapping(op->host_addr, frame, op-
>flags);
- if ( rc != GNTST_okay )
- {
- if ( !(op->flags & GNTMAP_readonly) )
- put_page_type(mfn_to_page(frame));
- put_page(mfn_to_page(frame));
+ if ( op->flags & GNTMAP_host_map )
+ {
+ /* Could be an iomem page for setting up permission */
+ if( iomem_page_test(frame, mfn_to_page(frame)) ) {
+ is_iomem = 1;
+ if ( iomem_permit_access(ld, frame, frame) ) {
+ gdprintk(XENLOG_WARNING,
+ "Could not permit access to grant frame %lx as
iomem\n",
+ frame);
+ rc = GNTST_general_error;
+ goto undo_out;
+ }
+ }
+ }
+
+ if (!is_iomem )
+ {
+ if ( unlikely(!mfn_valid(frame)) ||
+ unlikely(!((op->flags & GNTMAP_readonly) ?
+ get_page(mfn_to_page(frame), rd) :
+ get_page_and_type(mfn_to_page(frame), rd,
+ PGT_writable_page))))
+ {
+ if ( !rd->is_dying )
+ gdprintk(XENLOG_WARNING, "Could not pin grant frame %lx
\n", frame);
+ rc = GNTST_general_error;
goto undo_out;
}
-
- if ( op->flags & GNTMAP_device_map )
- {
- (void)get_page(mfn_to_page(frame), rd);
- if ( !(op->flags & GNTMAP_readonly) )
- get_page_type(mfn_to_page(frame), PGT_writable_page);
+
+ if ( op->flags & GNTMAP_host_map )
+ {
+ rc = create_grant_host_mapping(op->host_addr, frame, op-
>flags);
+ if ( rc != GNTST_okay )
+ {
+ if ( !(op->flags & GNTMAP_readonly) )
+ put_page_type(mfn_to_page(frame));
+ put_page(mfn_to_page(frame));
+ goto undo_out;
+ }
+
+ if ( op->flags & GNTMAP_device_map )
+ {
+ (void)get_page(mfn_to_page(frame), rd);
+ if ( !(op->flags & GNTMAP_readonly) )
+ get_page_type(mfn_to_page(frame),
PGT_writable_page);
+ }
}
}
@@ -474,7 +493,8 @@ __gnttab_unmap_common(
{
if ( unlikely(op->frame != act->frame) )
PIN_FAIL(unmap_out, GNTST_general_error,
- "Bad frame number doesn't match gntref.\n");
+ "Bad frame number doesn't match gntref. (%lx != %
lx)\n",
+ op->frame, act->frame);
if ( op->flags & GNTMAP_device_map )
{
ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask));
@@ -486,12 +506,21 @@ __gnttab_unmap_common(
}
}
- if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) )
- {
- if ( (rc = replace_grant_host_mapping(op->host_addr,
- op->frame, op->new_addr,
- op->flags)) < 0 )
- goto unmap_out;
+ if ( op->flags & GNTMAP_host_map )
+ {
+ if ( (op->host_addr != 0) )
+ {
+ if ( (rc = replace_grant_host_mapping(op->host_addr,
+ op->frame, op-
>new_addr,
+ op->flags)) < 0 )
+ goto unmap_out;
+ }
+ else if ( iomem_page_test(op->frame, mfn_to_page(op->frame)) &&
+ iomem_access_permitted(ld, op->frame, op->frame) )
+ {
+ if ( (rc = iomem_deny_access(ld, op->frame, op->frame)) <
0 )
+ goto unmap_out;
+ }
ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask));
op->map->flags &= ~GNTMAP_host_map;
@@ -499,7 +528,7 @@ __gnttab_unmap_common(
act->pin -= GNTPIN_hstr_inc;
else
act->pin -= GNTPIN_hstw_inc;
- }
+ }
/* If just unmapped a writable mapping, mark as dirtied */
if ( !(op->flags & GNTMAP_readonly) )
@@ -1538,6 +1567,7 @@ gnttab_release_mappings(
struct domain *rd;
struct active_grant_entry *act;
struct grant_entry *sha;
+ int rc;
BUG_ON(!d->is_dying);
@@ -1595,7 +1625,12 @@ gnttab_release_mappings(
{
BUG_ON(!(act->pin & GNTPIN_hstw_mask));
act->pin -= GNTPIN_hstw_inc;
- gnttab_release_put_page_and_type(mfn_to_page(act-
>frame));
+
+ if ( iomem_page_test(act->frame, mfn_to_page(act-
>frame)) &&
+ iomem_access_permitted(rd, act->frame, act-
>frame) )
+ rc = iomem_deny_access(rd, act->frame, act->frame);
+ else
+ gnttab_release_put_page_and_type(mfn_to_page(act-
>frame));
}
if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) ==
0 )
diff -r 749b60ccc177 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h Wed Jul 25 14:03:08 2007 +0100
+++ b/xen/include/asm-x86/mm.h Wed Jul 25 14:03:12 2007 +0100
@@ -197,6 +197,9 @@ static inline int get_page(struct page_i
return 1;
}
+/* Decide whether this page looks like iomem or real memory */
+int iomem_page_test(unsigned long mfn, struct page_info *page);
+
void put_page_type(struct page_info *page);
int get_page_type(struct page_info *page, unsigned long type);
int get_page_from_l1e(l1_pgentry_t l1e, struct domain *d);
iomem_grants
Description: Text document
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|