[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Implement sub-page grant support.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1254898019 -3600 # Node ID ef9f401b32ca43e1fc066f260a999dcbf0992010 # Parent 95ea2052b41b209fa913d6861143915140be4171 Implement sub-page grant support. Signed-off-by: Steven Smith <steven.smith@xxxxxxxxxx> --- xen/common/grant_table.c | 72 +++++++++++++++++++++++++++++++++------ xen/include/public/grant_table.h | 17 +++++++++ xen/include/xen/grant_table.h | 11 ++++- 3 files changed, 87 insertions(+), 13 deletions(-) diff -r 95ea2052b41b -r ef9f401b32ca xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Oct 07 07:46:36 2009 +0100 +++ b/xen/common/grant_table.c Wed Oct 07 07:46:59 2009 +0100 @@ -210,6 +210,7 @@ static unsigned int nr_grant_entries(str static int _set_status_v1(domid_t domid, int readonly, + int mapflag, grant_entry_header_t *shah, struct active_grant_entry *act) { @@ -227,6 +228,11 @@ static int _set_status_v1(domid_t domid */ int retries = 0; + /* if this is a grant mapping operation we should ensure GTF_sub_page + is not set */ + if (mapflag) + mask |= GTF_sub_page; + scombo.word = *(u32 *)shah; /* @@ -276,6 +282,7 @@ done: static int _set_status_v2(domid_t domid, int readonly, + int mapflag, grant_entry_header_t *shah, struct active_grant_entry *act, grant_status_t *status) @@ -295,6 +302,11 @@ static int _set_status_v2(domid_t domid flags = scombo.shorts.flags; id = scombo.shorts.domid; + /* if this is a grant mapping operation we should ensure GTF_sub_page + is not set */ + if (mapflag) + mask |= GTF_sub_page; + /* If not already pinned, check the grant domid and type. */ if ( !act->pin && (((flags & mask) != GTF_permit_access) || @@ -355,15 +367,16 @@ static int _set_status(unsigned gt_versi static int _set_status(unsigned gt_version, domid_t domid, int readonly, + int mapflag, grant_entry_header_t *shah, struct active_grant_entry *act, grant_status_t *status) { if (gt_version == 1) - return _set_status_v1(domid, readonly, shah, act); + return _set_status_v1(domid, readonly, mapflag, shah, act); else - return _set_status_v2(domid, readonly, shah, act, status); + return _set_status_v2(domid, readonly, mapflag, shah, act, status); } /* @@ -460,10 +473,11 @@ __gnttab_map_grant_ref( /* If already pinned, check the active domid and avoid refcnt overflow. */ if ( act->pin && ((act->domid != ld->domain_id) || - (act->pin & 0x80808080U) != 0) ) + (act->pin & 0x80808080U) != 0 || + (act->is_sub_page)) ) PIN_FAIL(unlock_out, GNTST_general_error, - "Bad domain (%d != %d), or risk of counter overflow %08x\n", - act->domid, ld->domain_id, act->pin); + "Bad domain (%d != %d), or risk of counter overflow %08x, or subpage %d\n", + act->domid, ld->domain_id, act->pin, act->is_sub_page); if ( !act->pin || (!(op->flags & GNTMAP_readonly) && @@ -471,7 +485,7 @@ __gnttab_map_grant_ref( { if ( (rc = _set_status(rd->grant_table->gt_version, ld->domain_id, op->flags & GNTMAP_readonly, - shah, act, status) ) != GNTST_okay ) + 1, shah, act, status) ) != GNTST_okay ) goto unlock_out; if ( !act->pin ) @@ -482,6 +496,9 @@ __gnttab_map_grant_ref( else act->gfn = sha2->full_page.frame; act->frame = gmfn_to_mfn(rd, act->gfn); + act->start = 0; + act->length = PAGE_SIZE; + act->is_sub_page = 0; } } @@ -1554,7 +1571,7 @@ static int static int __acquire_grant_for_copy( struct domain *rd, unsigned long gref, int readonly, - unsigned long *frame) + unsigned long *frame, unsigned *page_off, unsigned *length) { grant_entry_v1_t *sha1; grant_entry_v2_t *sha2; @@ -1601,21 +1618,40 @@ __acquire_grant_for_copy( { if ( (rc = _set_status(rd->grant_table->gt_version, current->domain->domain_id, - readonly, shah, act, status) ) != GNTST_okay ) + readonly, 0, shah, act, status) ) != GNTST_okay ) goto unlock_out; + if ( !act->pin ) { act->domid = current->domain->domain_id; + act->is_sub_page = 0; + act->start = 0; + act->length = PAGE_SIZE; + if ( sha1 ) + { act->gfn = sha1->frame; + } + else if ( shah->flags & GTF_sub_page ) + { + act->start = sha2->sub_page.page_off; + act->length = sha2->sub_page.length; + act->is_sub_page = 1; + act->gfn = sha2->sub_page.frame; + } else + { act->gfn = sha2->full_page.frame; + } + act->frame = gmfn_to_mfn(rd, act->gfn); } } act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc; + *page_off = act->start; + *length = act->length; *frame = act->frame; unlock_out: @@ -1667,10 +1703,18 @@ __gnttab_copy( if ( src_is_gref ) { - rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame); + unsigned source_off, source_len; + rc = __acquire_grant_for_copy(sd, op->source.u.ref, 1, &s_frame, + &source_off, &source_len); if ( rc != GNTST_okay ) goto error_out; have_s_grant = 1; + if ( op->source.offset < source_off || + op->len > source_len ) + PIN_FAIL(error_out, GNTST_general_error, + "copy source out of bounds: %d < %d || %d > %d\n", + op->source.offset, source_off, + op->len, source_len); } else { @@ -1690,10 +1734,18 @@ __gnttab_copy( if ( dest_is_gref ) { - rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame); + unsigned dest_off, dest_len; + rc = __acquire_grant_for_copy(dd, op->dest.u.ref, 0, &d_frame, + &dest_off, &dest_len); if ( rc != GNTST_okay ) goto error_out; have_d_grant = 1; + if ( op->dest.offset < dest_off || + op->len > dest_len ) + PIN_FAIL(error_out, GNTST_general_error, + "copy dest out of bounds: %d < %d || %d > %d\n", + op->dest.offset, dest_off, + op->len, dest_len); } else { diff -r 95ea2052b41b -r ef9f401b32ca xen/include/public/grant_table.h --- a/xen/include/public/grant_table.h Wed Oct 07 07:46:36 2009 +0100 +++ b/xen/include/public/grant_table.h Wed Oct 07 07:46:59 2009 +0100 @@ -130,6 +130,9 @@ typedef struct grant_entry_v1 grant_entr * 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_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST] + * 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) @@ -143,6 +146,8 @@ typedef struct grant_entry_v1 grant_entr #define GTF_PCD (1U<<_GTF_PCD) #define _GTF_PAT (7) #define GTF_PAT (1U<<_GTF_PAT) +#define _GTF_sub_page (8) +#define GTF_sub_page (1U<<_GTF_sub_page) /* * Subflags for GTF_accept_transfer: @@ -200,6 +205,18 @@ union grant_entry_v2 { 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+@length) + * in frame @frame. + */ + struct { + grant_entry_header_t hdr; + uint16_t page_off; + uint16_t length; + uint64_t frame; + } sub_page; uint32_t __spacer[4]; /* Pad to a power of two */ }; diff -r 95ea2052b41b -r ef9f401b32ca xen/include/xen/grant_table.h --- a/xen/include/xen/grant_table.h Wed Oct 07 07:46:36 2009 +0100 +++ b/xen/include/xen/grant_table.h Wed Oct 07 07:46:59 2009 +0100 @@ -30,10 +30,15 @@ /* Active grant entry - used for shadowing GTF_permit_access grants. */ struct active_grant_entry { - u32 pin; /* Reference count information. */ - domid_t domid; /* Domain being granted access. */ + u32 pin; /* Reference count information. */ + domid_t domid; /* Domain being granted access. */ + unsigned long frame; /* Frame being granted. */ unsigned long gfn; /* Guest's idea of the frame being granted. */ - unsigned long frame; /* Frame being granted. */ + unsigned is_sub_page:1; /* True if this is a sub-page grant. */ + unsigned start:15; /* For sub-page grants, the start offset + in the page. */ + unsigned length:16; /* For sub-page grants, the length of the + grant. */ }; /* Count of writable host-CPU mappings. */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |