Loop Jacob and Ashok. > -----Original Message----- > From: Lan, Tianyu > Sent: Sunday, February 19, 2017 10:47 PM > To: kvm@xxxxxxxxxxxxxxx > Cc: Lan, Tianyu <tianyu.lan@xxxxxxxxx>; Tian, Kevin <kevin.tian@xxxxxxxxx>; > mst@xxxxxxxxxx; jan.kiszka@xxxxxxxxxxx; jasowang@xxxxxxxxxx; > peterx@xxxxxxxxxx; david@xxxxxxxxxxxxxxxxxxxxx; > alex.williamson@xxxxxxxxxx; Liu, Yi L <yi.l.liu@xxxxxxxxx> > Subject: [RFC PATCH 2/3] VFIO: Add IOMMU fault notifier callback > > This patch is to add callback to handle fault event reported by IOMMU driver. > Callback stores fault into an array and notify userspace via eventfd to read fault > info. > > Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx> > --- > drivers/vfio/vfio_iommu_type1.c | 30 ++++++++++++++++++++++++++++++ > include/linux/iommu.h | 7 +++++++ > include/uapi/linux/vfio.h | 7 +++++++ > 3 files changed, 44 insertions(+) > > diff --git a/drivers/vfio/vfio_iommu_type1.c > b/drivers/vfio/vfio_iommu_type1.c index 46674ea..dc434a3 100644 > --- a/drivers/vfio/vfio_iommu_type1.c > +++ b/drivers/vfio/vfio_iommu_type1.c > @@ -56,6 +56,8 @@ > MODULE_PARM_DESC(disable_hugepages, > "Disable VFIO IOMMU support for IOMMU hugepages."); > > +#define NR_IOMMU_FAULT_INFO 10 > + > struct vfio_iommu { > struct list_head domain_list; > struct vfio_domain *external_domain; /* domain for external user > */ > @@ -64,6 +66,9 @@ struct vfio_iommu { > struct blocking_notifier_head notifier; > struct eventfd_ctx *iommu_fault_fd; > struct mutex fault_lock; > + struct vfio_iommu_fault_info fault_info[NR_IOMMU_FAULT_INFO]; > + struct blocking_notifier_head iommu_fault_notifier; > + u8 fault_count; > bool v2; > bool nesting; > }; > @@ -1456,6 +1461,7 @@ static void *vfio_iommu_type1_open(unsigned long > arg) > iommu->dma_list = RB_ROOT; > mutex_init(&iommu->lock); > mutex_init(&iommu->fault_lock); > + iommu->fault_count = 0; > BLOCKING_INIT_NOTIFIER_HEAD(&iommu->notifier); > > return iommu; > @@ -1516,6 +1522,30 @@ static int vfio_domains_have_iommu_cache(struct > vfio_iommu *iommu) > return ret; > } > > +static int vfio_iommu_fault_event_notifier(struct notifier_block *nb, > + struct iommu_fault_info *fault_info, > + void *data) > +{ > + struct vfio_iommu *iommu = data; > + struct vfio_iommu_fault_info *info; > + > + mutex_lock(&iommu->fault_lock); > + > + info = &iommu->fault_info[iommu->fault_count]; > + info->addr = fault_info->addr; > + info->sid = fault_info->sid; > + info->fault_reason = fault_info->fault_reason; > + info->is_write = fault_info->is_write; > + > + iommu->fault_count++; > + > + if (iommu->iommu_fault_fd) > + eventfd_signal(iommu->iommu_fault_fd, 1); > + > + mutex_unlock(&iommu->fault_lock); > + return 0; > +} > + > static long vfio_iommu_type1_ioctl(void *iommu_data, > unsigned int cmd, unsigned long arg) { diff --git > a/include/linux/iommu.h b/include/linux/iommu.h index 0ff5111..b6a7bdb > 100644 > --- a/include/linux/iommu.h > +++ b/include/linux/iommu.h > @@ -86,6 +86,13 @@ struct iommu_domain { > void *iova_cookie; > }; > > +struct iommu_fault_info { > + __u64 addr; > + __u16 sid; > + __u8 fault_reason; > + __u8 is_write:1; > +}; > + > enum iommu_cap { > IOMMU_CAP_CACHE_COHERENCY, /* IOMMU can enforce cache > coherent DMA > transactions */ > diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index > 8616334..da359dd 100644 > --- a/include/uapi/linux/vfio.h > +++ b/include/uapi/linux/vfio.h > @@ -562,6 +562,13 @@ struct vfio_iommu_type1_set_fault_eventfd { > > #define VFIO_IOMMU_SET_FAULT_EVENTFD _IO(VFIO_TYPE, VFIO_BASE + 17) > > +struct vfio_iommu_fault_info { > + __u64 addr; > + __u16 sid; > + __u8 fault_reason; > + __u8 is_write:1; > +}; > + > /* -------- Additional API for SPAPR TCE (Server POWERPC) IOMMU -------- */ > > /* > -- > 1.8.3.1