From 0920a8b360540a151476b521b99b838cf4a4d942 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 20 Nov 2007 17:30:31 +0000 Subject: [PATCH] Clean up gnttab interface and allow to grant iomem page access with arbitrary cache attributes (x86 only). Signed-off-by: Kieran Mansley --- drivers/char/tpm/tpm_xen.c | 3 +-- drivers/xen/blkfront/blkfront.c | 12 ++++++------ drivers/xen/core/gnttab.c | 17 +++++++++-------- drivers/xen/netfront/netfront.c | 18 ++++++++---------- drivers/xen/pcifront/xenbus.c | 2 +- include/xen/gnttab.h | 9 ++++----- include/xen/interface/grant_table.h | 7 +++++++ 7 files changed, 36 insertions(+), 32 deletions(-) diff --git a/drivers/char/tpm/tpm_xen.c b/drivers/char/tpm/tpm_xen.c index 54882174..d6628335 100644 --- a/drivers/char/tpm/tpm_xen.c +++ b/drivers/char/tpm/tpm_xen.c @@ -266,8 +266,7 @@ static void destroy_tpmring(struct tpm_private *tp) tpmif_set_connected_state(tp, 0); if (tp->ring_ref != GRANT_INVALID_REF) { - gnttab_end_foreign_access(tp->ring_ref, 0, - (unsigned long)tp->tx); + gnttab_end_foreign_access(tp->ring_ref, (unsigned long)tp->tx); tp->ring_ref = GRANT_INVALID_REF; tp->tx = NULL; } diff --git a/drivers/xen/blkfront/blkfront.c b/drivers/xen/blkfront/blkfront.c index c283d5e9..31dfa9b2 100644 --- a/drivers/xen/blkfront/blkfront.c +++ b/drivers/xen/blkfront/blkfront.c @@ -622,7 +622,7 @@ static int blkif_queue_request(struct request *req) ref, info->xbdev->otherend_id, buffer_mfn, - rq_data_dir(req) ); + rq_data_dir(req) ? GTF_readonly : 0 ); info->shadow[id].frame[ring_req->nr_segments] = mfn_to_pfn(buffer_mfn); @@ -790,7 +790,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) /* Free resources associated with old device channel. */ if (info->ring_ref != GRANT_INVALID_REF) { - gnttab_end_foreign_access(info->ring_ref, 0, + gnttab_end_foreign_access(info->ring_ref, (unsigned long)info->ring.sring); info->ring_ref = GRANT_INVALID_REF; info->ring.sring = NULL; @@ -804,7 +804,7 @@ static void blkif_completion(struct blk_shadow *s) { int i; for (i = 0; i < s->req.nr_segments; i++) - gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL); + gnttab_end_foreign_access(s->req.seg[i].gref, 0UL); } static void blkif_recover(struct blkfront_info *info) @@ -846,9 +846,9 @@ static void blkif_recover(struct blkfront_info *info) req->seg[j].gref, info->xbdev->otherend_id, pfn_to_mfn(info->shadow[req->id].frame[j]), - rq_data_dir( - (struct request *) - info->shadow[req->id].request)); + rq_data_dir((struct request *) + info->shadow[req->id].request) ? + GTF_readonly : 0); info->shadow[req->id].req = *req; info->ring.req_prod_pvt++; diff --git a/drivers/xen/core/gnttab.c b/drivers/xen/core/gnttab.c index 65a8a7e4..2b89f2c0 100644 --- a/drivers/xen/core/gnttab.c +++ b/drivers/xen/core/gnttab.c @@ -140,7 +140,7 @@ static void put_free_entry(grant_ref_t ref) */ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, - int readonly) + int flags) { int ref; @@ -150,19 +150,21 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, shared[ref].frame = frame; shared[ref].domid = domid; wmb(); - shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); + BUG_ON(flags & (GTF_accept_transfer | GTF_reading | GTF_writing)); + shared[ref].flags = GTF_permit_access | flags; return ref; } EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, - unsigned long frame, int readonly) + unsigned long frame, int flags) { shared[ref].frame = frame; shared[ref].domid = domid; wmb(); - shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); + BUG_ON(flags & (GTF_accept_transfer | GTF_reading | GTF_writing)); + shared[ref].flags = GTF_permit_access | flags; } EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); @@ -177,7 +179,7 @@ int gnttab_query_foreign_access(grant_ref_t ref) } EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); -int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) +int gnttab_end_foreign_access_ref(grant_ref_t ref) { u16 flags, nflags; @@ -194,10 +196,9 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) } EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); -void gnttab_end_foreign_access(grant_ref_t ref, int readonly, - unsigned long page) +void gnttab_end_foreign_access(grant_ref_t ref, unsigned long page) { - if (gnttab_end_foreign_access_ref(ref, readonly)) { + if (gnttab_end_foreign_access_ref(ref)) { put_free_entry(ref); if (page != 0) free_page(page); diff --git a/drivers/xen/netfront/netfront.c b/drivers/xen/netfront/netfront.c index 6de06891..f76cc10a 100644 --- a/drivers/xen/netfront/netfront.c +++ b/drivers/xen/netfront/netfront.c @@ -663,8 +663,7 @@ static void network_tx_buf_gc(struct net_device *dev) "domain.\n"); BUG(); } - gnttab_end_foreign_access_ref( - np->grant_tx_ref[id], GNTMAP_readonly); + gnttab_end_foreign_access_ref(np->grant_tx_ref[id]); gnttab_release_grant_reference( &np->gref_tx_head, np->grant_tx_ref[id]); np->grant_tx_ref[id] = GRANT_INVALID_REF; @@ -888,7 +887,7 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, mfn = virt_to_mfn(data); gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, - mfn, GNTMAP_readonly); + mfn, GTF_readonly); tx->gref = np->grant_tx_ref[id] = ref; tx->offset = offset; @@ -910,7 +909,7 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, mfn = pfn_to_mfn(page_to_pfn(frag->page)); gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, - mfn, GNTMAP_readonly); + mfn, GTF_readonly); tx->gref = np->grant_tx_ref[id] = ref; tx->offset = frag->page_offset; @@ -972,7 +971,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON((signed short)ref < 0); mfn = virt_to_mfn(data); gnttab_grant_foreign_access_ref( - ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly); + ref, np->xbdev->otherend_id, mfn, GTF_readonly); tx->gref = np->grant_tx_ref[id] = ref; tx->offset = offset; tx->size = len; @@ -1198,7 +1197,7 @@ static int xennet_get_responses(struct netfront_info *np, } pages_flipped++; } else { - ret = gnttab_end_foreign_access_ref(ref, 0); + ret = gnttab_end_foreign_access_ref(ref); BUG_ON(!ret); } @@ -1531,8 +1530,7 @@ static void netif_release_tx_bufs(struct netfront_info *np) continue; skb = np->tx_skbs[i]; - gnttab_end_foreign_access_ref( - np->grant_tx_ref[i], GNTMAP_readonly); + gnttab_end_foreign_access_ref(np->grant_tx_ref[i]); gnttab_release_grant_reference( &np->gref_tx_head, np->grant_tx_ref[i]); np->grant_tx_ref[i] = GRANT_INVALID_REF; @@ -1642,7 +1640,7 @@ static void netif_release_rx_bufs_copy(struct netfront_info *np) skb = np->rx_skbs[i]; - if (!gnttab_end_foreign_access_ref(ref, 0)) + if (!gnttab_end_foreign_access_ref(ref)) { busy++; continue; @@ -2151,7 +2149,7 @@ static void netif_disconnect_backend(struct netfront_info *info) static void end_access(int ref, void *page) { if (ref != GRANT_INVALID_REF) - gnttab_end_foreign_access(ref, 0, (unsigned long)page); + gnttab_end_foreign_access(ref, (unsigned long)page); } diff --git a/drivers/xen/pcifront/xenbus.c b/drivers/xen/pcifront/xenbus.c index 538ca0db..2d7c0192 100644 --- a/drivers/xen/pcifront/xenbus.c +++ b/drivers/xen/pcifront/xenbus.c @@ -57,7 +57,7 @@ static void free_pdev(struct pcifront_device *pdev) xenbus_free_evtchn(pdev->xdev, pdev->evtchn); if (pdev->gnt_ref != INVALID_GRANT_REF) - gnttab_end_foreign_access(pdev->gnt_ref, 0, + gnttab_end_foreign_access(pdev->gnt_ref, (unsigned long)pdev->sh_info); pdev->xdev->dev.driver_data = NULL; diff --git a/include/xen/gnttab.h b/include/xen/gnttab.h index aa8c896b..8f131224 100644 --- a/include/xen/gnttab.h +++ b/include/xen/gnttab.h @@ -51,14 +51,14 @@ struct gnttab_free_callback { }; int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, - int readonly); + int flags); /* * End access through the given grant reference, iff the grant entry is no * longer in use. Return 1 if the grant entry was freed, 0 if it is still in * use. */ -int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); +int gnttab_end_foreign_access_ref(grant_ref_t ref); /* * Eventually end access through the given grant reference, and once that @@ -66,8 +66,7 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); * immediately iff the grant entry is not in use, otherwise it will happen * some time later. page may be 0, in which case no freeing will occur. */ -void gnttab_end_foreign_access(grant_ref_t ref, int readonly, - unsigned long page); +void gnttab_end_foreign_access(grant_ref_t ref, unsigned long page); int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn); @@ -97,7 +96,7 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback, void gnttab_cancel_free_callback(struct gnttab_free_callback *callback); void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, - unsigned long frame, int readonly); + unsigned long frame, int flags); void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, unsigned long pfn); diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h index bae0bd1a..ba3467a9 100644 --- a/include/xen/interface/grant_table.h +++ b/include/xen/interface/grant_table.h @@ -119,6 +119,7 @@ typedef struct grant_entry grant_entry_t; * GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST] * 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] */ #define _GTF_readonly (2) #define GTF_readonly (1U<<_GTF_readonly) @@ -126,6 +127,12 @@ typedef struct grant_entry grant_entry_t; #define GTF_reading (1U<<_GTF_reading) #define _GTF_writing (4) #define GTF_writing (1U<<_GTF_writing) +#define _GTF_PWT (5) +#define GTF_PWT (1U<<_GTF_PWT) +#define _GTF_PCD (6) +#define GTF_PCD (1U<<_GTF_PCD) +#define _GTF_PAT (7) +#define GTF_PAT (1U<<_GTF_PAT) /* * Subflags for GTF_accept_transfer: -- 2.39.5