[SLOF] [PATCH v4 18/23] virtio: update features set/get register accessor

Nikunj A Dadhania nikunj at linux.vnet.ibm.com
Thu Jan 28 21:24:19 AEDT 2016


The new specification has a 64-bit feature register, change the
signature and update the routine to handle them.

Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
---
 lib/libvirtio/virtio-blk.c |  2 +-
 lib/libvirtio/virtio.c     | 42 ++++++++++++++++++++++++++++++++++++++----
 lib/libvirtio/virtio.h     |  4 ++--
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/lib/libvirtio/virtio-blk.c b/lib/libvirtio/virtio-blk.c
index bff86b2..bee39c8 100644
--- a/lib/libvirtio/virtio-blk.c
+++ b/lib/libvirtio/virtio-blk.c
@@ -57,7 +57,7 @@ virtioblk_init(struct virtio_device *dev)
 	status |= VIRTIO_STAT_DRIVER_OK;
 	virtio_set_status(dev, status);
 
-	virtio_get_host_features(dev, &features);
+	features = virtio_get_host_features(dev);
 	if (features & VIRTIO_BLK_F_BLK_SIZE) {
 		blk_size = virtio_get_config(dev,
 				offset_of(struct virtio_blk_cfg, blk_size),
diff --git a/lib/libvirtio/virtio.c b/lib/libvirtio/virtio.c
index 24d3bb8..ba7aced 100644
--- a/lib/libvirtio/virtio.c
+++ b/lib/libvirtio/virtio.c
@@ -301,19 +301,53 @@ void virtio_set_status(struct virtio_device *dev, int status)
 /**
  * Set guest feature bits
  */
-void virtio_set_guest_features(struct virtio_device *dev, int features)
+void virtio_set_guest_features(struct virtio_device *dev, uint64_t features)
 
 {
-	ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, bswap_32(features));
+	if (dev->is_modern) {
+		uint32_t f1 = (features >> 32) & 0xFFFFFFFF;
+		uint32_t f0 = features & 0xFFFFFFFF;
+		void *addr = dev->common.addr;
+
+		ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features_sel),
+			    cpu_to_le32(1));
+		ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features),
+			    cpu_to_le32(f1));
+
+		ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features_sel),
+			    cpu_to_le32(0));
+		ci_write_32(addr + offset_of(struct virtio_dev_common, drv_features),
+			    cpu_to_le32(f0));
+	} else {
+		ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, cpu_to_le32(features));
+	}
 }
 
 /**
  * Get host feature bits
  */
-void virtio_get_host_features(struct virtio_device *dev, int *features)
+uint64_t virtio_get_host_features(struct virtio_device *dev)
 
 {
-	*features = bswap_32(ci_read_32(dev->base+VIRTIOHDR_DEVICE_FEATURES));
+	uint64_t features = 0;
+	if (dev->is_modern) {
+		uint32_t f0 = 0, f1 = 0;
+		void *addr = dev->common.addr;
+
+		ci_write_32(addr + offset_of(struct virtio_dev_common, dev_features_sel),
+			    cpu_to_le32(1));
+		f1 = ci_read_32(addr +
+				offset_of(struct virtio_dev_common, dev_features));
+		ci_write_32(addr + offset_of(struct virtio_dev_common, dev_features_sel),
+			    cpu_to_le32(0));
+		f0 = ci_read_32(addr +
+				offset_of(struct virtio_dev_common, dev_features));
+
+		features = ((uint64_t)le32_to_cpu(f1) << 32) | le32_to_cpu(f0);
+	} else {
+		features = le32_to_cpu(ci_read_32(dev->base+VIRTIOHDR_DEVICE_FEATURES));
+	}
+	return features;
 }
 
 
diff --git a/lib/libvirtio/virtio.h b/lib/libvirtio/virtio.h
index e2543a1..bf8ea28 100644
--- a/lib/libvirtio/virtio.h
+++ b/lib/libvirtio/virtio.h
@@ -117,8 +117,8 @@ extern void virtio_reset_device(struct virtio_device *dev);
 extern void virtio_queue_notify(struct virtio_device *dev, int queue);
 extern void virtio_set_status(struct virtio_device *dev, int status);
 extern void virtio_set_qaddr(struct virtio_device *dev, int queue, unsigned long qaddr);
-extern void virtio_set_guest_features(struct virtio_device *dev, int features);
-extern void virtio_get_host_features(struct virtio_device *dev, int *features);
+extern void virtio_set_guest_features(struct virtio_device *dev, uint64_t features);
+extern uint64_t virtio_get_host_features(struct virtio_device *dev);
 extern uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size);
 extern int __virtio_read_config(struct virtio_device *dev, void *dst,
 				int offset, int len);
-- 
2.5.0



More information about the SLOF mailing list