x86: Prevent getting stuck while trying to clear the APIC

If some interrupt source (typically a level-triggered IOAPIC pin)
continuously sends messages to the APIC we are trying to clear from
pending bits in ISR and IRR, we will get stuck in the hypervisor in an
interrupt storm.

Avoid this by limiting the number of handled interrupts to the number of
vectors we have. When reaching this limit, simply raise TPR to break out
of the loop. It's cleared again on exit from apic_clear, and the code
booting the CPU can handle the then pending interrupt itself. That's
almost like real hardware would behave (low-prio IRR bits may remain set
due to a stuck high-prio interrupt). However, only buggy SMP cells will
once be able to trigger this, IOAPIC pins of exitings cells will soon be
masked to prevent this scenario.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Refactor x2apic_handle_read/write

Use the relative APIC registers number internally and prepare the
interface of x2apic_handle_write for returning access errors.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Move ICR access dispatching into x2apic_handle_write

More code sharing, specifically when AMD support will be added.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Filter writes to reserved APIC register bits

Set up a bitmap for all xAPIC/x2APIC register that marks reserved bits
(or complete registers). Check to-be-written values against this bitmap
before executing accesses in hypervisor context.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Filter LVT delivery modes

Do not allow cells to program anything else than Fixed or NMI mode. NMIs
will still be swallowed by the hypervisor NMI interception path, so perf
& Co. remain broken.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Block write access to IA32_APIC_BASE MSR

The hypervisor depends on a consistent APIC mode. So prevent that a cell
can mess it up. As the APIC is kept in the same state across cell
assignments, no cell has a need to change it.

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

Recently added APIC topics are addressed now. Also add new ideas
regarding error handling and cell watchdogs / message timeouts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Fix error path in arch_cell_create

Regression of 46ab6c2f1e: Properly return the error if vtd_cell_init
fails.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
inmates: pci-demo: Clear STATESTS before triggering the MSI

STATESTS may still have pending events which could prevent a MSI
delivery after controller reset. That reset doesn't clear them, so do
this explicitly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs: Adjust MSI capability address of HDA devices

Real hardware locates MSI at 0x60, only current QEMU has this at 0x50
(patch posted).

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Fix calculation of MMCONFIG region size

The PCI Firmware Specification says: "For PCI-X and PCI Express
platforms utilizing the enhanced configuration access method, the base
address of the memory mapped configuration space always corresponds to
bus number 0 (regardless of the start bus number decoded by the host
bridge) [...]." So drop the start bus from the size calculation.

Moreover, we had an off-by-one regarding end bus to size translation.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Drop useless conditions from data_port_in/out_handler

Size must be 4 if it's not 1 or 2.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Provide MMIO accessors for all sizes

Use a macro to define size-specific MMIO accessors and add support for
8 and 16 bit.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Privatize PCI_CONFIG_HEADER_SIZE define

No use case outside of hypervisor/pci.c

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Micro-refactor vtd_add_device_to_cell/vtd_remove_device_from_cell

Keep the pointer of referenced root table entry low-word instead of its
value. This simplifies its manipulation later on.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Restrict vtd_init_fault_nmi to 8-bit APIC IDs

There is more code in Jailhouse that is restricted to 8-bit IDs, so
let's simplify vtd_init_fault_nmi correspondingly.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core/configs/tools: Switch PCI configuration format to single BDF value

There is no value in splitting up the PCI device address in the config
format into bus and devfn. Fold them into a single value that can easier
be matched and is also easily be split up again via new helper macros
whenever needed.

This generates some work for locally maintained config file, sorry.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
core: Pass combined register address to pci_cfg_read/write_moderate

Fold reg_base and reg_bias parameters of the access moderation functions
into a single address value. It simplifies most callers.

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

These PIO-based access functions will be reused for providing
hypervisor-internal config access.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
x86: Clean up PCI defines

Most of them became unused. Use self-describing definitions for the
remaining ones.

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