Ejemplo n.º 1
0
/*
 * The virtio core takes the features the Host offers, and copies the ones
 * supported by the driver into the vdev->features array.  Once that's all
 * sorted out, this routine is called so we can tell the Host which features we
 * understand and accept.
 */
static void lg_finalize_features(struct virtio_device *vdev)
{
	unsigned int i, bits;
	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
	/* Second half of bitmap is features we accept. */
	u8 *out_features = lg_features(desc) + desc->feature_len;

	/* Give virtio_ring a chance to accept features. */
	vring_transport_features(vdev);

	/*
	 * The vdev->feature array is a Linux bitmask: this isn't the same as a
	 * the simple array of bits used by lguest devices for features.  So we
	 * do this slow, manual conversion which is completely general.
	 */
	memset(out_features, 0, desc->feature_len);
	bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
	for (i = 0; i < bits; i++) {
		if (test_bit(i, vdev->features))
			out_features[i / 8] |= (1 << (i % 8));
	}

	/* Tell Host we've finished with this device's feature negotiation */
	status_notify(vdev);
}
Ejemplo n.º 2
0
/* This gets the device's feature bits. */
static u32 lg_get_features(struct virtio_device *vdev)
{
	unsigned int i;
	u32 features = 0;
	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
	u8 *in_features = lg_features(desc);

	/* We do this the slow but generic way. */
	for (i = 0; i < min(desc->feature_len * 8, 32); i++)
		if (in_features[i / 8] & (1 << (i % 8)))
			features |= (1 << i);

	return features;
}
Ejemplo n.º 3
0
/* This tests (and acknowleges) a feature bit. */
static bool lg_feature(struct virtio_device *vdev, unsigned fbit)
{
	struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
	u8 *features;

	/* Obviously if they ask for a feature off the end of our feature
	 * bitmap, it's not set. */
	if (fbit / 8 > desc->feature_len)
		return false;

	/* The feature bitmap comes after the virtqueues. */
	features = lg_features(desc);
	if (!(features[fbit / 8] & (1 << (fbit % 8))))
		return false;

	/* We set the matching bit in the other half of the bitmap to tell the
	 * Host we want to use this feature.  We don't use this yet, but we
	 * could in future. */
	features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8));
	return true;
}
Ejemplo n.º 4
0
/* The config space comes after the two feature bitmasks. */
static u8 *lg_config(const struct lguest_device_desc *desc)
{
	return lg_features(desc) + desc->feature_len * 2;
}