Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/hw/virtio-blk.c | 2 +- src/hw/virtio-pci.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/hw/virtio-pci.h | 12 +++--------- 3 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/src/hw/virtio-blk.c b/src/hw/virtio-blk.c index 4f39aa2..9e56d42 100644 --- a/src/hw/virtio-blk.c +++ b/src/hw/virtio-blk.c @@ -123,7 +123,7 @@ init_virtio_blk(struct pci_device *pci) struct virtio_blk_config cfg; vp_get(vdrive->vp, 0, &cfg, sizeof(cfg));
- u32 f = vp_get_features(vdrive->vp); + u64 f = vp_get_features(vdrive->vp); vdrive->drive.blksize = (f & (1 << VIRTIO_BLK_F_BLK_SIZE)) ? cfg.blk_size : DISK_SECTOR_SIZE;
diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index 2abe601..68f1ded 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -24,6 +24,47 @@ #include "virtio-pci.h" #include "virtio-ring.h"
+u64 vp_get_features(struct vp_device *vp) +{ + u32 f0, f1; + + if (vp->use_modern) { + vp_modern_write(vp->common, virtio_pci_common_cfg, + device_feature_select, 0); + vp_modern_read(vp->common, virtio_pci_common_cfg, + device_feature, f0); + vp_modern_write(vp->common, virtio_pci_common_cfg, + device_feature_select, 1); + vp_modern_read(vp->common, virtio_pci_common_cfg, + device_feature, f1); + } else { + f0 = inl(vp->ioaddr + VIRTIO_PCI_HOST_FEATURES); + f1 = 0; + } + return ((u64)f1 << 32) | f0; +} + +void vp_set_features(struct vp_device *vp, u64 features) +{ + u32 f0, f1; + + f0 = features; + f1 = features >> 32; + + if (vp->use_modern) { + vp_modern_write(vp->common, virtio_pci_common_cfg, + guest_feature_select, 0); + vp_modern_write(vp->common, virtio_pci_common_cfg, + guest_feature, f0); + vp_modern_write(vp->common, virtio_pci_common_cfg, + guest_feature_select, 1); + vp_modern_write(vp->common, virtio_pci_common_cfg, + guest_feature, f1); + } else { + outl(f0, vp->ioaddr + VIRTIO_PCI_GUEST_FEATURES); + } +} + int vp_find_vq(struct vp_device *vp, int queue_index, struct vring_virtqueue **p_vq) { diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index e1d8b3e..e275703 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -109,6 +109,7 @@ struct vp_cap { struct vp_device { unsigned int ioaddr; struct vp_cap common, notify, isr, device; + u8 use_modern; };
#define vp_modern_read(_cap, _struct, _field, _var) { \ @@ -187,15 +188,8 @@ struct vp_device { } \ }
-static inline u32 vp_get_features(struct vp_device *vp) -{ - return inl(GET_LOWFLAT(vp->ioaddr) + VIRTIO_PCI_HOST_FEATURES); -} - -static inline void vp_set_features(struct vp_device *vp, u32 features) -{ - outl(features, GET_LOWFLAT(vp->ioaddr) + VIRTIO_PCI_GUEST_FEATURES); -} +u64 vp_get_features(struct vp_device *vp); +void vp_set_features(struct vp_device *vp, u64 features);
static inline void vp_get(struct vp_device *vp, unsigned offset, void *buf, unsigned len)