mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
vhost: add vhost_get_features and vhost_ack_features
Generalize the features get/ack to be used for both vhost-net and vhost-scsi. In vhost-net add vhost_net_get_feature_bits to select the feature bit set depending on the NetClient kind. Signed-off-by: Nikolay Nikolaev <n.nikolaev@virtualopensystems.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
cdaa86a54b
commit
2e6d46d77e
4 changed files with 71 additions and 42 deletions
|
@ -46,39 +46,41 @@ struct vhost_net {
|
|||
NetClientState *nc;
|
||||
};
|
||||
|
||||
/* Features supported by host kernel. */
|
||||
static const int kernel_feature_bits[] = {
|
||||
VIRTIO_F_NOTIFY_ON_EMPTY,
|
||||
VIRTIO_RING_F_INDIRECT_DESC,
|
||||
VIRTIO_RING_F_EVENT_IDX,
|
||||
VIRTIO_NET_F_MRG_RXBUF,
|
||||
VHOST_INVALID_FEATURE_BIT
|
||||
};
|
||||
|
||||
static const int *vhost_net_get_feature_bits(struct vhost_net *net)
|
||||
{
|
||||
const int *feature_bits = 0;
|
||||
|
||||
switch (net->nc->info->type) {
|
||||
case NET_CLIENT_OPTIONS_KIND_TAP:
|
||||
feature_bits = kernel_feature_bits;
|
||||
break;
|
||||
default:
|
||||
error_report("Feature bits not defined for this type: %d",
|
||||
net->nc->info->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return feature_bits;
|
||||
}
|
||||
|
||||
unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
|
||||
{
|
||||
/* Clear features not supported by host kernel. */
|
||||
if (!(net->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) {
|
||||
features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
}
|
||||
if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
|
||||
features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
}
|
||||
if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
|
||||
features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
|
||||
}
|
||||
if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) {
|
||||
features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
|
||||
}
|
||||
return features;
|
||||
return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
|
||||
features);
|
||||
}
|
||||
|
||||
void vhost_net_ack_features(struct vhost_net *net, unsigned features)
|
||||
{
|
||||
net->dev.acked_features = net->dev.backend_features;
|
||||
if (features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) {
|
||||
net->dev.acked_features |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
}
|
||||
if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) {
|
||||
net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
}
|
||||
if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
|
||||
net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX);
|
||||
}
|
||||
if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
|
||||
net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
|
||||
}
|
||||
vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
|
||||
}
|
||||
|
||||
static int vhost_net_get_fd(NetClientState *backend)
|
||||
|
|
|
@ -24,6 +24,15 @@
|
|||
#include "hw/virtio/virtio-scsi.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
|
||||
/* Features supported by host kernel. */
|
||||
static const int kernel_feature_bits[] = {
|
||||
VIRTIO_F_NOTIFY_ON_EMPTY,
|
||||
VIRTIO_RING_F_INDIRECT_DESC,
|
||||
VIRTIO_RING_F_EVENT_IDX,
|
||||
VIRTIO_SCSI_F_HOTPLUG,
|
||||
VHOST_INVALID_FEATURE_BIT
|
||||
};
|
||||
|
||||
static int vhost_scsi_set_endpoint(VHostSCSI *s)
|
||||
{
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
||||
|
@ -141,21 +150,7 @@ static uint32_t vhost_scsi_get_features(VirtIODevice *vdev,
|
|||
{
|
||||
VHostSCSI *s = VHOST_SCSI(vdev);
|
||||
|
||||
/* Clear features not supported by host kernel. */
|
||||
if (!(s->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) {
|
||||
features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY);
|
||||
}
|
||||
if (!(s->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
|
||||
features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
}
|
||||
if (!(s->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
|
||||
features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
|
||||
}
|
||||
if (!(s->dev.features & (1 << VIRTIO_SCSI_F_HOTPLUG))) {
|
||||
features &= ~(1 << VIRTIO_SCSI_F_HOTPLUG);
|
||||
}
|
||||
|
||||
return features;
|
||||
return vhost_get_features(&s->dev, kernel_feature_bits, features);
|
||||
}
|
||||
|
||||
static void vhost_scsi_set_config(VirtIODevice *vdev,
|
||||
|
|
|
@ -990,6 +990,33 @@ void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
|
|||
assert(r >= 0);
|
||||
}
|
||||
|
||||
unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
|
||||
unsigned features)
|
||||
{
|
||||
const int *bit = feature_bits;
|
||||
while (*bit != VHOST_INVALID_FEATURE_BIT) {
|
||||
unsigned bit_mask = (1 << *bit);
|
||||
if (!(hdev->features & bit_mask)) {
|
||||
features &= ~bit_mask;
|
||||
}
|
||||
bit++;
|
||||
}
|
||||
return features;
|
||||
}
|
||||
|
||||
void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
|
||||
unsigned features)
|
||||
{
|
||||
const int *bit = feature_bits;
|
||||
while (*bit != VHOST_INVALID_FEATURE_BIT) {
|
||||
unsigned bit_mask = (1 << *bit);
|
||||
if (features & bit_mask) {
|
||||
hdev->acked_features |= bit_mask;
|
||||
}
|
||||
bit++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Host notifiers must be enabled at this point. */
|
||||
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@ typedef unsigned long vhost_log_chunk_t;
|
|||
#define VHOST_LOG_PAGE 0x1000
|
||||
#define VHOST_LOG_BITS (8 * sizeof(vhost_log_chunk_t))
|
||||
#define VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)
|
||||
#define VHOST_INVALID_FEATURE_BIT (0xff)
|
||||
|
||||
struct vhost_memory;
|
||||
struct vhost_dev {
|
||||
|
@ -68,4 +69,8 @@ bool vhost_virtqueue_pending(struct vhost_dev *hdev, int n);
|
|||
*/
|
||||
void vhost_virtqueue_mask(struct vhost_dev *hdev, VirtIODevice *vdev, int n,
|
||||
bool mask);
|
||||
unsigned vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
|
||||
unsigned features);
|
||||
void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
|
||||
unsigned features);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue