[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] xenpaging: page-in granttable entries
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1285176564 -3600 # Node ID 50c1cc209f8fc08f8c47b4068e3a8cb15a4d52d2 # Parent e20ee3a576450c63ec4c7db49542b94610daec8b xenpaging: page-in granttable entries When converting a gfn to mfn, check if the page is paged-out. If it is, request a page-in and return GNTST_eagain to the caller to indicate a retry of the hypercall is required. This fixes granttable errors when xenpaging is enabled in the guest. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> --- xen/common/grant_table.c | 97 ++++++++++++++++++++++++++++------------------- 1 files changed, 59 insertions(+), 38 deletions(-) diff -r e20ee3a57645 -r 50c1cc209f8f xen/common/grant_table.c --- a/xen/common/grant_table.c Wed Sep 22 18:28:16 2010 +0100 +++ b/xen/common/grant_table.c Wed Sep 22 18:29:24 2010 +0100 @@ -139,6 +139,34 @@ shared_entry_header(struct grant_table * #define active_entry(t, e) \ ((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE]) +/* Check if the page has been paged out */ +static int __get_paged_frame(unsigned long gfn, unsigned long *frame, int readonly, struct domain *rd) +{ + struct p2m_domain *p2m; + p2m_type_t p2mt; + mfn_t mfn; + int rc = GNTST_okay; + + p2m = p2m_get_hostp2m(rd); + if ( readonly ) + mfn = gfn_to_mfn(p2m, gfn, &p2mt); + else + mfn = gfn_to_mfn_unshare(p2m, gfn, &p2mt, 1); + + if ( p2m_is_valid(p2mt) ) { + *frame = mfn_x(mfn); + if ( p2m_is_paged(p2mt) ) + p2m_mem_paging_populate(p2m, gfn); + if ( p2m_is_paging(p2mt) ) + rc = GNTST_eagain; + } else { + *frame = INVALID_MFN; + rc = GNTST_bad_page; + } + + return rc; +} + static inline int __get_maptrack_handle( struct grant_table *t) @@ -527,14 +555,16 @@ __gnttab_map_grant_ref( if ( !act->pin ) { + unsigned long gfn; + unsigned long frame; + + gfn = sha1 ? sha1->frame : sha2->full_page.frame; + rc = __get_paged_frame(gfn, &frame, !!(op->flags & GNTMAP_readonly), rd); + if ( rc != GNTST_okay ) + goto unlock_out; + act->gfn = gfn; act->domid = ld->domain_id; - if ( sha1 ) - act->gfn = sha1->frame; - else - act->gfn = sha2->full_page.frame; - act->frame = (op->flags & GNTMAP_readonly) ? - gmfn_to_mfn(rd, act->gfn) : - gfn_to_mfn_private(rd, act->gfn); + act->frame = frame; act->start = 0; act->length = PAGE_SIZE; act->is_sub_page = 0; @@ -1697,6 +1727,7 @@ __acquire_grant_for_copy( domid_t trans_domid; grant_ref_t trans_gref; struct domain *rrd; + unsigned long gfn; unsigned long grant_frame; unsigned trans_page_off; unsigned trans_length; @@ -1814,9 +1845,11 @@ __acquire_grant_for_copy( } else if ( sha1 ) { - act->gfn = sha1->frame; - grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) : - gfn_to_mfn_private(rd, act->gfn); + gfn = sha1->frame; + rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); + if ( rc != GNTST_okay ) + goto unlock_out; + act->gfn = gfn; is_sub_page = 0; trans_page_off = 0; trans_length = PAGE_SIZE; @@ -1824,9 +1857,11 @@ __acquire_grant_for_copy( } else if ( !(sha2->hdr.flags & GTF_sub_page) ) { - act->gfn = sha2->full_page.frame; - grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) : - gfn_to_mfn_private(rd, act->gfn); + gfn = sha2->full_page.frame; + rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); + if ( rc != GNTST_okay ) + goto unlock_out; + act->gfn = gfn; is_sub_page = 0; trans_page_off = 0; trans_length = PAGE_SIZE; @@ -1834,9 +1869,11 @@ __acquire_grant_for_copy( } else { - act->gfn = sha2->sub_page.frame; - grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) : - gfn_to_mfn_private(rd, act->gfn); + gfn = sha2->sub_page.frame; + rc = __get_paged_frame(gfn, &grant_frame, readonly, rd); + if ( rc != GNTST_okay ) + goto unlock_out; + act->gfn = gfn; is_sub_page = 1; trans_page_off = sha2->sub_page.page_off; trans_length = sha2->sub_page.length; @@ -1932,17 +1969,9 @@ __gnttab_copy( else { #ifdef CONFIG_X86 - p2m_type_t p2mt; - struct p2m_domain *p2m = p2m_get_hostp2m(sd); - s_frame = mfn_x(gfn_to_mfn(p2m, op->source.u.gmfn, &p2mt)); - if ( !p2m_is_valid(p2mt) ) - s_frame = INVALID_MFN; - if ( p2m_is_paging(p2mt) ) - { - p2m_mem_paging_populate(p2m, op->source.u.gmfn); - rc = -ENOENT; - goto error_out; - } + rc = __get_paged_frame(op->source.u.gmfn, &s_frame, 1, sd); + if ( rc != GNTST_okay ) + goto error_out; #else s_frame = gmfn_to_mfn(sd, op->source.u.gmfn); #endif @@ -1979,17 +2008,9 @@ __gnttab_copy( else { #ifdef CONFIG_X86 - p2m_type_t p2mt; - struct p2m_domain *p2m = p2m_get_hostp2m(dd); - d_frame = mfn_x(gfn_to_mfn_unshare(p2m, op->dest.u.gmfn, &p2mt, 1)); - if ( !p2m_is_valid(p2mt) ) - d_frame = INVALID_MFN; - if ( p2m_is_paging(p2mt) ) - { - p2m_mem_paging_populate(p2m, op->dest.u.gmfn); - rc = -ENOENT; - goto error_out; - } + rc = __get_paged_frame(op->dest.u.gmfn, &d_frame, 0, dd); + if ( rc != GNTST_okay ) + goto error_out; #else d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn); #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |