| .. | .. | 
|---|
 | 1 | +/* SPDX-License-Identifier: GPL-2.0-only */  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * Copyright (c) 2006, Intel Corporation. | 
|---|
| 3 |  | - *  | 
|---|
| 4 |  | - * This program is free software; you can redistribute it and/or modify it  | 
|---|
| 5 |  | - * under the terms and conditions of the GNU General Public License,  | 
|---|
| 6 |  | - * version 2, as published by the Free Software Foundation.  | 
|---|
| 7 |  | - *  | 
|---|
| 8 |  | - * This program is distributed in the hope it will be useful, but WITHOUT  | 
|---|
| 9 |  | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  | 
|---|
| 10 |  | - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  | 
|---|
| 11 |  | - * more details.  | 
|---|
| 12 |  | - *  | 
|---|
| 13 |  | - * You should have received a copy of the GNU General Public License along with  | 
|---|
| 14 |  | - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple  | 
|---|
| 15 |  | - * Place - Suite 330, Boston, MA 02111-1307 USA.  | 
|---|
| 16 | 4 |   * | 
|---|
| 17 | 5 |   * Copyright (C) Ashok Raj <ashok.raj@intel.com> | 
|---|
| 18 | 6 |   * Copyright (C) Shaohua Li <shaohua.li@intel.com> | 
|---|
| .. | .. | 
|---|
| 39 | 27 |  /* DMAR Flags */ | 
|---|
| 40 | 28 |  #define DMAR_INTR_REMAP		0x1 | 
|---|
| 41 | 29 |  #define DMAR_X2APIC_OPT_OUT	0x2 | 
|---|
 | 30 | +#define DMAR_PLATFORM_OPT_IN	0x4  | 
|---|
| 42 | 31 |   | 
|---|
| 43 | 32 |  struct intel_iommu; | 
|---|
| 44 | 33 |   | 
|---|
| .. | .. | 
|---|
| 59 | 48 |  	u16	segment;		/* PCI domain		*/ | 
|---|
| 60 | 49 |  	u8	ignored:1; 		/* ignore drhd		*/ | 
|---|
| 61 | 50 |  	u8	include_all:1; | 
|---|
 | 51 | +	u8	gfx_dedicated:1;	/* graphic dedicated	*/  | 
|---|
| 62 | 52 |  	struct intel_iommu *iommu; | 
|---|
| 63 | 53 |  }; | 
|---|
| 64 | 54 |   | 
|---|
| .. | .. | 
|---|
| 80 | 70 |  extern struct rw_semaphore dmar_global_lock; | 
|---|
| 81 | 71 |  extern struct list_head dmar_drhd_units; | 
|---|
| 82 | 72 |   | 
|---|
| 83 |  | -#define for_each_drhd_unit(drhd) \  | 
|---|
| 84 |  | -	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)  | 
|---|
 | 73 | +#define for_each_drhd_unit(drhd)					\  | 
|---|
 | 74 | +	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\  | 
|---|
 | 75 | +				dmar_rcu_check())  | 
|---|
| 85 | 76 |   | 
|---|
| 86 | 77 |  #define for_each_active_drhd_unit(drhd)					\ | 
|---|
| 87 |  | -	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)		\  | 
|---|
 | 78 | +	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\  | 
|---|
 | 79 | +				dmar_rcu_check())			\  | 
|---|
| 88 | 80 |  		if (drhd->ignored) {} else | 
|---|
| 89 | 81 |   | 
|---|
| 90 | 82 |  #define for_each_active_iommu(i, drhd)					\ | 
|---|
| 91 |  | -	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)		\  | 
|---|
 | 83 | +	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\  | 
|---|
 | 84 | +				dmar_rcu_check())			\  | 
|---|
| 92 | 85 |  		if (i=drhd->iommu, drhd->ignored) {} else | 
|---|
| 93 | 86 |   | 
|---|
| 94 | 87 |  #define for_each_iommu(i, drhd)						\ | 
|---|
| 95 |  | -	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list)		\  | 
|---|
 | 88 | +	list_for_each_entry_rcu(drhd, &dmar_drhd_units, list,		\  | 
|---|
 | 89 | +				dmar_rcu_check())			\  | 
|---|
| 96 | 90 |  		if (i=drhd->iommu, 0) {} else  | 
|---|
| 97 | 91 |   | 
|---|
| 98 | 92 |  static inline bool dmar_rcu_check(void) | 
|---|
| .. | .. | 
|---|
| 103 | 97 |   | 
|---|
| 104 | 98 |  #define	dmar_rcu_dereference(p)	rcu_dereference_check((p), dmar_rcu_check()) | 
|---|
| 105 | 99 |   | 
|---|
| 106 |  | -#define	for_each_dev_scope(a, c, p, d)	\  | 
|---|
| 107 |  | -	for ((p) = 0; ((d) = (p) < (c) ? dmar_rcu_dereference((a)[(p)].dev) : \  | 
|---|
| 108 |  | -			NULL, (p) < (c)); (p)++)  | 
|---|
 | 100 | +#define for_each_dev_scope(devs, cnt, i, tmp)				\  | 
|---|
 | 101 | +	for ((i) = 0; ((tmp) = (i) < (cnt) ?				\  | 
|---|
 | 102 | +	    dmar_rcu_dereference((devs)[(i)].dev) : NULL, (i) < (cnt)); \  | 
|---|
 | 103 | +	    (i)++)  | 
|---|
| 109 | 104 |   | 
|---|
| 110 |  | -#define	for_each_active_dev_scope(a, c, p, d)	\  | 
|---|
| 111 |  | -	for_each_dev_scope((a), (c), (p), (d))	if (!(d)) { continue; } else  | 
|---|
 | 105 | +#define for_each_active_dev_scope(devs, cnt, i, tmp)			\  | 
|---|
 | 106 | +	for_each_dev_scope((devs), (cnt), (i), (tmp))			\  | 
|---|
 | 107 | +		if (!(tmp)) { continue; } else  | 
|---|
| 112 | 108 |   | 
|---|
| 113 | 109 |  extern int dmar_table_init(void); | 
|---|
| 114 | 110 |  extern int dmar_dev_scope_init(void); | 
|---|
| .. | .. | 
|---|
| 138 | 134 |  #ifdef CONFIG_INTEL_IOMMU | 
|---|
| 139 | 135 |  extern int iommu_detected, no_iommu; | 
|---|
| 140 | 136 |  extern int intel_iommu_init(void); | 
|---|
 | 137 | +extern void intel_iommu_shutdown(void);  | 
|---|
| 141 | 138 |  extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg); | 
|---|
| 142 | 139 |  extern int dmar_parse_one_atsr(struct acpi_dmar_header *header, void *arg); | 
|---|
| 143 | 140 |  extern int dmar_check_one_atsr(struct acpi_dmar_header *hdr, void *arg); | 
|---|
| .. | .. | 
|---|
| 146 | 143 |  extern int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info); | 
|---|
| 147 | 144 |  #else /* !CONFIG_INTEL_IOMMU: */ | 
|---|
| 148 | 145 |  static inline int intel_iommu_init(void) { return -ENODEV; } | 
|---|
 | 146 | +static inline void intel_iommu_shutdown(void) { }  | 
|---|
| 149 | 147 |   | 
|---|
| 150 | 148 |  #define	dmar_parse_one_rmrr		dmar_res_noop | 
|---|
| 151 | 149 |  #define	dmar_parse_one_atsr		dmar_res_noop | 
|---|
| .. | .. | 
|---|
| 170 | 168 |  { return 0; } | 
|---|
| 171 | 169 |  #endif /* CONFIG_IRQ_REMAP */ | 
|---|
| 172 | 170 |   | 
|---|
 | 171 | +extern bool dmar_platform_optin(void);  | 
|---|
 | 172 | +  | 
|---|
| 173 | 173 |  #else /* CONFIG_DMAR_TABLE */ | 
|---|
| 174 | 174 |   | 
|---|
| 175 | 175 |  static inline int dmar_device_add(void *handle) | 
|---|
| .. | .. | 
|---|
| 182 | 182 |  	return 0; | 
|---|
| 183 | 183 |  } | 
|---|
| 184 | 184 |   | 
|---|
 | 185 | +static inline bool dmar_platform_optin(void)  | 
|---|
 | 186 | +{  | 
|---|
 | 187 | +	return false;  | 
|---|
 | 188 | +}  | 
|---|
 | 189 | +  | 
|---|
| 185 | 190 |  #endif /* CONFIG_DMAR_TABLE */ | 
|---|
| 186 | 191 |   | 
|---|
| 187 | 192 |  struct irte { | 
|---|