tools: config-create: Remove write restriction for ACPI regions

We don't depend on ACPI in the hypervisor anymore. Also, the NVS memory
may contain some semaphore the kernel updates to synchronize with the
chipset-embedded controller. So let's give Linux full access to this
memory again.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
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>
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 order 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>
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>
configs/tools: Exclude MSI-X table from memory regions

We need to virtualize the access to the MSI-X table, thus we have to
prevent that the cells access them directly. As the table may be
embedded into a larger BAR, specifically followed by the PBA, split up
the BAR region as required.

Update the QEMU config accordingly - currently the only config with
MSI-X devices.

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

Will be reused for MSI-X support

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

Similar to MSI support, this adds virtualization of MSI-X in order to
remap those interrupts via VT-d.

We have to intercept the MMIO access to the MSI-X tables of PCI devices
for this. Finding the corresponding device is done via a separate
per-cell list of all MSI-X capable PCI devices a cell contains. It is
built during cell creation, i.e. when devices are added, and it shrinks
again when devices are removed from a cell.

MSI-X device handover from/to Linux is simpler as we can centrally mask
all MSI-X vectors of a device.

As we may intercept more than the MSI-X table, accesses beyond it have
to be processed as well. Writes to the PBA are not allowed, reads from
anything after the table are simply performed on behalf of the cell.

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