Some IOMMU hardware features, for example PCI PRI and Arm SMMU Stall, enable recoverable I/O page faults. Allow IOMMU drivers to report PRI Page Requests and Stall events through the new fault reporting API. The consumer of the fault can be either an I/O page fault handler in the host, or a guest OS. Once handled, the fault must be completed by sending a page response back to the IOMMU. Add an iommu_page_response() function to complete a page fault. There are two ways to extend the userspace API: * Add a field to iommu_page_response and a flag to iommu_page_response::flags describing the validity of this field. * Introduce a new iommu_page_response_X structure with a different version number. The kernel must then support both versions.
Showing the changes to include/linux (1 of 3 files). Show all
Unified · Split
| @@ -227,6 +227,7 @@ struct iommu_sva_ops { · 226 unmodified lines | ||
| 227 | 227 | * @sva_bind: Bind process address space to device |
| 228 | 228 | * @sva_unbind: Unbind process address space from device |
| 229 | 229 | * @sva_get_pasid: Get PASID associated to a SVA handle |
| 230 | + * @page_response: handle page request response | |
| 230 | 231 | * @pgsize_bitmap: bitmap of all possible supported page sizes |
| 231 | 232 | */ |
| 232 | 233 | struct iommu_ops { |
| @@ -287,6 +288,10 @@ struct iommu_ops { · 54 unmodified lines | ||
| 287 | 288 | void (*sva_unbind)(struct iommu_sva *handle); |
| 288 | 289 | int (*sva_get_pasid)(struct iommu_sva *handle); |
| 289 | 290 | |
| 291 | + int (*page_response)(struct device *dev, | |
| 292 | + struct iommu_fault_event *evt, | |
| 293 | + struct iommu_page_response *msg); | |
| 294 | + | |
| 290 | 295 | unsigned long pgsize_bitmap; |
| 291 | 296 | }; |
| 292 | 297 | |
| @@ -311,19 +316,25 @@ struct iommu_device { · 18 unmodified lines | ||
| 311 | 316 | * unrecoverable faults such as DMA or IRQ remapping faults. |
| 312 | 317 | * |
| 313 | 318 | * @fault: fault descriptor |
| 319 | + * @list: pending fault event list, used for tracking responses | |
| 314 | 320 | */ |
| 315 | 321 | struct iommu_fault_event { |
| 316 | 322 | struct iommu_fault fault; |
| 323 | + struct list_head list; | |
| 317 | 324 | }; |
| 318 | 325 | |
| 319 | 326 | /** |
| 320 | 327 | * struct iommu_fault_param - per-device IOMMU fault data |
| 321 | 328 | * @handler: Callback function to handle IOMMU faults at device level |
| 322 | 329 | * @data: handler private data |
| 330 | + * @faults: holds the pending faults which needs response | |
| 331 | + * @lock: protect pending faults list | |
| 323 | 332 | */ |
| 324 | 333 | struct iommu_fault_param { |
| 325 | 334 | iommu_dev_fault_handler_t handler; |
| 326 | 335 | void *data; |
| 336 | + struct list_head faults; | |
| 337 | + struct mutex lock; | |
| 327 | 338 | }; |
| 328 | 339 | |
| 329 | 340 | /** |
| @@ -437,6 +448,8 @@ extern int iommu_unregister_device_fault_handler(struct device *dev); · 107 unmodified lines | ||
| 437 | 448 | |
| 438 | 449 | extern int iommu_report_device_fault(struct device *dev, |
| 439 | 450 | struct iommu_fault_event *evt); |
| 451 | +extern int iommu_page_response(struct device *dev, | |
| 452 | + struct iommu_page_response *msg); | |
| 440 | 453 | |
| 441 | 454 | extern int iommu_group_id(struct iommu_group *group); |
| 442 | 455 | extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); |
| @@ -765,6 +778,12 @@ int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt) · 322 unmodified lines | ||
| 765 | 778 | return -ENODEV; |
| 766 | 779 | } |
| 767 | 780 | |
| 781 | +static inline int iommu_page_response(struct device *dev, | |
| 782 | + struct iommu_page_response *msg) | |
| 783 | +{ | |
| 784 | + return -ENODEV; | |
| 785 | +} | |
| 786 | + | |
| 768 | 787 | static inline int iommu_group_id(struct iommu_group *group) |
| 769 | 788 | { |
| 770 | 789 | return -ENODEV; |