1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms and conditions of the GNU General Public License,
4 * version 2, as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9 * more details.
10 *
11 * You should have received a copy of the GNU General Public License along with
12 * this program; If not, see <http://www.gnu.org/licenses/>.
13 */
14
15 #include <xen/sched.h>
16 #include <xen/iommu.h>
17 #include <xen/paging.h>
18 #include <xen/guest_access.h>
19 #include <xen/event.h>
20 #include <xen/softirq.h>
21 #include <xsm/xsm.h>
22
23 #include <asm/hvm/io.h>
24 #include <asm/io_apic.h>
25 #include <asm/setup.h>
26
27 const struct iommu_init_ops *__initdata iommu_init_ops;
28 struct iommu_ops __read_mostly iommu_ops;
29
30 enum iommu_intremap __read_mostly iommu_intremap = iommu_intremap_full;
31
32 #ifndef iommu_intpost
33 /*
34 * In the current implementation of VT-d posted interrupts, in some extreme
35 * cases, the per cpu list which saves the blocked vCPU will be very long,
36 * and this will affect the interrupt latency, so let this feature off by
37 * default until we find a good solution to resolve it.
38 */
39 bool __read_mostly iommu_intpost;
40 #endif
41
iommu_hardware_setup(void)42 int __init iommu_hardware_setup(void)
43 {
44 struct IO_APIC_route_entry **ioapic_entries = NULL;
45 int rc;
46
47 if ( !iommu_init_ops )
48 return -ENODEV;
49
50 rc = scan_pci_devices();
51 if ( rc )
52 return rc;
53
54 if ( !iommu_ops.init )
55 iommu_ops = *iommu_init_ops->ops;
56 else
57 /* x2apic setup may have previously initialised the struct. */
58 ASSERT(iommu_ops.init == iommu_init_ops->ops->init);
59
60 if ( !x2apic_enabled && iommu_intremap )
61 {
62 /*
63 * If x2APIC is enabled interrupt remapping is already enabled, so
64 * there's no need to mess with the IO-APIC because the remapping
65 * entries are already correctly setup by x2apic_bsp_setup.
66 */
67 ioapic_entries = alloc_ioapic_entries();
68 if ( !ioapic_entries )
69 return -ENOMEM;
70 rc = save_IO_APIC_setup(ioapic_entries);
71 if ( rc )
72 {
73 free_ioapic_entries(ioapic_entries);
74 return rc;
75 }
76
77 mask_8259A();
78 mask_IO_APIC_setup(ioapic_entries);
79 }
80
81 rc = iommu_init_ops->setup();
82
83 if ( ioapic_entries )
84 {
85 restore_IO_APIC_setup(ioapic_entries, rc);
86 unmask_8259A();
87 free_ioapic_entries(ioapic_entries);
88 }
89
90 return rc;
91 }
92
iommu_enable_x2apic(void)93 int iommu_enable_x2apic(void)
94 {
95 if ( system_state < SYS_STATE_active )
96 {
97 if ( !iommu_supports_x2apic() )
98 return -EOPNOTSUPP;
99
100 iommu_ops = *iommu_init_ops->ops;
101 }
102 else if ( !x2apic_enabled )
103 return -EOPNOTSUPP;
104
105 if ( !iommu_ops.enable_x2apic )
106 return -EOPNOTSUPP;
107
108 return iommu_ops.enable_x2apic();
109 }
110
iommu_update_ire_from_apic(unsigned int apic,unsigned int reg,unsigned int value)111 void iommu_update_ire_from_apic(
112 unsigned int apic, unsigned int reg, unsigned int value)
113 {
114 iommu_vcall(&iommu_ops, update_ire_from_apic, apic, reg, value);
115 }
116
iommu_read_apic_from_ire(unsigned int apic,unsigned int reg)117 unsigned int iommu_read_apic_from_ire(unsigned int apic, unsigned int reg)
118 {
119 return iommu_call(&iommu_ops, read_apic_from_ire, apic, reg);
120 }
121
iommu_setup_hpet_msi(struct msi_desc * msi)122 int __init iommu_setup_hpet_msi(struct msi_desc *msi)
123 {
124 const struct iommu_ops *ops = iommu_get_ops();
125 return ops->setup_hpet_msi ? ops->setup_hpet_msi(msi) : -ENODEV;
126 }
127
arch_iommu_check_autotranslated_hwdom(struct domain * d)128 void __hwdom_init arch_iommu_check_autotranslated_hwdom(struct domain *d)
129 {
130 if ( !is_iommu_enabled(d) )
131 panic("Presently, iommu must be enabled for PVH hardware domain\n");
132
133 if ( !iommu_hwdom_strict )
134 panic("PVH hardware domain iommu must be set in 'strict' mode\n");
135 }
136
arch_iommu_domain_init(struct domain * d)137 int arch_iommu_domain_init(struct domain *d)
138 {
139 struct domain_iommu *hd = dom_iommu(d);
140
141 spin_lock_init(&hd->arch.mapping_lock);
142 INIT_LIST_HEAD(&hd->arch.mapped_rmrrs);
143
144 return 0;
145 }
146
arch_iommu_domain_destroy(struct domain * d)147 void arch_iommu_domain_destroy(struct domain *d)
148 {
149 }
150
hwdom_iommu_map(const struct domain * d,unsigned long pfn,unsigned long max_pfn)151 static bool __hwdom_init hwdom_iommu_map(const struct domain *d,
152 unsigned long pfn,
153 unsigned long max_pfn)
154 {
155 mfn_t mfn = _mfn(pfn);
156 unsigned int i, type;
157
158 /*
159 * Set up 1:1 mapping for dom0. Default to include only conventional RAM
160 * areas and let RMRRs include needed reserved regions. When set, the
161 * inclusive mapping additionally maps in every pfn up to 4GB except those
162 * that fall in unusable ranges for PV Dom0.
163 */
164 if ( (pfn > max_pfn && !mfn_valid(mfn)) || xen_in_range(pfn) )
165 return false;
166
167 switch ( type = page_get_ram_type(mfn) )
168 {
169 case RAM_TYPE_UNUSABLE:
170 return false;
171
172 case RAM_TYPE_CONVENTIONAL:
173 if ( iommu_hwdom_strict )
174 return false;
175 break;
176
177 default:
178 if ( type & RAM_TYPE_RESERVED )
179 {
180 if ( !iommu_hwdom_inclusive && !iommu_hwdom_reserved )
181 return false;
182 }
183 else if ( is_hvm_domain(d) || !iommu_hwdom_inclusive || pfn > max_pfn )
184 return false;
185 }
186
187 /* Check that it doesn't overlap with the Interrupt Address Range. */
188 if ( pfn >= 0xfee00 && pfn <= 0xfeeff )
189 return false;
190 /* ... or the IO-APIC */
191 for ( i = 0; has_vioapic(d) && i < d->arch.hvm.nr_vioapics; i++ )
192 if ( pfn == PFN_DOWN(domain_vioapic(d, i)->base_address) )
193 return false;
194 /*
195 * ... or the PCIe MCFG regions.
196 * TODO: runtime added MMCFG regions are not checked to make sure they
197 * don't overlap with already mapped regions, thus preventing trapping.
198 */
199 if ( has_vpci(d) && vpci_is_mmcfg_address(d, pfn_to_paddr(pfn)) )
200 return false;
201
202 return true;
203 }
204
arch_iommu_hwdom_init(struct domain * d)205 void __hwdom_init arch_iommu_hwdom_init(struct domain *d)
206 {
207 unsigned long i, top, max_pfn;
208 unsigned int flush_flags = 0;
209
210 BUG_ON(!is_hardware_domain(d));
211
212 /* Reserved IOMMU mappings are enabled by default. */
213 if ( iommu_hwdom_reserved == -1 )
214 iommu_hwdom_reserved = 1;
215
216 if ( iommu_hwdom_inclusive )
217 {
218 printk(XENLOG_WARNING
219 "IOMMU inclusive mappings are deprecated and will be removed in future versions\n");
220
221 if ( !is_pv_domain(d) )
222 {
223 printk(XENLOG_WARNING
224 "IOMMU inclusive mappings are only supported on PV Dom0\n");
225 iommu_hwdom_inclusive = false;
226 }
227 }
228
229 if ( iommu_hwdom_passthrough )
230 return;
231
232 max_pfn = (GB(4) >> PAGE_SHIFT) - 1;
233 top = max(max_pdx, pfn_to_pdx(max_pfn) + 1);
234
235 for ( i = 0; i < top; i++ )
236 {
237 unsigned long pfn = pdx_to_pfn(i);
238 int rc;
239
240 if ( !hwdom_iommu_map(d, pfn, max_pfn) )
241 rc = 0;
242 else if ( paging_mode_translate(d) )
243 rc = set_identity_p2m_entry(d, pfn, p2m_access_rw, 0);
244 else
245 rc = iommu_map(d, _dfn(pfn), _mfn(pfn), PAGE_ORDER_4K,
246 IOMMUF_readable | IOMMUF_writable, &flush_flags);
247
248 if ( rc )
249 printk(XENLOG_WARNING "%pd: identity %smapping of %lx failed: %d\n",
250 d, !paging_mode_translate(d) ? "IOMMU " : "", pfn, rc);
251
252 if (!(i & 0xfffff))
253 process_pending_softirqs();
254 }
255
256 /* Use if to avoid compiler warning */
257 if ( iommu_iotlb_flush_all(d, flush_flags) )
258 return;
259 }
260
261 /*
262 * Local variables:
263 * mode: C
264 * c-file-style: "BSD"
265 * c-basic-offset: 4
266 * indent-tabs-mode: nil
267 * End:
268 */
269