@@ -1229,32 +1229,11 @@ int xenmem_add_to_physmap_one(
switch ( space )
{
case XENMAPSPACE_grant_table:
- grant_write_lock(d->grant_table);
-
- if ( d->grant_table->gt_version == 0 )
- d->grant_table->gt_version = 1;
-
- if ( d->grant_table->gt_version == 2 &&
- (idx & XENMAPIDX_grant_table_status) )
- {
- idx &= ~XENMAPIDX_grant_table_status;
- if ( idx < nr_status_frames(d->grant_table) )
- mfn = virt_to_mfn(d->grant_table->status[idx]);
- else
- return -EINVAL;
- }
- else
- {
- if ( (idx >= nr_grant_frames(d->grant_table)) &&
- (idx < max_grant_frames) )
- gnttab_grow_table(d, idx + 1);
-
- if ( idx < nr_grant_frames(d->grant_table) )
- mfn = virt_to_mfn(d->grant_table->shared_raw[idx]);
- else
- return -EINVAL;
- }
+ mfn = gnttab_get_frame(d, idx);
+ if ( mfn_eq(mfn, INVALID_MFN) )
+ return -EINVAL;
+ grant_write_lock(d->grant_table);
d->arch.grant_table_gfn[idx] = gfn;
t = p2m_ram_rw;
@@ -4863,29 +4863,9 @@ int xenmem_add_to_physmap_one(
mfn = virt_to_mfn(d->shared_info);
break;
case XENMAPSPACE_grant_table:
- grant_write_lock(d->grant_table);
-
- if ( d->grant_table->gt_version == 0 )
- d->grant_table->gt_version = 1;
-
- if ( d->grant_table->gt_version == 2 &&
- (idx & XENMAPIDX_grant_table_status) )
- {
- idx &= ~XENMAPIDX_grant_table_status;
- if ( idx < nr_status_frames(d->grant_table) )
- mfn = virt_to_mfn(d->grant_table->status[idx]);
- }
- else
- {
- if ( (idx >= nr_grant_frames(d->grant_table)) &&
- (idx < max_grant_frames) )
- gnttab_grow_table(d, idx + 1);
-
- if ( idx < nr_grant_frames(d->grant_table) )
- mfn = virt_to_mfn(d->grant_table->shared_raw[idx]);
- }
-
- grant_write_unlock(d->grant_table);
+ mfn = mfn_x(gnttab_get_frame(d, idx));
+ if ( mfn_eq(_mfn(mfn), INVALID_MFN) )
+ return -EINVAL;
break;
case XENMAPSPACE_gmfn_range:
case XENMAPSPACE_gmfn:
@@ -1604,6 +1604,39 @@ active_alloc_failed:
return 0;
}
+mfn_t
+gnttab_get_frame(struct domain *d, unsigned int idx)
+{
+ struct grant_table *gt = d->grant_table;
+ mfn_t mfn = INVALID_MFN;
+
+ grant_write_lock(gt);
+
+ if ( gt->gt_version == 0 )
+ gt->gt_version = 1;
+
+ if ( gt->gt_version == 2 &&
+ (idx & XENMAPIDX_grant_table_status) )
+ {
+ idx &= ~XENMAPIDX_grant_table_status;
+ if ( idx < nr_status_frames(gt) )
+ mfn = _mfn(virt_to_mfn(gt->status[idx]));
+ }
+ else
+ {
+ if ( (idx >= nr_grant_frames(gt)) &&
+ (idx < max_grant_frames) )
+ gnttab_grow_table(d, idx + 1);
+
+ if ( idx < nr_grant_frames(gt) )
+ mfn = _mfn(virt_to_mfn(gt->shared_raw[idx]));
+ }
+
+ grant_write_unlock(gt);
+
+ return mfn;
+}
+
static long
gnttab_setup_table(
XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count)
@@ -128,6 +128,9 @@ gnttab_release_mappings(
int
gnttab_grow_table(struct domain *d, unsigned int req_nr_frames);
+/* Get mfn of grant frame */
+mfn_t gnttab_get_frame(struct domain *d, unsigned int idx);
+
/* Number of grant table frames. Caller must hold d's grant table lock. */
static inline unsigned int nr_grant_frames(struct grant_table *gt)
{
There is a substantial amount of code duplicated between the x86 and arm implementations of mm.c:xenmem_add_to_physmap_one() for XENMAPSPACE_grant_table. Also, the code in question looks like it really should be in common/grant_table.c This patch introduces a new function in common/grant_table.c to get the mfn of a specified frame in the grant table of a specified guest, and calls to that from the arch-specific code in mm.c. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> --- Cc: Stefano Stabellini <sstabellini@kernel.org> Cc: Julien Grall <julien.grall@arm.com> Cc: Jan Beulich <jbeulich@suse.com> Cc: Andrew Cooper <andrew.cooper3@citrix.com> --- xen/arch/arm/mm.c | 29 ++++------------------------- xen/arch/x86/mm.c | 26 +++----------------------- xen/common/grant_table.c | 33 +++++++++++++++++++++++++++++++++ xen/include/xen/grant_table.h | 3 +++ 4 files changed, 43 insertions(+), 48 deletions(-)