2018-08-28 15:40:15 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
2008-04-03 01:54:00 +08:00
|
|
|
/******************************************************************************
|
|
|
|
* grant_table.c
|
|
|
|
* x86 specific part
|
|
|
|
*
|
|
|
|
* Granting foreign access to our memory reservation.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2005-2006, Christopher Clark
|
|
|
|
* Copyright (c) 2004-2005, K A Fraser
|
|
|
|
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
|
|
|
|
* VA Linux Systems Japan. Split out x86 specific part.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/mm.h>
|
2014-07-11 23:42:34 +08:00
|
|
|
#include <linux/slab.h>
|
2008-04-03 01:54:00 +08:00
|
|
|
#include <linux/vmalloc.h>
|
|
|
|
|
|
|
|
#include <xen/interface/xen.h>
|
|
|
|
#include <xen/page.h>
|
|
|
|
#include <xen/grant_table.h>
|
2014-07-11 23:42:34 +08:00
|
|
|
#include <xen/xen.h>
|
2008-04-03 01:54:00 +08:00
|
|
|
|
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
static struct gnttab_vm_area {
|
|
|
|
struct vm_struct *area;
|
|
|
|
pte_t **ptes;
|
2020-10-18 07:15:36 +08:00
|
|
|
int idx;
|
2017-11-02 17:19:17 +08:00
|
|
|
} gnttab_shared_vm_area, gnttab_status_vm_area;
|
2014-07-11 23:42:34 +08:00
|
|
|
|
|
|
|
int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
|
|
|
|
unsigned long max_nr_gframes,
|
|
|
|
void **__shared)
|
2008-04-03 01:54:00 +08:00
|
|
|
{
|
2014-07-11 23:42:34 +08:00
|
|
|
void *shared = *__shared;
|
|
|
|
unsigned long addr;
|
|
|
|
unsigned long i;
|
2008-04-03 01:54:00 +08:00
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
if (shared == NULL)
|
|
|
|
*__shared = shared = gnttab_shared_vm_area.area->addr;
|
2008-04-03 01:54:00 +08:00
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
addr = (unsigned long)shared;
|
|
|
|
|
|
|
|
for (i = 0; i < nr_gframes; i++) {
|
|
|
|
set_pte_at(&init_mm, addr, gnttab_shared_vm_area.ptes[i],
|
|
|
|
mfn_pte(frames[i], PAGE_KERNEL));
|
|
|
|
addr += PAGE_SIZE;
|
|
|
|
}
|
xen/granttable: Grant tables V2 implementation
Receiver-side copying of packets is based on this implementation, it gives
better performance and better CPU accounting. It totally supports three types:
full-page, sub-page and transitive grants.
However this patch does not cover sub-page and transitive grants, it mainly
focus on Full-page part and implements grant table V2 interfaces corresponding
to what already exists in grant table V1, such as: grant table V2
initialization, mapping, releasing and exported interfaces.
Each guest can only supports one type of grant table type, every entry in grant
table should be the same version. It is necessary to set V1 or V2 version before
initializing the grant table.
Grant table exported interfaces of V2 are same with those of V1, Xen is
responsible to judge what grant table version guests are using in every grant
operation.
V2 fulfills the same role of V1, and it is totally backwards compitable with V1.
If dom0 support grant table V2, the guests runing on it can run with either V1
or V2.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Annie Li <annie.li@oracle.com>
[v1: Modified alloc_vm_area call (new parameters), indentation, and cleanpatch
warnings]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2011-11-22 09:59:21 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-02 17:19:17 +08:00
|
|
|
int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
|
|
|
|
unsigned long max_nr_gframes,
|
|
|
|
grant_status_t **__shared)
|
|
|
|
{
|
|
|
|
grant_status_t *shared = *__shared;
|
|
|
|
unsigned long addr;
|
|
|
|
unsigned long i;
|
|
|
|
|
|
|
|
if (shared == NULL)
|
|
|
|
*__shared = shared = gnttab_status_vm_area.area->addr;
|
|
|
|
|
|
|
|
addr = (unsigned long)shared;
|
|
|
|
|
|
|
|
for (i = 0; i < nr_gframes; i++) {
|
|
|
|
set_pte_at(&init_mm, addr, gnttab_status_vm_area.ptes[i],
|
|
|
|
mfn_pte(frames[i], PAGE_KERNEL));
|
|
|
|
addr += PAGE_SIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
|
2008-04-03 01:54:00 +08:00
|
|
|
{
|
2017-11-02 17:19:17 +08:00
|
|
|
pte_t **ptes;
|
2014-07-11 23:42:34 +08:00
|
|
|
unsigned long addr;
|
|
|
|
unsigned long i;
|
2008-04-03 01:54:00 +08:00
|
|
|
|
2017-11-02 17:19:17 +08:00
|
|
|
if (shared == gnttab_status_vm_area.area->addr)
|
|
|
|
ptes = gnttab_status_vm_area.ptes;
|
|
|
|
else
|
|
|
|
ptes = gnttab_shared_vm_area.ptes;
|
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
addr = (unsigned long)shared;
|
|
|
|
|
|
|
|
for (i = 0; i < nr_gframes; i++) {
|
2017-11-02 17:19:17 +08:00
|
|
|
set_pte_at(&init_mm, addr, ptes[i], __pte(0));
|
2014-07-11 23:42:34 +08:00
|
|
|
addr += PAGE_SIZE;
|
|
|
|
}
|
2008-04-03 01:54:00 +08:00
|
|
|
}
|
|
|
|
|
2020-10-18 07:15:36 +08:00
|
|
|
static int gnttab_apply(pte_t *pte, unsigned long addr, void *data)
|
|
|
|
{
|
|
|
|
struct gnttab_vm_area *area = data;
|
|
|
|
|
|
|
|
area->ptes[area->idx++] = pte;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
|
xen/granttable: Grant tables V2 implementation
Receiver-side copying of packets is based on this implementation, it gives
better performance and better CPU accounting. It totally supports three types:
full-page, sub-page and transitive grants.
However this patch does not cover sub-page and transitive grants, it mainly
focus on Full-page part and implements grant table V2 interfaces corresponding
to what already exists in grant table V1, such as: grant table V2
initialization, mapping, releasing and exported interfaces.
Each guest can only supports one type of grant table type, every entry in grant
table should be the same version. It is necessary to set V1 or V2 version before
initializing the grant table.
Grant table exported interfaces of V2 are same with those of V1, Xen is
responsible to judge what grant table version guests are using in every grant
operation.
V2 fulfills the same role of V1, and it is totally backwards compitable with V1.
If dom0 support grant table V2, the guests runing on it can run with either V1
or V2.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Annie Li <annie.li@oracle.com>
[v1: Modified alloc_vm_area call (new parameters), indentation, and cleanpatch
warnings]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2011-11-22 09:59:21 +08:00
|
|
|
{
|
2016-08-25 19:23:06 +08:00
|
|
|
area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
|
2014-07-11 23:42:34 +08:00
|
|
|
if (area->ptes == NULL)
|
|
|
|
return -ENOMEM;
|
2020-10-18 07:15:36 +08:00
|
|
|
area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP);
|
|
|
|
if (!area->area)
|
|
|
|
goto out_free_ptes;
|
|
|
|
if (apply_to_page_range(&init_mm, (unsigned long)area->area->addr,
|
|
|
|
PAGE_SIZE * nr_frames, gnttab_apply, area))
|
|
|
|
goto out_free_vm_area;
|
2014-07-11 23:42:34 +08:00
|
|
|
return 0;
|
2020-10-18 07:15:36 +08:00
|
|
|
out_free_vm_area:
|
|
|
|
free_vm_area(area->area);
|
|
|
|
out_free_ptes:
|
|
|
|
kfree(area->ptes);
|
|
|
|
return -ENOMEM;
|
xen/granttable: Grant tables V2 implementation
Receiver-side copying of packets is based on this implementation, it gives
better performance and better CPU accounting. It totally supports three types:
full-page, sub-page and transitive grants.
However this patch does not cover sub-page and transitive grants, it mainly
focus on Full-page part and implements grant table V2 interfaces corresponding
to what already exists in grant table V1, such as: grant table V2
initialization, mapping, releasing and exported interfaces.
Each guest can only supports one type of grant table type, every entry in grant
table should be the same version. It is necessary to set V1 or V2 version before
initializing the grant table.
Grant table exported interfaces of V2 are same with those of V1, Xen is
responsible to judge what grant table version guests are using in every grant
operation.
V2 fulfills the same role of V1, and it is totally backwards compitable with V1.
If dom0 support grant table V2, the guests runing on it can run with either V1
or V2.
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Annie Li <annie.li@oracle.com>
[v1: Modified alloc_vm_area call (new parameters), indentation, and cleanpatch
warnings]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
2011-11-22 09:59:21 +08:00
|
|
|
}
|
|
|
|
|
2017-11-02 17:19:17 +08:00
|
|
|
static void arch_gnttab_vfree(struct gnttab_vm_area *area)
|
2014-07-11 23:42:34 +08:00
|
|
|
{
|
2017-11-02 17:19:17 +08:00
|
|
|
free_vm_area(area->area);
|
|
|
|
kfree(area->ptes);
|
|
|
|
}
|
|
|
|
|
|
|
|
int arch_gnttab_init(unsigned long nr_shared, unsigned long nr_status)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2014-07-11 23:42:34 +08:00
|
|
|
if (!xen_pv_domain())
|
|
|
|
return 0;
|
|
|
|
|
2017-11-02 17:19:17 +08:00
|
|
|
ret = arch_gnttab_valloc(&gnttab_shared_vm_area, nr_shared);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Always allocate the space for the status frames in case
|
|
|
|
* we're migrated to a host with V2 support.
|
|
|
|
*/
|
|
|
|
ret = arch_gnttab_valloc(&gnttab_status_vm_area, nr_status);
|
|
|
|
if (ret < 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
err:
|
|
|
|
arch_gnttab_vfree(&gnttab_shared_vm_area);
|
|
|
|
return -ENOMEM;
|
2008-04-03 01:54:00 +08:00
|
|
|
}
|
2014-07-11 23:42:34 +08:00
|
|
|
|
2014-01-03 23:20:18 +08:00
|
|
|
#ifdef CONFIG_XEN_PVH
|
|
|
|
#include <xen/events.h>
|
2016-04-07 20:03:19 +08:00
|
|
|
#include <xen/xen-ops.h>
|
2014-01-03 23:20:18 +08:00
|
|
|
static int __init xen_pvh_gnttab_setup(void)
|
|
|
|
{
|
|
|
|
if (!xen_pvh_domain())
|
|
|
|
return -ENODEV;
|
|
|
|
|
2016-04-07 20:03:19 +08:00
|
|
|
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);
|
2014-01-03 23:20:18 +08:00
|
|
|
}
|
|
|
|
/* Call it _before_ __gnttab_init as we need to initialize the
|
|
|
|
* xen_auto_xlat_grant_frames first. */
|
|
|
|
core_initcall(xen_pvh_gnttab_setup);
|
|
|
|
#endif
|