Exemple #1
0
/**
 * Create event channel
 *
 * @v netfront		Netfront device
 * @ret rc		Return status code
 */
static int netfront_create_event ( struct netfront_nic *netfront ) {
	struct xen_device *xendev = netfront->xendev;
	struct xen_hypervisor *xen = xendev->xen;
	struct evtchn_alloc_unbound alloc_unbound;
	struct evtchn_close close;
	int xenrc;
	int rc;

	/* Allocate event */
	alloc_unbound.dom = DOMID_SELF;
	alloc_unbound.remote_dom = xendev->backend_id;
	if ( ( xenrc = xenevent_alloc_unbound ( xen, &alloc_unbound ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( netfront, "NETFRONT %s could not allocate event: %s\n",
		       xendev->key, strerror ( rc ) );
		goto err_alloc_unbound;
	}
	netfront->event.port = alloc_unbound.port;

	/* Publish event channel */
	if ( ( rc = netfront_write_num ( netfront, "event-channel",
					 netfront->event.port ) ) != 0 )
		goto err_write_num;

	DBGC ( netfront, "NETFRONT %s event-channel=\"%d\"\n",
	       xendev->key, netfront->event.port );
	return 0;

	netfront_rm ( netfront, "event-channel" );
 err_write_num:
	close.port = netfront->event.port;
	xenevent_close ( xen, &close );
 err_alloc_unbound:
	return rc;
}
Exemple #2
0
/**
 * Send XenStore request
 *
 * @v xen		Xen hypervisor
 * @v type		Message type
 * @v req_id		Request ID
 * @v value		Value, or NULL to omit
 * @v key		Key path components
 * @ret rc		Return status code
 */
static int xenstore_request ( struct xen_hypervisor *xen,
			      enum xsd_sockmsg_type type, uint32_t req_id,
			      const char *value, va_list key ) {
	struct xsd_sockmsg msg;
	struct evtchn_send event;
	const char *string;
	va_list tmp;
	int xenrc;
	int rc;

	/* Construct message header */
	msg.type = type;
	msg.req_id = req_id;
	msg.tx_id = 0;
	msg.len = 0;
	DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );

	/* Calculate total length */
	va_copy ( tmp, key );
	while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
		DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
		msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
	}
	va_end ( tmp );
	if ( value ) {
		DBGC2 ( xen, " = \"%s\"", value );
		msg.len += strlen ( value );
	}
	DBGC2 ( xen, "\n" );

	/* Send message */
	xenstore_send ( xen, &msg, sizeof ( msg ) );
	string = va_arg ( key, const char * );
	assert ( string != NULL );
	xenstore_send_string ( xen, string );
	while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
		xenstore_send_string ( xen, "/" );
		xenstore_send_string ( xen, string );
	}
	xenstore_send ( xen, "", 1 ); /* Separating NUL */
	if ( value )
		xenstore_send_string ( xen, value );

	/* Notify the back end */
	event.port = xen->store.port;
	if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( xen, "XENSTORE could not notify back end: %s\n",
		       strerror ( rc ) );
		return rc;
	}

	return 0;
}
Exemple #3
0
/**
 * Send event
 *
 * @v netfront		Netfront device
 * @ret rc		Return status code
 */
static inline __attribute__ (( always_inline )) int
netfront_send_event ( struct netfront_nic *netfront ) {
	struct xen_device *xendev = netfront->xendev;
	struct xen_hypervisor *xen = xendev->xen;
	int xenrc;
	int rc;

	/* Send event */
	if ( ( xenrc = xenevent_send ( xen, &netfront->event ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( netfront, "NETFRONT %s could not send event: %s\n",
		       xendev->key, strerror ( rc ) );
		return rc;
	}

	return 0;
}
Exemple #4
0
/**
 * Initialise grant table
 *
 * @v xen		Xen hypervisor
 * @ret rc		Return status code
 */
int xengrant_init ( struct xen_hypervisor *xen ) {
	struct gnttab_query_size size;
	struct gnttab_set_version set_version;
	struct gnttab_get_version get_version;
	struct grant_entry_v1 *v1;
	union grant_entry_v2 *v2;
	unsigned int version;
	int xenrc;
	int rc;

	/* Get grant table size */
	size.dom = DOMID_SELF;
	if ( ( xenrc = xengrant_query_size ( xen, &size ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( xen, "XENGRANT could not get table size: %s\n",
		       strerror ( rc ) );
		return rc;
	}
	xen->grant.len = ( size.nr_frames * PAGE_SIZE );

	/* Set grant table version, if applicable */
	set_version.version = XENGRANT_TRY_VERSION;
	if ( ( xenrc = xengrant_set_version ( xen, &set_version ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( xen, "XENGRANT could not set version %d: %s\n",
		       XENGRANT_TRY_VERSION, strerror ( rc ) );
		/* Continue; use whatever version is current */
	}

	/* Get grant table version */
	get_version.dom = DOMID_SELF;
	get_version.pad = 0;
	if ( ( xenrc = xengrant_get_version ( xen, &get_version ) ) == 0 ) {
		version = get_version.version;
		switch ( version ) {

		case 0:
			/* Version not yet specified: will be version 1 */
			version = 1;
			break;

		case 1 :
			/* Version 1 table: nothing special to do */
			break;

		case 2:
			/* Version 2 table: configure shift appropriately */
			xen->grant.shift = ( fls ( sizeof ( *v2 ) /
						   sizeof ( *v1 ) ) - 1 );
			break;

		default:
			/* Unsupported version */
			DBGC ( xen, "XENGRANT detected unsupported version "
			       "%d\n", version );
			return -ENOTSUP;

		}
	} else {
		rc = -EXEN ( xenrc );
		DBGC ( xen, "XENGRANT could not get version (assuming v1): "
		       "%s\n", strerror ( rc ) );
		version = 1;
	}

	DBGC ( xen, "XENGRANT using v%d table with %d entries\n",
	       version, xengrant_entries ( xen ) );
	return 0;
}