2 * Jailhouse, a Linux-based partitioning hypervisor
4 * Copyright (c) Valentine Sinitsyn, 2014, 2015
5 * Copyright (c) Siemens AG, 2016
8 * Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
9 * Jan Kiszka <jan.kiszka@siemens.com>
11 * Commands posting and event log parsing code, as well as many defines
12 * were adapted from Linux's amd_iommu driver written by Joerg Roedel
15 * This work is licensed under the terms of the GNU GPL, version 2. See
16 * the COPYING file in the top-level directory.
19 #include <jailhouse/cell.h>
20 #include <jailhouse/cell-config.h>
21 #include <jailhouse/control.h>
22 #include <jailhouse/mmio.h>
23 #include <jailhouse/pci.h>
24 #include <jailhouse/printk.h>
25 #include <jailhouse/string.h>
26 #include <asm/amd_iommu.h>
28 #include <asm/iommu.h>
30 #define CAPS_IOMMU_HEADER_REG 0x00
31 #define CAPS_IOMMU_EFR_SUP (1 << 27)
32 #define CAPS_IOMMU_BASE_LOW_REG 0x04
33 #define CAPS_IOMMU_ENABLE (1 << 0)
34 #define CAPS_IOMMU_BASE_HI_REG 0x08
36 #define ACPI_REPORTING_HE_SUP (1 << 7)
38 #define AMD_DEV_TABLE_BASE_REG 0x0000
39 #define AMD_CMD_BUF_BASE_REG 0x0008
40 #define AMD_EVT_LOG_BASE_REG 0x0010
41 #define AMD_CONTROL_REG 0x0018
42 #define AMD_CONTROL_IOMMU_EN (1UL << 0)
43 #define AMD_CONTROL_EVT_LOG_EN (1UL << 2)
44 #define AMD_CONTROL_EVT_INT_EN (1UL << 3)
45 #define AMD_CONTROL_COMM_WAIT_INT_EN (1UL << 4)
46 #define AMD_CONTROL_CMD_BUF_EN (1UL << 12)
47 #define AMD_CONTROL_SMIF_EN (1UL << 22)
48 #define AMD_CONTROL_SMIFLOG_EN (1UL << 24)
49 #define AMD_CONTROL_SEG_EN_MASK BIT_MASK(36, 34)
50 #define AMD_CONTROL_SEG_EN_SHIFT 34
51 #define AMD_EXT_FEATURES_REG 0x0030
52 #define AMD_EXT_FEAT_HE_SUP (1UL << 7)
53 #define AMD_EXT_FEAT_SMI_FSUP_MASK BIT_MASK(17, 16)
54 #define AMD_EXT_FEAT_SMI_FSUP_SHIFT 16
55 #define AMD_EXT_FEAT_SMI_FRC_MASK BIT_MASK(20, 18)
56 #define AMD_EXT_FEAT_SMI_FRC_SHIFT 18
57 #define AMD_EXT_FEAT_SEG_SUP_MASK BIT_MASK(39, 38)
58 #define AMD_EXT_FEAT_SEG_SUP_SHIFT 38
59 #define AMD_HEV_UPPER_REG 0x0040
60 #define AMD_HEV_LOWER_REG 0x0048
61 #define AMD_HEV_STATUS_REG 0x0050
62 #define AMD_HEV_VALID (1UL << 1)
63 #define AMD_HEV_OVERFLOW (1UL << 2)
64 #define AMD_SMI_FILTER0_REG 0x0060
65 #define AMD_SMI_FILTER_VALID (1UL << 16)
66 #define AMD_SMI_FILTER_LOCKED (1UL << 17)
67 #define AMD_DEV_TABLE_SEG1_REG 0x0100
68 #define AMD_CMD_BUF_HEAD_REG 0x2000
69 #define AMD_CMD_BUF_TAIL_REG 0x2008
70 #define AMD_EVT_LOG_HEAD_REG 0x2010
71 #define AMD_EVT_LOG_TAIL_REG 0x2018
72 #define AMD_STATUS_REG 0x2020
73 # define AMD_STATUS_EVT_OVERFLOW (1UL << 0)
74 # define AMD_STATUS_EVT_LOG_INT (1UL << 1)
75 # define AMD_STATUS_EVT_LOG_RUN (1UL << 3)
77 struct dev_table_entry {
79 } __attribute__((packed));
81 #define DTE_VALID (1UL << 0)
82 #define DTE_TRANSLATION_VALID (1UL << 1)
83 #define DTE_PAGING_MODE_4_LEVEL (4UL << 9)
84 #define DTE_IR (1UL << 61)
85 #define DTE_IW (1UL << 62)
87 #define DEV_TABLE_SEG_MAX 8
88 #define DEV_TABLE_SIZE 0x200000
98 } __attribute__((packed));
100 #define CMD_COMPL_WAIT 0x01
101 # define CMD_COMPL_WAIT_STORE (1 << 0)
102 # define CMD_COMPL_WAIT_INT (1 << 1)
104 #define CMD_INV_DEVTAB_ENTRY 0x02
106 #define CMD_INV_IOMMU_PAGES 0x03
107 # define CMD_INV_IOMMU_PAGES_SIZE (1 << 0)
108 # define CMD_INV_IOMMU_PAGES_PDE (1 << 1)
110 #define EVENT_TYPE_ILL_DEV_TAB_ENTRY 0x01
111 #define EVENT_TYPE_PAGE_TAB_HW_ERR 0x04
112 #define EVENT_TYPE_ILL_CMD_ERR 0x05
113 #define EVENT_TYPE_CMD_HW_ERR 0x06
114 #define EVENT_TYPE_IOTLB_INV_TIMEOUT 0x07
115 #define EVENT_TYPE_INV_PPR_REQ 0x09
117 #define BUF_LEN_EXPONENT_SHIFT 56
119 /* Allocate minimum space possible (4K or 256 entries) */
120 #define BUF_SIZE(name, entry) ((1UL << name##_LEN_EXPONENT) * \
123 #define CMD_BUF_LEN_EXPONENT 8
124 #define EVT_LOG_LEN_EXPONENT 8
126 #define CMD_BUF_SIZE BUF_SIZE(CMD_BUF, union buf_entry)
127 #define EVT_LOG_SIZE BUF_SIZE(EVT_LOG, union buf_entry)
129 #define BITS_PER_SHORT 16
131 #define AMD_IOMMU_MAX_PAGE_TABLE_LEVELS 4
133 static struct amd_iommu {
136 /* Command Buffer, Event Log */
137 unsigned char *cmd_buf_base;
138 unsigned char *evt_log_base;
140 void *devtable_segments[DEV_TABLE_SEG_MAX];
144 } iommu_units[JAILHOUSE_MAX_IOMMU_UNITS];
146 #define for_each_iommu(iommu) for (iommu = iommu_units; \
147 iommu < iommu_units + iommu_units_count; \
150 static unsigned int iommu_units_count;
153 * Interrupt remapping is not emulated on AMD,
154 * thus we have no MMIO to intercept.
156 unsigned int iommu_mmio_count_regions(struct cell *cell)
161 bool iommu_cell_emulates_ir(struct cell *cell)
166 static int amd_iommu_init_pci(struct amd_iommu *entry,
167 struct jailhouse_iommu *iommu)
169 u64 caps_header, hi, lo;
171 /* Check alignment */
172 if (iommu->size & (iommu->size - 1))
173 return trace_error(-EINVAL);
175 /* Check that EFR is supported */
176 caps_header = pci_read_config(iommu->amd_bdf, iommu->amd_base_cap, 4);
177 if (!(caps_header & CAPS_IOMMU_EFR_SUP))
178 return trace_error(-EIO);
180 lo = pci_read_config(iommu->amd_bdf,
181 iommu->amd_base_cap + CAPS_IOMMU_BASE_LOW_REG, 4);
182 hi = pci_read_config(iommu->amd_bdf,
183 iommu->amd_base_cap + CAPS_IOMMU_BASE_HI_REG, 4);
185 if (lo & CAPS_IOMMU_ENABLE &&
186 ((hi << 32) | lo) != (iommu->base | CAPS_IOMMU_ENABLE)) {
187 printk("FATAL: IOMMU %d config is locked in invalid state.\n",
189 return trace_error(-EPERM);
192 /* Should be configured by BIOS, but we want to be sure */
193 pci_write_config(iommu->amd_bdf,
194 iommu->amd_base_cap + CAPS_IOMMU_BASE_HI_REG,
195 (u32)(iommu->base >> 32), 4);
196 pci_write_config(iommu->amd_bdf,
197 iommu->amd_base_cap + CAPS_IOMMU_BASE_LOW_REG,
198 (u32)(iommu->base & 0xffffffff) | CAPS_IOMMU_ENABLE,
201 /* Allocate and map MMIO space */
202 entry->mmio_base = page_alloc(&remap_pool, PAGES(iommu->size));
203 if (!entry->mmio_base)
206 return paging_create(&hv_paging_structs, iommu->base, iommu->size,
207 (unsigned long)entry->mmio_base,
208 PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
209 PAGING_NON_COHERENT);
212 static int amd_iommu_init_features(struct amd_iommu *entry,
213 struct jailhouse_iommu *iommu)
215 u64 efr = mmio_read64(entry->mmio_base + AMD_EXT_FEATURES_REG);
216 unsigned char smi_filter_regcnt;
217 u64 val, ctrl_reg = 0, smi_freg = 0;
222 * Require SMI Filter support. Enable and lock filter but
223 * mark all entries as invalid to disable SMI delivery.
225 if (!(efr & AMD_EXT_FEAT_SMI_FSUP_MASK))
226 return trace_error(-EINVAL);
228 /* Figure out if hardware events are supported. */
229 if (iommu->amd_features)
230 entry->he_supported =
231 iommu->amd_features & ACPI_REPORTING_HE_SUP;
233 entry->he_supported = efr & AMD_EXT_FEAT_HE_SUP;
235 smi_filter_regcnt = (1 << (efr & AMD_EXT_FEAT_SMI_FRC_MASK) >>
236 AMD_EXT_FEAT_SMI_FRC_SHIFT);
237 for (n = 0; n < smi_filter_regcnt; n++) {
238 reg_base = entry->mmio_base + AMD_SMI_FILTER0_REG + (n << 3);
239 smi_freg = mmio_read64(reg_base);
241 if (!(smi_freg & AMD_SMI_FILTER_LOCKED)) {
243 * Program unlocked register the way we need:
244 * invalid and locked.
246 mmio_write64(reg_base, AMD_SMI_FILTER_LOCKED);
247 } else if (smi_freg & AMD_SMI_FILTER_VALID) {
249 * The register is locked and programed
250 * the way we don't want - error.
252 printk("ERROR: SMI Filter register %d is locked "
253 "and can't be reprogrammed.\n"
254 "Reboot and check no other component uses the "
255 "IOMMU %d.\n", n, entry->idx);
256 return trace_error(-EPERM);
259 * The register is locked, but programmed
260 * the way we need - OK to go.
264 ctrl_reg |= (AMD_CONTROL_SMIF_EN | AMD_CONTROL_SMIFLOG_EN);
266 /* Enable maximum Device Table segmentation possible */
267 entry->dev_tbl_seg_sup = (efr & AMD_EXT_FEAT_SEG_SUP_MASK) >>
268 AMD_EXT_FEAT_SEG_SUP_SHIFT;
269 if (entry->dev_tbl_seg_sup) {
270 val = (u64)entry->dev_tbl_seg_sup << AMD_CONTROL_SEG_EN_SHIFT;
271 ctrl_reg |= val & AMD_CONTROL_SEG_EN_MASK;
274 mmio_write64(entry->mmio_base + AMD_CONTROL_REG, ctrl_reg);
279 static int amd_iommu_init_buffers(struct amd_iommu *entry,
280 struct jailhouse_iommu *iommu)
282 /* Allocate and configure command buffer */
283 entry->cmd_buf_base = page_alloc(&mem_pool, PAGES(CMD_BUF_SIZE));
284 if (!entry->cmd_buf_base)
287 mmio_write64(entry->mmio_base + AMD_CMD_BUF_BASE_REG,
288 paging_hvirt2phys(entry->cmd_buf_base) |
289 ((u64)CMD_BUF_LEN_EXPONENT << BUF_LEN_EXPONENT_SHIFT));
291 entry->cmd_tail_ptr = 0;
293 /* Allocate and configure event log */
294 entry->evt_log_base = page_alloc(&mem_pool, PAGES(EVT_LOG_SIZE));
295 if (!entry->evt_log_base)
298 mmio_write64(entry->mmio_base + AMD_EVT_LOG_BASE_REG,
299 paging_hvirt2phys(entry->evt_log_base) |
300 ((u64)EVT_LOG_LEN_EXPONENT << BUF_LEN_EXPONENT_SHIFT));
305 static void amd_iommu_enable_command_processing(struct amd_iommu *iommu)
309 ctrl_reg = mmio_read64(iommu->mmio_base + AMD_CONTROL_REG);
310 ctrl_reg |= AMD_CONTROL_IOMMU_EN | AMD_CONTROL_CMD_BUF_EN |
311 AMD_CONTROL_EVT_LOG_EN | AMD_CONTROL_EVT_INT_EN;
312 mmio_write64(iommu->mmio_base + AMD_CONTROL_REG, ctrl_reg);
317 struct jailhouse_iommu *iommu;
318 struct amd_iommu *entry;
322 iommu = &system_config->platform_info.x86.iommu_units[0];
323 for (n = 0; iommu->base && n < iommu_count_units(); iommu++, n++) {
324 entry = &iommu_units[iommu_units_count];
328 /* Protect against accidental VT-d configs. */
330 return trace_error(-EINVAL);
332 printk("AMD IOMMU @0x%lx/0x%x\n", iommu->base, iommu->size);
334 /* Initialize PCI registers and MMIO space */
335 err = amd_iommu_init_pci(entry, iommu);
339 /* Setup IOMMU features */
340 err = amd_iommu_init_features(entry, iommu);
344 /* Initialize command buffer and event log */
345 err = amd_iommu_init_buffers(entry, iommu);
349 /* Enable the IOMMU */
350 amd_iommu_enable_command_processing(entry);
355 return iommu_cell_init(&root_cell);
358 int iommu_cell_init(struct cell *cell)
361 if (iommu_units_count == 0)
364 if (cell->id > 0xffff)
365 return trace_error(-ERANGE);
370 static void amd_iommu_completion_wait(struct amd_iommu *iommu);
372 static void amd_iommu_submit_command(struct amd_iommu *iommu,
373 union buf_entry *cmd, bool draining)
375 u32 head, next_tail, bytes_free;
376 unsigned char *cur_ptr;
378 head = mmio_read64(iommu->mmio_base + AMD_CMD_BUF_HEAD_REG);
379 next_tail = (iommu->cmd_tail_ptr + sizeof(*cmd)) % CMD_BUF_SIZE;
380 bytes_free = (head - next_tail) % CMD_BUF_SIZE;
382 /* Leave space for COMPLETION_WAIT that drains the buffer. */
383 if (bytes_free < (2 * sizeof(*cmd)) && !draining)
384 /* Drain the buffer */
385 amd_iommu_completion_wait(iommu);
387 cur_ptr = &iommu->cmd_buf_base[iommu->cmd_tail_ptr];
388 memcpy(cur_ptr, cmd, sizeof(*cmd));
390 /* Just to be sure. */
391 arch_paging_flush_cpu_caches(cur_ptr, sizeof(*cmd));
393 iommu->cmd_tail_ptr =
394 (iommu->cmd_tail_ptr + sizeof(*cmd)) % CMD_BUF_SIZE;
397 u64 amd_iommu_get_memory_region_flags(const struct jailhouse_memory *mem)
399 unsigned long flags = AMD_IOMMU_PTE_P;
401 if (!(mem->flags & JAILHOUSE_MEM_DMA))
404 if (mem->flags & JAILHOUSE_MEM_READ)
405 flags |= AMD_IOMMU_PTE_IR;
406 if (mem->flags & JAILHOUSE_MEM_WRITE)
407 flags |= AMD_IOMMU_PTE_IW;
412 int iommu_map_memory_region(struct cell *cell,
413 const struct jailhouse_memory *mem)
416 * Check that the address is not outside the scope of the page tables.
417 * With 4 levels, we only support 48 address bits.
419 if (mem->virt_start & BIT_MASK(63, 48))
420 return trace_error(-E2BIG);
422 /* vcpu_map_memory_region already did the actual work. */
426 int iommu_unmap_memory_region(struct cell *cell,
427 const struct jailhouse_memory *mem)
429 /* vcpu_map_memory_region already did the actual work. */
433 static void amd_iommu_inv_dte(struct amd_iommu *iommu, u16 device_id)
435 union buf_entry invalidate_dte = {{ 0 }};
437 invalidate_dte.raw32[0] = device_id;
438 invalidate_dte.type = CMD_INV_DEVTAB_ENTRY;
440 amd_iommu_submit_command(iommu, &invalidate_dte, false);
443 static struct dev_table_entry *get_dev_table_entry(struct amd_iommu *iommu,
444 u16 bdf, bool allocate)
446 struct dev_table_entry *devtable_seg;
447 u8 seg_idx, seg_shift;
448 u64 reg_base, reg_val;
452 if (!iommu->dev_tbl_seg_sup) {
455 seg_size = DEV_TABLE_SIZE;
457 seg_shift = BITS_PER_SHORT - iommu->dev_tbl_seg_sup;
458 seg_mask = ~((1 << seg_shift) - 1);
459 seg_idx = (seg_mask & bdf) >> seg_shift;
460 seg_size = DEV_TABLE_SIZE / (1 << iommu->dev_tbl_seg_sup);
464 * Device table segmentation is tricky in Jailhouse. As cells can
465 * "share" the IOMMU, we don't know maximum bdf in each segment
466 * because cells are initialized independently. Thus, we can't simply
467 * adjust segment sizes for our maximum bdfs.
469 * The next best things is to lazily allocate segments as we add
470 * device using maximum possible size for segments. In the worst case
471 * scenario, we waste around 2M chunk per IOMMU.
473 devtable_seg = iommu->devtable_segments[seg_idx];
475 /* If we are not permitted to allocate, just fail */
479 devtable_seg = page_alloc(&mem_pool, PAGES(seg_size));
482 iommu->devtable_segments[seg_idx] = devtable_seg;
485 reg_base = AMD_DEV_TABLE_BASE_REG;
487 reg_base = AMD_DEV_TABLE_SEG1_REG + (seg_idx - 1) * 8;
489 /* Size in Kbytes = (m + 1) * 4, see Sect 3.3.6 */
490 reg_val = paging_hvirt2phys(devtable_seg) |
491 (seg_size / PAGE_SIZE - 1);
492 mmio_write64(iommu->mmio_base + reg_base, reg_val);
495 return &devtable_seg[bdf & ~seg_mask];
498 int iommu_add_pci_device(struct cell *cell, struct pci_device *device)
500 struct dev_table_entry *dte = NULL;
501 struct amd_iommu *iommu;
505 if (iommu_units_count == 0)
508 if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
511 if (device->info->iommu >= JAILHOUSE_MAX_IOMMU_UNITS)
512 return trace_error(-ERANGE);
514 iommu = &iommu_units[device->info->iommu];
515 bdf = device->info->bdf;
517 dte = get_dev_table_entry(iommu, bdf, true);
521 memset(dte, 0, sizeof(*dte));
524 dte->raw64[1] = cell->id & 0xffff;
526 /* Translation information */
527 dte->raw64[0] = DTE_IR | DTE_IW |
528 paging_hvirt2phys(cell->arch.svm.npt_iommu_structs.root_table) |
529 DTE_PAGING_MODE_4_LEVEL | DTE_TRANSLATION_VALID | DTE_VALID;
531 /* TODO: Interrupt remapping. For now, just forward them unmapped. */
533 /* Flush caches, just to be sure. */
534 arch_paging_flush_cpu_caches(dte, sizeof(*dte));
536 amd_iommu_inv_dte(iommu, bdf);
541 void iommu_remove_pci_device(struct pci_device *device)
543 struct dev_table_entry *dte = NULL;
544 struct amd_iommu *iommu;
548 if (iommu_units_count == 0)
551 if (device->info->type == JAILHOUSE_PCI_TYPE_IVSHMEM)
554 iommu = &iommu_units[device->info->iommu];
555 bdf = device->info->bdf;
557 dte = get_dev_table_entry(iommu, bdf, false);
562 * Set Mode to 0 (translation disabled) and clear IR and IW to block
563 * DMA requests until the entry is reprogrammed for its new owner.
565 dte->raw64[0] = DTE_VALID | DTE_TRANSLATION_VALID;
567 /* Flush caches, just to be sure. */
568 arch_paging_flush_cpu_caches(dte, sizeof(*dte));
570 amd_iommu_inv_dte(iommu, bdf);
573 void iommu_cell_exit(struct cell *cell)
577 static void wait_for_zero(volatile u64 *sem, unsigned long mask)
583 static void amd_iommu_invalidate_pages(struct amd_iommu *iommu,
586 union buf_entry invalidate_pages = {{ 0 }};
589 * Flush everything, including PDEs, in whole address range, i.e.
590 * 0x7ffffffffffff000 with S bit (see Sect. 2.2.3).
592 invalidate_pages.raw32[1] = domain_id;
593 invalidate_pages.raw32[2] = 0xfffff000 | CMD_INV_IOMMU_PAGES_SIZE |
594 CMD_INV_IOMMU_PAGES_PDE;
595 invalidate_pages.raw32[3] = 0x7fffffff;
596 invalidate_pages.type = CMD_INV_IOMMU_PAGES;
598 amd_iommu_submit_command(iommu, &invalidate_pages, false);
601 static void amd_iommu_completion_wait(struct amd_iommu *iommu)
603 union buf_entry completion_wait = {{ 0 }};
604 volatile u64 sem = 1;
607 addr = paging_hvirt2phys(&sem);
609 completion_wait.raw32[0] = (addr & BIT_MASK(31, 3)) |
610 CMD_COMPL_WAIT_STORE;
611 completion_wait.raw32[1] = (addr & BIT_MASK(51, 32)) >> 32;
612 completion_wait.type = CMD_COMPL_WAIT;
614 amd_iommu_submit_command(iommu, &completion_wait, true);
615 mmio_write64(iommu->mmio_base + AMD_CMD_BUF_TAIL_REG,
616 iommu->cmd_tail_ptr);
618 wait_for_zero(&sem, -1);
621 static void amd_iommu_init_fault_nmi(void)
623 union x86_msi_vector msi_vec = {{ 0 }};
624 union pci_msi_registers msi_reg;
625 struct per_cpu *cpu_data;
626 struct amd_iommu *iommu;
629 cpu_data = iommu_select_fault_reporting_cpu();
631 /* Send NMI to fault reporting CPU */
632 msi_vec.native.address = MSI_ADDRESS_VALUE;
633 msi_vec.native.destination = cpu_data->apic_id;
635 msi_reg.msg32.enable = 1;
636 msi_reg.msg64.address = msi_vec.raw.address;
637 msi_reg.msg64.data = MSI_DM_NMI;
639 for_each_iommu(iommu) {
640 struct jailhouse_iommu *cfg =
641 &system_config->platform_info.x86.iommu_units[iommu->idx];
643 /* Disable MSI during interrupt reprogramming. */
644 pci_write_config(cfg->amd_bdf, cfg->amd_msi_cap + 2 , 0, 2);
647 * Write new MSI capability block, re-enabling interrupts with
650 for (n = 3; n >= 0; n--)
651 pci_write_config(cfg->amd_bdf, cfg->amd_msi_cap + 4 * n,
656 * There is a race window in between we change fault_reporting_cpu_id
657 * and actually reprogram the MSI. To prevent event loss, signal an
658 * interrupt when done, so iommu_check_pending_faults() is called
659 * upon completion even if no further NMIs due to events would occurr.
661 * Note we can't simply use CMD_COMPL_WAIT_INT_MASK in
662 * amd_iommu_completion_wait(), as it seems that IOMMU either signal
663 * an interrupt or do memory write, but not both.
665 apic_send_nmi_ipi(cpu_data);
668 void iommu_config_commit(struct cell *cell_added_removed)
670 struct amd_iommu *iommu;
673 if (iommu_units_count == 0)
676 /* Ensure we'll get NMI on completion, or if anything goes wrong. */
677 if (cell_added_removed)
678 amd_iommu_init_fault_nmi();
680 for_each_iommu(iommu) {
682 if (cell_added_removed) {
683 amd_iommu_invalidate_pages(iommu,
684 cell_added_removed->id & 0xffff);
685 amd_iommu_invalidate_pages(iommu,
686 root_cell.id & 0xffff);
688 /* Execute all commands in the buffer */
689 amd_iommu_completion_wait(iommu);
693 struct apic_irq_message iommu_get_remapped_root_int(unsigned int iommu,
696 unsigned int remap_index)
698 struct apic_irq_message dummy = { .valid = 0 };
700 /* TODO: Implement */
704 int iommu_map_interrupt(struct cell *cell, u16 device_id, unsigned int vector,
705 struct apic_irq_message irq_msg)
707 /* TODO: Implement */
711 void iommu_shutdown(void)
713 struct amd_iommu *iommu;
716 for_each_iommu(iommu) {
717 /* Disable the IOMMU */
718 ctrl_reg = mmio_read64(iommu->mmio_base + AMD_CONTROL_REG);
719 ctrl_reg &= ~(AMD_CONTROL_IOMMU_EN | AMD_CONTROL_CMD_BUF_EN |
720 AMD_CONTROL_EVT_LOG_EN | AMD_CONTROL_EVT_INT_EN);
721 mmio_write64(iommu->mmio_base + AMD_CONTROL_REG, ctrl_reg);
725 static void amd_iommu_print_event(struct amd_iommu *iommu,
726 union buf_entry *entry)
728 printk("AMD IOMMU %d reported event\n", iommu->idx);
729 printk(" EventCode: %lx, Operand 1: %lx, Operand 2: %lx\n",
730 entry->type, entry->raw64[0], entry->raw64[1]);
731 switch (entry->type) {
732 case EVENT_TYPE_ILL_DEV_TAB_ENTRY...EVENT_TYPE_PAGE_TAB_HW_ERR:
733 case EVENT_TYPE_IOTLB_INV_TIMEOUT...EVENT_TYPE_INV_PPR_REQ:
734 printk(" DeviceId (bus:dev.func): %02x:%02x.%x\n",
735 PCI_BDF_PARAMS(entry->raw32[0] & 0xffff));
737 case EVENT_TYPE_ILL_CMD_ERR:
738 case EVENT_TYPE_CMD_HW_ERR:
739 panic_printk("FATAL: IOMMU %d command error\n");
744 static void amd_iommu_restart_event_log(struct amd_iommu *iommu)
746 void *base = iommu->mmio_base;
748 wait_for_zero(base + AMD_STATUS_REG, AMD_STATUS_EVT_LOG_RUN);
750 mmio_write64_field(base + AMD_CONTROL_REG, AMD_CONTROL_EVT_LOG_EN, 0);
752 /* Simply start from the scratch */
753 mmio_write64(base + AMD_EVT_LOG_HEAD_REG, 0);
754 mmio_write64(base + AMD_EVT_LOG_TAIL_REG, 0);
756 /* Clear EventOverflow (RW1C) */
757 mmio_write64_field(base + AMD_STATUS_REG, AMD_STATUS_EVT_OVERFLOW, 1);
759 /* Bring logging back */
760 mmio_write64_field(base + AMD_CONTROL_REG, AMD_CONTROL_EVT_LOG_EN, 1);
763 static void amd_iommu_poll_events(struct amd_iommu *iommu)
765 union buf_entry *evt;
769 status = mmio_read64(iommu->mmio_base + AMD_STATUS_REG);
771 if (status & AMD_STATUS_EVT_OVERFLOW) {
772 printk("IOMMU %d: Event Log overflow occurred, "
773 "some events were lost!\n", iommu->idx);
774 amd_iommu_restart_event_log(iommu);
777 while (status & AMD_STATUS_EVT_LOG_INT) {
778 /* Clear EventLogInt (RW1C) */
779 mmio_write64_field(iommu->mmio_base + AMD_STATUS_REG,
780 AMD_STATUS_EVT_LOG_INT, 1);
782 head = mmio_read32(iommu->mmio_base + AMD_EVT_LOG_HEAD_REG);
783 tail = mmio_read32(iommu->mmio_base + AMD_EVT_LOG_TAIL_REG);
785 while (head != tail) {
786 evt = (union buf_entry *)(iommu->evt_log_base + head);
787 amd_iommu_print_event(iommu, evt);
788 head = (head + sizeof(*evt)) % EVT_LOG_SIZE;
791 mmio_write32(iommu->evt_log_base + AMD_EVT_LOG_HEAD_REG, head);
793 /* Re-read status to catch new events, as Linux does */
794 status = mmio_read64(iommu->mmio_base + AMD_STATUS_REG);
798 static void amd_iommu_handle_hardware_event(struct amd_iommu *iommu)
800 union buf_entry hev_entry;
803 hev = mmio_read64(iommu->mmio_base + AMD_HEV_STATUS_REG);
805 /* Check if hardware event is present and print it */
806 if (hev & AMD_HEV_VALID) {
807 if (hev & AMD_HEV_OVERFLOW)
808 printk("IOMMU %d: Hardware Event Overflow occurred, "
809 "some events were lost!\n", iommu->idx);
811 mmio_read64(iommu->mmio_base + AMD_HEV_UPPER_REG);
813 mmio_read64(iommu->mmio_base + AMD_HEV_LOWER_REG);
815 amd_iommu_print_event(iommu, &hev_entry);
817 /* Clear Hardware Event */
818 mmio_write64(iommu->mmio_base + AMD_HEV_STATUS_REG, 0);
822 void iommu_check_pending_faults(void)
824 struct amd_iommu *iommu;
826 if (this_cpu_data()->cpu_id != fault_reporting_cpu_id)
829 for_each_iommu(iommu) {
830 if (iommu->he_supported)
831 amd_iommu_handle_hardware_event(iommu);
832 amd_iommu_poll_events(iommu);