drivers/xen/grant-table.c

Source file repositories/reference/linux-study-clean/drivers/xen/grant-table.c

File Facts

System
Linux kernel
Corpus path
drivers/xen/grant-table.c
Extension
.c
Size
43199 bytes
Lines
1700
Domain
Driver Families
Bucket
drivers/xen
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct gnttab_ops {
	/*
	 * Version of the grant interface.
	 */
	unsigned int version;
	/*
	 * Grant refs per grant frame.
	 */
	unsigned int grefs_per_grant_frame;
	/*
	 * Mapping a list of frames for storing grant entries. Frames parameter
	 * is used to store grant table address when grant table being setup,
	 * nr_gframes is the number of frames to map grant table. Returning
	 * GNTST_okay means success and negative value means failure.
	 */
	int (*map_frames)(xen_pfn_t *frames, unsigned int nr_gframes);
	/*
	 * Release a list of frames which are mapped in map_frames for grant
	 * entry status.
	 */
	void (*unmap_frames)(void);
	/*
	 * Introducing a valid entry into the grant table, granting the frame of
	 * this grant entry to domain for accessing. Ref
	 * parameter is reference of this introduced grant entry, domid is id of
	 * granted domain, frame is the page frame to be granted, and flags is
	 * status of the grant entry to be updated.
	 */
	void (*update_entry)(grant_ref_t ref, domid_t domid,
			     unsigned long frame, unsigned flags);
	/*
	 * Stop granting a grant entry to domain for accessing. Ref parameter is
	 * reference of a grant entry whose grant access will be stopped.
	 * If the grant entry is currently mapped for reading or writing, just
	 * return failure(==0) directly and don't tear down the grant access.
	 * Otherwise, stop grant access for this entry and return success(==1).
	 */
	int (*end_foreign_access_ref)(grant_ref_t ref);
	/*
	 * Read the frame number related to a given grant reference.
	 */
	unsigned long (*read_frame)(grant_ref_t ref);
};

struct unmap_refs_callback_data {
	struct completion completion;
	int result;
};

static const struct gnttab_ops *gnttab_interface;

/* This reflects status of grant entries, so act as a global value. */
static grant_status_t *grstatus;

static struct gnttab_free_callback *gnttab_free_callback_list;

static int gnttab_expand(unsigned int req_entries);

#define RPP (PAGE_SIZE / sizeof(grant_ref_t))
#define SPP (PAGE_SIZE / sizeof(grant_status_t))

static inline grant_ref_t *__gnttab_entry(grant_ref_t entry)
{
	return &gnttab_list[(entry) / RPP][(entry) % RPP];
}
/* This can be used as an l-value */
#define gnttab_entry(entry) (*__gnttab_entry(entry))

static int get_free_entries(unsigned count)
{
	unsigned long flags;
	int ref, rc = 0;
	grant_ref_t head;

	spin_lock_irqsave(&gnttab_list_lock, flags);

	if ((gnttab_free_count < count) &&
	    ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) {
		spin_unlock_irqrestore(&gnttab_list_lock, flags);
		return rc;
	}

	ref = head = gnttab_free_head;
	gnttab_free_count -= count;
	while (count--) {
		bitmap_clear(gnttab_free_bitmap, head, 1);
		if (gnttab_free_tail_ptr == __gnttab_entry(head))
			gnttab_free_tail_ptr = &gnttab_free_head;
		if (count)
			head = gnttab_entry(head);

Annotation

Implementation Notes