configs/tools: Add number of MSI vectors to PCI device config structure

This avoids having to scan in the hypervisor the MSI/MSI-X capabilities
regarding the maximum number of vectors a PCI device may use.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/tools: Introduce device and interrupt number limit

VT-d interrupt remapping but also (one day) AMD IOMMUs require us to
dimension related tables during setup. Introduce two parameters to the
config file, one set an upper limit of interrupts (all types) that the
system may have to control (for all cells) and another one for devices
in the system. The former will be used for VT-d, the latter should once
be helpful for AMD support, thus it can remain unset in Intel configs.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
tools: config-create: make sure we are root when reading input files

File access permissions allow users and root to read PCI config spaces
of devices via sysfs. But depending on your uid you will read different
content.
That is why we have to make sure we open those files as root and can not
just rely on getting an EPERM.

Signed-off-by: Henning Schild <henning.schild@siemens.com>
[Jan: removed extra blank line]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Add support for sending interrupts to CPUs

Will be used to inject events from temporarily masked edge-triggered
sources or to generate interrupts from virtual devices.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Switch VT-d to queued invalidation

Required for interrupt remapping support.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Factor out vtd_update_gcmd_reg

This encapsulates changes to the global command register that preserve
the current state and wait for the state change to become effective.
Both setting and clearing is supported.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Provide stub for programming VT-d interrupt remapping table entries

This allows us to step-wise build up the infrastructure on the IOAPIC
and PCI subsystem side.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs: Prepare h87i for interrupt remapping

Add the missing configuration bits that will allow us to remap IOAPIC
interrupts and MSIs.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Factor out ioapic_reg_read/write

There will be more spots where we need to talk to the IOAPIC. These
helpers enable and coordinate the access.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Define access moderation for IOAPIC EOI register

There is no point in virtualizating this register. Only avoid that a
cell without any business with the IOAPIC can write to it.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Report root cell as added/removed on initial config commit

This aligns the initial config commit with those performed on non-root
cell creation and destruction. We only need to avoid some then redundant
operations on the root cell in x86's arch_config_commit and
vtd_config_commit.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Virtualize IOAPIC redir table for interrupt remapping support

Handover the IOAPIC on hypervisor setup by first masking all pins, then
requesting interrupt remapping from VT-d and finally reprogramming them
according to the index that VT-d reported. If vtd_map_interrupt returns
-ENOSYS, unconditionally right now due to a missing implementation,
later on when running in QEMU, we continue to write the redirection
table entry unmodified.

As we may lose edge-triggered interrupts while they are makes, we inject
them unconditionally into the target CPU. This may cause one spurious
interrupt per handover to/from the hypervisor, but Linux can deal with
that.

Whenever a cell is added or removed, we rewrite all root cell IOAPIC
redir table entries in oder to validate them regarding the target CPU
masks.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Virtualize legacy MSI for interrupt remapping support

Analogously to edge-triggered IOAPIC interrupts, handover all legacy
MSIs by disabling them first, programming the VT-d remapping table and
then writing remappable parameters into the MSI capability registers.
An additional triggering of active vector unsures that we do not lose
events during handover.

Disabling is done on x86 via a trick: we program an empty CPU mask in
logical destination mode.

MSI-X remains on the to-do list. Thus, once enabling interrupt
remapping, systems that use MSI-X will become unsupported for the time
being.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Perform VT-d interrupt remapping table programming

This fills vtd_map_interrupt with the missing logic to set entries in
the interrupt remapping table and programs the hardware to use that
table, blocking all non-remappable interrupts.

vtd_map_interrupt performs the required entry validation and rejects any
improper settings. There is one exception: CPU masks in logical
destination mode will silently be adjusted instead of failing the
service call. The reason is that Linux may have these masks set for
practically inactive interrupt vectors programmed  (e.g. enabled MSI
vectors of PCIe ports without any port service using them) and will only
update them when they may be used again. Failing such settings would
stop Linux prematurely.

We reserve remapping table entries for the IOAPIC upon cell creation. We
also reserve as many entries as MSI vectors are reported for each PCI
device of a cell. IOAPIC reservation happens only once, and the region
is kept over the lifetime of the hypervisor as the IOAPIC may be shared
between cells (though this is not recommended). PCI device reservations
are released again when the device is removed from its owning cell.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/x86: Add check for VT-d existence

Add a check that validates the existence of configured VT-d units.
Require that every config contains at least one unit. Experimental VT-d
emulation, including interrupt remapping support, is now available for
QEMU. So we can set the config fields accordingly. If VT-d is disabled
or a QEMU version without that support is used, the hypervisor continues
to ignore this error.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Update TODO

Remove recently added features, add VT-d emulation and a check for
virtualized environment (safety requirement).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
tools: config-create: more fine grained parsing of /proc/iomem

Parse /proc/iomem keeping the tree structure. So far we only looked at
the top level entries, mainly at the type strings. But for more fine
grained selection of memory regions we need to look deeper into the
tree.

Signed-off-by: Henning Schild <henning.schild@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
tools: config-create: fix shell template

Not every shell supports the "-ne" operator in its builtin test, use
string compare instead. Also $UID is not always set.

Signed-off-by: Henning Schild <henning.schild@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
tools: config-create: Exclude DMAR units from memory regions

The cells must not be able to access the physical units. We will emulate
what is required for interrupt remapping.

At this chance, clarify in a comment that the IOAPIC is also excluded.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/tools: Provide MSI-X parameters via config

It is simpler to calculate and validate these offline than to do it
during hypervisor setup.

Add the new information to the QEMU config file.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>