diff options
author | Andres Lagar-Cavilla <andres@lagarcavilla.org> | 2012-01-26 12:46:26 +0000 |
---|---|---|
committer | Andres Lagar-Cavilla <andres@lagarcavilla.org> | 2012-01-26 12:46:26 +0000 |
commit | 3881f1a903ada4573be2eec5458a1defe5a34313 (patch) | |
tree | e8801efb5b90a2c87c29f4e6c0788823d32a5e2f /xen | |
parent | 76dd1b023d82f0461a6678c4c689a179d9a0c256 (diff) | |
download | xen-3881f1a903ada4573be2eec5458a1defe5a34313.tar.gz xen-3881f1a903ada4573be2eec5458a1defe5a34313.tar.bz2 xen-3881f1a903ada4573be2eec5458a1defe5a34313.zip |
x86/mm: Update mem sharing interface to (re)allow sharing of grants
Previously, the mem sharing code would return an opaque handle to index shared
pages (and nominees) in its global hash table. By removing the hash table, the
new interfaces requires a gfn and a version. However, when sharing grants, the
caller provides a grant ref and a version. Update interface to handle this
case.
The use case for grant sharing is when sharing from within a backend (e.g.
memshr + blktap2), in which case the backend is only exposed to grant
references.
Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Signed-off-by: Adin Scannell <adin@scannell.ca>
Committed-by: Tim Deegan <tim@xen.org>
Acked-by: Tim Deegan <tim@xen.org>
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/x86/mm/mem_sharing.c | 57 | ||||
-rw-r--r-- | xen/include/public/domctl.h | 13 |
2 files changed, 61 insertions, 9 deletions
diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 2b51b69c98..4e3873409f 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -728,18 +728,57 @@ int mem_sharing_domctl(struct domain *d, xen_domctl_mem_sharing_op_t *mec) case XEN_DOMCTL_MEM_EVENT_OP_SHARING_SHARE: { - unsigned long sgfn = mec->u.share.source_gfn; - shr_handle_t sh = mec->u.share.source_handle; - struct domain *cd = get_domain_by_id(mec->u.share.client_domain); - if ( cd ) + unsigned long sgfn, cgfn; + struct domain *cd; + shr_handle_t sh, ch; + + if ( !mem_sharing_enabled(d) ) + return -EINVAL; + + cd = get_domain_by_id(mec->u.share.client_domain); + if ( !cd ) + return -ESRCH; + + if ( !mem_sharing_enabled(cd) ) { - unsigned long cgfn = mec->u.share.client_gfn; - shr_handle_t ch = mec->u.share.client_handle; - rc = mem_sharing_share_pages(d, sgfn, sh, cd, cgfn, ch); put_domain(cd); + return -EINVAL; } - else - return -EEXIST; + + if ( XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF(mec->u.share.source_gfn) ) + { + grant_ref_t gref = (grant_ref_t) + (XEN_DOMCTL_MEM_SHARING_FIELD_GET_GREF( + mec->u.share.source_gfn)); + if ( mem_sharing_gref_to_gfn(d, gref, &sgfn) < 0 ) + { + put_domain(cd); + return -EINVAL; + } + } else { + sgfn = mec->u.share.source_gfn; + } + + if ( XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF(mec->u.share.client_gfn) ) + { + grant_ref_t gref = (grant_ref_t) + (XEN_DOMCTL_MEM_SHARING_FIELD_GET_GREF( + mec->u.share.client_gfn)); + if ( mem_sharing_gref_to_gfn(cd, gref, &cgfn) < 0 ) + { + put_domain(cd); + return -EINVAL; + } + } else { + cgfn = mec->u.share.client_gfn; + } + + sh = mec->u.share.source_handle; + ch = mec->u.share.client_handle; + + rc = mem_sharing_share_pages(d, sgfn, sh, cd, cgfn, ch); + + put_domain(cd); } break; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index ca5eb61eeb..457762603e 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -775,6 +775,19 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_mem_event_op_t); #define XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID (-10) #define XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID (-9) +/* The following allows sharing of grant refs. This is useful + * for sharing utilities sitting as "filters" in IO backends + * (e.g. memshr + blktap(2)). The IO backend is only exposed + * to grant references, and this allows sharing of the grefs */ +#define XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF_FLAG (1ULL << 62) + +#define XEN_DOMCTL_MEM_SHARING_FIELD_MAKE_GREF(field, val) \ + (field) = (XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF_FLAG | val) +#define XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF(field) \ + ((field) & XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF_FLAG) +#define XEN_DOMCTL_MEM_SHARING_FIELD_GET_GREF(field) \ + ((field) & (~XEN_DOMCTL_MEM_SHARING_FIELD_IS_GREF_FLAG)) + struct xen_domctl_mem_sharing_op { uint8_t op; /* XEN_DOMCTL_MEM_EVENT_OP_* */ |