Skip to content

Commit 22195cb

Browse files
l1viathanawilliam
authored andcommitted
vfio: vfio_register_notifier: classify iommu notifier
Currently vfio_register_notifier assumes that there is only one notifier chain, which is in vfio_iommu. However, the user might also be interested in events other than vfio_iommu, for example, vfio_group. Refactor vfio_{un}register_notifier implementation to make it feasible. Cc: Paolo Bonzini <[email protected]> Cc: Xiao Guangrong <[email protected]> Reviewed-by: Kirti Wankhede <[email protected]> Signed-off-by: Jike Song <[email protected]> [aw: merge with commit 816ca69ea9c7 ("vfio: Fix handling of error returned by 'vfio_group_get_from_dev()'"), remove typedef] Signed-off-by: Alex Williamson <[email protected]>
1 parent d256459 commit 22195cb

File tree

3 files changed

+78
-27
lines changed

3 files changed

+78
-27
lines changed

drivers/vfio/vfio.c

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,59 +2008,44 @@ int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, int npage)
20082008
}
20092009
EXPORT_SYMBOL(vfio_unpin_pages);
20102010

2011-
int vfio_register_notifier(struct device *dev, struct notifier_block *nb)
2011+
static int vfio_register_iommu_notifier(struct vfio_group *group,
2012+
unsigned long *events,
2013+
struct notifier_block *nb)
20122014
{
20132015
struct vfio_container *container;
2014-
struct vfio_group *group;
20152016
struct vfio_iommu_driver *driver;
20162017
int ret;
20172018

2018-
if (!dev || !nb)
2019-
return -EINVAL;
2020-
2021-
group = vfio_group_get_from_dev(dev);
2022-
if (!group)
2023-
return -ENODEV;
2024-
20252019
ret = vfio_group_add_container_user(group);
20262020
if (ret)
2027-
goto err_register_nb;
2021+
return -EINVAL;
20282022

20292023
container = group->container;
20302024
down_read(&container->group_lock);
20312025

20322026
driver = container->iommu_driver;
20332027
if (likely(driver && driver->ops->register_notifier))
2034-
ret = driver->ops->register_notifier(container->iommu_data, nb);
2028+
ret = driver->ops->register_notifier(container->iommu_data,
2029+
events, nb);
20352030
else
20362031
ret = -ENOTTY;
20372032

20382033
up_read(&container->group_lock);
20392034
vfio_group_try_dissolve_container(group);
20402035

2041-
err_register_nb:
2042-
vfio_group_put(group);
20432036
return ret;
20442037
}
2045-
EXPORT_SYMBOL(vfio_register_notifier);
20462038

2047-
int vfio_unregister_notifier(struct device *dev, struct notifier_block *nb)
2039+
static int vfio_unregister_iommu_notifier(struct vfio_group *group,
2040+
struct notifier_block *nb)
20482041
{
20492042
struct vfio_container *container;
2050-
struct vfio_group *group;
20512043
struct vfio_iommu_driver *driver;
20522044
int ret;
20532045

2054-
if (!dev || !nb)
2055-
return -EINVAL;
2056-
2057-
group = vfio_group_get_from_dev(dev);
2058-
if (!group)
2059-
return -ENODEV;
2060-
20612046
ret = vfio_group_add_container_user(group);
20622047
if (ret)
2063-
goto err_unregister_nb;
2048+
return -EINVAL;
20642049

20652050
container = group->container;
20662051
down_read(&container->group_lock);
@@ -2075,7 +2060,56 @@ int vfio_unregister_notifier(struct device *dev, struct notifier_block *nb)
20752060
up_read(&container->group_lock);
20762061
vfio_group_try_dissolve_container(group);
20772062

2078-
err_unregister_nb:
2063+
return ret;
2064+
}
2065+
2066+
int vfio_register_notifier(struct device *dev, enum vfio_notify_type type,
2067+
unsigned long *events, struct notifier_block *nb)
2068+
{
2069+
struct vfio_group *group;
2070+
int ret;
2071+
2072+
if (!dev || !nb || !events || (*events == 0))
2073+
return -EINVAL;
2074+
2075+
group = vfio_group_get_from_dev(dev);
2076+
if (!group)
2077+
return -ENODEV;
2078+
2079+
switch (type) {
2080+
case VFIO_IOMMU_NOTIFY:
2081+
ret = vfio_register_iommu_notifier(group, events, nb);
2082+
break;
2083+
default:
2084+
ret = -EINVAL;
2085+
}
2086+
2087+
vfio_group_put(group);
2088+
return ret;
2089+
}
2090+
EXPORT_SYMBOL(vfio_register_notifier);
2091+
2092+
int vfio_unregister_notifier(struct device *dev, enum vfio_notify_type type,
2093+
struct notifier_block *nb)
2094+
{
2095+
struct vfio_group *group;
2096+
int ret;
2097+
2098+
if (!dev || !nb)
2099+
return -EINVAL;
2100+
2101+
group = vfio_group_get_from_dev(dev);
2102+
if (!group)
2103+
return -ENODEV;
2104+
2105+
switch (type) {
2106+
case VFIO_IOMMU_NOTIFY:
2107+
ret = vfio_unregister_iommu_notifier(group, nb);
2108+
break;
2109+
default:
2110+
ret = -EINVAL;
2111+
}
2112+
20792113
vfio_group_put(group);
20802114
return ret;
20812115
}

drivers/vfio/vfio_iommu_type1.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,10 +1584,18 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
15841584
}
15851585

15861586
static int vfio_iommu_type1_register_notifier(void *iommu_data,
1587+
unsigned long *events,
15871588
struct notifier_block *nb)
15881589
{
15891590
struct vfio_iommu *iommu = iommu_data;
15901591

1592+
/* clear known events */
1593+
*events &= ~VFIO_IOMMU_NOTIFY_DMA_UNMAP;
1594+
1595+
/* refuse to register if still events remaining */
1596+
if (*events)
1597+
return -EINVAL;
1598+
15911599
return blocking_notifier_chain_register(&iommu->notifier, nb);
15921600
}
15931601

include/linux/vfio.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct vfio_iommu_driver_ops {
8181
int (*unpin_pages)(void *iommu_data,
8282
unsigned long *user_pfn, int npage);
8383
int (*register_notifier)(void *iommu_data,
84+
unsigned long *events,
8485
struct notifier_block *nb);
8586
int (*unregister_notifier)(void *iommu_data,
8687
struct notifier_block *nb);
@@ -107,12 +108,20 @@ extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
107108
extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
108109
int npage);
109110

110-
#define VFIO_IOMMU_NOTIFY_DMA_UNMAP (1)
111+
/* each type has independent events */
112+
enum vfio_notify_type {
113+
VFIO_IOMMU_NOTIFY = 0,
114+
};
115+
116+
/* events for VFIO_IOMMU_NOTIFY */
117+
#define VFIO_IOMMU_NOTIFY_DMA_UNMAP BIT(0)
111118

112119
extern int vfio_register_notifier(struct device *dev,
120+
enum vfio_notify_type type,
121+
unsigned long *required_events,
113122
struct notifier_block *nb);
114-
115123
extern int vfio_unregister_notifier(struct device *dev,
124+
enum vfio_notify_type type,
116125
struct notifier_block *nb);
117126

118127
/*

0 commit comments

Comments
 (0)