From 4c890c3160a0aa9910be2f5107214451fb746936 Mon Sep 17 00:00:00 2001 From: Jin Yu Date: Mon, 9 Nov 2020 21:35:36 +0800 Subject: [PATCH] virtio: add transitional virtio device support SPDK virtio driver does not support the virtio legacy device but it's ok for the modern and transitional device. So update the probe function. From the spec: Transitional PCI Device ID Virtio Device 0x1000 network card 0x1001 block device 0x1002 memory ballooning (traditional) 0x1003 console 0x1004 SCSI host 0x1005 entropy source 0x1009 9P transport Transitional Device: a device supporting both drivers conforming to modern specification, and allowing legacy drivers. Change-Id: I28cd277fb2b2e07a429082b7d7bd581f254eae9c Signed-off-by: Jin Yu Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5053 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto --- include/spdk_internal/virtio.h | 4 ++-- lib/virtio/virtio_pci.c | 22 +++++++++++++++++++--- module/bdev/virtio/bdev_virtio_blk.c | 3 ++- module/bdev/virtio/bdev_virtio_scsi.c | 3 ++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/spdk_internal/virtio.h b/include/spdk_internal/virtio.h index 3d3e93372..5f9f18f8c 100644 --- a/include/spdk_internal/virtio.h +++ b/include/spdk_internal/virtio.h @@ -452,11 +452,11 @@ int virtio_pci_dev_enumerate(virtio_pci_create_cb enum_cb, void *enum_ctx, * Returning any other value will cause the PCI context to be freed, * making it unusable. * \param enum_ctx additional opaque context to be passed into `enum_cb` - * \param pci_device_id PCI Device ID of devices to iterate through + * \param device_id Device ID of devices to iterate through * \param pci_addr PCI address of the device to attach */ int virtio_pci_dev_attach(virtio_pci_create_cb create_cb, void *enum_ctx, - uint16_t pci_device_id, struct spdk_pci_addr *pci_addr); + uint16_t device_id, struct spdk_pci_addr *pci_addr); /** * Connect to a vhost-user device and init corresponding virtio_dev struct. diff --git a/lib/virtio/virtio_pci.c b/lib/virtio/virtio_pci.c index ac37558d4..3be6cc1b9 100644 --- a/lib/virtio/virtio_pci.c +++ b/lib/virtio/virtio_pci.c @@ -538,8 +538,24 @@ virtio_pci_dev_probe_cb(void *probe_ctx, struct spdk_pci_device *pci_dev) { struct virtio_pci_probe_ctx *ctx = probe_ctx; uint16_t pci_device_id = spdk_pci_device_get_device_id(pci_dev); + uint16_t device_id; - if (pci_device_id != ctx->device_id) { + if (pci_device_id < 0x1000 || pci_device_id > 0x107f) { + SPDK_ERRLOG("Probe device is not a virtio device\n"); + return 1; + } + + if (pci_device_id < 0x1040) { + /* Transitional devices: use the PCI subsystem device id as + * virtio device id, same as legacy driver always did. + */ + device_id = spdk_pci_device_get_subdevice_id(pci_dev); + } else { + /* Modern devices: simply use PCI device id, but start from 0x1040. */ + device_id = pci_device_id - 0x1040; + } + + if (device_id != ctx->device_id) { return 1; } @@ -567,7 +583,7 @@ virtio_pci_dev_enumerate(virtio_pci_create_cb enum_cb, void *enum_ctx, int virtio_pci_dev_attach(virtio_pci_create_cb enum_cb, void *enum_ctx, - uint16_t pci_device_id, struct spdk_pci_addr *pci_address) + uint16_t device_id, struct spdk_pci_addr *pci_address) { struct virtio_pci_probe_ctx ctx; @@ -578,7 +594,7 @@ virtio_pci_dev_attach(virtio_pci_create_cb enum_cb, void *enum_ctx, ctx.enum_cb = enum_cb; ctx.enum_ctx = enum_ctx; - ctx.device_id = pci_device_id; + ctx.device_id = device_id; return spdk_pci_device_attach(spdk_pci_virtio_get_driver(), virtio_pci_dev_probe_cb, &ctx, pci_address); diff --git a/module/bdev/virtio/bdev_virtio_blk.c b/module/bdev/virtio/bdev_virtio_blk.c index 198d67ca9..7d5d0298f 100644 --- a/module/bdev/virtio/bdev_virtio_blk.c +++ b/module/bdev/virtio/bdev_virtio_blk.c @@ -48,6 +48,7 @@ #include "spdk_internal/vhost_user.h" #include +#include #include "bdev_virtio.h" @@ -646,7 +647,7 @@ bdev_virtio_pci_blk_dev_create(const char *name, struct spdk_pci_addr *pci_addr) create_ctx.ret = NULL; virtio_pci_dev_attach(bdev_virtio_pci_blk_dev_create_cb, &create_ctx, - PCI_DEVICE_ID_VIRTIO_BLK_MODERN, pci_addr); + VIRTIO_ID_BLOCK, pci_addr); if (create_ctx.ret == NULL) { return NULL; diff --git a/module/bdev/virtio/bdev_virtio_scsi.c b/module/bdev/virtio/bdev_virtio_scsi.c index 6091b541b..1283881e9 100644 --- a/module/bdev/virtio/bdev_virtio_scsi.c +++ b/module/bdev/virtio/bdev_virtio_scsi.c @@ -48,6 +48,7 @@ #include "spdk_internal/vhost_user.h" #include +#include #include "bdev_virtio.h" @@ -1862,7 +1863,7 @@ bdev_virtio_pci_scsi_dev_create(const char *name, struct spdk_pci_addr *pci_addr create_ctx.cb_arg = cb_arg; return virtio_pci_dev_attach(bdev_virtio_pci_scsi_dev_create_cb, &create_ctx, - PCI_DEVICE_ID_VIRTIO_SCSI_MODERN, pci_addr); + VIRTIO_ID_SCSI, pci_addr); } int