Commit 243848fc authored by Shannon Zhao's avatar Shannon Zhao Committed by David Vrabel

xen/grant-table: Move xlated_setup_gnttab_pages to common place

Move xlated_setup_gnttab_pages to common place, so it can be reused by
ARM to setup grant table.

Rename it to xen_xlate_map_ballooned_pages.
Signed-off-by: default avatarShannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: default avatarStefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: default avatarJulien Grall <julien.grall@arm.com>
Tested-by: default avatarJulien Grall <julien.grall@arm.com>
parent a4e081b0
...@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared) ...@@ -111,63 +111,18 @@ int arch_gnttab_init(unsigned long nr_shared)
} }
#ifdef CONFIG_XEN_PVH #ifdef CONFIG_XEN_PVH
#include <xen/balloon.h>
#include <xen/events.h> #include <xen/events.h>
#include <linux/slab.h> #include <xen/xen-ops.h>
static int __init xlated_setup_gnttab_pages(void)
{
struct page **pages;
xen_pfn_t *pfns;
void *vaddr;
int rc;
unsigned int i;
unsigned long nr_grant_frames = gnttab_max_grant_frames();
BUG_ON(nr_grant_frames == 0);
pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
if (!pages)
return -ENOMEM;
pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
if (!pfns) {
kfree(pages);
return -ENOMEM;
}
rc = alloc_xenballooned_pages(nr_grant_frames, pages);
if (rc) {
pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
kfree(pages);
kfree(pfns);
return rc;
}
for (i = 0; i < nr_grant_frames; i++)
pfns[i] = page_to_pfn(pages[i]);
vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
if (!vaddr) {
pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
free_xenballooned_pages(nr_grant_frames, pages);
kfree(pages);
kfree(pfns);
return -ENOMEM;
}
kfree(pages);
xen_auto_xlat_grant_frames.pfn = pfns;
xen_auto_xlat_grant_frames.count = nr_grant_frames;
xen_auto_xlat_grant_frames.vaddr = vaddr;
return 0;
}
static int __init xen_pvh_gnttab_setup(void) static int __init xen_pvh_gnttab_setup(void)
{ {
if (!xen_pvh_domain()) if (!xen_pvh_domain())
return -ENODEV; return -ENODEV;
return xlated_setup_gnttab_pages(); xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
return xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn,
&xen_auto_xlat_grant_frames.vaddr,
xen_auto_xlat_grant_frames.count);
} }
/* Call it _before_ __gnttab_init as we need to initialize the /* Call it _before_ __gnttab_init as we need to initialize the
* xen_auto_xlat_grant_frames first. */ * xen_auto_xlat_grant_frames first. */
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/xen/hypercall.h> #include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h> #include <asm/xen/hypervisor.h>
...@@ -37,6 +39,7 @@ ...@@ -37,6 +39,7 @@
#include <xen/page.h> #include <xen/page.h>
#include <xen/interface/xen.h> #include <xen/interface/xen.h>
#include <xen/interface/memory.h> #include <xen/interface/memory.h>
#include <xen/balloon.h>
typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data); typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
...@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, ...@@ -185,3 +188,61 @@ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range); EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
/**
* xen_xlate_map_ballooned_pages - map a new set of ballooned pages
* @gfns: returns the array of corresponding GFNs
* @virt: returns the virtual address of the mapped region
* @nr_grant_frames: number of GFNs
* @return 0 on success, error otherwise
*
* This allocates a set of ballooned pages and maps them into the
* kernel's address space.
*/
int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt,
unsigned long nr_grant_frames)
{
struct page **pages;
xen_pfn_t *pfns;
void *vaddr;
int rc;
unsigned int i;
BUG_ON(nr_grant_frames == 0);
pages = kcalloc(nr_grant_frames, sizeof(pages[0]), GFP_KERNEL);
if (!pages)
return -ENOMEM;
pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL);
if (!pfns) {
kfree(pages);
return -ENOMEM;
}
rc = alloc_xenballooned_pages(nr_grant_frames, pages);
if (rc) {
pr_warn("%s Couldn't balloon alloc %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
kfree(pages);
kfree(pfns);
return rc;
}
for (i = 0; i < nr_grant_frames; i++)
pfns[i] = page_to_pfn(pages[i]);
vaddr = vmap(pages, nr_grant_frames, 0, PAGE_KERNEL);
if (!vaddr) {
pr_warn("%s Couldn't map %ld pfns rc:%d\n", __func__,
nr_grant_frames, rc);
free_xenballooned_pages(nr_grant_frames, pages);
kfree(pages);
kfree(pfns);
return -ENOMEM;
}
kfree(pages);
*gfns = pfns;
*virt = vaddr;
return 0;
}
EXPORT_SYMBOL_GPL(xen_xlate_map_ballooned_pages);
...@@ -85,6 +85,8 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma, ...@@ -85,6 +85,8 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
struct page **pages); struct page **pages);
int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma, int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
int nr, struct page **pages); int nr, struct page **pages);
int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
unsigned long nr_grant_frames);
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor); bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment