diff options
Diffstat (limited to 'drivers/xen/grant-table.c')
| -rw-r--r-- | drivers/xen/grant-table.c | 309 | 
1 files changed, 6 insertions, 303 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index eeba7544f0cd..c254ae036f18 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -69,7 +69,6 @@ struct grant_frames xen_auto_xlat_grant_frames;  static union {  	struct grant_entry_v1 *v1; -	union grant_entry_v2 *v2;  	void *addr;  } gnttab_shared; @@ -120,36 +119,10 @@ struct gnttab_ops {  	 * by bit operations.  	 */  	int (*query_foreign_access)(grant_ref_t ref); -	/* -	 * Grant a domain to access a range of bytes within the page referred by -	 * an available grant entry. Ref parameter is reference of a grant entry -	 * which will be sub-page accessed, domid is id of grantee domain, frame -	 * is frame address of subpage grant, flags is grant type and flag -	 * information, page_off is offset of the range of bytes, and length is -	 * length of bytes to be accessed. -	 */ -	void (*update_subpage_entry)(grant_ref_t ref, domid_t domid, -				     unsigned long frame, int flags, -				     unsigned page_off, unsigned length); -	/* -	 * Redirect an available grant entry on domain A to another grant -	 * reference of domain B, then allow domain C to use grant reference -	 * of domain B transitively. Ref parameter is an available grant entry -	 * reference on domain A, domid is id of domain C which accesses grant -	 * entry transitively, flags is grant type and flag information, -	 * trans_domid is id of domain B whose grant entry is finally accessed -	 * transitively, trans_gref is grant entry transitive reference of -	 * domain B. -	 */ -	void (*update_trans_entry)(grant_ref_t ref, domid_t domid, int flags, -				   domid_t trans_domid, grant_ref_t trans_gref);  };  static struct gnttab_ops *gnttab_interface; -/*This reflects status of grant entries, so act as a global value*/ -static grant_status_t *grstatus; -  static int grant_table_version;  static int grefs_per_grant_frame; @@ -231,7 +204,7 @@ static void put_free_entry(grant_ref_t ref)  }  /* - * Following applies to gnttab_update_entry_v1 and gnttab_update_entry_v2. + * Following applies to gnttab_update_entry_v1.   * Introducing a valid entry into the grant table:   *  1. Write ent->domid.   *  2. Write ent->frame: @@ -250,15 +223,6 @@ static void gnttab_update_entry_v1(grant_ref_t ref, domid_t domid,  	gnttab_shared.v1[ref].flags = flags;  } -static void gnttab_update_entry_v2(grant_ref_t ref, domid_t domid, -				   unsigned long frame, unsigned flags) -{ -	gnttab_shared.v2[ref].hdr.domid = domid; -	gnttab_shared.v2[ref].full_page.frame = frame; -	wmb(); -	gnttab_shared.v2[ref].hdr.flags = GTF_permit_access | flags; -} -  /*   * Public grant-issuing interface functions   */ @@ -285,132 +249,11 @@ int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,  }  EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); -static void gnttab_update_subpage_entry_v2(grant_ref_t ref, domid_t domid, -					   unsigned long frame, int flags, -					   unsigned page_off, unsigned length) -{ -	gnttab_shared.v2[ref].sub_page.frame = frame; -	gnttab_shared.v2[ref].sub_page.page_off = page_off; -	gnttab_shared.v2[ref].sub_page.length = length; -	gnttab_shared.v2[ref].hdr.domid = domid; -	wmb(); -	gnttab_shared.v2[ref].hdr.flags = -				GTF_permit_access | GTF_sub_page | flags; -} - -int gnttab_grant_foreign_access_subpage_ref(grant_ref_t ref, domid_t domid, -					    unsigned long frame, int flags, -					    unsigned page_off, -					    unsigned length) -{ -	if (flags & (GTF_accept_transfer | GTF_reading | -		     GTF_writing | GTF_transitive)) -		return -EPERM; - -	if (gnttab_interface->update_subpage_entry == NULL) -		return -ENOSYS; - -	gnttab_interface->update_subpage_entry(ref, domid, frame, flags, -					       page_off, length); - -	return 0; -} -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage_ref); - -int gnttab_grant_foreign_access_subpage(domid_t domid, unsigned long frame, -					int flags, unsigned page_off, -					unsigned length) -{ -	int ref, rc; - -	ref = get_free_entries(1); -	if (unlikely(ref < 0)) -		return -ENOSPC; - -	rc = gnttab_grant_foreign_access_subpage_ref(ref, domid, frame, flags, -						     page_off, length); -	if (rc < 0) { -		put_free_entry(ref); -		return rc; -	} - -	return ref; -} -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_subpage); - -bool gnttab_subpage_grants_available(void) -{ -	return gnttab_interface->update_subpage_entry != NULL; -} -EXPORT_SYMBOL_GPL(gnttab_subpage_grants_available); - -static void gnttab_update_trans_entry_v2(grant_ref_t ref, domid_t domid, -					 int flags, domid_t trans_domid, -					 grant_ref_t trans_gref) -{ -	gnttab_shared.v2[ref].transitive.trans_domid = trans_domid; -	gnttab_shared.v2[ref].transitive.gref = trans_gref; -	gnttab_shared.v2[ref].hdr.domid = domid; -	wmb(); -	gnttab_shared.v2[ref].hdr.flags = -				GTF_permit_access | GTF_transitive | flags; -} - -int gnttab_grant_foreign_access_trans_ref(grant_ref_t ref, domid_t domid, -					  int flags, domid_t trans_domid, -					  grant_ref_t trans_gref) -{ -	if (flags & (GTF_accept_transfer | GTF_reading | -		     GTF_writing | GTF_sub_page)) -		return -EPERM; - -	if (gnttab_interface->update_trans_entry == NULL) -		return -ENOSYS; - -	gnttab_interface->update_trans_entry(ref, domid, flags, trans_domid, -					     trans_gref); - -	return 0; -} -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_trans_ref); - -int gnttab_grant_foreign_access_trans(domid_t domid, int flags, -				      domid_t trans_domid, -				      grant_ref_t trans_gref) -{ -	int ref, rc; - -	ref = get_free_entries(1); -	if (unlikely(ref < 0)) -		return -ENOSPC; - -	rc = gnttab_grant_foreign_access_trans_ref(ref, domid, flags, -						   trans_domid, trans_gref); -	if (rc < 0) { -		put_free_entry(ref); -		return rc; -	} - -	return ref; -} -EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_trans); - -bool gnttab_trans_grants_available(void) -{ -	return gnttab_interface->update_trans_entry != NULL; -} -EXPORT_SYMBOL_GPL(gnttab_trans_grants_available); -  static int gnttab_query_foreign_access_v1(grant_ref_t ref)  {  	return gnttab_shared.v1[ref].flags & (GTF_reading|GTF_writing);  } -static int gnttab_query_foreign_access_v2(grant_ref_t ref) -{ -	return grstatus[ref] & (GTF_reading|GTF_writing); -} -  int gnttab_query_foreign_access(grant_ref_t ref)  {  	return gnttab_interface->query_foreign_access(ref); @@ -433,29 +276,6 @@ static int gnttab_end_foreign_access_ref_v1(grant_ref_t ref, int readonly)  	return 1;  } -static int gnttab_end_foreign_access_ref_v2(grant_ref_t ref, int readonly) -{ -	gnttab_shared.v2[ref].hdr.flags = 0; -	mb(); -	if (grstatus[ref] & (GTF_reading|GTF_writing)) { -		return 0; -	} else { -		/* The read of grstatus needs to have acquire -		semantics.  On x86, reads already have -		that, and we just need to protect against -		compiler reorderings.  On other -		architectures we may need a full -		barrier. */ -#ifdef CONFIG_X86 -		barrier(); -#else -		mb(); -#endif -	} - -	return 1; -} -  static inline int _gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)  {  	return gnttab_interface->end_foreign_access_ref(ref, readonly); @@ -616,37 +436,6 @@ static unsigned long gnttab_end_foreign_transfer_ref_v1(grant_ref_t ref)  	return frame;  } -static unsigned long gnttab_end_foreign_transfer_ref_v2(grant_ref_t ref) -{ -	unsigned long frame; -	u16           flags; -	u16          *pflags; - -	pflags = &gnttab_shared.v2[ref].hdr.flags; - -	/* -	 * If a transfer is not even yet started, try to reclaim the grant -	 * reference and return failure (== 0). -	 */ -	while (!((flags = *pflags) & GTF_transfer_committed)) { -		if (sync_cmpxchg(pflags, flags, 0) == flags) -			return 0; -		cpu_relax(); -	} - -	/* If a transfer is in progress then wait until it is completed. */ -	while (!(flags & GTF_transfer_completed)) { -		flags = *pflags; -		cpu_relax(); -	} - -	rmb();  /* Read the frame number /after/ reading completion status. */ -	frame = gnttab_shared.v2[ref].full_page.frame; -	BUG_ON(frame == 0); - -	return frame; -} -  unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref)  {  	return gnttab_interface->end_foreign_transfer_ref(ref); @@ -962,12 +751,6 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,  }  EXPORT_SYMBOL_GPL(gnttab_unmap_refs); -static unsigned nr_status_frames(unsigned nr_grant_frames) -{ -	BUG_ON(grefs_per_grant_frame == 0); -	return (nr_grant_frames * grefs_per_grant_frame + SPP - 1) / SPP; -} -  static int gnttab_map_frames_v1(xen_pfn_t *frames, unsigned int nr_gframes)  {  	int rc; @@ -985,55 +768,6 @@ static void gnttab_unmap_frames_v1(void)  	arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames);  } -static int gnttab_map_frames_v2(xen_pfn_t *frames, unsigned int nr_gframes) -{ -	uint64_t *sframes; -	unsigned int nr_sframes; -	struct gnttab_get_status_frames getframes; -	int rc; - -	nr_sframes = nr_status_frames(nr_gframes); - -	/* No need for kzalloc as it is initialized in following hypercall -	 * GNTTABOP_get_status_frames. -	 */ -	sframes = kmalloc(nr_sframes  * sizeof(uint64_t), GFP_ATOMIC); -	if (!sframes) -		return -ENOMEM; - -	getframes.dom        = DOMID_SELF; -	getframes.nr_frames  = nr_sframes; -	set_xen_guest_handle(getframes.frame_list, sframes); - -	rc = HYPERVISOR_grant_table_op(GNTTABOP_get_status_frames, -				       &getframes, 1); -	if (rc == -ENOSYS) { -		kfree(sframes); -		return -ENOSYS; -	} - -	BUG_ON(rc || getframes.status); - -	rc = arch_gnttab_map_status(sframes, nr_sframes, -				    nr_status_frames(gnttab_max_grant_frames()), -				    &grstatus); -	BUG_ON(rc); -	kfree(sframes); - -	rc = arch_gnttab_map_shared(frames, nr_gframes, -				    gnttab_max_grant_frames(), -				    &gnttab_shared.addr); -	BUG_ON(rc); - -	return 0; -} - -static void gnttab_unmap_frames_v2(void) -{ -	arch_gnttab_unmap(gnttab_shared.addr, nr_grant_frames); -	arch_gnttab_unmap(grstatus, nr_status_frames(nr_grant_frames)); -} -  static int gnttab_map(unsigned int start_idx, unsigned int end_idx)  {  	struct gnttab_setup_table setup; @@ -1101,43 +835,13 @@ static struct gnttab_ops gnttab_v1_ops = {  	.query_foreign_access		= gnttab_query_foreign_access_v1,  }; -static struct gnttab_ops gnttab_v2_ops = { -	.map_frames			= gnttab_map_frames_v2, -	.unmap_frames			= gnttab_unmap_frames_v2, -	.update_entry			= gnttab_update_entry_v2, -	.end_foreign_access_ref		= gnttab_end_foreign_access_ref_v2, -	.end_foreign_transfer_ref	= gnttab_end_foreign_transfer_ref_v2, -	.query_foreign_access		= gnttab_query_foreign_access_v2, -	.update_subpage_entry		= gnttab_update_subpage_entry_v2, -	.update_trans_entry		= gnttab_update_trans_entry_v2, -}; -  static void gnttab_request_version(void)  { -	int rc; -	struct gnttab_set_version gsv; +	/* Only version 1 is used, which will always be available. */ +	grant_table_version = 1; +	grefs_per_grant_frame = PAGE_SIZE / sizeof(struct grant_entry_v1); +	gnttab_interface = &gnttab_v1_ops; -	gsv.version = 1; - -	rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); -	if (rc == 0 && gsv.version == 2) { -		grant_table_version = 2; -		grefs_per_grant_frame = PAGE_SIZE / sizeof(union grant_entry_v2); -		gnttab_interface = &gnttab_v2_ops; -	} else if (grant_table_version == 2) { -		/* -		 * If we've already used version 2 features, -		 * but then suddenly discover that they're not -		 * available (e.g. migrating to an older -		 * version of Xen), almost unbounded badness -		 * can happen. -		 */ -		panic("we need grant tables version 2, but only version 1 is available"); -	} else { -		grant_table_version = 1; -		grefs_per_grant_frame = PAGE_SIZE / sizeof(struct grant_entry_v1); -		gnttab_interface = &gnttab_v1_ops; -	}  	pr_info("Grant tables using version %d layout\n", grant_table_version);  } @@ -1225,8 +929,7 @@ int gnttab_init(void)  		}  	} -	ret = arch_gnttab_init(max_nr_grant_frames, -			       nr_status_frames(max_nr_grant_frames)); +	ret = arch_gnttab_init(max_nr_grant_frames);  	if (ret < 0)  		goto ini_nomem;  |