From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
sstabellini@kernel.org, wei.liu2@citrix.com,
George.Dunlap@eu.citrix.com, andrew.cooper3@citrix.com,
ian.jackson@eu.citrix.com, tim@xen.org, julien.grall@arm.com,
jbeulich@suse.com, dgdegra@tycho.nsa.gov
Subject: [PATCH v8 13/15] xen: make grant resource limits per domain
Date: Wed, 20 Sep 2017 08:34:28 +0200 [thread overview]
Message-ID: <20170920063430.9105-14-jgross@suse.com> (raw)
In-Reply-To: <20170920063430.9105-1-jgross@suse.com>
Instead of using the same global resource limits of grant tables (max.
number of grant frames, max. number of maptrack frames) for all domains
make these limits per domain. Set those per-domain limits in
grant_table_set_limits().
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
---
V6:
- several changes due to new patch order
V3:
- correct error message (Paul Durrant)
---
xen/common/compat/grant_table.c | 31 +++-------
xen/common/grant_table.c | 121 ++++++++++++++++++++++++--------------
xen/include/asm-arm/grant_table.h | 6 +-
3 files changed, 88 insertions(+), 70 deletions(-)
diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_table.c
index cce3ff0b9a..ff1d678f01 100644
--- a/xen/common/compat/grant_table.c
+++ b/xen/common/compat/grant_table.c
@@ -157,21 +157,14 @@ 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_grant_frames )
- {
- gdprintk(XENLOG_WARNING,
- "max_grant_frames is too large (%u,%u)\n",
- max_grant_frames, max_frame_list_size_in_page);
- rc = -EINVAL;
- }
- else
- {
+
#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
- set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
- XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
+ set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
+ XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
#undef XLAT_gnttab_setup_table_HNDL_frame_list
- rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
- }
+ rc = gnttab_setup_table(guest_handle_cast(nat.uop,
+ gnttab_setup_table_t),
+ 1, max_frame_list_size_in_page);
}
ASSERT(rc <= 0);
if ( rc == 0 )
@@ -294,16 +287,6 @@ int compat_grant_table_op(unsigned int cmd,
rc = -EFAULT;
break;
}
- if ( max_frame_list_size_in_pages <
- grant_to_status_frames(max_grant_frames) )
- {
- gdprintk(XENLOG_WARNING,
- "grant_to_status_frames(max_grant_frames) is too large (%u,%u)\n",
- grant_to_status_frames(max_grant_frames),
- max_frame_list_size_in_pages);
- rc = -EINVAL;
- break;
- }
#define XLAT_gnttab_get_status_frames_HNDL_frame_list(_d_, _s_) \
set_xen_guest_handle((_d_)->frame_list, (uint64_t *)(nat.get_status + 1))
@@ -312,7 +295,7 @@ int compat_grant_table_op(unsigned int cmd,
rc = gnttab_get_status_frames(
guest_handle_cast(nat.uop, gnttab_get_status_frames_t),
- count);
+ count, max_frame_list_size_in_pages);
if ( rc >= 0 )
{
#define XLAT_gnttab_get_status_frames_HNDL_frame_list(_d_, _s_) \
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 26f9a32656..a0d8f32869 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -54,6 +54,9 @@ struct grant_table {
* what version to use yet.
*/
unsigned int gt_version;
+ /* Resource limits of the domain. */
+ unsigned int max_grant_frames;
+ unsigned int max_maptrack_frames;
/* Table size. Number of frames shared with guest */
unsigned int nr_grant_frames;
/* Number of grant status frames shared with guest (for version 2) */
@@ -290,8 +293,8 @@ num_act_frames_from_sha_frames(const unsigned int num)
return DIV_ROUND_UP(num * sha_per_page, ACGNT_PER_PAGE);
}
-#define max_nr_active_grant_frames \
- num_act_frames_from_sha_frames(max_grant_frames)
+#define max_nr_active_grant_frames(gt) \
+ num_act_frames_from_sha_frames(gt->max_grant_frames)
static inline unsigned int
nr_active_grant_frames(struct grant_table *gt)
@@ -528,7 +531,7 @@ get_maptrack_handle(
* out of memory, try stealing an entry from another VCPU (in case the
* guest isn't mapping across its VCPUs evenly).
*/
- if ( nr_maptrack_frames(lgt) < max_maptrack_frames )
+ if ( nr_maptrack_frames(lgt) < lgt->max_maptrack_frames )
new_mt = alloc_xenheap_page();
if ( !new_mt )
@@ -1667,23 +1670,26 @@ grant_table_init(struct grant_table *gt)
/* Active grant table. */
gt->active = xzalloc_array(struct active_grant_entry *,
- max_nr_active_grant_frames);
+ max_nr_active_grant_frames(gt));
if ( gt->active == NULL )
goto out;
/* Tracking of mapped foreign frames table */
- gt->maptrack = vzalloc(max_maptrack_frames * sizeof(*gt->maptrack));
- if ( gt->maptrack == NULL )
- goto out;
+ if ( gt->max_maptrack_frames )
+ {
+ gt->maptrack = vzalloc(gt->max_maptrack_frames * sizeof(*gt->maptrack));
+ if ( gt->maptrack == NULL )
+ goto out;
+ }
/* Shared grant table. */
- gt->shared_raw = xzalloc_array(void *, max_grant_frames);
+ gt->shared_raw = xzalloc_array(void *, gt->max_grant_frames);
if ( gt->shared_raw == NULL )
goto out;
/* Status pages for grant table - for version 2 */
gt->status = xzalloc_array(grant_status_t *,
- grant_to_status_frames(max_grant_frames));
+ grant_to_status_frames(gt->max_grant_frames));
if ( gt->status == NULL )
goto out;
@@ -1718,8 +1724,9 @@ gnttab_grow_table(struct domain *d, unsigned int req_nr_frames)
ASSERT(gt->active);
if ( req_nr_frames < INITIAL_NR_GRANT_FRAMES )
- req_nr_frames = INITIAL_NR_GRANT_FRAMES;
- ASSERT(req_nr_frames <= max_grant_frames);
+ req_nr_frames = min_t(unsigned int, INITIAL_NR_GRANT_FRAMES,
+ gt->max_grant_frames);
+ ASSERT(req_nr_frames <= gt->max_grant_frames);
gdprintk(XENLOG_INFO,
"Expanding dom (%d) grant table from (%d) to (%d) frames.\n",
@@ -1777,13 +1784,15 @@ active_alloc_failed:
static long
gnttab_setup_table(
- XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count)
+ XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count,
+ unsigned int limit_max)
{
struct vcpu *curr = current;
struct gnttab_setup_table op;
struct domain *d = NULL;
struct grant_table *gt;
unsigned int i;
+ long ret = 0;
if ( count != 1 )
return -EINVAL;
@@ -1791,15 +1800,6 @@ gnttab_setup_table(
if ( unlikely(copy_from_guest(&op, uop, 1)) )
return -EFAULT;
- if ( unlikely(op.nr_frames > max_grant_frames) )
- {
- gdprintk(XENLOG_INFO, "Xen only supports up to %d grant-table frames"
- " per domain.\n",
- max_grant_frames);
- op.status = GNTST_general_error;
- goto out;
- }
-
if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
return -EFAULT;
@@ -1819,6 +1819,21 @@ gnttab_setup_table(
gt = d->grant_table;
grant_write_lock(gt);
+ if ( unlikely(op.nr_frames > gt->max_grant_frames) )
+ {
+ gdprintk(XENLOG_INFO, "Domain is limited to %d grant-table frames.\n",
+ gt->max_grant_frames);
+ op.status = GNTST_general_error;
+ goto unlock;
+ }
+ if ( unlikely(limit_max < gt->max_grant_frames) )
+ {
+ gdprintk(XENLOG_WARNING, "max_grant_frames is too large (%u,%u)\n",
+ gt->max_grant_frames, limit_max);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
if ( gt->gt_version == 0 )
gt->gt_version = 1;
@@ -1829,7 +1844,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_grant_frames);
+ op.nr_frames, nr_grant_frames(gt), gt->max_grant_frames);
op.status = GNTST_general_error;
goto unlock;
}
@@ -1852,10 +1867,10 @@ gnttab_setup_table(
if ( d )
rcu_unlock_domain(d);
- if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
+ if ( !ret && unlikely(__copy_field_to_guest(uop, &op, status)) )
return -EFAULT;
- return 0;
+ return ret;
}
static long
@@ -1864,6 +1879,7 @@ gnttab_query_size(
{
struct gnttab_query_size op;
struct domain *d;
+ struct grant_table *gt;
if ( count != 1 )
return -EINVAL;
@@ -1884,13 +1900,15 @@ gnttab_query_size(
goto out;
}
- grant_read_lock(d->grant_table);
+ gt = d->grant_table;
- op.nr_frames = nr_grant_frames(d->grant_table);
- op.max_nr_frames = max_grant_frames;
+ grant_read_lock(gt);
+
+ op.nr_frames = nr_grant_frames(gt);
+ op.max_nr_frames = gt->max_grant_frames;
op.status = GNTST_okay;
- grant_read_unlock(d->grant_table);
+ grant_read_unlock(gt);
out:
if ( d )
@@ -2965,14 +2983,14 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
static long
gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
- int count)
+ int count, unsigned int limit_max)
{
gnttab_get_status_frames_t op;
struct domain *d;
struct grant_table *gt;
uint64_t gmfn;
int i;
- int rc;
+ int rc, ret = 0;
if ( count != 1 )
return -EINVAL;
@@ -3012,6 +3030,15 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
goto unlock;
}
+ if ( unlikely(limit_max < grant_to_status_frames(gt->max_grant_frames)) )
+ {
+ gdprintk(XENLOG_WARNING,
+ "grant_to_status_frames(max_grant_frames) is too large (%u,%u)\n",
+ grant_to_status_frames(gt->max_grant_frames), limit_max);
+ ret = -EINVAL;
+ goto unlock;
+ }
+
for ( i = 0; i < op.nr_frames; i++ )
{
gmfn = gnttab_status_gmfn(d, gt, i);
@@ -3024,10 +3051,10 @@ gnttab_get_status_frames(XEN_GUEST_HANDLE_PARAM(gnttab_get_status_frames_t) uop,
out2:
rcu_unlock_domain(d);
out1:
- if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
+ if ( !ret && unlikely(__copy_field_to_guest(uop, &op, status)) )
return -EFAULT;
- return 0;
+ return ret;
}
static long
@@ -3320,7 +3347,7 @@ do_grant_table_op(
case GNTTABOP_setup_table:
rc = gnttab_setup_table(
- guest_handle_cast(uop, gnttab_setup_table_t), count);
+ guest_handle_cast(uop, gnttab_setup_table_t), count, ~0);
ASSERT(rc <= 0);
break;
@@ -3369,7 +3396,7 @@ do_grant_table_op(
case GNTTABOP_get_status_frames:
rc = gnttab_get_status_frames(
- guest_handle_cast(uop, gnttab_get_status_frames_t), count);
+ guest_handle_cast(uop, gnttab_get_status_frames_t), count, ~0);
break;
case GNTTABOP_get_version:
@@ -3442,6 +3469,8 @@ grant_table_create(
/* Simple stuff. */
percpu_rwlock_resource_init(&t->lock, grant_rwlock);
spin_lock_init(&t->maptrack_lock);
+ t->max_grant_frames = max_grant_frames;
+ t->max_maptrack_frames = max_maptrack_frames;
/* Okay, install the structure. */
d->grant_table = t;
@@ -3648,6 +3677,8 @@ int grant_table_set_limits(struct domain *d, unsigned int grant_frames,
struct grant_table *gt = d->grant_table;
int ret = -EBUSY;
+ if ( !grant_frames )
+ return -EINVAL;
if ( !gt )
return -ENOENT;
@@ -3655,7 +3686,11 @@ int grant_table_set_limits(struct domain *d, unsigned int grant_frames,
/* Set limits. */
if ( !gt->active )
+ {
+ gt->max_grant_frames = grant_frames;
+ gt->max_maptrack_frames = maptrack_frames;
ret = grant_table_init(gt);
+ }
grant_write_unlock(gt);
@@ -3731,7 +3766,7 @@ int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn,
}
else
{
- if ( (idx >= nr_grant_frames(gt)) && (idx < max_grant_frames) )
+ if ( (idx >= nr_grant_frames(gt)) && (idx < gt->max_grant_frames) )
gnttab_grow_table(d, idx + 1);
if ( idx < nr_grant_frames(gt) )
@@ -3759,6 +3794,12 @@ static void gnttab_usage_print(struct domain *rd)
grant_read_lock(gt);
+ printk("grant-table for remote domain:%5d (v%d)\n"
+ " %d frames (%d max), %d maptrack frames (%d max)\n",
+ rd->domain_id, gt->gt_version,
+ nr_grant_frames(gt), gt->max_grant_frames,
+ nr_maptrack_frames(gt), gt->max_maptrack_frames);
+
for ( ref = 0; ref != nr_grant_entries(gt); ref++ )
{
struct active_grant_entry *act;
@@ -3786,12 +3827,7 @@ static void gnttab_usage_print(struct domain *rd)
status = status_entry(gt, ref);
}
- if ( first )
- {
- printk("grant-table for remote domain:%5d (v%d)\n",
- rd->domain_id, gt->gt_version);
- first = 0;
- }
+ first = 0;
/* [0xXXX] ddddd 0xXXXXXX 0xXXXXXXXX ddddd 0xXXXXXX 0xXX */
printk("[0x%03x] %5d 0x%06lx 0x%08x %5d 0x%06"PRIx64" 0x%02x\n",
@@ -3803,8 +3839,7 @@ static void gnttab_usage_print(struct domain *rd)
grant_read_unlock(gt);
if ( first )
- printk("grant-table for remote domain:%5d ... "
- "no active grant table entries\n", rd->domain_id);
+ printk("no active grant table entries\n");
}
static void gnttab_usage_print_all(unsigned char key)
diff --git a/xen/include/asm-arm/grant_table.h b/xen/include/asm-arm/grant_table.h
index 0870b5b782..9a60e4e614 100644
--- a/xen/include/asm-arm/grant_table.h
+++ b/xen/include/asm-arm/grant_table.h
@@ -26,8 +26,8 @@ static inline int replace_grant_supported(void)
return 1;
}
-#define gnttab_init_arch(gt) \
- ( ((gt)->arch.gfn = xzalloc_array(gfn_t, max_grant_frames)) == 0 \
+#define gnttab_init_arch(gt) \
+ ( ((gt)->arch.gfn = xzalloc_array(gfn_t, (gt)->max_grant_frames)) == 0 \
? 0 : -ENOMEM )
#define gnttab_destroy_arch(gt) \
@@ -49,7 +49,7 @@ static inline int replace_grant_supported(void)
#define gnttab_shared_gmfn(d, t, i) \
( ((i >= nr_grant_frames(t)) && \
- (i < max_grant_frames)) ? 0 : gfn_x(t->arch.gfn[i]))
+ (i < (t)->max_grant_frames))? 0 : gfn_x((t)->arch.gfn[i]))
#define gnttab_need_iommu_mapping(d) \
(is_domain_direct_mapped(d) && need_iommu(d))
--
2.12.3
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-09-20 6:34 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-20 6:34 [PATCH v8 00/15] xen: better grant v2 support Juergen Gross
2017-09-20 6:34 ` [PATCH v8 01/15] xen: move XENMAPSPACE_grant_table code into grant_table.c Juergen Gross
2017-09-20 12:40 ` Julien Grall
2017-09-20 6:34 ` [PATCH v8 02/15] xen: clean up grant_table.h Juergen Gross
2017-09-20 6:34 ` [PATCH v8 03/15] xen: add new domctl hypercall to set grant table resource limits Juergen Gross
2017-09-20 8:26 ` Paul Durrant
2017-09-20 8:49 ` Jan Beulich
2017-09-20 6:34 ` [PATCH v8 04/15] xen: add function for obtaining highest possible memory address Juergen Gross
2017-09-20 8:57 ` Jan Beulich
[not found] ` <59C2499A020000780017D412@suse.com>
2017-09-20 8:58 ` Juergen Gross
2017-09-20 9:32 ` Jan Beulich
[not found] ` <59C251C8020000780017D4D7@suse.com>
2017-09-20 9:39 ` Juergen Gross
2017-09-20 12:51 ` Julien Grall
2017-09-20 13:08 ` Juergen Gross
2017-09-20 14:24 ` Julien Grall
2017-09-20 14:33 ` Juergen Gross
2017-09-20 17:15 ` Julien Grall
2017-09-21 4:18 ` Juergen Gross
2017-09-20 6:34 ` [PATCH v8 05/15] xen: add max possible mfn to struct xen_sysctl_physinfo Juergen Gross
2017-09-20 8:58 ` Jan Beulich
[not found] ` <59C249F3020000780017D415@suse.com>
2017-09-20 9:00 ` Juergen Gross
2017-09-20 12:53 ` Julien Grall
2017-09-20 13:06 ` Juergen Gross
2017-09-20 6:34 ` [PATCH v8 06/15] libxc: add libxc support for setting grant table resource limits Juergen Gross
2017-09-20 6:34 ` [PATCH v8 07/15] tools: set grant limits for xenstore stubdom Juergen Gross
2017-09-20 6:34 ` [PATCH v8 08/15] libxl: add max possible mfn to libxl_physinfo Juergen Gross
2017-09-20 6:34 ` [PATCH v8 09/15] xl: add global grant limit config items Juergen Gross
2017-09-20 6:34 ` [PATCH v8 10/15] libxl: add libxl support for setting grant table resource limits Juergen Gross
2017-09-20 6:34 ` [PATCH v8 11/15] xen: delay allocation of grant table sub structures Juergen Gross
2017-09-20 9:22 ` Jan Beulich
[not found] ` <59C24F80020000780017D473@suse.com>
2017-09-20 9:44 ` Juergen Gross
2017-09-20 10:02 ` Jan Beulich
[not found] ` <59C258D4020000780017D521@suse.com>
2017-09-20 10:05 ` Juergen Gross
2017-09-20 6:34 ` [PATCH v8 12/15] xen/arm: move arch specific grant table bits into grant_table.c Juergen Gross
2017-09-20 9:25 ` Jan Beulich
2017-09-20 14:34 ` Julien Grall
2017-09-21 4:36 ` Juergen Gross
2017-09-20 6:34 ` Juergen Gross [this message]
2017-09-20 10:34 ` [PATCH v8 13/15] xen: make grant resource limits per domain Jan Beulich
2017-09-20 14:37 ` Julien Grall
[not found] ` <59C2603C020000780017D561@suse.com>
2017-09-20 11:10 ` Juergen Gross
2017-09-20 11:48 ` Jan Beulich
[not found] ` <59C271B9020000780017D620@suse.com>
2017-09-20 12:44 ` Juergen Gross
2017-09-20 15:35 ` Jan Beulich
[not found] ` <59C2A6DE020000780017D874@suse.com>
2017-09-21 4:35 ` Juergen Gross
2017-09-21 6:15 ` Jan Beulich
[not found] ` <59C3751D020000780017DCB6@suse.com>
2017-09-21 7:53 ` Juergen Gross
2017-09-21 11:31 ` Jan Beulich
[not found] ` <59C3BF28020000780017DE68@suse.com>
2017-09-21 11:39 ` Juergen Gross
2017-09-21 11:48 ` Jan Beulich
[not found] ` <59C3C33E020000780017DEC3@suse.com>
2017-09-21 11:51 ` Juergen Gross
2017-09-22 6:19 ` Juergen Gross
2017-09-22 7:53 ` Jan Beulich
[not found] ` <59C4DD9B020000780017E575@suse.com>
2017-09-22 8:27 ` Juergen Gross
2017-09-22 8:35 ` Jan Beulich
[not found] ` <59C4E78B020000780017E67D@suse.com>
2017-09-22 8:44 ` Juergen Gross
2017-09-22 8:51 ` Jan Beulich
2017-09-20 6:34 ` [PATCH v8 14/15] xen: make grant table limits boot parameters dom0 only Juergen Gross
2017-09-20 12:07 ` Jan Beulich
[not found] ` <59C27619020000780017D66F@suse.com>
2017-09-20 12:48 ` Juergen Gross
2017-09-20 15:36 ` Jan Beulich
[not found] ` <59C2A72D020000780017D881@suse.com>
2017-09-21 4:27 ` Juergen Gross
2017-09-21 6:16 ` Jan Beulich
2017-09-20 6:34 ` [PATCH v8 15/15] xen: add new Xen cpuid node for max address width info Juergen Gross
2017-09-20 12:18 ` Jan Beulich
[not found] ` <59C278A3020000780017D689@suse.com>
2017-09-20 12:58 ` Juergen Gross
2017-09-20 15:42 ` Jan Beulich
[not found] ` <59C2A880020000780017D8A2@suse.com>
2017-09-21 4:21 ` Juergen Gross
2017-09-20 13:00 ` Julien Grall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170920063430.9105-14-jgross@suse.com \
--to=jgross@suse.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@arm.com \
--cc=sstabellini@kernel.org \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).