}
/* Get the features of the plugged device. */
- assert(vdc->get_features != NULL);
- vdev->host_features = vdc->get_features(vdev, vdev->host_features,
- &local_err);
+ if (vdc->get_features_ex) {
+ vdc->get_features_ex(vdev, vdev->host_features_ex, &local_err);
+ } else {
+ assert(vdc->get_features != NULL);
+ virtio_features_from_u64(vdev->host_features_ex,
+ vdc->get_features(vdev, vdev->host_features,
+ &local_err));
+ }
if (local_err) {
error_propagate(errp, local_err);
return;
bad = virtio_features_andnot(tmp, val, vdev->host_features_ex);
virtio_features_and(tmp, val, vdev->host_features_ex);
- if (k->set_features) {
+ if (k->set_features_ex) {
+ k->set_features_ex(vdev, val);
+ } else if (k->set_features) {
bad = bad || virtio_features_use_ex(tmp);
k->set_features(vdev, tmp[0]);
}
int virtio_set_features(VirtIODevice *vdev, uint64_t val)
{
uint64_t features[VIRTIO_FEATURES_NU64S];
+
+ virtio_features_from_u64(features, val);
+ return virtio_set_features_ex(vdev, features);
+}
+
+int virtio_set_features_ex(VirtIODevice *vdev, const uint64_t *features)
+{
int ret;
/*
* The driver must not attempt to set features after feature negotiation
return -EINVAL;
}
- if (val & (1ull << VIRTIO_F_BAD_FEATURE)) {
+ if (features[0] & (1ull << VIRTIO_F_BAD_FEATURE)) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: guest driver for %s has enabled UNUSED(30) feature bit!\n",
__func__, vdev->name);
}
- virtio_features_from_u64(features, val);
ret = virtio_set_features_nocheck(vdev, features);
if (virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
/* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */
/* This is what a VirtioDevice must implement */
DeviceRealize realize;
DeviceUnrealize unrealize;
+ void (*get_features_ex)(VirtIODevice *vdev, uint64_t *requested_features,
+ Error **errp);
+ void (*set_features_ex)(VirtIODevice *vdev, const uint64_t *val);
uint64_t (*get_features)(VirtIODevice *vdev,
uint64_t requested_features,
Error **errp);
void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
void virtio_update_irq(VirtIODevice *vdev);
int virtio_set_features(VirtIODevice *vdev, uint64_t val);
+int virtio_set_features_ex(VirtIODevice *vdev, const uint64_t *val);
/* Base devices. */
typedef struct VirtIOBlkConf VirtIOBlkConf;