Michael S. Tsirkin
2023-Sep-21 14:02 UTC
[PATCH v14 30/42] virtio_pci: introduce helper to get/set queue reset
On Mon, Aug 01, 2022 at 02:38:50PM +0800, Xuan Zhuo wrote:> Introduce new helpers to implement queue reset and get queue reset > status. > > https://github.com/oasis-tcs/virtio-spec/issues/124 > https://github.com/oasis-tcs/virtio-spec/issues/139 > > Signed-off-by: Xuan Zhuo <xuanzhuo at linux.alibaba.com> > Acked-by: Jason Wang <jasowang at redhat.com> > --- > drivers/virtio/virtio_pci_modern_dev.c | 39 ++++++++++++++++++++++++++ > include/linux/virtio_pci_modern.h | 2 ++ > 2 files changed, 41 insertions(+) > > diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c > index fa2a9445bb18..869cb46bef96 100644 > --- a/drivers/virtio/virtio_pci_modern_dev.c > +++ b/drivers/virtio/virtio_pci_modern_dev.c > @@ -3,6 +3,7 @@ > #include <linux/virtio_pci_modern.h> > #include <linux/module.h> > #include <linux/pci.h> > +#include <linux/delay.h> > > /* > * vp_modern_map_capability - map a part of virtio pci capability > @@ -474,6 +475,44 @@ void vp_modern_set_status(struct virtio_pci_modern_device *mdev, > } > EXPORT_SYMBOL_GPL(vp_modern_set_status); > > +/* > + * vp_modern_get_queue_reset - get the queue reset status > + * @mdev: the modern virtio-pci device > + * @index: queue index > + */ > +int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index) > +{ > + struct virtio_pci_modern_common_cfg __iomem *cfg; > + > + cfg = (struct virtio_pci_modern_common_cfg __iomem *)mdev->common; > + > + vp_iowrite16(index, &cfg->cfg.queue_select); > + return vp_ioread16(&cfg->queue_reset); > +} > +EXPORT_SYMBOL_GPL(vp_modern_get_queue_reset); > +Actually, this does not validate that the config structure is big enough. So it can access some unrelated memory. Don't know whether that's exploitable e.g. for CoCo but not nice, anyway. Need to validate the size and disable reset if it's too small.> +/* > + * vp_modern_set_queue_reset - reset the queue > + * @mdev: the modern virtio-pci device > + * @index: queue index > + */ > +void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index) > +{ > + struct virtio_pci_modern_common_cfg __iomem *cfg; > + > + cfg = (struct virtio_pci_modern_common_cfg __iomem *)mdev->common; > + > + vp_iowrite16(index, &cfg->cfg.queue_select); > + vp_iowrite16(1, &cfg->queue_reset); > + > + while (vp_ioread16(&cfg->queue_reset)) > + msleep(1); > + > + while (vp_ioread16(&cfg->cfg.queue_enable)) > + msleep(1); > +} > +EXPORT_SYMBOL_GPL(vp_modern_set_queue_reset); > + > /* > * vp_modern_queue_vector - set the MSIX vector for a specific virtqueue > * @mdev: the modern virtio-pci device > diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h > index 05123b9a606f..c4eeb79b0139 100644 > --- a/include/linux/virtio_pci_modern.h > +++ b/include/linux/virtio_pci_modern.h > @@ -113,4 +113,6 @@ void __iomem * vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev, > u16 index, resource_size_t *pa); > int vp_modern_probe(struct virtio_pci_modern_device *mdev); > void vp_modern_remove(struct virtio_pci_modern_device *mdev); > +int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); > +void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); > #endif > -- > 2.31.0
Xuan Zhuo
2023-Sep-22 01:49 UTC
[PATCH v14 30/42] virtio_pci: introduce helper to get/set queue reset
On Thu, 21 Sep 2023 10:02:53 -0400, "Michael S. Tsirkin" <mst at redhat.com> wrote:> On Mon, Aug 01, 2022 at 02:38:50PM +0800, Xuan Zhuo wrote: > > Introduce new helpers to implement queue reset and get queue reset > > status. > > > > https://github.com/oasis-tcs/virtio-spec/issues/124 > > https://github.com/oasis-tcs/virtio-spec/issues/139 > > > > Signed-off-by: Xuan Zhuo <xuanzhuo at linux.alibaba.com> > > Acked-by: Jason Wang <jasowang at redhat.com> > > --- > > drivers/virtio/virtio_pci_modern_dev.c | 39 ++++++++++++++++++++++++++ > > include/linux/virtio_pci_modern.h | 2 ++ > > 2 files changed, 41 insertions(+) > > > > diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c > > index fa2a9445bb18..869cb46bef96 100644 > > --- a/drivers/virtio/virtio_pci_modern_dev.c > > +++ b/drivers/virtio/virtio_pci_modern_dev.c > > @@ -3,6 +3,7 @@ > > #include <linux/virtio_pci_modern.h> > > #include <linux/module.h> > > #include <linux/pci.h> > > +#include <linux/delay.h> > > > > /* > > * vp_modern_map_capability - map a part of virtio pci capability > > @@ -474,6 +475,44 @@ void vp_modern_set_status(struct virtio_pci_modern_device *mdev, > > } > > EXPORT_SYMBOL_GPL(vp_modern_set_status); > > > > +/* > > + * vp_modern_get_queue_reset - get the queue reset status > > + * @mdev: the modern virtio-pci device > > + * @index: queue index > > + */ > > +int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index) > > +{ > > + struct virtio_pci_modern_common_cfg __iomem *cfg; > > + > > + cfg = (struct virtio_pci_modern_common_cfg __iomem *)mdev->common; > > + > > + vp_iowrite16(index, &cfg->cfg.queue_select); > > + return vp_ioread16(&cfg->queue_reset); > > +} > > +EXPORT_SYMBOL_GPL(vp_modern_get_queue_reset); > > + > > Actually, this does not validate that the config structure is big > enough. So it can access some unrelated memory. Don't know whether > that's exploitable e.g. for CoCo but not nice, anyway. > Need to validate the size and disable reset if it's too small.static int vp_modern_disable_vq_and_reset(struct virtqueue *vq) { struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); struct virtio_pci_modern_device *mdev = &vp_dev->mdev; struct virtio_pci_vq_info *info; unsigned long flags; -> if (!virtio_has_feature(vq->vdev, VIRTIO_F_RING_RESET)) return -ENOENT; vp_modern_set_queue_reset(mdev, vq->index); I checked VIRTIO_F_RING_RESET before call this. Do you mean, we should put the check to this function. Thanks.> > > > +/* > > + * vp_modern_set_queue_reset - reset the queue > > + * @mdev: the modern virtio-pci device > > + * @index: queue index > > + */ > > +void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index) > > +{ > > + struct virtio_pci_modern_common_cfg __iomem *cfg; > > + > > + cfg = (struct virtio_pci_modern_common_cfg __iomem *)mdev->common; > > + > > + vp_iowrite16(index, &cfg->cfg.queue_select); > > + vp_iowrite16(1, &cfg->queue_reset); > > + > > + while (vp_ioread16(&cfg->queue_reset)) > > + msleep(1); > > + > > + while (vp_ioread16(&cfg->cfg.queue_enable)) > > + msleep(1); > > +} > > +EXPORT_SYMBOL_GPL(vp_modern_set_queue_reset); > > + > > /* > > * vp_modern_queue_vector - set the MSIX vector for a specific virtqueue > > * @mdev: the modern virtio-pci device > > diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h > > index 05123b9a606f..c4eeb79b0139 100644 > > --- a/include/linux/virtio_pci_modern.h > > +++ b/include/linux/virtio_pci_modern.h > > @@ -113,4 +113,6 @@ void __iomem * vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev, > > u16 index, resource_size_t *pa); > > int vp_modern_probe(struct virtio_pci_modern_device *mdev); > > void vp_modern_remove(struct virtio_pci_modern_device *mdev); > > +int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); > > +void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index); > > #endif > > -- > > 2.31.0 >