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 #ifndef __ARCH_X86_IOMMU_H__
15 #define __ARCH_X86_IOMMU_H__
16 
17 #include <xen/errno.h>
18 #include <xen/list.h>
19 #include <xen/spinlock.h>
20 #include <asm/processor.h>
21 #include <asm/hvm/vmx/vmcs.h>
22 
23 #define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
24 #define MAX_IOMMUS 32
25 
26 struct g2m_ioport {
27     struct list_head list;
28     unsigned int gport;
29     unsigned int mport;
30     unsigned int np;
31 };
32 
33 struct arch_iommu
34 {
35     u64 pgd_maddr;                 /* io page directory machine address */
36     spinlock_t mapping_lock;            /* io page table lock */
37     int agaw;     /* adjusted guest address width, 0 is level 2 30-bit */
38     u64 iommu_bitmap;              /* bitmap of iommu(s) that the domain uses */
39     struct list_head mapped_rmrrs;
40 
41     /* amd iommu support */
42     int paging_mode;
43     struct page_info *root_table;
44     struct guest_iommu *g_iommu;
45 };
46 
47 extern const struct iommu_ops intel_iommu_ops;
48 extern const struct iommu_ops amd_iommu_ops;
49 int intel_vtd_setup(void);
50 int amd_iov_detect(void);
51 
iommu_get_ops(void)52 static inline const struct iommu_ops *iommu_get_ops(void)
53 {
54     switch ( boot_cpu_data.x86_vendor )
55     {
56     case X86_VENDOR_INTEL:
57         return &intel_iommu_ops;
58     case X86_VENDOR_AMD:
59         return &amd_iommu_ops;
60     }
61 
62     BUG();
63 
64     return NULL;
65 }
66 
iommu_hardware_setup(void)67 static inline int iommu_hardware_setup(void)
68 {
69     switch ( boot_cpu_data.x86_vendor )
70     {
71     case X86_VENDOR_INTEL:
72         return intel_vtd_setup();
73     case X86_VENDOR_AMD:
74         return amd_iov_detect();
75     }
76 
77     return -ENODEV;
78 }
79 
80 /* Does this domain have a P2M table we can use as its IOMMU pagetable? */
81 #define iommu_use_hap_pt(d) (hap_enabled(d) && iommu_hap_pt_share)
82 
83 void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value);
84 unsigned int iommu_read_apic_from_ire(unsigned int apic, unsigned int reg);
85 int iommu_setup_hpet_msi(struct msi_desc *);
86 
87 /* While VT-d specific, this must get declared in a generic header. */
88 int adjust_vtd_irq_affinities(void);
89 int __must_check iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
90                                  int order, int present);
91 bool_t iommu_supports_eim(void);
92 int iommu_enable_x2apic_IR(void);
93 void iommu_disable_x2apic_IR(void);
94 
95 extern bool untrusted_msi;
96 
97 int pi_update_irte(const struct pi_desc *pi_desc, const struct pirq *pirq,
98                    const uint8_t gvec);
99 
100 #endif /* !__ARCH_X86_IOMMU_H__ */
101 /*
102  * Local variables:
103  * mode: C
104  * c-file-style: "BSD"
105  * c-basic-offset: 4
106  * indent-tabs-mode: nil
107  * End:
108  */
109