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 | * @sva_bind: Bind process address space to device | 227 | * @sva_bind: Bind process address space to device |
| 228 | * @sva_unbind: Unbind process address space from device | 228 | * @sva_unbind: Unbind process address space from device |
| 229 | * @sva_get_pasid: Get PASID associated to a SVA handle | 229 | * @sva_get_pasid: Get PASID associated to a SVA handle |
| 230 | * @page_response: handle page request response | ||
| 230 | * @pgsize_bitmap: bitmap of all possible supported page sizes | 231 | * @pgsize_bitmap: bitmap of all possible supported page sizes |
| 231 | */ | 232 | */ |
| 232 | struct iommu_ops { | 233 | struct iommu_ops { |
| @@ -287,6 +288,10 @@ struct iommu_ops { · 54 unmodified lines | |||
| 287 | void (*sva_unbind)(struct iommu_sva *handle); | 288 | void (*sva_unbind)(struct iommu_sva *handle); |
| 288 | int (*sva_get_pasid)(struct iommu_sva *handle); | 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 | unsigned long pgsize_bitmap; | 295 | unsigned long pgsize_bitmap; |
| 291 | }; | 296 | }; |
| 292 | 297 | ||
| @@ -311,19 +316,25 @@ struct iommu_device { · 18 unmodified lines | |||
| 311 | * unrecoverable faults such as DMA or IRQ remapping faults. | 316 | * unrecoverable faults such as DMA or IRQ remapping faults. |
| 312 | * | 317 | * |
| 313 | * @fault: fault descriptor | 318 | * @fault: fault descriptor |
| 319 | * @list: pending fault event list, used for tracking responses | ||
| 314 | */ | 320 | */ |
| 315 | struct iommu_fault_event { | 321 | struct iommu_fault_event { |
| 316 | struct iommu_fault fault; | 322 | struct iommu_fault fault; |
| 323 | struct list_head list; | ||
| 317 | }; | 324 | }; |
| 318 | 325 | ||
| 319 | /** | 326 | /** |
| 320 | * struct iommu_fault_param - per-device IOMMU fault data | 327 | * struct iommu_fault_param - per-device IOMMU fault data |
| 321 | * @handler: Callback function to handle IOMMU faults at device level | 328 | * @handler: Callback function to handle IOMMU faults at device level |
| 322 | * @data: handler private data | 329 | * @data: handler private data |
| 330 | * @faults: holds the pending faults which needs response | ||
| 331 | * @lock: protect pending faults list | ||
| 323 | */ | 332 | */ |
| 324 | struct iommu_fault_param { | 333 | struct iommu_fault_param { |
| 325 | iommu_dev_fault_handler_t handler; | 334 | iommu_dev_fault_handler_t handler; |
| 326 | void *data; | 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 | extern int iommu_report_device_fault(struct device *dev, | 449 | extern int iommu_report_device_fault(struct device *dev, |
| 439 | struct iommu_fault_event *evt); | 450 | struct iommu_fault_event *evt); |
| 451 | extern int iommu_page_response(struct device *dev, | ||
| 452 | struct iommu_page_response *msg); | ||
| 440 | 453 | ||
| 441 | extern int iommu_group_id(struct iommu_group *group); | 454 | extern int iommu_group_id(struct iommu_group *group); |
| 442 | extern struct iommu_group *iommu_group_get_for_dev(struct device *dev); | 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 | return -ENODEV; | 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 | static inline int iommu_group_id(struct iommu_group *group) | 787 | static inline int iommu_group_id(struct iommu_group *group) |
| 769 | { | 788 | { |
| 770 | return -ENODEV; | 789 | return -ENODEV; |