iommu: populate functions for setup/teardown of page tables
[akaros.git] / kern / drivers / dev / iommu.c
1 /*
2  * File: iommu.c - Driver for accessing Intel iommu
3  * Author: Aditya Basu <mitthu@google.com>
4  *
5  * (1) proc->proc_lock => (2) iommu->iommu_lock
6  *
7  * TODO
8  * ====
9  *  - iommu_process_cleanup() is untested.
10  *  - In iommu_map_pci_devices() assign the correct iommu for scoped DRHD. Right
11  *    now the default iommu is assigned to all devices.
12  *  - In assign_device() make sure the process in not in DYING or DYING_ABORT
13  *    state.
14  *  - Assigning processes across multiple IOMMUs / DRHDs will result in
15  *    corruption of iommu->procs. This is because the tailq relies on
16  *    proc->iommu_link.
17  *  - IOMMU_DID_DEFAULT = 1; this means pid = 1 cannot have a device passthru
18  *    because we use the pid as "did" or domain ID.
19  */
20
21 #include <stdio.h>
22 #include <error.h>
23 #include <common.h>
24 #include <net/ip.h>
25 #include <atomic.h>
26
27 #include <acpi.h>
28 #include <arch/intel-iommu.h>
29 #include <env.h>
30 #include <arch/pci.h>
31 #include <linux_compat.h>
32
33 #define IOMMU "iommu: "
34 #define BUFFERSZ 8192
35
36 struct dev iommudevtab;
37 struct iommu_list_tq iommu_list = TAILQ_HEAD_INITIALIZER(iommu_list);
38 static bool is_initialized; /* to detect absence of IOMMU */
39
40 /* QID Path */
41 enum {
42         Qdir         = 0,
43         Qmappings    = 1,
44         Qadddev      = 2,
45         Qremovedev   = 3,
46         Qinfo        = 4,
47         Qpower       = 5,
48 };
49
50 static struct dirtab iommudir[] = {
51         {".",                   {Qdir, 0, QTDIR}, 0, 0555},
52         {"mappings",            {Qmappings, 0, QTFILE}, 0, 0755},
53         {"attach",              {Qadddev, 0, QTFILE}, 0, 0755},
54         {"detach",              {Qremovedev, 0, QTFILE}, 0, 0755},
55         {"info",                {Qinfo, 0, QTFILE}, 0, 0755},
56         {"power",               {Qpower, 0, QTFILE}, 0, 0755},
57 };
58
59 /* this is might be necessary when updating mapping structures: context-cache,
60  * IOTLB or IEC. */
61 static inline void write_buffer_flush(struct iommu *iommu)
62 {
63         uint32_t cmd, status;
64
65         if (!iommu->rwbf)
66                 return;
67
68         cmd = read32(iommu->regio + DMAR_GCMD_REG) | DMA_GCMD_WBF;
69         write32(cmd, iommu->regio + DMAR_GCMD_REG);
70
71         /* read status */
72         do {
73                 status = read32(iommu->regio + DMAR_GSTS_REG);
74         } while (status & DMA_GSTS_WBFS);
75 }
76
77 /* this is necessary when caching mode is supported.
78  * ASSUMES: No pending flush requests. This is a problem only if other function
79  * is used to perform the flush. */
80 static inline void iotlb_flush(struct iommu *iommu, uint16_t did)
81 {
82         uint64_t cmd, status;
83
84         cmd = 0x0
85         | DMA_TLB_IVT        /* issue the flush command */
86         | DMA_TLB_DSI_FLUSH  /* DID specific shootdown */
87         | DMA_TLB_READ_DRAIN
88         | DMA_TLB_WRITE_DRAIN
89         | DMA_TLB_DID(did);
90         write64(cmd, iommu->regio + iommu->iotlb_cmd_offset);
91
92         /* read status */
93         do {
94                 status = read64(iommu->regio + iommu->iotlb_cmd_offset);
95                 status >>= 63; /* bit 64 (IVT): gets cleared on completion */
96         } while (status);
97 }
98
99 static inline struct root_entry *get_root_entry(physaddr_t paddr)
100 {
101         return (struct root_entry *) KADDR(paddr);
102 }
103
104 static inline struct context_entry *get_context_entry(physaddr_t paddr)
105 {
106         return (struct context_entry *) KADDR(paddr);
107 }
108
109 /* iommu is not modified by this function or its callees. */
110 static physaddr_t ct_init(struct iommu *iommu, uint16_t did)
111 {
112         struct context_entry *cte;
113         physaddr_t ct;
114         uint8_t ctx_aw = CTX_AW_L4;
115
116         cte = (struct context_entry *) kpage_zalloc_addr();
117         ct = PADDR(cte);
118
119         for (int i = 0; i < 32 * 8; i++, cte++) { // device * func
120                 /* initializations such as the domain */
121                 cte->hi = 0
122                         | (did << CTX_HI_DID_SHIFT) // DID bit: 72 to 87
123                         | (ctx_aw << CTX_HI_AW_SHIFT); // AW
124                 cte->lo = 0
125                         | (0x2 << CTX_LO_TRANS_SHIFT) // 0x2: pass through
126                         | (0x1 << CTX_LO_FPD_SHIFT) // disable faults
127                         | (0x1 << CTX_LO_PRESENT_SHIFT); // is present
128         }
129
130         return ct;
131 }
132
133 /* Get a new root_entry table. Allocates all context entries.
134  * iommu is not modified by this function or its callees. */
135 static physaddr_t rt_init(struct iommu *iommu, uint16_t did)
136 {
137         struct root_entry *rte;
138         physaddr_t rt;
139         physaddr_t ct;
140
141         /* Page Align = 0x1000 */
142         rte = (struct root_entry *) kpage_zalloc_addr();
143         rt = PADDR(rte);
144
145         /* create context table */
146         for (int i = 0; i < 256; i++, rte++) {
147                 ct = ct_init(iommu, did);
148                 rte->hi = 0;
149                 rte->lo = 0
150                         | ct
151                         | (0x1 << RT_LO_PRESENT_SHIFT);
152         }
153
154         return rt;
155 }
156
157 static struct context_entry *get_ctx_for(int bus, int dev, int func,
158         physaddr_t roottable)
159 {
160         struct root_entry *rte;
161         physaddr_t cte_phy;
162         struct context_entry *cte;
163         uint32_t offset = 0;
164
165         rte = get_root_entry(roottable) + bus;
166
167         cte_phy = rte->lo & 0xFFFFFFFFFFFFF000;
168         cte = get_context_entry(cte_phy);
169
170         offset = (dev * 8) + func;
171         cte += offset;
172
173         return cte;
174 }
175
176 /* The process pid is used as the Domain ID (DID) */
177 static void setup_page_tables(struct proc *p, struct pci_device *d)
178 {
179         uint32_t cmd, status;
180         uint16_t did = p->pid; /* casts down to 16-bit */
181         struct iommu *iommu = d->iommu;
182         struct context_entry *cte =
183                 get_ctx_for(d->bus, d->dev, d->func, iommu->roottable);
184
185         /* Mark the entry as not present */
186         cte->lo &= ~0x1;
187         write_buffer_flush(iommu);
188         iotlb_flush(iommu, IOMMU_DID_DEFAULT);
189
190         cte->hi = 0
191                 | (did << CTX_HI_DID_SHIFT) // DID bit: 72 to 87
192                 | (CTX_AW_L4 << CTX_HI_AW_SHIFT); // AW
193
194         cte->lo = PTE_ADDR(p->env_pgdir.eptp)
195                 | (0x0 << CTX_LO_TRANS_SHIFT)
196                 | (0x1 << CTX_LO_FPD_SHIFT) // disable faults
197                 | (0x1 << CTX_LO_PRESENT_SHIFT); /* mark present */
198 }
199
200 /* TODO: We should mark the entry as not present to block any stray DMAs from
201  * reaching the kernel. To force a re-attach the device to the kernel, we can
202  * use pid 0. */
203 static void teardown_page_tables(struct proc *p, struct pci_device *d)
204 {
205         uint16_t did = IOMMU_DID_DEFAULT;
206         struct iommu *iommu = d->iommu;
207         struct context_entry *cte =
208                 get_ctx_for(d->bus, d->dev, d->func, iommu->roottable);
209
210         /* Mark the entry as not present */
211         cte->lo &= ~0x1;
212         write_buffer_flush(iommu);
213         iotlb_flush(iommu, p->pid);
214
215         cte->hi = 0
216                 | (did << CTX_HI_DID_SHIFT) // DID bit: 72 to 87
217                 | (CTX_AW_L4 << CTX_HI_AW_SHIFT); // AW
218
219         cte->lo = 0 /* assumes page alignment */
220                 | (0x2 << CTX_LO_TRANS_SHIFT)
221                 | (0x1 << CTX_LO_FPD_SHIFT) // disable faults
222                 | (0x1 << CTX_LO_PRESENT_SHIFT); /* mark present */
223 }
224
225 static bool _iommu_enable(struct iommu *iommu)
226 {
227         uint32_t cmd, status;
228
229         spin_lock_irqsave(&iommu->iommu_lock);
230
231         /* write the root table address */
232         write64(iommu->roottable, iommu->regio + DMAR_RTADDR_REG);
233
234         // TODO: flush IOTLB if reported as necessary by cap register
235         // TODO: issue TE only once
236
237         /* set root table - needs to be done first */
238         cmd = DMA_GCMD_SRTP;
239         write32(cmd, iommu->regio + DMAR_GCMD_REG);
240
241         /* enable translation */
242         cmd = DMA_GCMD_TE;
243         write32(cmd, iommu->regio + DMAR_GCMD_REG);
244
245         /* read status */
246         status = read32(iommu->regio + DMAR_GSTS_REG);
247
248         spin_unlock_irqsave(&iommu->iommu_lock);
249
250         return status & DMA_GSTS_TES;
251 }
252
253 void iommu_enable(void)
254 {
255         struct iommu *iommu;
256
257         /* races are possible; add a global lock? */
258         if (iommu_status())
259                 return;
260
261         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
262                 _iommu_enable(iommu);
263 }
264
265 static bool _iommu_disable(struct iommu *iommu)
266 {
267         uint32_t cmd, status;
268
269         spin_lock_irqsave(&iommu->iommu_lock);
270
271         /* write the root table address */
272         write64(iommu->roottable, iommu->regio + DMAR_RTADDR_REG);
273
274         // TODO: flush IOTLB if reported as necessary by cap register
275         /* disable translation */
276         cmd = 0;
277         write32(cmd, iommu->regio + DMAR_GCMD_REG);
278
279         /* read status */
280         status = read32(iommu->regio + DMAR_GSTS_REG);
281
282         spin_unlock_irqsave(&iommu->iommu_lock);
283
284         return status & DMA_GSTS_TES;
285 }
286
287 void iommu_disable(void)
288 {
289         struct iommu *iommu;
290
291         /* races are possible; add a global lock? */
292         if (!iommu_status())
293                 return;
294
295         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
296                 _iommu_disable(iommu);
297 }
298
299 static bool _iommu_status(struct iommu *iommu)
300 {
301         uint32_t status = 0;
302
303         spin_lock_irqsave(&iommu->iommu_lock);
304
305         /* read status */
306         status = read32(iommu->regio + DMAR_GSTS_REG);
307
308         spin_unlock_irqsave(&iommu->iommu_lock);
309
310         return status & DMA_GSTS_TES;
311 }
312
313 bool iommu_status(void)
314 {
315         struct iommu *iommu;
316
317         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
318                 if (_iommu_status(iommu))
319                         return true;
320
321         return false;
322 }
323
324 /* Helpers for set/get/init PCI device (BDF) <=> Process map */
325 static bool proc_already_in_iommu_list(struct iommu *iommu, struct proc *p)
326 {
327         struct proc *proc_iter;
328
329         TAILQ_FOREACH(proc_iter, &iommu->procs, iommu_link)
330                 if (proc_iter == p)
331                         return true;
332
333         return false;
334 }
335
336 /* this function retains a KREF to struct proc for each assigned PCI device */
337 static bool assign_device(int bus, int dev, int func, pid_t pid)
338 {
339         int tbdf = MKBUS(BusPCI, bus, dev, func);
340         struct pci_device *d = pci_match_tbdf(tbdf);
341         struct proc *p = pid2proc(pid);
342
343         if (!p)
344                 error(EIO, "cannot find pid %d\n", pid);
345
346         if (pid == 1) {
347                 proc_decref(p);
348                 error(EIO, "device passthru not supported for pid = 1");
349         }
350
351         if (!d) {
352                 proc_decref(p);
353                 error(EIO, "cannot find dev %x:%x.%x\n", bus, dev, func);
354         }
355
356         /* grab locks */
357         spin_lock_irqsave(&p->proc_lock);
358         spin_lock_irqsave(&d->iommu->iommu_lock);
359
360         if (d->proc_owner) {
361                 spin_unlock_irqsave(&d->iommu->iommu_lock);
362                 spin_unlock_irqsave(&p->proc_lock);
363                 proc_decref(p);
364                 error(EIO, "dev already assigned to pid = %d\n", p->pid);
365         }
366
367         d->proc_owner = p; /* protected by iommu_lock */
368         d->iommu->num_assigned_devs += 1; /* protected by iommu_lock */
369
370         /* add device to list in struct proc */
371         TAILQ_INSERT_TAIL(&p->pci_devices, d, proc_link);
372
373         /* add proc to list in struct iommu */
374         if (!proc_already_in_iommu_list(d->iommu, p))
375                 TAILQ_INSERT_TAIL(&d->iommu->procs, p, iommu_link);
376
377         /* setup the actual page tables */
378         setup_page_tables(p, d);
379
380         /* release locks */
381         spin_unlock_irqsave(&d->iommu->iommu_lock);
382         spin_unlock_irqsave(&p->proc_lock);
383
384         return true;
385 }
386
387 static bool unassign_device(int bus, int dev, int func)
388 {
389         int tbdf = MKBUS(BusPCI, bus, dev, func);
390         struct pci_device *d = pci_match_tbdf(tbdf);
391         struct proc *p;
392
393         if (!d)
394                 error(EIO, "cannot find dev %x:%x.%x", bus, dev, func);
395
396         /* TODO: this will break if there are multiple threads calling unassign.
397          * Might require rethinking the lock ordering and synchronization */
398         p = d->proc_owner;
399         if (!p)
400                 error(EIO, "%x:%x.%x is not assigned to any process",
401                         bus, dev, func);
402
403         /* grab locks */
404         spin_lock_irqsave(&p->proc_lock);
405         spin_lock_irqsave(&d->iommu->iommu_lock);
406
407         /* teardown page table association */
408         teardown_page_tables(p, d);
409
410         d->proc_owner = NULL; /* protected by iommu_lock */
411         d->iommu->num_assigned_devs -= 1; /* protected by iommu_lock */
412
413         /* remove device from list in struct proc */
414         TAILQ_REMOVE(&p->pci_devices, d, proc_link);
415
416         /* remove proc from list in struct iommu, if active device passthru */
417         if (TAILQ_EMPTY(&p->pci_devices))
418                 TAILQ_REMOVE(&d->iommu->procs, p, iommu_link);
419
420         /* release locks */
421         spin_unlock_irqsave(&d->iommu->iommu_lock);
422         spin_unlock_irqsave(&p->proc_lock);
423
424         /* decrement KREF for this PCI device */
425         proc_decref(p);
426
427         return true;
428 }
429
430 void iommu_process_cleanup(struct proc *p)
431 {
432         struct pci_device *pcidev;
433
434         // TODO: grab proc_lock
435         TAILQ_FOREACH(pcidev, &p->pci_devices, proc_link)
436                 unassign_device(pcidev->bus, pcidev->dev, pcidev->func);
437 }
438
439 static int write_add_dev(char *va, size_t n)
440 {
441         int bus, dev, func, err;
442         pid_t pid;
443
444         err = sscanf(va, "%x:%x.%x %d\n", &bus, &dev, &func, &pid);
445
446         if (err != 4)
447                 error(EIO,
448                   IOMMU "error parsing #iommu/attach; items parsed: %d", err);
449
450         if (pid == 1)
451                 error(EIO, IOMMU "device passthru not supported for pid = 1");
452
453         if (!assign_device(bus, dev, func, pid))
454                 error(EIO, "passthru failed");
455
456         return n;
457 }
458
459 static int write_remove_dev(char *va, size_t n)
460 {
461         int bus, dev, func, err;
462
463         err = sscanf(va, "%x:%x.%x\n", &bus, &dev, &func);
464
465         if (err != 3)
466                 error(EIO,
467                   IOMMU "error parsing #iommu/detach; items parsed: %d", err);
468
469         unassign_device(bus, dev, func);
470
471         return n;
472 }
473
474 static int write_power(char *va, size_t n)
475 {
476         int err;
477
478         if (!strcmp(va, "enable") || !strcmp(va, "on")) {
479                 iommu_enable();
480                 return n;
481         } else if (!strcmp(va, "disable") || !strcmp(va, "off")) {
482                 iommu_disable();
483                 return n;
484         } else
485                 return n;
486 }
487
488 static void _open_mappings(struct sized_alloc *sza, struct proc *proc)
489 {
490         struct pci_device *pcidev;
491
492         sza_printf(sza, "\tpid = %d\n", proc->pid);
493         TAILQ_FOREACH(pcidev, &proc->pci_devices, proc_link) {
494                 sza_printf(sza, "\t\tdevice = %x:%x.%x\n", pcidev->bus,
495                                 pcidev->dev, pcidev->func);
496         }
497 }
498
499 static struct sized_alloc *open_mappings(void)
500 {
501         struct iommu *iommu;
502         struct proc *proc;
503         struct sized_alloc *sza = sized_kzmalloc(BUFFERSZ, MEM_WAIT);
504
505         TAILQ_FOREACH(iommu, &iommu_list, iommu_link) {
506                 spin_lock_irqsave(&iommu->iommu_lock);
507
508                 sza_printf(sza, "Mappings for iommu@%p\n", iommu);
509                 if (TAILQ_EMPTY(&iommu->procs))
510                         sza_printf(sza, "\t<empty>\n");
511                 else
512                         TAILQ_FOREACH(proc, &iommu->procs, iommu_link)
513                                 _open_mappings(sza, proc);
514
515                 spin_unlock_irqsave(&iommu->iommu_lock);
516         }
517
518         return sza;
519 }
520
521 static void _open_info(struct iommu *iommu, struct sized_alloc *sza)
522 {
523         uint64_t value;
524
525         sza_printf(sza, "\niommu@%p\n", iommu);
526         sza_printf(sza, "\trba = %p\n", iommu->rba);
527         sza_printf(sza, "\tsupported = %s\n", iommu->supported ? "yes" : "no");
528         sza_printf(sza, "\tnum_assigned_devs = %d\n", iommu->num_assigned_devs);
529         sza_printf(sza, "\tregspace = %p\n", iommu->regio);
530         sza_printf(sza, "\thost addr width (dmar) = %d\n", iommu->haw_dmar);
531         sza_printf(sza, "\thost addr width (cap[mgaw]) = %d\n",
532                 iommu->haw_cap);
533         value = read32(iommu->regio + DMAR_VER_REG);
534         sza_printf(sza, "\tversion = 0x%x\n", value);
535
536         value = read64(iommu->regio + DMAR_CAP_REG);
537         sza_printf(sza, "\tcapabilities = %p\n", value);
538         sza_printf(sza, "\t\tmgaw: %d\n", cap_mgaw(value));
539         sza_printf(sza, "\t\tsagaw (paging level): 0x%x\n", cap_sagaw(value));
540         sza_printf(sza, "\t\tcaching mode: %s (%d)\n", cap_caching_mode(value) ?
541                 "yes" : "no", cap_caching_mode(value));
542         sza_printf(sza, "\t\tzlr: 0x%x\n", cap_zlr(value));
543         sza_printf(sza, "\t\trwbf: %s\n", cap_rwbf(value) ? "required"
544                                                           : "not required");
545         sza_printf(sza, "\t\tnum domains: %d\n", cap_ndoms(value));
546         sza_printf(sza, "\t\tsupports protected high-memory region: %s\n",
547                 cap_phmr(value) ? "yes" : "no");
548         sza_printf(sza, "\t\tsupports Protected low-memory region: %s\n",
549                 cap_plmr(value) ? "yes" : "no");
550
551         value = read64(iommu->regio + DMAR_ECAP_REG);
552         sza_printf(sza, "\text. capabilities = %p\n", value);
553         sza_printf(sza, "\t\tpass through: %s\n",
554                 ecap_pass_through(value) ? "yes" : "no");
555         sza_printf(sza, "\t\tdevice iotlb: %s\n",
556                 ecap_dev_iotlb_support(value) ? "yes" : "no");
557         sza_printf(sza, "\t\tiotlb register offset: 0x%x\n",
558                 ecap_iotlb_offset(value));
559         sza_printf(sza, "\t\tsnoop control: %s\n",
560                 ecap_sc_support(value) ? "yes" : "no");
561         sza_printf(sza, "\t\tcoherency: %s\n",
562                 ecap_coherent(value) ? "yes" : "no");
563         sza_printf(sza, "\t\tqueue invalidation support: %s\n",
564                 ecap_qis(value) ? "yes" : "no");
565         sza_printf(sza, "\t\tinterrupt remapping support: %s\n",
566                 ecap_ir_support(value) ? "yes" : "no");
567         sza_printf(sza, "\t\textended interrupt mode: 0x%x\n",
568                 ecap_eim_support(value));
569
570         value = read32(iommu->regio + DMAR_GSTS_REG);
571         sza_printf(sza, "\tglobal status = 0x%x\n", value);
572         sza_printf(sza, "\t\ttranslation: %s\n",
573                 value & DMA_GSTS_TES ? "enabled" : "disabled");
574         sza_printf(sza, "\t\troot table: %s\n",
575                 value & DMA_GSTS_RTPS ? "set" : "not set");
576
577         value = read64(iommu->regio + DMAR_RTADDR_REG);
578         sza_printf(sza, "\troot entry table = %p (phy) or %p (vir)\n",
579                         value, KADDR(value));
580 }
581
582 static struct sized_alloc *open_info(void)
583 {
584         struct sized_alloc *sza = sized_kzmalloc(BUFFERSZ, MEM_WAIT);
585         uint64_t value;
586         struct iommu *iommu;
587
588         sza_printf(sza, "driver info:\n");
589
590         value = IOMMU_DID_DEFAULT;
591         sza_printf(sza, "\tdefault did = %d\n", value);
592         sza_printf(sza, "\tstatus = %s\n",
593                 iommu_status() ? "enabled" : "disabled");
594
595         TAILQ_FOREACH(iommu, &iommu_list, iommu_link) {
596                 _open_info(iommu, sza);
597         }
598
599         return sza;
600 }
601
602 static struct sized_alloc *open_power(void)
603 {
604         struct sized_alloc *sza = sized_kzmalloc(BUFFERSZ, MEM_WAIT);
605         uint64_t value;
606         struct iommu *iommu;
607
608         sza_printf(sza, "IOMMU status: %s\n\n",
609                 iommu_status() ? "enabled" : "disabled");
610
611         sza_printf(sza,
612              "Write 'enable' or 'disable' OR 'on' or 'off' to change status\n");
613
614         return sza;
615 }
616
617 static char *devname(void)
618 {
619         return iommudevtab.name;
620 }
621
622 static struct chan *iommuattach(char *spec)
623 {
624         return devattach(devname(), spec);
625 }
626
627 static struct walkqid *iommuwalk(struct chan *c, struct chan *nc, char **name,
628                          unsigned int nname)
629 {
630         return devwalk(c, nc, name, nname, iommudir,
631                        ARRAY_SIZE(iommudir), devgen);
632 }
633
634 static size_t iommustat(struct chan *c, uint8_t *dp, size_t n)
635 {
636         return devstat(c, dp, n, iommudir, ARRAY_SIZE(iommudir), devgen);
637 }
638
639 static struct chan *iommuopen(struct chan *c, int omode)
640 {
641         switch (c->qid.path) {
642         case Qmappings:
643                 c->synth_buf = open_mappings();
644                 break;
645         case Qinfo:
646                 c->synth_buf = open_info();
647                 break;
648         case Qpower:
649                 c->synth_buf = open_power();
650                 break;
651         case Qadddev:
652         case Qremovedev:
653         case Qdir:
654         default:
655                 break;
656         }
657
658         return devopen(c, omode, iommudir, ARRAY_SIZE(iommudir), devgen);
659 }
660
661 /*
662  * All files are synthetic. Hence we do not need to implement any close
663  * function.
664  */
665 static void iommuclose(struct chan *c)
666 {
667         switch (c->qid.path) {
668         case Qmappings:
669         case Qinfo:
670         case Qpower:
671                 kfree(c->synth_buf);
672                 c->synth_buf = NULL;
673                 break;
674         case Qadddev:
675         case Qremovedev:
676         case Qdir:
677         default:
678                 break;
679         }
680 }
681
682 static size_t iommuread(struct chan *c, void *va, size_t n, off64_t offset)
683 {
684         struct sized_alloc *sza = c->synth_buf;
685
686         switch (c->qid.path) {
687         case Qdir:
688                 return devdirread(c, va, n, iommudir,
689                                   ARRAY_SIZE(iommudir), devgen);
690         case Qadddev:
691                 return readstr(offset, va, n,
692                     "write format: xx:yy.z pid\n"
693                     "   xx  = bus (in hex)\n"
694                     "   yy  = device (in hex)\n"
695                     "   z   = function (in hex)\n"
696                     "   pid = process pid\n"
697                     "\nexample:\n"
698                     "$ echo 00:1f.2 13 >\\#iommu/attach\n");
699         case Qremovedev:
700                 return readstr(offset, va, n,
701                     "write format: xx:yy.z\n"
702                     "   xx  = bus (in hex)\n"
703                     "   yy  = device (in hex)\n"
704                     "   z   = function (in hex)\n"
705                     "\nexample:\n"
706                     "$ echo 00:1f.2 >\\#iommu/detach\n");
707         case Qmappings:
708         case Qinfo:
709         case Qpower:
710                 return readstr(offset, va, n, sza->buf);
711         default:
712                 error(EIO, "read: qid %d is impossible", c->qid.path);
713         }
714
715         return -1; /* not reached */
716 }
717
718 static size_t iommuwrite(struct chan *c, void *va, size_t n, off64_t offset)
719 {
720         int err = -1;
721
722         switch (c->qid.path) {
723         case Qadddev:
724                 if (!iommu_supported())
725                         error(EROFS, IOMMU "not supported");
726                 err = write_add_dev(va, n);
727                 break;
728         case Qremovedev:
729                 if (!iommu_supported())
730                         error(EROFS, IOMMU "not supported");
731                 err = write_remove_dev(va, n);
732                 break;
733         case Qpower:
734                 err = write_power(va, n);
735                 break;
736         case Qmappings:
737         case Qinfo:
738         case Qdir:
739                 error(EROFS, IOMMU "cannot modify");
740         default:
741                 error(EIO, "write: qid %d is impossible", c->qid.path);
742         }
743
744         return err;
745 }
746
747 /* Iterate over all IOMMUs and make sure the "rba" present in DRHD are unique */
748 static bool iommu_asset_unique_regio(void)
749 {
750         struct iommu *outer, *inner;
751         uint64_t rba;
752         bool result = true;
753
754         TAILQ_FOREACH(outer, &iommu_list, iommu_link) {
755                 rba = outer->rba;
756
757                 TAILQ_FOREACH(inner, &iommu_list, iommu_link) {
758                         if (outer != inner && rba == inner->rba) {
759                                 outer->supported = false;
760                                 result = false;
761                         }
762                 }
763         }
764
765         return result;
766 }
767
768 static bool iommu_assert_required_capabilities(struct iommu *iommu)
769 {
770         uint64_t cap, ecap;
771         bool support, result;
772
773         if (!iommu || !iommu->regio)
774                 return false;
775
776         cap = read64(iommu->regio + DMAR_CAP_REG);
777         ecap = read64(iommu->regio + DMAR_ECAP_REG);
778         result = true; /* default */
779
780         support = (cap_sagaw(cap) & 0x4) >> 2;
781         if (!support) {
782                 printk(IOMMU "%p: unsupported paging level: 0x%x\n",
783                         iommu, cap_sagaw(cap));
784                 result = false;
785         }
786
787         support = cap_super_page_val(cap) & 0x1;
788         if (!support) {
789                 printk(IOMMU "%p: 1GB super pages not supported\n", iommu);
790                 result = false;
791         }
792
793         support = ecap_pass_through(ecap);
794         if (!support) {
795                 printk(IOMMU "%p: pass-through translation type in context entries not supported\n", iommu);
796                 result = false;
797         }
798
799         /* max haw reported by iommu */
800         iommu->haw_cap = cap_mgaw(cap);
801         if (iommu->haw_cap != iommu->haw_dmar) {
802                 printk(IOMMU "%p: HAW mismatch; DAMR reports %d, CAP reports %d\n",
803                         iommu, iommu->haw_dmar, iommu->haw_cap);
804         }
805
806         /* mark the iommu as not supported, if any required cap is present */
807         if (!result)
808                 iommu->supported = false;
809
810         return result;
811 }
812
813 static void iommu_assert_all(void)
814 {
815         struct iommu *iommu;
816
817         if (!iommu_asset_unique_regio())
818                 warn(IOMMU "same register base addresses detected");
819
820         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
821                 iommu_assert_required_capabilities(iommu);
822 }
823
824 static void iommu_populate_fields(void)
825 {
826         struct iommu *iommu;
827
828         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
829                 iommu->roottable = rt_init(iommu, IOMMU_DID_DEFAULT);
830 }
831
832 /* Run this function after all individual IOMMUs are initialized. */
833 void iommu_initialize_global(void)
834 {
835         if (!is_initialized)
836                 return;
837
838         /* fill the supported field in struct iommu */
839         run_once(iommu_assert_all());
840         run_once(iommu_populate_fields());
841
842         iommu_enable();
843 }
844
845 /* should only be called after all iommus are initialized */
846 bool iommu_supported(void)
847 {
848         struct iommu *iommu;
849
850         if (!is_initialized)
851                 return false;
852
853         /* return false if any of the iommus isn't supported  */
854         TAILQ_FOREACH(iommu, &iommu_list, iommu_link)
855                 if (!iommu->supported)
856                         return false;
857
858         return true;
859 }
860
861 /* grabs the iommu of the first DRHD with INCLUDE_PCI_ALL */
862 struct iommu *get_default_iommu(void)
863 {
864         struct Dmar *dt;
865
866         /* dmar is a global variable; see acpi.h */
867         if (dmar == NULL)
868                 return NULL;
869
870         dt = dmar->tbl;
871         for (int i = 0; i < dmar->nchildren; i++) {
872                 struct Atable *at = dmar->children[i];
873                 struct Drhd *drhd = at->tbl;
874
875                 if (drhd->all & 1)
876                         return &drhd->iommu;
877         }
878
879         return NULL;
880 }
881
882 void iommu_map_pci_devices(void)
883 {
884         struct pci_device *pci_iter;
885         struct iommu *iommu = get_default_iommu();
886
887         if (!iommu)
888                 return;
889
890         /* set the default iommu */
891         STAILQ_FOREACH(pci_iter, &pci_devices, all_dev)
892                 pci_iter->iommu = iommu;
893
894         // TODO: parse devscope and assign scoped iommus
895 }
896
897 /* This is called from acpi.c to initialize struct iommu.
898  * The actual IOMMU hardware is not touch or configured in any way. */
899 void iommu_initialize(struct iommu *iommu, uint8_t haw, uint64_t rba)
900 {
901         is_initialized = true;
902
903         /* initialize the struct */
904         TAILQ_INIT(&iommu->procs);
905         spinlock_init_irqsave(&iommu->iommu_lock);
906         iommu->rba = rba;
907         iommu->regio = (void __iomem *) vmap_pmem_nocache(rba, VTD_PAGE_SIZE);
908         iommu->supported = true; /* this gets updated by iommu_supported() */
909         iommu->num_assigned_devs = 0;
910         iommu->haw_dmar = haw;
911
912         /* add the iommu to the list of all discovered iommu */
913         TAILQ_INSERT_TAIL(&iommu_list, iommu, iommu_link);
914 }
915
916 static void iommuinit(void)
917 {
918         if (iommu_supported())
919                 printk(IOMMU "initialized\n");
920         else
921                 printk(IOMMU "not supported\n");
922 }
923
924 struct dev iommudevtab __devtab = {
925         .name       = "iommu",
926         .reset      = devreset,
927         .init       = iommuinit,
928         .shutdown   = devshutdown,
929         .attach     = iommuattach,
930         .walk       = iommuwalk,
931         .stat       = iommustat,
932         .open       = iommuopen,
933         .create     = devcreate,
934         .close      = iommuclose,
935         .read       = iommuread,
936         .bread      = devbread,
937         .write      = iommuwrite,
938         .bwrite     = devbwrite,
939         .remove     = devremove,
940         .wstat      = devwstat,
941 };