forked from mirrors/linux
		
	Ease future extensions of struct iommu_fault_page_request and struct iommu_fault_unrecoverable by adding a few bytes of padding. That way, a new field can be added to either of these structures by simply introducing a new flag. To extend it after the size limit is reached, a new fault reporting structure will have to be negotiated with userspace. With 56 bytes of padding, the total size of iommu_fault is 64 bytes and fits in a cache line on a lot of contemporary machines, while providing 16 and 24 bytes of extension to structures iommu_fault_page_request and iommu_fault_unrecoverable respectively. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> Acked-by: Jacob Pan <jacob.jun.pan@linux.intel.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
		
			
				
	
	
		
			155 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 | 
						|
/*
 | 
						|
 * IOMMU user API definitions
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef _UAPI_IOMMU_H
 | 
						|
#define _UAPI_IOMMU_H
 | 
						|
 | 
						|
#include <linux/types.h>
 | 
						|
 | 
						|
#define IOMMU_FAULT_PERM_READ	(1 << 0) /* read */
 | 
						|
#define IOMMU_FAULT_PERM_WRITE	(1 << 1) /* write */
 | 
						|
#define IOMMU_FAULT_PERM_EXEC	(1 << 2) /* exec */
 | 
						|
#define IOMMU_FAULT_PERM_PRIV	(1 << 3) /* privileged */
 | 
						|
 | 
						|
/* Generic fault types, can be expanded IRQ remapping fault */
 | 
						|
enum iommu_fault_type {
 | 
						|
	IOMMU_FAULT_DMA_UNRECOV = 1,	/* unrecoverable fault */
 | 
						|
	IOMMU_FAULT_PAGE_REQ,		/* page request fault */
 | 
						|
};
 | 
						|
 | 
						|
enum iommu_fault_reason {
 | 
						|
	IOMMU_FAULT_REASON_UNKNOWN = 0,
 | 
						|
 | 
						|
	/* Could not access the PASID table (fetch caused external abort) */
 | 
						|
	IOMMU_FAULT_REASON_PASID_FETCH,
 | 
						|
 | 
						|
	/* PASID entry is invalid or has configuration errors */
 | 
						|
	IOMMU_FAULT_REASON_BAD_PASID_ENTRY,
 | 
						|
 | 
						|
	/*
 | 
						|
	 * PASID is out of range (e.g. exceeds the maximum PASID
 | 
						|
	 * supported by the IOMMU) or disabled.
 | 
						|
	 */
 | 
						|
	IOMMU_FAULT_REASON_PASID_INVALID,
 | 
						|
 | 
						|
	/*
 | 
						|
	 * An external abort occurred fetching (or updating) a translation
 | 
						|
	 * table descriptor
 | 
						|
	 */
 | 
						|
	IOMMU_FAULT_REASON_WALK_EABT,
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Could not access the page table entry (Bad address),
 | 
						|
	 * actual translation fault
 | 
						|
	 */
 | 
						|
	IOMMU_FAULT_REASON_PTE_FETCH,
 | 
						|
 | 
						|
	/* Protection flag check failed */
 | 
						|
	IOMMU_FAULT_REASON_PERMISSION,
 | 
						|
 | 
						|
	/* access flag check failed */
 | 
						|
	IOMMU_FAULT_REASON_ACCESS,
 | 
						|
 | 
						|
	/* Output address of a translation stage caused Address Size fault */
 | 
						|
	IOMMU_FAULT_REASON_OOR_ADDRESS,
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct iommu_fault_unrecoverable - Unrecoverable fault data
 | 
						|
 * @reason: reason of the fault, from &enum iommu_fault_reason
 | 
						|
 * @flags: parameters of this fault (IOMMU_FAULT_UNRECOV_* values)
 | 
						|
 * @pasid: Process Address Space ID
 | 
						|
 * @perm: requested permission access using by the incoming transaction
 | 
						|
 *        (IOMMU_FAULT_PERM_* values)
 | 
						|
 * @addr: offending page address
 | 
						|
 * @fetch_addr: address that caused a fetch abort, if any
 | 
						|
 */
 | 
						|
struct iommu_fault_unrecoverable {
 | 
						|
	__u32	reason;
 | 
						|
#define IOMMU_FAULT_UNRECOV_PASID_VALID		(1 << 0)
 | 
						|
#define IOMMU_FAULT_UNRECOV_ADDR_VALID		(1 << 1)
 | 
						|
#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID	(1 << 2)
 | 
						|
	__u32	flags;
 | 
						|
	__u32	pasid;
 | 
						|
	__u32	perm;
 | 
						|
	__u64	addr;
 | 
						|
	__u64	fetch_addr;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct iommu_fault_page_request - Page Request data
 | 
						|
 * @flags: encodes whether the corresponding fields are valid and whether this
 | 
						|
 *         is the last page in group (IOMMU_FAULT_PAGE_REQUEST_* values)
 | 
						|
 * @pasid: Process Address Space ID
 | 
						|
 * @grpid: Page Request Group Index
 | 
						|
 * @perm: requested page permissions (IOMMU_FAULT_PERM_* values)
 | 
						|
 * @addr: page address
 | 
						|
 * @private_data: device-specific private information
 | 
						|
 */
 | 
						|
struct iommu_fault_page_request {
 | 
						|
#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID	(1 << 0)
 | 
						|
#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE	(1 << 1)
 | 
						|
#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA	(1 << 2)
 | 
						|
	__u32	flags;
 | 
						|
	__u32	pasid;
 | 
						|
	__u32	grpid;
 | 
						|
	__u32	perm;
 | 
						|
	__u64	addr;
 | 
						|
	__u64	private_data[2];
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct iommu_fault - Generic fault data
 | 
						|
 * @type: fault type from &enum iommu_fault_type
 | 
						|
 * @padding: reserved for future use (should be zero)
 | 
						|
 * @event: fault event, when @type is %IOMMU_FAULT_DMA_UNRECOV
 | 
						|
 * @prm: Page Request message, when @type is %IOMMU_FAULT_PAGE_REQ
 | 
						|
 * @padding2: sets the fault size to allow for future extensions
 | 
						|
 */
 | 
						|
struct iommu_fault {
 | 
						|
	__u32	type;
 | 
						|
	__u32	padding;
 | 
						|
	union {
 | 
						|
		struct iommu_fault_unrecoverable event;
 | 
						|
		struct iommu_fault_page_request prm;
 | 
						|
		__u8 padding2[56];
 | 
						|
	};
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * enum iommu_page_response_code - Return status of fault handlers
 | 
						|
 * @IOMMU_PAGE_RESP_SUCCESS: Fault has been handled and the page tables
 | 
						|
 *	populated, retry the access. This is "Success" in PCI PRI.
 | 
						|
 * @IOMMU_PAGE_RESP_FAILURE: General error. Drop all subsequent faults from
 | 
						|
 *	this device if possible. This is "Response Failure" in PCI PRI.
 | 
						|
 * @IOMMU_PAGE_RESP_INVALID: Could not handle this fault, don't retry the
 | 
						|
 *	access. This is "Invalid Request" in PCI PRI.
 | 
						|
 */
 | 
						|
enum iommu_page_response_code {
 | 
						|
	IOMMU_PAGE_RESP_SUCCESS = 0,
 | 
						|
	IOMMU_PAGE_RESP_INVALID,
 | 
						|
	IOMMU_PAGE_RESP_FAILURE,
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct iommu_page_response - Generic page response information
 | 
						|
 * @version: API version of this structure
 | 
						|
 * @flags: encodes whether the corresponding fields are valid
 | 
						|
 *         (IOMMU_FAULT_PAGE_RESPONSE_* values)
 | 
						|
 * @pasid: Process Address Space ID
 | 
						|
 * @grpid: Page Request Group Index
 | 
						|
 * @code: response code from &enum iommu_page_response_code
 | 
						|
 */
 | 
						|
struct iommu_page_response {
 | 
						|
#define IOMMU_PAGE_RESP_VERSION_1	1
 | 
						|
	__u32	version;
 | 
						|
#define IOMMU_PAGE_RESP_PASID_VALID	(1 << 0)
 | 
						|
	__u32	flags;
 | 
						|
	__u32	pasid;
 | 
						|
	__u32	grpid;
 | 
						|
	__u32	code;
 | 
						|
};
 | 
						|
 | 
						|
#endif /* _UAPI_IOMMU_H */
 |