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