History log of /freebsd-current/sys/x86/iommu/intel_ctx.c
Revision Date Author Comments
# 40d951bc 24-May-2024 Konstantin Belousov <kib@FreeBSD.org>

x86/iommu: extract useful utilities into x86_iommu.c

related to the page tables page allocation and mapping.

Sponsored by: The FreeBSD Foundation
Sponsored by: Advanced Micro Devices (AMD)
MFC after: 1 week


# 24e38af6 23-Dec-2023 Konstantin Belousov <kib@FreeBSD.org>

DMAR: add knob to disable RMRR entries installation into domains

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 1228b93b 06-Dec-2023 Mitchell Horne <mhorne@FreeBSD.org>

busdma: remove parent tag tracking

Without filter functions, we do not need to keep track of tag ancestry.
All inheritance of the parent tag's parameters occurs when creating the
new child tag.

Reviewed by: jhb
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D42895


# fdafd315 24-Nov-2023 Warner Losh <imp@FreeBSD.org>

sys: Automated cleanup of cdefs and other formatting

Apply the following automated changes to try to eliminate
no-longer-needed sys/cdefs.h includes as well as now-empty
blank lines in a row.

Remove /^#if.*\n#endif.*\n#include\s+<sys/cdefs.h>.*\n/
Remove /\n+#include\s+<sys/cdefs.h>.*\n+#if.*\n#endif.*\n+/
Remove /\n+#if.*\n#endif.*\n+/
Remove /^#if.*\n#endif.*\n/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/types.h>/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/param.h>/
Remove /\n+#include\s+<sys/cdefs.h>\n#include\s+<sys/capsicum.h>/

Sponsored by: Netflix


# 685dc743 16-Aug-2023 Warner Losh <imp@FreeBSD.org>

sys: Remove $FreeBSD$: one-line .c pattern

Remove /^[\s*]*__FBSDID\("\$FreeBSD\$"\);?\s*\n/


# 4d846d26 10-May-2023 Warner Losh <imp@FreeBSD.org>

spdx: The BSD-2-Clause-FreeBSD identifier is obsolete, drop -FreeBSD

The SPDX folks have obsoleted the BSD-2-Clause-FreeBSD identifier. Catch
up to that fact and revert to their recommended match of BSD-2-Clause.

Discussed with: pfg
MFC After: 3 days
Sponsored by: Netflix


# 4670f908 29-Jul-2022 Alan Cox <alc@FreeBSD.org>

iommu_gas: Eliminate redundant parameters and push down lock acquisition

Since IOMMU map entries store a reference to the domain in which they
reside, there is no need to pass the domain to iommu_gas_free_entry(),
iommu_gas_free_space(), and iommu_gas_free_region().

Push down the acquisition and release of the IOMMU domain lock into
iommu_gas_free_space() and iommu_gas_free_region().

Both of these changes allow for simplifications in the callers of the
functions without really complicating the functions themselves.
Moreover, the latter change eliminates the direct use of the IOMMU
domain lock from the x86-specific DMAR code.

Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D35995


# 42736dc4 26-Jul-2022 Alan Cox <alc@FreeBSD.org>

x86/iommu: Reduce DMAR lock contention

Replace the DMAR unit's tlb_flush TAILQ by a custom list implementation
that enables dmar_qi_task() to dequeue entries without holding the DMAR
lock.

Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D35951


# c2515634 25-Jul-2022 Alan Cox <alc@FreeBSD.org>

x86/iommu: Correct a recent change to iommu_domain_unload_entry()

Correct 8bc367384745. When iommu_domain_unload_entry() performs a
synchronous IOTLB invalidation, it must call dmar_domain_free_entry()
to remove the entry from the domain's RB_TREE.

Push down the acquisition and release of the DMAR lock into the
recently introduced function dmar_qi_invalidate_sync_locked() and
remove the _locked suffix.

MFC with: 8bc367384745


# 8bc36738 21-Jul-2022 Alan Cox <alc@FreeBSD.org>

iommu_gas: Eliminate a possible case of use-after-free

Eliminate a possible case of use-after-free in an error handling path
after a mapping failure. Specifically, eliminate IOMMU_MAP_ENTRY_QI_NF
and instead perform the IOTLB invalidation synchronously. Otherwise,
when iommu_domain_unload_entry() is called and told not to free the
IOMMU map entry, the caller could free the entry before dmar_qi_task()
is finished with it.

Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D35878


# da55f86c 15-Jul-2022 Alan Cox <alc@FreeBSD.org>

x86/iommu: Eliminate redundant wrappers

Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D35832


# db0110a5 10-Jul-2022 Alan Cox <alc@FreeBSD.org>

iommu: Shrink the iommu map entry structure

Eliminate the unroll_entry field from struct iommu_map_entry, shrinking
the struct by 16 bytes on 64-bit architectures.

Reviewed by: kib
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D35769


# 06e6ca6d 21-Oct-2021 Kornel Duleba <mindal@semihalf.com>

dmar: Disable protected memory regions after initialization

Some BIOSes protect memory region they reside in by using DMAR to
prevent devices from doing any DMA transactions to that part of RAM.
AMI refers to this as "DMA Control Guarantee".
Disable the protection when address translation is enabled.
I stumbled upon this while investigation a failing coredump on a device
which has this feature enabled.

Sponsored by: Stormshield
Obtained from: Semihalf
Reviewed by: kib
Differential revision: https://reviews.freebsd.org/D32591


# 3c02da80 21-Oct-2021 Kornel Duleba <mindal@semihalf.com>

dmar: Don't try to reserve PCI regions for non-existing devices

In some cases we might have to create DMAR context before the
corresponding device has been enumerated by the PCI bus.
In that case we get called with NULL dev, because of that trying
to reserve PCI regions causes a NULL pointer dereference in
pci_find_pcie_root_port.

Sponsored by: Stormshield
Obtained from: Semihalf
MFC after: 2 weeks
Reviewed by: kib, rlibby
Differential revision: https://reviews.freebsd.org/D32589


# 661bd70b 21-Oct-2021 Konstantin Belousov <kib@FreeBSD.org>

DMAR: clean up warnings about write-only variables

For some of them, used only when KTR or KMSAN are configured, apply
__unused attribute directly.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 9feff969 08-Aug-2021 Ed Maste <emaste@FreeBSD.org>

Remove "All Rights Reserved" from FreeBSD Foundation sys/ copyrights

These ones were unambiguous cases where the Foundation was the only
listed copyright holder (in the associated license block).

Sponsored by: The FreeBSD Foundation


# ee47a12a 09-Dec-2020 Ryan Libby <rlibby@FreeBSD.org>

dmar: reserve memory windows of PCIe root port

PCI memory address space is shared between memory-mapped devices (MMIO)
and host memory (which may be remapped by an IOMMU). Device accesses to
an address within a memory aperture in a PCIe root port will be treated
as peer-to-peer and not forwarded to an IOMMU. To avoid this, reserve
the address space of the root port's memory apertures in the address
space used by the IOMMU for remapping.

Reviewed by: kib, tychon
Discussed with: Anton Rang <rang@acm.org>
Tested by: tychon
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D27503


# 94dfb28e 19-Oct-2020 Ruslan Bukin <br@FreeBSD.org>

Assign the reserved apic region (GAS entry) to the iommu domain msi_entry.

Requested by: kib
Reviewed by: kib
Sponsored by: Innovate DSbD
Differential Revision: https://reviews.freebsd.org/D26859


# cb9050dd 10-Sep-2020 Ruslan Bukin <br@FreeBSD.org>

Move the rid variable to the generic iommu context.
It could be used in various IOMMU platforms, not only DMAR.

Reviewed by: kib
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D26373


# 0424f19e 05-Aug-2020 Ruslan Bukin <br@FreeBSD.org>

Move dmar_domain_unload_task to busdma_iommu.c.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25972


# 16696f60 06-Aug-2020 Ruslan Bukin <br@FreeBSD.org>

Add iommu_domain constructor and destructor.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25956


# 78b51754 04-Aug-2020 Ruslan Bukin <br@FreeBSD.org>

Add a few macroses for conversion between DMAR unit, domain, ctx
and IOMMU unit, domain, ctx.

Reviewed by: kib
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D25926


# 0eed04c8 31-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

Add iommu_domain_map_ops virtual table with map/unmap methods
so x86 can support Intel DMAR and AMD IOMMU simultaneously.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25894


# c8597a1f 29-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

o Don't include headers from iommu.h, include them from the header
consumers instead;
o Order includes properly.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25878


# ea4c0115 28-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

o Move the buswide_ctxs bitmap to iommu_unit and rename related functions.
o Rename bus_dma_dmar_load_ident() as well.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25852


# 15f6baf4 25-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

Rename DMAR flags:
o DMAR_DOMAIN_* -> IOMMU_DOMAIN_*
o DMAR_PGF_* -> IOMMU_PGF_*

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25812


# 62ad310c 25-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

Split-out the Intel GAS (Guest Address Space) management component
from Intel DMAR support, so it can be used on other IOMMU systems.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25743


# f2b2f317 21-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

Move the Intel DMAR busdma backend to a generic place so
it can be used on other IOMMU systems.

Reviewed by: kib
Sponsored by: DARPA/AFRL
Differential Revision: https://reviews.freebsd.org/D25720


# 59e37c8a 14-Jul-2020 Ruslan Bukin <br@FreeBSD.org>

Start splitting-out the Intel DMAR busdma backend to a generic place,
so it can be used on other IOMMU systems.

Provide MI iommu_unit, iommu_domain and iommu_ctx structs in sys/iommu.h;
use them as a first member of MD dmar_unit, dmar_domain and dmar_ctx.

Change the namespace in DMAR backend: use iommu_ prefix instead of dmar_.

Move some macroses and function prototypes to sys/iommu.h.

Reviewed by: kib
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D25574


# 5c3771d2 27-Nov-2019 Konstantin Belousov <kib@FreeBSD.org>

bus_dma_dmar_load_ident(9): load identity mapping into the map.

Requested, reviewed and tested by: mav
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D22559


# 685666aa 18-Nov-2019 Konstantin Belousov <kib@FreeBSD.org>

bus_dma_dmar_set_buswide(9): KPI to indicate that the whole dmar
context should share page tables.

Practically it means that dma requests from any device on the bus are
translated according to the entries loaded for the bus:0:0 device.
KPI requires that the slot and function of the device be 0:0, and that
no tags for other devices on the bus were used.

The intended use are NTBs which pass TLPs from the downstream to the
host with slot:func of the downstream originator.

Reviewed and tested by: mav
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D22434


# 96ca24dc 19-Apr-2019 Tycho Nightingale <tychon@FreeBSD.org>

remove the 4GB boundary requirement on PCI DMA segments

Reviewed by: kib
Discussed with: jhb
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D19867


# f9feb091 18-Apr-2019 Konstantin Belousov <kib@FreeBSD.org>

Correct handling of RMRR during early enumeration stages.

On some machines, DMAR contexts must be created before all devices
under the scope of the corresponding DMAR unit are enumerated.
Current code has two problems with that:
- scope lookup returns NULL device_t, which causes to skip creating a
context with RMRR, which is fatal for the affected device.
- calculation of the final pci dbsf address fails if any bridge in the
scope is not yet enumerated, because code relies on pcib_get_bus().

Make creation of contexts work either with device_t, or with DMAR PCI
scope paths. Scope provides enough information to infer context
address, and it is directly matched against DMAR tables scopes.

When calculating bus addresses for the scope or device, use direct
pci_cfgregread(PCIR_SECBUS_1) to get the secondary bus number, instead
of pcib_get_bus().

The issue was observed on HP Gen servers, where iLO PCI devices are
located behind south bridge switch. Turning on translation without
satisfying RMRR requests caused iLO to mostly hang, up to the level of
being unusable to control the server.

While there, remove hw.dmar.dmar_match_verbose tunable, and make the
normal logging under bootverbose useful and sufficient to diagnose
DRHD and RMRR parsing and matching.

Sponsored by: Mellanox Technologies
MFC after: 1 week


# ebf5747b 27-Nov-2017 Pedro F. Giffuni <pfg@FreeBSD.org>

sys/x86: further adoption of SPDX licensing ID tags.

Mainly focus on files that use BSD 2-Clause license, however the tool I
was using misidentified many licenses so this was mostly a manual - error
prone - task.

The Software Package Data Exchange (SPDX) group provides a specification
to make it easier for automated tools to detect and summarize well known
opensource licenses. We are gradually adopting the specification, noting
that the tags are considered only advisory and do not, in any way,
superceed or replace the license texts.


# cf619a92 19-Jun-2017 Konstantin Belousov <kib@FreeBSD.org>

Fix batched unload for DMAR busdma in qi mode.

Do not queue dmar_map_entries with zeroed gseq to
dmar_qi_invalidate_locked(). Zero gseq stops the processing in the qi
task. Do not assign possibly uninitialized on-stack gseq to map
entries when requeuing them on unit tlb_flush queue. Random garbage
in gsec is interpreted as too high invalidation sequence number and
again stop the processing in the task.

Make the sequence numbers generation completely contained in
dmar_qi_invalidate_locked() and dmar_qi_emit_wait_seq(). Upper code
directly passes boolean requesting emiting wait command instead of
trying to provide hint to avoid it by passing NULL gseq pointer.

Microoptimize the requeueing to tlb_flush queue by doing it for the
whole queue.

Diagnosed and tested by: Brett Gutstein <bgutstein@rice.edu>
Discussed with: alc
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 3d47c58b 25-Mar-2017 Konstantin Belousov <kib@FreeBSD.org>

Avoid leaking allocated but unused context after creation race.

As noted in the comment, nothing special needs to be done to destroy
the unneeded context after the allocation race, but the context memory
itself still should to be freed.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 5f8e5c7f 25-Mar-2017 Konstantin Belousov <kib@FreeBSD.org>

Do not create RMRR entries for identity-mapped domains.

It does not make sense since identity mapping already provides the
required mapping for RMRR ranges. More, since identity page tables do
not reflect content of map entries for id domains, creating RMRR
entries makes domain data inconsistent.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# e164cafc 17-Apr-2016 Konstantin Belousov <kib@FreeBSD.org>

Add hw.dmar.batch_coalesce tunable/sysctl, which specifies rate at
which queued invalidation completion interrupt is requested with
regard to the queued invalidation requests. In other words, setting
the value of the knob to N requests completion interrupt after N items
are processed. Existing behaviour is restored by setting
hw.dmar.batch_coalesce=1.

The knob significantly decreases the DMAR qi interrupt rate at the
cost of slightly longer DMAR map entries recycling.

Sponsored by: The FreeBSD Foundation


# 6b1ad46a 22-Sep-2015 Bjoern A. Zeeb <bz@FreeBSD.org>

dmar_ctx_dtr() does not exist since r284869. Remove the static function
declaration to avoid a cmpile time warning.


# 1abfd355 26-Jun-2015 Konstantin Belousov <kib@FreeBSD.org>

Split the DMAR unit domains and contexts. Domains carry address space
and related data structures. Contexts attach requests initiators to
domains. There is still 1:1 correspondence between contexts and
domains on the running system, since only busdma currently allocates
them, using dmar_get_ctx_for_dev().

Large part of the change is formal rename of the ctx to domain, but
patch also reworks the context allocation and free to allow for
independent domain creation.

The helper dmar_move_ctx_to_domain() is introduced for future use, to
reassign request initiator from one domain to another. The hard issue
which is not yet resolved with the context move is proper handling (or
reserving) RMRR entries in the destination domain as required by ACPI
DMAR table for moved context.

Tested by: pho
Sponsored by: The FreeBSD Foundation


# 0a110d5b 19-Mar-2015 Konstantin Belousov <kib@FreeBSD.org>

Use VT-d interrupt remapping block (IR) to perform FSB messages
translation. In particular, despite IO-APICs only take 8bit apic id,
IR translation structures accept 32bit APIC Id, which allows x2APIC
mode to function properly. Extend msi_cpu of struct msi_intrsrc and
io_cpu of ioapic_intsrc to full int from one byte.

KPI of IR is isolated into the x86/iommu/iommu_intrmap.h, to avoid
bringing all dmar headers into interrupt code. The non-PCI(e) devices
which generate message interrupts on FSB require special handling. The
HPET FSB interrupts are remapped, while DMAR interrupts are not.

For each msi and ioapic interrupt source, the iommu cookie is added,
which is in fact index of the IRE (interrupt remap entry) in the IR
table. Cookie is made at the source allocation time, and then used at
the map time to fill both IRE and device registers. The MSI
address/data registers and IO-APIC redirection registers are
programmed with the special values which are recognized by IR and used
to restore the IRE index, to find proper delivery mode and target.
Map all MSI interrupts in the block when msi_map() is called.

Since an interrupt source setup and dismantle code are done in the
non-sleepable context, flushing interrupt entries cache in the IR
hardware, which is done async and ideally waits for the interrupt,
requires busy-wait for queue to drain. The dmar_qi_wait_for_seq() is
modified to take a boolean argument requesting busy-wait for the
written sequence number instead of waiting for interrupt.

Some interrupts are configured before IR is initialized, e.g. ACPI
SCI. Add intr_reprogram() function to reprogram all already
configured interrupts, and call it immediately before an IR unit is
enabled. There is still a small window after the IO-APIC redirection
entry is reprogrammed with cookie but before the unit is enabled, but
to fix this properly, IR must be started much earlier.

Add workarounds for 5500 and X58 northbridges, some revisions of which
have severe flaws in handling IR. Use the same identification methods
as employed by Linux.

Review: https://reviews.freebsd.org/D1892
Reviewed by: neel
Discussed with: jhb
Tested by: glebius, pho (previous versions)
Sponsored by: The FreeBSD Foundation
MFC after: 3 weeks


# 6b7c46af 11-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Right now, for non-coherent DMARs, page table update code flushes the
cache for whole page containing modified pte, and more, only last page
in the series of the consequtive pages is flushed (i.e. the affected
mappings should be larger than 2MB).

Avoid excessive flushing and do missed neccessary flushing, by
splitting invalidation and unmapping. For now, flush exactly the
range of the changed pte. This is still somewhat bigger than
neccessary, since pte is 8 bytes, while cache flush line is at least
32 bytes.

The originator of the issue reports that after the change,
'dmar_bus_dmamap_unload went from 13,288 cycles down to
3,257. dmar_bus_dmamap_load_buffer went from 9,686 cycles down to
3,517. and I am now able to get line 1GbE speed with Netperf TCP
(even with 1K message size).'

Diagnosed and tested by: Nadav Amit <nadav.amit@gmail.com>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 34e8337b 10-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Print rid when announcing DMAR context creation. Print sid when fault
occurs. This allows to connect dots in case the requester is
calculated erronously.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# b29d186c 08-Jan-2015 Konstantin Belousov <kib@FreeBSD.org>

Fix DMAR context allocations for the devices behind PCIe->PCI bridges
after dmar driver was converted to use rids. The bus component to
calculate context page must be taken from the requestor rid, which is
a bridge, and not from the device bus number.

Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 67499354 01-Apr-2014 Ryan Stone <rstone@FreeBSD.org>

Re-implement the DMAR I/O MMU code in terms of PCI RIDs

Under the hood the VT-d spec is really implemented in terms of
PCI RIDs instead of bus/slot/function, even though the spec makes
pains to convert back to bus/slot/function in examples. However
working with bus/slot/function is not correct when PCI ARI is
in use, so convert to using RIDs in most cases. bus/slot/function
will only be used when reporting errors to a user.

Reviewed by: kib
MFC after: 2 months
Sponsored by: Sandvine Inc.


# 7036ae46 01-Apr-2014 Ryan Stone <rstone@FreeBSD.org>

Revert PCI RID changes.

My PCI RID changes somehow got intermixed with my PCI ARI patch when I
committed it. I may have accidentally applied a patch to a non-clean
working tree. Revert everything while I figure out what went wrong.

Pointy hat to: rstone


# b5eb8abe 01-Apr-2014 Ryan Stone <rstone@FreeBSD.org>

Re-implement the DMAR I/O MMU code in terms of PCI RIDs

Under the hood the VT-d spec is really implemented in terms of
PCI RIDs instead of bus/slot/function, even though the spec makes
pains to convert back to bus/slot/function in examples. However
working with bus/slot/function is not correct when PCI ARI is
in use, so convert to using RIDs in most cases. bus/slot/function
will only be used when reporting errors to a user.

Reviewed by: kib
Sponsored by: Sandvine Inc.


# 9d0bc6d8 18-Mar-2014 Konstantin Belousov <kib@FreeBSD.org>

Add support for the PCI(e)-PCI bridges to the Intel VT-d driver. The
bridge takes ownership of the transaction, so bsf of the requester is
the bridge and not a device behind it. As result, code needs to walk
the hierarchy up to use correct context.

Note that PCIe->PCI-X bridges are not handled quite correctly since
such bridges are allowed to only take ownership of some transactions.
Also, weird but unrealistic cases of PCIe behind PCI bus are also not
handled.

Still, the patch provides significant step forward for the bridge
handling.

Submitted by: Jason Harmening <jason.harmening@gmail.com>
MFC after: 1 week


# e02b05b3 18-Mar-2014 Konstantin Belousov <kib@FreeBSD.org>

It is not uncommon for BIOSes to report wrong RMRR entries in DMAR
table. Among them, some (old AMI ?) BIOSes report entries with range
like (bf7ec000, bf7ebfff). Attempts to ignore the bogus entries
result in faults, so the range must be covered somehow.

Provide a workaround by identity mapping the 32 pages after the bogus
entry start, which seems to be enough for the reported BIOS.

Reported and tested by: Jason Harmening <jason.harmening@gmail.com>
Sponsored by: The FreeBSD Foundation
MFC after: 1 week


# 68eeb96a 01-Nov-2013 Konstantin Belousov <kib@FreeBSD.org>

Add support for queued invalidation.

Right now, the semaphore write is scheduled after each batch, which is
not optimal and must be tuned.

Discussed with: alc
Tested by: pho
MFC after: 1 month


# 86be9f0d 28-Oct-2013 Konstantin Belousov <kib@FreeBSD.org>

Import the driver for VT-d DMAR hardware, as specified in the revision
1.3 of Intelб╝ Virtualization Technology for Directed I/O Architecture
Specification. The Extended Context and PASIDs from the rev. 2.2 are
not supported, but I am not aware of any released hardware which
implements them. Code does not use queued invalidation, see comments
for the reason, and does not provide interrupt remapping services.

Code implements the management of the guest address space per domain
and allows to establish and tear down arbitrary mappings, but not
partial unmapping. The superpages are created as needed, but not
promoted. Faults are recorded, fault records could be obtained
programmatically, and printed on the console.

Implement the busdma(9) using DMARs. This busdma backend avoids
bouncing and provides security against misbehaving hardware and driver
bad programming, preventing leaks and corruption of the memory by wild
DMA accesses.

By default, the implementation is compiled into amd64 GENERIC kernel
but disabled; to enable, set hw.dmar.enable=1 loader tunable. Code is
written to work on i386, but testing there was low priority, and
driver is not enabled in GENERIC. Even with the DMAR turned on,
individual devices could be directed to use the bounce busdma with the
hw.busdma.pci<domain>:<bus>:<device>:<function>.bounce=1 tunable. If
DMARs are capable of the pass-through translations, it is used,
otherwise, an identity-mapping page table is constructed.

The driver was tested on Xeon 5400/5500 chipset legacy machine,
Haswell desktop and E5 SandyBridge dual-socket boxes, with ahci(4),
ata(4), bce(4), ehci(4), mfi(4), uhci(4), xhci(4) devices. It also
works with em(4) and igb(4), but there some fixes are needed for
drivers, which are not committed yet. Intel GPUs do not work with
DMAR (yet).

Many thanks to John Baldwin, who explained me the newbus integration;
Peter Holm, who did all testing and helped me to discover and
understand several incredible bugs; and to Jim Harris for the access
to the EDS and BWG and for listening when I have to explain my
findings to somebody.

Sponsored by: The FreeBSD Foundation
MFC after: 1 month