@@ -609,7 +609,9 @@ does not provide VM\_ENTRY\_LOAD\_GUEST\_PAT.
Specify the serial parameters for the GDB stub.
### gnttab\_max\_nr\_frames
-> `= <integer>`
+> `= [<domU number>][,<dom0 number>]`
+
+> Default: `32,32`
Specify the maximum number of frames per grant table operation.
@@ -409,7 +409,7 @@ struct domain *alloc_domain_struct(void)
return NULL;
clear_page(d);
- d->arch.grant_table_gpfn = xzalloc_array(xen_pfn_t, max_nr_grant_frames);
+ d->arch.grant_table_gpfn = xzalloc_array(xen_pfn_t, max_nr_domU_grant_frames);
return d;
}
@@ -1040,7 +1040,7 @@ int xenmem_add_to_physmap_one(
else
{
if ( (idx >= nr_grant_frames(d->grant_table)) &&
- (idx < max_nr_grant_frames) )
+ (idx < max_nr_grant_frames(d)) )
gnttab_grow_table(d, idx + 1);
if ( idx < nr_grant_frames(d->grant_table) )
@@ -4539,7 +4539,7 @@ int xenmem_add_to_physmap_one(
else
{
if ( (idx >= nr_grant_frames(d->grant_table)) &&
- (idx < max_nr_grant_frames) )
+ (idx < max_nr_grant_frames(d)) )
gnttab_grow_table(d, idx + 1);
if ( idx < nr_grant_frames(d->grant_table) )
@@ -146,11 +146,11 @@ int compat_grant_table_op(unsigned int cmd,
unsigned int max_frame_list_size_in_page =
(COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) /
sizeof(*nat.setup->frame_list.p);
- if ( max_frame_list_size_in_page < max_nr_grant_frames )
+ if ( max_frame_list_size_in_page < max_nr_grant_frames(current->domain) )
{
gdprintk(XENLOG_WARNING,
"max_nr_grant_frames is too large (%u,%u)\n",
- max_nr_grant_frames, max_frame_list_size_in_page);
+ max_nr_grant_frames(current->domain), max_frame_list_size_in_page);
rc = -EINVAL;
}
else
@@ -284,11 +284,11 @@ int compat_grant_table_op(unsigned int cmd,
break;
}
if ( max_frame_list_size_in_pages <
- grant_to_status_frames(max_nr_grant_frames) )
+ grant_to_status_frames(max_nr_grant_frames(current->domain)) )
{
gdprintk(XENLOG_WARNING,
"grant_to_status_frames(max_nr_grant_frames) is too large (%u,%u)\n",
- grant_to_status_frames(max_nr_grant_frames),
+ grant_to_status_frames(max_nr_grant_frames(current->domain)),
max_frame_list_size_in_pages);
rc = -EINVAL;
break;
@@ -24,6 +24,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <xen/ctype.h>
#include <xen/err.h>
#include <xen/iocap.h>
#include <xen/lib.h>
@@ -40,10 +41,25 @@
#include <xsm/xsm.h>
#include <asm/flushtlb.h>
-#ifndef max_nr_grant_frames
-unsigned int max_nr_grant_frames = DEFAULT_MAX_NR_GRANT_FRAMES;
-integer_param("gnttab_max_nr_frames", max_nr_grant_frames);
-#endif
+unsigned int max_nr_dom0_grant_frames = DEFAULT_MAX_NR_GRANT_FRAMES;
+unsigned int max_nr_domU_grant_frames = DEFAULT_MAX_NR_GRANT_FRAMES;
+
+unsigned int max_nr_grant_frames(struct domain *d)
+{
+ if ( is_hardware_domain(d) )
+ return max_nr_dom0_grant_frames;
+ else
+ return max_nr_domU_grant_frames;
+}
+
+static void __init parse_gnttab_max_nr_frames(const char *s)
+{
+ if ( isdigit(*s) )
+ max_nr_domU_grant_frames = simple_strtoul(s, &s, 0);
+ if ( *s == ',' && isdigit(*++s) )
+ max_nr_dom0_grant_frames = simple_strtoul(s, &s, 0);
+}
+custom_param("gnttab_max_nr_frames", parse_gnttab_max_nr_frames);
/* The maximum number of grant mappings is defined as a multiplier of the
* maximum number of grant table entries. This defines the multiplier used.
@@ -102,9 +118,9 @@ nr_maptrack_frames(struct grant_table *t)
return t->maptrack_limit / MAPTRACK_PER_PAGE;
}
-static unsigned inline int max_nr_maptrack_frames(void)
+static unsigned inline int max_nr_maptrack_frames(struct domain *d)
{
- return (max_nr_grant_frames * MAX_MAPTRACK_TO_GRANTS_RATIO);
+ return (max_nr_grant_frames(d) * MAX_MAPTRACK_TO_GRANTS_RATIO);
}
#define MAPTRACK_TAIL (~0u)
@@ -163,8 +179,8 @@ num_act_frames_from_sha_frames(const unsigned int num)
return (num_sha_entries + (ACGNT_PER_PAGE - 1)) / ACGNT_PER_PAGE;
}
-#define max_nr_active_grant_frames \
- num_act_frames_from_sha_frames(max_nr_grant_frames)
+#define max_nr_active_grant_frames(d) \
+ num_act_frames_from_sha_frames(max_nr_grant_frames(d))
static inline unsigned int
nr_active_grant_frames(struct grant_table *gt)
@@ -259,19 +275,20 @@ put_maptrack_handle(
static inline int
get_maptrack_handle(
- struct grant_table *lgt)
+ struct domain *ld)
{
int i;
grant_handle_t handle;
struct grant_mapping *new_mt;
unsigned int new_mt_limit, nr_frames;
+ struct grant_table *lgt = ld->grant_table;
spin_lock(&lgt->lock);
while ( unlikely((handle = __get_maptrack_handle(lgt)) == -1) )
{
nr_frames = nr_maptrack_frames(lgt);
- if ( nr_frames >= max_nr_maptrack_frames() )
+ if ( nr_frames >= max_nr_maptrack_frames(ld) )
break;
new_mt = alloc_xenheap_page();
@@ -567,7 +584,7 @@ __gnttab_map_grant_ref(
}
lgt = ld->grant_table;
- if ( unlikely((handle = get_maptrack_handle(lgt)) == -1) )
+ if ( unlikely((handle = get_maptrack_handle(ld)) == -1) )
{
rcu_unlock_domain(rd);
gdprintk(XENLOG_INFO, "Failed to obtain maptrack handle.\n");
@@ -1265,7 +1282,7 @@ gnttab_grow_table(struct domain *d, unsigned int req_nr_frames)
struct grant_table *gt = d->grant_table;
unsigned int i;
- ASSERT(req_nr_frames <= max_nr_grant_frames);
+ ASSERT(req_nr_frames <= max_nr_grant_frames(d));
gdprintk(XENLOG_INFO,
"Expanding dom (%d) grant table from (%d) to (%d) frames.\n",
@@ -1338,15 +1355,6 @@ gnttab_setup_table(
return -EFAULT;
}
- if ( unlikely(op.nr_frames > max_nr_grant_frames) )
- {
- gdprintk(XENLOG_INFO, "Xen only supports up to %d grant-table frames"
- " per domain.\n",
- max_nr_grant_frames);
- op.status = GNTST_general_error;
- goto out1;
- }
-
if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
return -EFAULT;
@@ -1358,6 +1366,15 @@ gnttab_setup_table(
goto out2;
}
+ if ( unlikely(op.nr_frames > max_nr_grant_frames(d)) )
+ {
+ gdprintk(XENLOG_INFO, "Xen only supports up to %d grant-table frames"
+ " per domain.\n",
+ max_nr_grant_frames(d));
+ op.status = GNTST_general_error;
+ goto out2;
+ }
+
if ( xsm_grant_setup(XSM_TARGET, current->domain, d) )
{
op.status = GNTST_permission_denied;
@@ -1377,7 +1394,7 @@ gnttab_setup_table(
{
gdprintk(XENLOG_INFO,
"Expand grant table to %u failed. Current: %u Max: %u\n",
- op.nr_frames, nr_grant_frames(gt), max_nr_grant_frames);
+ op.nr_frames, nr_grant_frames(gt), max_nr_grant_frames(d));
op.status = GNTST_general_error;
goto out3;
}
@@ -1396,7 +1413,6 @@ gnttab_setup_table(
spin_unlock(>->lock);
out2:
rcu_unlock_domain(d);
- out1:
if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
return -EFAULT;
@@ -1438,7 +1454,7 @@ gnttab_query_size(
spin_lock(&d->grant_table->lock);
op.nr_frames = nr_grant_frames(d->grant_table);
- op.max_nr_frames = max_nr_grant_frames;
+ op.max_nr_frames = max_nr_grant_frames(d);
op.status = GNTST_okay;
spin_unlock(&d->grant_table->lock);
@@ -2647,7 +2663,7 @@ grant_table_create(
/* Active grant table. */
if ( (t->active = xzalloc_array(struct active_grant_entry *,
- max_nr_active_grant_frames)) == NULL )
+ max_nr_active_grant_frames(d))) == NULL )
goto no_mem_1;
for ( i = 0;
i < num_act_frames_from_sha_frames(INITIAL_NR_GRANT_FRAMES); i++ )
@@ -2659,7 +2675,7 @@ grant_table_create(
/* Tracking of mapped foreign frames table */
if ( (t->maptrack = xzalloc_array(struct grant_mapping *,
- max_nr_maptrack_frames())) == NULL )
+ max_nr_maptrack_frames(d))) == NULL )
goto no_mem_2;
if ( (t->maptrack[0] = alloc_xenheap_page()) == NULL )
goto no_mem_3;
@@ -2670,7 +2686,7 @@ grant_table_create(
t->maptrack[0][i - 1].ref = MAPTRACK_TAIL;
/* Shared grant table. */
- if ( (t->shared_raw = xzalloc_array(void *, max_nr_grant_frames)) == NULL )
+ if ( (t->shared_raw = xzalloc_array(void *, max_nr_grant_frames(d))) == NULL )
goto no_mem_3;
for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
{
@@ -2681,7 +2697,7 @@ grant_table_create(
/* Status pages for grant table - for version 2 */
t->status = xzalloc_array(grant_status_t *,
- grant_to_status_frames(max_nr_grant_frames));
+ grant_to_status_frames(max_nr_grant_frames(d)));
if ( t->status == NULL )
goto no_mem_4;
@@ -31,7 +31,7 @@ static inline int replace_grant_supported(void)
#define gnttab_shared_gmfn(d, t, i) \
( ((i >= nr_grant_frames(d->grant_table)) && \
- (i < max_nr_grant_frames)) ? 0 : (d->arch.grant_table_gpfn[i]))
+ (i < max_nr_grant_frames(d))) ? 0 : (d->arch.grant_table_gpfn[i]))
#define gnttab_need_iommu_mapping(d) (is_domain_direct_mapped(d))
@@ -49,10 +49,10 @@
/* Default maximum size of a grant table. [POLICY] */
#define DEFAULT_MAX_NR_GRANT_FRAMES 32
#endif
-#ifndef max_nr_grant_frames /* to allow arch to override */
/* The maximum size of a grant table. */
-extern unsigned int max_nr_grant_frames;
-#endif
+extern unsigned int max_nr_dom0_grant_frames;
+extern unsigned int max_nr_domU_grant_frames;
+unsigned int max_nr_grant_frames(struct domain *d);
/*
* Tracks a mapping of another domain's grant reference. Each domain has a
Remove max_nr_grant_frames, both variable and preprocessor symbol. Introduce two global variables max_nr_dom0_grant_frames and max_nr_domU_grant_frames, separately configurable via the Xen command line option "gnttab_max_nr_frames". Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- docs/misc/xen-command-line.markdown | 4 +- xen/arch/arm/domain.c | 2 +- xen/arch/arm/mm.c | 2 +- xen/arch/x86/mm.c | 2 +- xen/common/compat/grant_table.c | 8 ++-- xen/common/grant_table.c | 72 +++++++++++++++++++++-------------- xen/include/asm-arm/grant_table.h | 2 +- xen/include/xen/grant_table.h | 6 +-- 8 files changed, 58 insertions(+), 40 deletions(-)