@@ -141,6 +141,7 @@ struct virtio_device {
void *virtio;
struct virtio_ops *ops;
u16 endian;
+ u32 features;
};
struct virtio_ops {
@@ -180,4 +181,7 @@ static inline void virtio_init_device_vq(struct virtio_device *vdev,
vq->endian = vdev->endian;
}
+void virtio_set_guest_features(struct kvm *kvm, struct virtio_device *vdev,
+ void *dev, u32 features);
+
#endif /* KVM__VIRTIO_H */
@@ -198,6 +198,15 @@ bool virtio_queue__should_signal(struct virt_queue *vq)
return false;
}
+void virtio_set_guest_features(struct kvm *kvm, struct virtio_device *vdev,
+ void *dev, u32 features)
+{
+ /* TODO: fail negotiation if features & ~host_features */
+
+ vdev->features = features;
+ vdev->ops->set_guest_features(kvm, dev, features);
+}
+
int virtio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
struct virtio_ops *ops, enum virtio_trans trans,
int device_id, int subsys_id, int class)
@@ -159,8 +159,8 @@ static void virtio_mmio_config_out(struct kvm_cpu *vcpu,
case VIRTIO_MMIO_GUEST_FEATURES:
if (vmmio->hdr.guest_features_sel == 0) {
val = ioport__read32(data);
- vdev->ops->set_guest_features(vmmio->kvm,
- vmmio->dev, val);
+ virtio_set_guest_features(vmmio->kvm, vdev,
+ vmmio->dev, val);
}
break;
case VIRTIO_MMIO_GUEST_PAGE_SIZE:
@@ -267,7 +267,7 @@ static bool virtio_pci__io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16
switch (offset) {
case VIRTIO_PCI_GUEST_FEATURES:
val = ioport__read32(data);
- vdev->ops->set_guest_features(kvm, vpci->dev, val);
+ virtio_set_guest_features(kvm, vdev, vpci->dev, val);
break;
case VIRTIO_PCI_QUEUE_PFN:
val = ioport__read32(data);
We're going to need the features bits negotiated between host and guest in the core code. Save them in the virtio_device structure. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> --- include/kvm/virtio.h | 4 ++++ virtio/core.c | 9 +++++++++ virtio/mmio.c | 4 ++-- virtio/pci.c | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-)