forked from Minki/linux
xen/grant: Introduce helpers to split a page into grant
Currently, a grant is always based on the Xen page granularity (i.e 4KB). When Linux is using a different page granularity, a single page will be split between multiple grants. The new helpers will be in charge of splitting the Linux page into grants and call a function given by the caller on each grant. Also provide an helper to count the number of grants within a given contiguous region. Note that the x86/include/asm/xen/page.h is now including xen/interface/grant_table.h rather than xen/grant_table.h. It's necessary because xen/grant_table.h depends on asm/xen/page.h and will break the compilation. Furthermore, only definition in interface/grant_table.h is required. Signed-off-by: Julien Grall <julien.grall@citrix.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
This commit is contained in:
parent
1084b1988d
commit
008c320a96
@ -12,7 +12,7 @@
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/grant_table.h>
|
||||
#include <xen/interface/grant_table.h>
|
||||
#include <xen/features.h>
|
||||
|
||||
/* Xen machine address */
|
||||
|
@ -776,6 +776,32 @@ void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gnttab_batch_copy);
|
||||
|
||||
void gnttab_foreach_grant_in_range(struct page *page,
|
||||
unsigned int offset,
|
||||
unsigned int len,
|
||||
xen_grant_fn_t fn,
|
||||
void *data)
|
||||
{
|
||||
unsigned int goffset;
|
||||
unsigned int glen;
|
||||
unsigned long xen_pfn;
|
||||
|
||||
len = min_t(unsigned int, PAGE_SIZE - offset, len);
|
||||
goffset = xen_offset_in_page(offset);
|
||||
|
||||
xen_pfn = page_to_xen_pfn(page) + XEN_PFN_DOWN(offset);
|
||||
|
||||
while (len) {
|
||||
glen = min_t(unsigned int, XEN_PAGE_SIZE - goffset, len);
|
||||
fn(pfn_to_gfn(xen_pfn), goffset, glen, data);
|
||||
|
||||
goffset = 0;
|
||||
xen_pfn++;
|
||||
len -= glen;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gnttab_foreach_grant_in_range);
|
||||
|
||||
int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
|
||||
struct gnttab_map_grant_ref *kmap_ops,
|
||||
struct page **pages, unsigned int count)
|
||||
|
@ -45,8 +45,10 @@
|
||||
#include <asm/xen/hypervisor.h>
|
||||
|
||||
#include <xen/features.h>
|
||||
#include <xen/page.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/page-flags.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define GNTTAB_RESERVED_XENSTORE 1
|
||||
|
||||
@ -224,4 +226,44 @@ static inline struct xen_page_foreign *xen_page_foreign(struct page *page)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Split Linux page in chunk of the size of the grant and call fn
|
||||
*
|
||||
* Parameters of fn:
|
||||
* gfn: guest frame number
|
||||
* offset: offset in the grant
|
||||
* len: length of the data in the grant.
|
||||
* data: internal information
|
||||
*/
|
||||
typedef void (*xen_grant_fn_t)(unsigned long gfn, unsigned int offset,
|
||||
unsigned int len, void *data);
|
||||
|
||||
void gnttab_foreach_grant_in_range(struct page *page,
|
||||
unsigned int offset,
|
||||
unsigned int len,
|
||||
xen_grant_fn_t fn,
|
||||
void *data);
|
||||
|
||||
/* Helper to get to call fn only on the first "grant chunk" */
|
||||
static inline void gnttab_for_one_grant(struct page *page, unsigned int offset,
|
||||
unsigned len, xen_grant_fn_t fn,
|
||||
void *data)
|
||||
{
|
||||
/* The first request is limited to the size of one grant */
|
||||
len = min_t(unsigned int, XEN_PAGE_SIZE - (offset & ~XEN_PAGE_MASK),
|
||||
len);
|
||||
|
||||
gnttab_foreach_grant_in_range(page, offset, len, fn, data);
|
||||
}
|
||||
|
||||
/* Get the number of grant in a specified region
|
||||
*
|
||||
* start: Offset from the beginning of the first page
|
||||
* len: total length of data (can cross multiple page)
|
||||
*/
|
||||
static inline unsigned int gnttab_count_grant(unsigned int start,
|
||||
unsigned int len)
|
||||
{
|
||||
return XEN_PFN_UP(xen_offset_in_page(start) + len);
|
||||
}
|
||||
|
||||
#endif /* __ASM_GNTTAB_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user