Commit 1ddd0027 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'vfio-v5.4-rc1' of git://github.com/awilliam/linux-vfio

Pull VFIO updates from Alex Williamson:

 - Fix spapr iommu error case case (Alexey Kardashevskiy)

 - Consolidate region type definitions (Cornelia Huck)

 - Restore saved original PCI state on release (hexin)

 - Simplify mtty sample driver interrupt path (Parav Pandit)

 - Support for reporting valid IOVA regions to user (Shameer Kolothum)

* tag 'vfio-v5.4-rc1' of git://github.com/awilliam/linux-vfio:
  vfio_pci: Restore original state on release
  vfio/type1: remove duplicate retrieval of reserved regions
  vfio/type1: Add IOVA range capability support
  vfio/type1: check dma map request is within a valid iova range
  vfio/spapr_tce: Fix incorrect tce_iommu_group memory free
  vfio-mdev/mtty: Simplify interrupt generation
  vfio: re-arrange vfio region definitions
  vfio/type1: Update iova list on detach
  vfio/type1: Check reserved region conflict and update iova list
  vfio/type1: Introduce iova list and add iommu aperture validity check
parents 45824fc0 e6c5d727
......@@ -438,11 +438,20 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)
pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
/*
* Try to reset the device. The success of this is dependent on
* being able to lock the device, which is not always possible.
* Try to get the locks ourselves to prevent a deadlock. The
* success of this is dependent on being able to lock the device,
* which is not always possible.
* We can not use the "try" reset interface here, which will
* overwrite the previously restored configuration information.
*/
if (vdev->reset_works && !pci_try_reset_function(pdev))
vdev->needs_reset = false;
if (vdev->reset_works && pci_cfg_access_trylock(pdev)) {
if (device_trylock(&pdev->dev)) {
if (!__pci_reset_function_locked(pdev))
vdev->needs_reset = false;
device_unlock(&pdev->dev);
}
pci_cfg_access_unlock(pdev);
}
pci_restore_state(pdev);
out:
......
......@@ -1240,7 +1240,7 @@ static long tce_iommu_take_ownership_ddw(struct tce_container *container,
static int tce_iommu_attach_group(void *iommu_data,
struct iommu_group *iommu_group)
{
int ret;
int ret = 0;
struct tce_container *container = iommu_data;
struct iommu_table_group *table_group;
struct tce_iommu_group *tcegrp = NULL;
......@@ -1293,13 +1293,13 @@ static int tce_iommu_attach_group(void *iommu_data,
!table_group->ops->release_ownership) {
if (container->v2) {
ret = -EPERM;
goto unlock_exit;
goto free_exit;
}
ret = tce_iommu_take_ownership(container, table_group);
} else {
if (!container->v2) {
ret = -EPERM;
goto unlock_exit;
goto free_exit;
}
ret = tce_iommu_take_ownership_ddw(container, table_group);
if (!tce_groups_attached(container) && !container->tables[0])
......@@ -1311,10 +1311,11 @@ static int tce_iommu_attach_group(void *iommu_data,
list_add(&tcegrp->next, &container->group_list);
}
unlock_exit:
free_exit:
if (ret && tcegrp)
kfree(tcegrp);
unlock_exit:
mutex_unlock(&container->lock);
return ret;
......
This diff is collapsed.
......@@ -295,15 +295,38 @@ struct vfio_region_info_cap_type {
__u32 subtype; /* type specific */
};
/*
* List of region types, global per bus driver.
* If you introduce a new type, please add it here.
*/
/* PCI region type containing a PCI vendor part */
#define VFIO_REGION_TYPE_PCI_VENDOR_TYPE (1 << 31)
#define VFIO_REGION_TYPE_PCI_VENDOR_MASK (0xffff)
#define VFIO_REGION_TYPE_GFX (1)
#define VFIO_REGION_TYPE_CCW (2)
/* sub-types for VFIO_REGION_TYPE_PCI_* */
/* 8086 Vendor sub-types */
/* 8086 vendor PCI sub-types */
#define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
#define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
#define VFIO_REGION_TYPE_GFX (1)
/* 10de vendor PCI sub-types */
/*
* NVIDIA GPU NVlink2 RAM is coherent RAM mapped onto the host address space.
*/
#define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1)
/* 1014 vendor PCI sub-types */
/*
* IBM NPU NVlink2 ATSD (Address Translation Shootdown) register of NPU
* to do TLB invalidation on a GPU.
*/
#define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1)
/* sub-types for VFIO_REGION_TYPE_GFX */
#define VFIO_REGION_SUBTYPE_GFX_EDID (1)
/**
......@@ -353,25 +376,9 @@ struct vfio_region_gfx_edid {
#define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
};
#define VFIO_REGION_TYPE_CCW (2)
/* ccw sub-types */
/* sub-types for VFIO_REGION_TYPE_CCW */
#define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD (1)
/*
* 10de vendor sub-type
*
* NVIDIA GPU NVlink2 RAM is coherent RAM mapped onto the host address space.
*/
#define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1)
/*
* 1014 vendor sub-type
*
* IBM NPU NVlink2 ATSD (Address Translation Shootdown) register of NPU
* to do TLB invalidation on a GPU.
*/
#define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1)
/*
* The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
* which allows direct access to non-MSIX registers which happened to be within
......@@ -714,7 +721,31 @@ struct vfio_iommu_type1_info {
__u32 argsz;
__u32 flags;
#define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
__u64 iova_pgsizes; /* Bitmap of supported page sizes */
#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */
__u64 iova_pgsizes; /* Bitmap of supported page sizes */
__u32 cap_offset; /* Offset within info struct of first cap */
};
/*
* The IOVA capability allows to report the valid IOVA range(s)
* excluding any non-relaxable reserved regions exposed by
* devices attached to the container. Any DMA map attempt
* outside the valid iova range will return error.
*
* The structures below define version 1 of this capability.
*/
#define VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE 1
struct vfio_iova_range {
__u64 start;
__u64 end;
};
struct vfio_iommu_type1_info_cap_iova_range {
struct vfio_info_cap_header header;
__u32 nr_iovas;
__u32 reserved;
struct vfio_iova_range iova_ranges[];
};
#define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
......
......@@ -152,20 +152,9 @@ static const struct file_operations vd_fops = {
/* function prototypes */
static int mtty_trigger_interrupt(const guid_t *uuid);
static int mtty_trigger_interrupt(struct mdev_state *mdev_state);
/* Helper functions */
static struct mdev_state *find_mdev_state_by_uuid(const guid_t *uuid)
{
struct mdev_state *mds;
list_for_each_entry(mds, &mdev_devices_list, next) {
if (guid_equal(mdev_uuid(mds->mdev), uuid))
return mds;
}
return NULL;
}
static void dump_buffer(u8 *buf, uint32_t count)
{
......@@ -337,8 +326,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
pr_err("Serial port %d: Fifo level trigger\n",
index);
#endif
mtty_trigger_interrupt(
mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
} else {
#if defined(DEBUG_INTR)
......@@ -352,8 +340,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
*/
if (mdev_state->s[index].uart_reg[UART_IER] &
UART_IER_RLSI)
mtty_trigger_interrupt(
mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
mutex_unlock(&mdev_state->rxtx_lock);
break;
......@@ -372,8 +359,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
pr_err("Serial port %d: IER_THRI write\n",
index);
#endif
mtty_trigger_interrupt(
mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
mutex_unlock(&mdev_state->rxtx_lock);
......@@ -444,7 +430,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
#if defined(DEBUG_INTR)
pr_err("Serial port %d: MCR_OUT2 write\n", index);
#endif
mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) &&
......@@ -452,7 +438,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
#if defined(DEBUG_INTR)
pr_err("Serial port %d: MCR RTS/DTR write\n", index);
#endif
mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
break;
......@@ -503,8 +489,7 @@ static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state,
#endif
if (mdev_state->s[index].uart_reg[UART_IER] &
UART_IER_THRI)
mtty_trigger_interrupt(
mdev_uuid(mdev_state->mdev));
mtty_trigger_interrupt(mdev_state);
}
mutex_unlock(&mdev_state->rxtx_lock);
......@@ -1028,17 +1013,9 @@ static int mtty_set_irqs(struct mdev_device *mdev, uint32_t flags,
return ret;
}
static int mtty_trigger_interrupt(const guid_t *uuid)
static int mtty_trigger_interrupt(struct mdev_state *mdev_state)
{
int ret = -1;
struct mdev_state *mdev_state;
mdev_state = find_mdev_state_by_uuid(uuid);
if (!mdev_state) {
pr_info("%s: mdev not found\n", __func__);
return -EINVAL;
}
if ((mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX) &&
(!mdev_state->msi_evtfd))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment