x86/tools/inmates: Account for 32-bit PM timers

Some systems may use 32-bit PM timer (as defined by TMR_VAL_EXT feature
flag in FADT), however pm_timer_read() assumes it is always 24-bit. Where
this assumption is wrong, return value becomes incorrect, and the error
grows over time leading to obscure bugs, including lockups in the hypervisor.

To fix this, TMR_VAL_EXT is made part of platform config and is passed to
inmates in the communication region. Config generator was also adapted
to parse FADT to get TMR_VAL_EXT value for target system. pm_timer_init()
function was also introduced to the inmates framework to the overflow value.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Keep IOAPIC entries consistent when unmasked

When an IOAPIC redirection entry is masked, only lower half of the register
is written. This causes the upper half to contain stale data when the entry
is unmasked. On systems that don't do interrupt remapping (currently, QEMU
and AMD) this may result in interrupts being lost or delivered to the wrong
destination.

Fix this by unconditionally writing the upper half of the register when
it is unmasked.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Enable Extended Interrupt LVT

Extended Interrupt LVTs are vendor-specific APIC registers (0x50-0x53),
defined by AMD (see APMv2, Sect. 16.3.2). Jailhouse lists this MMIO
range as reserved, as it is not used on Intel systems. On AMD systems,
Extended Interrupt LVT is no more "privileged" than other LVT registers,
so enable them if Jailhouse is built for AMD.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Introduce AMD-V code skeleton

Introduce a set of vendor-specific headers and sources that contain stubs for
functions required to support AMD-V (SVM) in Jailhouse. As AMD IOMMU support
is not planned for now, iommu_init() does nothing more than print a warning.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
makefiles: Build jailhouse-{amd,intel} together

This build system update brings an ability to build "jailhouse.bin"
firmware for different architecture "variants" (currently, AMD and
Intel on x86_64) simultaneously. Corresponding firmware files are
called 'jailhouse-$variant.bin'.

Variants are configured in hypervisor/Makefile: BUILD_VARIANTS store
their names, and jailhouse-$variant_DEFS contain macro definitions
needed to configure sources properly.

ARM port should remain unaffected by these changes, however,
regressions were not tested.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
driver: Support "variants" in firmware name

Jailhouse loader was also updated to locate and load a correct firmware
binary depending on a type of the system hypervisor executes on.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Choose a hypercall instruction in run-time

VMX and SVM use different instructions to make a hypercall (vmcall and
vmmcall, respectively). Jailhouse abstracts hypercall instructions with
inlined functions in jailhouse_hypercall.h, and these need to be able to
differentiate between VMX and SVM. As these functions are never called on
a CPU without VM extensions (the driver checks if Jailhouse is enabled
before issuing a hypercall, and inmates do not run outside cells), it is
safe to assume that the CPU without VMX support is an SVM one.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V definitions and data structures

AMD-V data structures (VMCB, exit codes, flags etc) were adapted
from the Xvisor code. See http://xhypervisor.org for details.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Setup VMCB for Linux CPUs

Configure VMCB so that Linux can continue run safely on the Jailhouse-managed
CPU. This is done mostly the same way as for VMX (except CPUID is not intercepted
and only CR0 writes that change paging state are trapped). AMD-V guests can also
use ASID to tag TLB entries; as Jailhouse cells run on the same CPUs during all
their lifespan, it is assigned a static value (1).

AVIC is not present in any known AMD chip, so it is not configured yet.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V initialization routines

Implemented functions responsible for checking AMD-V features present and
enabling/disabling SVM mode. Nested Page Tables (NPT) support is required,
and Decode Assists can optionally be used if available. For AVIC, only a
backing page is allocated.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V memory management functions

Implemented functions to map and unmap memory regions in NPT, get guest page
tables (including "fake" identity mappings if the guest runs in real mode), and
also to translate guest physical to host physical address. For TLB flush, only
mappings for the guest and not Jailhouse itself are cleaned, if possible.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V cell initialization/exit code

AMD-V vendor-specific parts of vcpu_cell_init() and vcpu_cell_exit() are
implemented.

On startup, if AVIC is not available (which is usually the case) APIC is
mapped to cells read-only so only register writes are trapped and emulated.

On cell exits, the mapping is destroyed.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add vcpu_handle_exit() function for AMD-V

Add the infrastructure required to handle VM exits. It is mostly boilerplate
code in its current state, and any VM exit will cause a CPU to dump registers
and halt.

Appropriate handlers are added in subsequent commits.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add vcpu_skip_emulated_instruction() for AMD-V

Many VM exit handlers need a way to skip the instruction they emulated.
Add vcpu_skip_emulated_instruction() that does this for AMD-V guests.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Implement vcpu_get_guest_bytes() for AMD-V

mmio_parse() can use accelerated guest memory access function, if the one
is provided in vendor-specific code. If Decode Assists are available on a
given CPU, we can avoid a costly page table walk and read guest instruction
directly from VMCB. However, since Decode Assists are optional as they may
not be advertised in nested SVM setup, a fallback route is provided as well.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V hypercall handler

Provide a way for guests to call into Jailhouse on AMD-V systems. Real work
is delegated to generic vcpu_handle_hypercall() handler.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Trap MSR access for AMD-V cells

Jailhouse traps read and write MSR access for two main purposes:

 * Emulating x2APIC  on xAPIC-only hardware (all real-world AMD CPUs)
 * Preventing cells from clearing EFER.SVME bit

In the latter case, TLB also needs to be flushed.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Trap xAPIC register writes under AMD-V

Jailhouse maps APIC MMIO page to cells read-only, so it only needs to handle
register writes, which are translated to Nested Page Faults. The real work is
delegated to generic apic_mmio_access(), which requires guest page tables to
work. These are obtained with vcpu_get_guest_paging_structs(), which supports
real mode cells as well.

As there is no AVIC support for any known AMD hardware, AVIC-related VM exits
are nor intercepted neither handled in Jailhouse.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add generic NPF handler for AMD-V code

This completes Nested Page Fault handler introduced in the previous commit
with generic NPF handling route. The actual handling code is shared between
VMX and SVM, so we simply need to call vcpu_handle_pt_violation() and
implement the appropriate data wrapper.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
x86: Add AMD-V port-based I/O VM exit handler

This is just the same as NPF handler: all real work is done in
vcpu_handle_io_access().

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>