Unverified Commit 10bacee0 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6137 vfio/pci: Lock external INTx masking ops

parents 5e8b8205 e875c3ec
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ static void vfio_send_intx_eventfd(void *opaque, void *unused)
		eventfd_signal(vdev->ctx[0].trigger, 1);
}

void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
static void __vfio_pci_intx_mask(struct vfio_pci_device *vdev)
{
	struct pci_dev *pdev = vdev->pdev;
	unsigned long flags;

	lockdep_assert_held(&vdev->igate);

	spin_lock_irqsave(&vdev->irqlock, flags);

	/*
@@ -65,6 +67,13 @@ void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
	spin_unlock_irqrestore(&vdev->irqlock, flags);
}

void vfio_pci_intx_mask(struct vfio_pci_device *vdev)
{
	mutex_lock(&vdev->igate);
	__vfio_pci_intx_mask(vdev);
	mutex_unlock(&vdev->igate);
}

/*
 * If this is triggered by an eventfd, we can't call eventfd_signal
 * or else we'll deadlock on the eventfd wait queue.  Return >0 when
@@ -107,12 +116,21 @@ static int vfio_pci_intx_unmask_handler(void *opaque, void *unused)
	return ret;
}

void vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
static void __vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
{
	lockdep_assert_held(&vdev->igate);

	if (vfio_pci_intx_unmask_handler(vdev, NULL) > 0)
		vfio_send_intx_eventfd(vdev, NULL);
}

void vfio_pci_intx_unmask(struct vfio_pci_device *vdev)
{
	mutex_lock(&vdev->igate);
	__vfio_pci_intx_unmask(vdev);
	mutex_unlock(&vdev->igate);
}

static irqreturn_t vfio_intx_handler(int irq, void *dev_id)
{
	struct vfio_pci_device *vdev = dev_id;
@@ -428,11 +446,11 @@ static int vfio_pci_set_intx_unmask(struct vfio_pci_device *vdev,
		return -EINVAL;

	if (flags & VFIO_IRQ_SET_DATA_NONE) {
		vfio_pci_intx_unmask(vdev);
		__vfio_pci_intx_unmask(vdev);
	} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
		uint8_t unmask = *(uint8_t *)data;
		if (unmask)
			vfio_pci_intx_unmask(vdev);
			__vfio_pci_intx_unmask(vdev);
	} else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
		int32_t fd = *(int32_t *)data;
		if (fd >= 0)
@@ -455,11 +473,11 @@ static int vfio_pci_set_intx_mask(struct vfio_pci_device *vdev,
		return -EINVAL;

	if (flags & VFIO_IRQ_SET_DATA_NONE) {
		vfio_pci_intx_mask(vdev);
		__vfio_pci_intx_mask(vdev);
	} else if (flags & VFIO_IRQ_SET_DATA_BOOL) {
		uint8_t mask = *(uint8_t *)data;
		if (mask)
			vfio_pci_intx_mask(vdev);
			__vfio_pci_intx_mask(vdev);
	} else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) {
		return -ENOTTY; /* XXX implement me */
	}