xref: /OK3568_Linux_fs/kernel/include/linux/amd-iommu.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
4*4882a593Smuzhiyun  * Author: Joerg Roedel <joerg.roedel@amd.com>
5*4882a593Smuzhiyun  *         Leo Duran <leo.duran@amd.com>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef _ASM_X86_AMD_IOMMU_H
9*4882a593Smuzhiyun #define _ASM_X86_AMD_IOMMU_H
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <linux/types.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun  * This is mainly used to communicate information back-and-forth
15*4882a593Smuzhiyun  * between SVM and IOMMU for setting up and tearing down posted
16*4882a593Smuzhiyun  * interrupt
17*4882a593Smuzhiyun  */
18*4882a593Smuzhiyun struct amd_iommu_pi_data {
19*4882a593Smuzhiyun 	u32 ga_tag;
20*4882a593Smuzhiyun 	u32 prev_ga_tag;
21*4882a593Smuzhiyun 	u64 base;
22*4882a593Smuzhiyun 	bool is_guest_mode;
23*4882a593Smuzhiyun 	struct vcpu_data *vcpu_data;
24*4882a593Smuzhiyun 	void *ir_data;
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #ifdef CONFIG_AMD_IOMMU
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun struct task_struct;
30*4882a593Smuzhiyun struct pci_dev;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun extern int amd_iommu_detect(void);
33*4882a593Smuzhiyun extern int amd_iommu_init_hardware(void);
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /**
36*4882a593Smuzhiyun  * amd_iommu_enable_device_erratum() - Enable erratum workaround for device
37*4882a593Smuzhiyun  *				       in the IOMMUv2 driver
38*4882a593Smuzhiyun  * @pdev: The PCI device the workaround is necessary for
39*4882a593Smuzhiyun  * @erratum: The erratum workaround to enable
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  * The function needs to be called before amd_iommu_init_device().
42*4882a593Smuzhiyun  * Possible values for the erratum number are for now:
43*4882a593Smuzhiyun  * - AMD_PRI_DEV_ERRATUM_ENABLE_RESET - Reset PRI capability when PRI
44*4882a593Smuzhiyun  *					is enabled
45*4882a593Smuzhiyun  * - AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE - Limit number of outstanding PRI
46*4882a593Smuzhiyun  *					 requests to one
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun #define AMD_PRI_DEV_ERRATUM_ENABLE_RESET		0
49*4882a593Smuzhiyun #define AMD_PRI_DEV_ERRATUM_LIMIT_REQ_ONE		1
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun extern void amd_iommu_enable_device_erratum(struct pci_dev *pdev, u32 erratum);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /**
54*4882a593Smuzhiyun  * amd_iommu_init_device() - Init device for use with IOMMUv2 driver
55*4882a593Smuzhiyun  * @pdev: The PCI device to initialize
56*4882a593Smuzhiyun  * @pasids: Number of PASIDs to support for this device
57*4882a593Smuzhiyun  *
58*4882a593Smuzhiyun  * This function does all setup for the device pdev so that it can be
59*4882a593Smuzhiyun  * used with IOMMUv2.
60*4882a593Smuzhiyun  * Returns 0 on success or negative value on error.
61*4882a593Smuzhiyun  */
62*4882a593Smuzhiyun extern int amd_iommu_init_device(struct pci_dev *pdev, int pasids);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /**
65*4882a593Smuzhiyun  * amd_iommu_free_device() - Free all IOMMUv2 related device resources
66*4882a593Smuzhiyun  *			     and disable IOMMUv2 usage for this device
67*4882a593Smuzhiyun  * @pdev: The PCI device to disable IOMMUv2 usage for'
68*4882a593Smuzhiyun  */
69*4882a593Smuzhiyun extern void amd_iommu_free_device(struct pci_dev *pdev);
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /**
72*4882a593Smuzhiyun  * amd_iommu_bind_pasid() - Bind a given task to a PASID on a device
73*4882a593Smuzhiyun  * @pdev: The PCI device to bind the task to
74*4882a593Smuzhiyun  * @pasid: The PASID on the device the task should be bound to
75*4882a593Smuzhiyun  * @task: the task to bind
76*4882a593Smuzhiyun  *
77*4882a593Smuzhiyun  * The function returns 0 on success or a negative value on error.
78*4882a593Smuzhiyun  */
79*4882a593Smuzhiyun extern int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid,
80*4882a593Smuzhiyun 				struct task_struct *task);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /**
83*4882a593Smuzhiyun  * amd_iommu_unbind_pasid() - Unbind a PASID from its task on
84*4882a593Smuzhiyun  *			      a device
85*4882a593Smuzhiyun  * @pdev: The device of the PASID
86*4882a593Smuzhiyun  * @pasid: The PASID to unbind
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * When this function returns the device is no longer using the PASID
89*4882a593Smuzhiyun  * and the PASID is no longer bound to its task.
90*4882a593Smuzhiyun  */
91*4882a593Smuzhiyun extern void amd_iommu_unbind_pasid(struct pci_dev *pdev, u32 pasid);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun /**
94*4882a593Smuzhiyun  * amd_iommu_set_invalid_ppr_cb() - Register a call-back for failed
95*4882a593Smuzhiyun  *				    PRI requests
96*4882a593Smuzhiyun  * @pdev: The PCI device the call-back should be registered for
97*4882a593Smuzhiyun  * @cb: The call-back function
98*4882a593Smuzhiyun  *
99*4882a593Smuzhiyun  * The IOMMUv2 driver invokes this call-back when it is unable to
100*4882a593Smuzhiyun  * successfully handle a PRI request. The device driver can then decide
101*4882a593Smuzhiyun  * which PRI response the device should see. Possible return values for
102*4882a593Smuzhiyun  * the call-back are:
103*4882a593Smuzhiyun  *
104*4882a593Smuzhiyun  * - AMD_IOMMU_INV_PRI_RSP_SUCCESS - Send SUCCESS back to the device
105*4882a593Smuzhiyun  * - AMD_IOMMU_INV_PRI_RSP_INVALID - Send INVALID back to the device
106*4882a593Smuzhiyun  * - AMD_IOMMU_INV_PRI_RSP_FAIL    - Send Failure back to the device,
107*4882a593Smuzhiyun  *				     the device is required to disable
108*4882a593Smuzhiyun  *				     PRI when it receives this response
109*4882a593Smuzhiyun  *
110*4882a593Smuzhiyun  * The function returns 0 on success or negative value on error.
111*4882a593Smuzhiyun  */
112*4882a593Smuzhiyun #define AMD_IOMMU_INV_PRI_RSP_SUCCESS	0
113*4882a593Smuzhiyun #define AMD_IOMMU_INV_PRI_RSP_INVALID	1
114*4882a593Smuzhiyun #define AMD_IOMMU_INV_PRI_RSP_FAIL	2
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun typedef int (*amd_iommu_invalid_ppr_cb)(struct pci_dev *pdev,
117*4882a593Smuzhiyun 					u32 pasid,
118*4882a593Smuzhiyun 					unsigned long address,
119*4882a593Smuzhiyun 					u16);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun extern int amd_iommu_set_invalid_ppr_cb(struct pci_dev *pdev,
122*4882a593Smuzhiyun 					amd_iommu_invalid_ppr_cb cb);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #define PPR_FAULT_EXEC	(1 << 1)
125*4882a593Smuzhiyun #define PPR_FAULT_READ  (1 << 2)
126*4882a593Smuzhiyun #define PPR_FAULT_WRITE (1 << 5)
127*4882a593Smuzhiyun #define PPR_FAULT_USER  (1 << 6)
128*4882a593Smuzhiyun #define PPR_FAULT_RSVD  (1 << 7)
129*4882a593Smuzhiyun #define PPR_FAULT_GN    (1 << 8)
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun /**
132*4882a593Smuzhiyun  * amd_iommu_device_info() - Get information about IOMMUv2 support of a
133*4882a593Smuzhiyun  *			     PCI device
134*4882a593Smuzhiyun  * @pdev: PCI device to query information from
135*4882a593Smuzhiyun  * @info: A pointer to an amd_iommu_device_info structure which will contain
136*4882a593Smuzhiyun  *	  the information about the PCI device
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * Returns 0 on success, negative value on error
139*4882a593Smuzhiyun  */
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun #define AMD_IOMMU_DEVICE_FLAG_ATS_SUP     0x1    /* ATS feature supported */
142*4882a593Smuzhiyun #define AMD_IOMMU_DEVICE_FLAG_PRI_SUP     0x2    /* PRI feature supported */
143*4882a593Smuzhiyun #define AMD_IOMMU_DEVICE_FLAG_PASID_SUP   0x4    /* PASID context supported */
144*4882a593Smuzhiyun #define AMD_IOMMU_DEVICE_FLAG_EXEC_SUP    0x8    /* Device may request execution
145*4882a593Smuzhiyun 						    on memory pages */
146*4882a593Smuzhiyun #define AMD_IOMMU_DEVICE_FLAG_PRIV_SUP   0x10    /* Device may request
147*4882a593Smuzhiyun 						    super-user privileges */
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun struct amd_iommu_device_info {
150*4882a593Smuzhiyun 	int max_pasids;
151*4882a593Smuzhiyun 	u32 flags;
152*4882a593Smuzhiyun };
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun extern int amd_iommu_device_info(struct pci_dev *pdev,
155*4882a593Smuzhiyun 				 struct amd_iommu_device_info *info);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /**
158*4882a593Smuzhiyun  * amd_iommu_set_invalidate_ctx_cb() - Register a call-back for invalidating
159*4882a593Smuzhiyun  *				       a pasid context. This call-back is
160*4882a593Smuzhiyun  *				       invoked when the IOMMUv2 driver needs to
161*4882a593Smuzhiyun  *				       invalidate a PASID context, for example
162*4882a593Smuzhiyun  *				       because the task that is bound to that
163*4882a593Smuzhiyun  *				       context is about to exit.
164*4882a593Smuzhiyun  *
165*4882a593Smuzhiyun  * @pdev: The PCI device the call-back should be registered for
166*4882a593Smuzhiyun  * @cb: The call-back function
167*4882a593Smuzhiyun  */
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun typedef void (*amd_iommu_invalidate_ctx)(struct pci_dev *pdev, u32 pasid);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun extern int amd_iommu_set_invalidate_ctx_cb(struct pci_dev *pdev,
172*4882a593Smuzhiyun 					   amd_iommu_invalidate_ctx cb);
173*4882a593Smuzhiyun #else /* CONFIG_AMD_IOMMU */
174*4882a593Smuzhiyun 
amd_iommu_detect(void)175*4882a593Smuzhiyun static inline int amd_iommu_detect(void) { return -ENODEV; }
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun #endif /* CONFIG_AMD_IOMMU */
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #if defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP)
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun /* IOMMU AVIC Function */
182*4882a593Smuzhiyun extern int amd_iommu_register_ga_log_notifier(int (*notifier)(u32));
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun extern int
185*4882a593Smuzhiyun amd_iommu_update_ga(int cpu, bool is_run, void *data);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun extern int amd_iommu_activate_guest_mode(void *data);
188*4882a593Smuzhiyun extern int amd_iommu_deactivate_guest_mode(void *data);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun #else /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun static inline int
amd_iommu_register_ga_log_notifier(int (* notifier)(u32))193*4882a593Smuzhiyun amd_iommu_register_ga_log_notifier(int (*notifier)(u32))
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun 	return 0;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun static inline int
amd_iommu_update_ga(int cpu,bool is_run,void * data)199*4882a593Smuzhiyun amd_iommu_update_ga(int cpu, bool is_run, void *data)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	return 0;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
amd_iommu_activate_guest_mode(void * data)204*4882a593Smuzhiyun static inline int amd_iommu_activate_guest_mode(void *data)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun 	return 0;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun 
amd_iommu_deactivate_guest_mode(void * data)209*4882a593Smuzhiyun static inline int amd_iommu_deactivate_guest_mode(void *data)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun 	return 0;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun #endif /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun #endif /* _ASM_X86_AMD_IOMMU_H */
216