69 Commits
Author SHA1 Message Date
Sergey Dyasli b95a72bb5b tools/xen-ucode: print information about currently loaded ucode
Add an option to xen-ucode tool to print the currently loaded ucode
revision and also print it during usage info.  Print CPU signature and
platform flags as well.  The raw data comes from XENPF_get_cpu_version
and XENPF_get_ucode_revision platform ops.

Example output:
    Intel: CPU signature 06-55-04 (raw 0x00050654) pf 0x1 revision 0x02006e05
      AMD: CPU signature 19-01-01 (raw 0x00a00f11) revision 0x0a0011ce

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2023-05-03 18:36:46 +01:00
Sergey Dyasli 161c37d020 x86/platform: introduce XENPF_get_ucode_revision
Currently it's hard to get CPU's microcode revision from Xen after late
loading without looking into Xen logs, which is not always convenient.

Add a new platform op in order to get the required data from Xen and
provide a wrapper for libxenctrl.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2023-05-03 18:36:46 +01:00
Sergey Dyasli f1e574fa6d tools/xenctrl: add xc_get_cpu_version()
As a wrapper for XENPF_get_cpu_version platform op.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2023-05-03 18:36:46 +01:00
Sergey Dyasli f1315e48a0 x86/ucode/AMD: late load the patch on every logical thread
Currently late ucode loading is performed only on the first core of CPU
siblings.  But according to the latest recommendation from AMD, late
ucode loading should happen on every logical thread/core on AMD CPUs.

To achieve that, introduce is_cpu_primary() helper which will consider
every logical cpu as "primary" when running on AMD CPUs.  Also include
Hygon in the check for future-proofing.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2023-02-28 14:51:28 +01:00
Sergey Dyasli f4ef8a41b8 x86/ucode/AMD: apply the patch early on every logical thread
The original issue has been reported on AMD Bulldozer-based CPUs where
ucode loading loses the LWP feature bit in order to gain the IBPB bit.
LWP disabling is per-SMT/CMT core modification and needs to happen on
each sibling thread despite the shared microcode engine. Otherwise,
logical CPUs will end up with different cpuid capabilities.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216211

Guests running under Xen happen to be not affected because of levelling
logic for the feature masking/override MSRs which causes the LWP bit to
fall out and hides the issue. The latest recommendation from AMD, after
discussing this bug, is to load ucode on every logical CPU.

In Linux kernel this issue has been addressed by e7ad18d1169c
("x86/microcode/AMD: Apply the patch early on every logical thread").
Follow the same approach in Xen.

Introduce SAME_UCODE match result and use it for early AMD ucode
loading. Take this opportunity and move opt_ucode_allow_same out of
compare_revisions() to the relevant callers and also modify the warning
message based on it. Intel's side of things is modified for consistency
but provides no functional change.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2023-02-21 15:08:05 +01:00
Sergey Dyasli dc380df12a x86/ucode: load microcode earlier on boot CPU
Call early_microcode_init() straight after multiboot modules become
accessible. Modify it to load the ucode directly from the blob bypassing
populating microcode_cache because xmalloc is still not available at
that point during Xen boot.

Introduce early_microcode_init_cache() for populating microcode_cache.
It needs to rescan the modules in order to find the new virtual address
of the ucode blob because it changes during the boot process, e.g.
from 0x00000000010802fc to 0xffff83204dac52fc.

While at it, drop alternative_vcall() from early_microcode_init() since
it's not useful in an __init fuction.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2022-12-20 19:33:04 +00:00
Sergey Dyasli 44a6871a5b x86/ucode: allow cpu_request_microcode() to skip memory allocation
This is a preparatory step in order to do earlier microcode loading on
the boot CPU when the domain heap has not been initialized yet and
xmalloc still unavailable.

Add make_copy argument which will allow to load microcode directly from
the blob bypassing microcode_cache.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2022-12-20 19:33:04 +00:00
Sergey Dyasli 1233294a8d xen/multiboot: add proper struct definitions to typedefs
This allows to use them for forward declaration in other headers.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2022-12-20 19:33:04 +00:00
Sergey Dyasli 35b819c45c sched: print information about scheduling granularity
Currently it might be not obvious which scheduling mode (e.g. core-
scheduling) is being used by the scheduler. Alleviate this by printing
additional information about the selected granularity per-cpupool.

Note: per-cpupool granularity selection is not implemented yet. Every
      cpupool gets its granularity from the single global value.

Take this opportunity to introduce struct sched_gran_name array and
refactor sched_select_granularity().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Dario Faggioli <dfaggioli@suse.com>
2020-05-07 18:58:04 +01:00
Sergey Dyasli 82dd1a956d sched: fix scheduler_disable() with core scheduling
In core-scheduling mode, Xen might crash when entering ACPI S5 state.
This happens in sched_slave() during is_idle_unit(next) check because
next->vcpu_list is stale and points to an already freed memory.

This situation happens shortly after scheduler_disable() is called if
some CPU is still inside sched_slave() softirq. Current logic simply
returns prev->next_task from sched_wait_rendezvous_in() which causes
the described crash because next_task->vcpu_list has become invalid.

Fix the crash by returning NULL from sched_wait_rendezvous_in() in
the case when scheduler_disable() has been called.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Dario Faggioli <dfaggioli@suse.com>
2020-04-17 09:28:16 +02:00
Sergey Dyasli 72580a8d3c x86/microcode: refuse to load the same revision ucode
Currently if a user tries to live-load the same or older ucode revision
than CPU already has, he will get a single message in Xen log like:

    (XEN) 128 cores are to update their microcode

No actual ucode loading will happen and this situation can be quite
confusing. Fix this by starting ucode update only when the provided
ucode revision is higher than the currently cached one (if any).
This is based on the property that if microcode_cache exists, all CPUs
in the system should have at least that ucode revision.

Additionally, print a user friendly message if no matching or newer
ucode can be found in the provided blob. This also requires ignoring
-ENODATA in AMD-side code, otherwise the message given to the user is:

    (XEN) Parsing microcode blob error -61

Which actually means that a ucode blob was parsed fine, but no matching
ucode was found.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Chao Gao <chao.gao@intel.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
2019-11-27 12:53:41 +00:00
Sergey Dyasli 83ac5ab54b x86/e820: fix 640k - 1M region reservation logic
Converting a guest from PV to PV-in-PVH makes the guest to have 384k
less memory, which may confuse guest's balloon driver. This happens
because Xen unconditionally reserves 640k - 1M region in E820 despite
the fact that it's really a usable RAM in PVH boot mode.

Fix this by skipping region type change in virtualised environments,
trusting whatever memory map our hypervisor has provided.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
2019-11-21 15:49:58 +00:00
Sergey Dyasli 5ed12565aa microcode: rendezvous CPUs in NMI handler and load ucode
When one core is loading ucode, handling NMI on sibling threads or
on other cores in the system might be problematic. By rendezvousing
all CPUs in NMI handler, it prevents NMI acceptance during ucode
loading.

Basically, some work previously done in stop_machine context is
moved to NMI handler. Primary threads call in and load ucode in
NMI handler. Secondary threads wait for the completion of ucode
loading on all CPU cores. An option is introduced to disable this
behavior.

Control thread doesn't rendezvous in NMI handler by calling self_nmi()
(in case of unknown_nmi_error() being triggered). The side effect is
control thread might be handling an NMI while other threads are loading
ucode. If an ucode is to update something shared by a whole socket,
control thread may be accessing things that are being updating by the
ucode loading on other cores. It is not safe. Update ucode on the
control thread first to mitigate this issue.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2019-10-02 13:35:44 +02:00
Sergey Dyasli ddc5a85fbc x86/shim: fix ballooning down the guest
Currently ballooning down a pvshim guest causes the following errors
inside the shim:

    d3v0 failed to reserve 512 extents of order 512 for offlining

And the ballooned-out pages stay inside shim and don't reach L0 Xen.

Fix this by passing the correct arguments to pv_shim_offline_memory()
during a XENMEM_decrease_reservation request.

Fixes: b2245acc60 ('xen/pvshim: memory hotplug')
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
2019-09-26 18:06:07 +02:00
Sergey Dyasli 2bb2c55cf8 x86/microcode: always collect_cpu_info() during boot
Currently cpu_sig struct is not updated during boot if no microcode blob
is specified by "ucode=[<interger>| scan]".

It will result in cpu_sig.rev being 0 which affects APIC's
check_deadline_errata() and retpoline_safe() functions.

Fix this by getting ucode revision early during boot and SMP bring up.
While at it, protect early_microcode_update_cpu() for cases when
microcode_ops is NULL.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Chao Gao <chao.gao@intel.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2019-08-01 18:45:32 +01:00
Sergey Dyasli 3af3c95b81 x86/vvmx: set CR4 before CR0
Otherwise hvm_set_cr0() will check the wrong CR4 bits (L1 instead of L2
and vice-versa).

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2019-06-28 13:17:53 +01:00
Sergey Dyasli 5ac2dddb17 mm/page_alloc: fix MEMF_no_dma allocations for single NUMA
Currently dma_bitsize is zero by default on single NUMA node machines.
This makes all alloc_domheap_pages() calls with MEMF_no_dma return NULL.

There is only 1 user of MEMF_no_dma: dom0_memflags, which are used
during memory allocation for Dom0. Failing allocation with default
dom0_memflags is especially severe for the PV Dom0 case: it makes
alloc_chunk() to use suboptimal 2MB allocation algorithm with a search
for higher memory addresses.

This can lead to the NMI watchdog timeout during PV Dom0 construction
on some machines, which can be worked around by specifying "dma_bits"
in Xen's cmdline manually.

Fix the issue by ignoring MEMF_no_dma in cases when dma_bitsize is zero,
which means there is no DMA zone. This shouldn't cause any issues for
Dom0 because alloc_heap_pages() will first use higher memory addresses
for satisfying memory allocation requests.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2019-01-09 15:45:14 +01:00
Sergey Dyasli b81b9b9bdb x86/dom0: use MEMF_no_scrub during Dom0 construction
Now that idle scrub is the default option, all memory is marked as dirty
and alloc_domheap_pages() will do eager scrubbing by default. This can
lead to longer Dom0 construction and potentially to a watchdog timeout,
especially on older H/W (e.g. Harpertown).

Pass MEMF_no_scrub to optimise this process since there is little point
in scrubbing memory for Dom0.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
2018-11-22 14:30:14 +01:00
Sergey Dyasli 5dbbaa0fe1 x86/vvmx: fix I/O and MSR bitmaps mapping
Currently Xen tries to map bitmaps during emulation of vmptrld and
vmwrite. This is wrong: a guest can store arbitrary values in those
fields.

Make bitmaps mapping happen only during a nested vmentry and only if
the appropriate execution controls are turned on by L1 hypervisor.

For performance reasons, Xen maps bitmaps only:

    1. During the first nested vmentry
    2. After L1 has changed an appropriate vmcs field
    3. After nvmx_purge_vvmcs() was previously called

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli 8885ac7f18 x86/vvmx: correctly report vvmcs size
The size of Xen's virtual vmcs region is 4096 bytes (see comment about
Virtual VMCS layout in include/asm-x86/hvm/vmx/vvmx.h). Correctly report
it to the guest in case when VMCS shadowing is not available instead of
providing H/W value (which is usually smaller).

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli 6f4c1f8a00 x86/vvmx: refactor nvmx_handle_vmclear()
1. Add VMX_INSN_VMCLEAR_WITH_VMXON_PTR errno and add the appropriate
   check to the function.

2. Correct the return value for not-4KB-aligned case and for invalid
   physaddr (when hvm_map_guest_frame_rw() fails).

3. Remove enum vmx_ops_result and use vmfail/vmsucceed() calls directly.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli cd04762497 x86/vvmx: add VMX_INSN_VMPTRLD_WITH_VMXON_PTR errno
And make nvmx_handle_vmptrld() return the new errno in case the provided
address is the same as vmxon region address.

While at it, correct the return value for not-4KB-aligned case.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli cadebcebfd x86/vvmx: correct vmfail() usage for vmptrld and vmclear
Calling vmfail_valid() is correct only if vvmcx is valid. Modify
functions to use vmfail() instead which performs the necessary check.

While at it, add ASSERTs into vmfail_valid/invalid() to quickly catch
an incorrect usage in the future.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli 2593a14e20 x86/vvmx: add VMX_INSN_INVEPT_INVVPID_INVALID_OP errno
And use it in nvmx_handle_invept() and nvmx_handle_invvpid().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli 006cf1093d x86/nestedhvm: introduce vvmcx_valid()
As a convenient helper function and refactor the code to use it.

No functional change.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli 51c475f4b8 x86/nestedhvm: init nv_vvmcxaddr in hvm_vcpu_initialise()
This allows to safely use nestedhvm functions that rely on the values
inside struct nestedvcpu independently of the nested virtualisation
(HVM_PARAM_NESTEDHVM) status of a domain.

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2018-11-14 18:42:48 +00:00
Sergey Dyasli c2b640cd40 mm/page_alloc: fix a typo in printk for idle scrub
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2018-11-14 18:22:40 +00:00
Sergey Dyasli 0b24ef7853 mm/page_alloc: make bootscrub happen in idle-loop
Scrubbing RAM during boot may take a long time on machines with lots
of RAM. Add 'idle' option to bootscrub which marks all pages dirty
initially so they will eventually be scrubbed in idle-loop on every
online CPU.

It's guaranteed that the allocator will return scrubbed pages by doing
eager scrubbing during allocation (unless MEMF_no_scrub was provided).

Use the new 'idle' option as the default one.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2018-11-07 09:34:17 +01:00
Sergey Dyasli 60529dfeca x86/domctl: Implement XEN_DOMCTL_get_cpu_policy
This finally (after literally years of work!) marks the point where the
toolstack can ask the hypervisor for the current CPUID configuration of a
specific domain.

Introduce a new flask access vector and update the default policies.

Also extend xen-cpuid's --policy mode to be able to take a domid and dump a
specific domains CPUID and MSR policy.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
2018-11-06 17:51:18 +00:00
Sergey Dyasli 6b85e42709 x86/sysctl: Implement XEN_SYSCTL_get_cpu_policy
Provide a SYSCTL for the toolstack to obtain complete system CPUID and MSR
policy information.

For the flask side of things, this subop is closely related to
{phys,cputopo,numa}info, so shares the physinfo access vector.

Extend the xen-cpuid utility to be able to dump the system policies.  An
example output is:

  Xen reports there are maximum 113 leaves and 3 MSRs
  Raw policy: 93 leaves, 3 MSRs
   CPUID:
    leaf     subleaf  -> eax      ebx      ecx      edx
    00000000:ffffffff -> 0000000d:756e6547:6c65746e:49656e69
    00000001:ffffffff -> 000306c3:00100800:7ffafbff:bfebfbff
    00000002:ffffffff -> 76036301:00f0b5ff:00000000:00c10000
    00000004:00000000 -> 1c004121:01c0003f:0000003f:00000000
    00000004:00000001 -> 1c004122:01c0003f:0000003f:00000000
    00000004:00000002 -> 1c004143:01c0003f:000001ff:00000000
    00000004:00000003 -> 1c03c163:03c0003f:00001fff:00000006
    00000005:ffffffff -> 00000040:00000040:00000003:00042120
    00000006:ffffffff -> 00000077:00000002:00000009:00000000
    00000007:00000000 -> 00000000:000027ab:00000000:9c000000
    0000000a:ffffffff -> 07300403:00000000:00000000:00000603
    0000000b:00000000 -> 00000001:00000002:00000100:00000000
    0000000b:00000001 -> 00000004:00000008:00000201:00000000
    0000000d:00000000 -> 00000007:00000340:00000340:00000000
    0000000d:00000001 -> 00000001:00000000:00000000:00000000
    0000000d:00000002 -> 00000100:00000240:00000000:00000000
    80000000:ffffffff -> 80000008:00000000:00000000:00000000
    80000001:ffffffff -> 00000000:00000000:00000021:2c100800
    80000002:ffffffff -> 65746e49:2952286c:6f655820:2952286e
    80000003:ffffffff -> 55504320:2d334520:30343231:20337620
    80000004:ffffffff -> 2e332040:48473034:0000007a:00000000
    80000006:ffffffff -> 00000000:00000000:01006040:00000000
    80000007:ffffffff -> 00000000:00000000:00000000:00000100
    80000008:ffffffff -> 00003027:00000000:00000000:00000000
   MSRs:
    index    -> value
    000000ce -> 0000000080000000

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Wei Liu <wei.liu2@citrix.com>
2018-11-06 17:51:18 +00:00
Sergey Dyasli 072e054359 x86/boot: enable NMIs after traps init
In certain scenarios, NMIs might be disabled during Xen boot process.
Such situation will cause alternative_instructions() to:

    panic("Timed out waiting for alternatives self-NMI to hit\n");

This bug was originally seen when using Tboot to boot Xen 4.11

To prevent this from happening, enable NMIs during cpu_init() and
during __start_xen() for BSP.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2018-10-23 12:33:54 +01:00
Sergey Dyasli 1e2df96088 mm/page_alloc: correct first_dirty calculations during block merging
Currently it's possible to hit an assertion in alloc_heap_pages():

Assertion 'first_dirty != INVALID_DIRTY_IDX || !(pg[i].count_info & PGC_need_scrub)' failed at page_alloc.c:988

This can happen because a piece of logic to calculate first_dirty
during block merging in free_heap_pages() is missing for the following
scenario:

1. Current block's first_dirty equals to INVALID_DIRTY_IDX
2. Successor block is free but its first_dirty != INVALID_DIRTY_IDX
3. The successor is merged into current block
4. Current block's first_dirty still equals to INVALID_DIRTY_IDX

This will trigger the assertion during allocation of such block in
alloc_heap_pages() because there will be pages with PGC_need_scrub
bit set despite the claim of first_dirty that the block is scrubbed.

Add the missing piece of logic and slightly update the comment for
the predecessor case to better capture the code's intent.

Fixes 1a37f33ea6 ("mm: Place unscrubbed pages at the end of pagelist")

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
2018-07-12 10:45:11 +02:00
Sergey Dyasli 4510046032 x86/cpuid: update signature of hvm_cr4_guest_valid_bits()
With the new cpuid infrastructure there is a domain-wide struct cpuid
policy and there is no need to pass a separate struct vcpu * into
hvm_cr4_guest_valid_bits() anymore. Make the function accept struct
domain * instead and update callers.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2018-04-05 10:41:42 +01:00
Sergey Dyasli 0d9acbdd8d pv_console: remove unnecessary #ifdefs
The header for PV console contains empty function definitions in case of
!CONFIG_XEN_GUEST specially to avoid #ifdefs in a code that uses them
to make the code look cleaner.

Unfortunately, during the release of shim-comet, PV console functions
were enclosed into unnecessary #ifdefs CONFIG_X86. Remove them.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
2018-03-06 16:47:34 +01:00
Sergey Dyasli 197fbdb501 x86/msr: add Raw and Host domain policies
Raw policy contains the actual values from H/W MSRs. Add PLATFORM_INFO
msr to the policy during probe_cpuid_faulting().

Host policy may have certain features disabled if Xen decides not
to use them. For now, make Host policy equal to Raw policy with
cpuid_faulting availability dependent on X86_FEATURE_CPUID_FAULTING.

Finally, derive HVM/PV max domain policies from the Host policy.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2018-02-20 18:35:27 +00:00
Sergey Dyasli daed6261fd xen/pvshim: add shim_mem cmdline parameter
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
2018-01-16 18:34:05 +00:00
Sergey Dyasli 5ef49f185c x86/pv-shim: shadow PV console's page for L2 DomU
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
[remove notify_guest helper and directly use pv_shim_inject_evtchn]
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
2018-01-16 18:34:05 +00:00
Sergey Dyasli 4f6609d6a6 x86/guest: use PV console for Xen/Dom0 I/O
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
2018-01-16 18:34:04 +00:00
Sergey Dyasli 335eba772b x86/guest: add PV console code
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
2018-01-16 18:34:04 +00:00
Sergey Dyasli 19fdb8e258 x86/vvmx: don't enable vmcs shadowing for nested guests
Running "./xtf_runner vvmx" in L1 Xen under L0 Xen produces the
following result on H/W with VMCS shadowing:

    Test: vmxon
    Failure in test_vmxon_in_root_cpl0()
      Expected 0x8200000f: VMfailValid(15) VMXON_IN_ROOT
           Got 0x82004400: VMfailValid(17408) <unknown>
    Test result: FAILURE

This happens because SDM allows vmentries with enabled VMCS shadowing
VM-execution control and VMCS link pointer value of ~0ull. But results
of a nested VMREAD are undefined in such cases.

Fix this by not copying the value of VMCS shadowing control from vmcs01
to vmcs02.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-12-01 19:03:27 +00:00
Sergey Dyasli 23044a4e00 x86/np2m: add break to np2m_flush_eptp()
Now that np2m sharing is implemented, there can be only one np2m object
with the same np2m_base. Break from loop if the required np2m was found
during np2m_flush_eptp().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli cf23c69fdd x86/np2m: refactor p2m_get_nestedp2m_locked()
Remove some code duplication.

Suggested-by: George Dunlap <george.dunlap@citrix.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli 6df4b481b0 x86/np2m: implement sharing of np2m between vCPUs
At the moment, nested p2ms are not shared between vcpus even if they
share the same base pointer.

Modify p2m_get_nestedp2m() to allow sharing a np2m between multiple
vcpus with the same np2m_base (L1 np2m_base value in VMCx12).

If the current np2m doesn't match the current base pointer, first look
for another nested p2m in the same domain with the same base pointer,
before reclaiming one from the LRU.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli a65a24209c x86/np2m: send flush IPIs only when a vcpu is actively using an np2m
Flush IPIs are sent to all cpus in an np2m's dirty_cpumask when
updated.  This mask however is far too broad.  A pcpu's bit is set in
the cpumask when a vcpu runs on that pcpu, but is only cleared when a
flush happens.  This means that the IPI includes the current pcpu of
vcpus that are not currently running, and also includes any pcpu that
has ever had a vcpu use this p2m since the last flush (which in turn
will cause spurious invalidations if a different vcpu is using an np2m).

Avoid these IPIs by keeping closer track of where an np2m is being used,
and when a vcpu needs to be flushed:

- On schedule-out, clear v->processor in p2m->dirty_cpumask
- Add a 'generation' counter to the p2m and nestedvcpu structs to
  detect changes that would require re-loads on re-entry
- On schedule-in or p2m change:
  - Set v->processor in p2m->dirty_cpumask
  - flush the vcpu's nested p2m pointer (and update nv->generation) if
    the generation changed

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli 7b6546e831 x86/vvmx: make updating shadow EPTP value more efficient
At the moment, the shadow EPTP value is written unconditionally in
ept_handle_violation().

Instead, write the value on vmentry to the guest; but only write it if
the value needs updating.

To detect this, add a flag to the nestedvcpu struct, stale_np2m, to
indicate when such an action is necessary.  Set it when the nested p2m
changes or when the np2m is flushed by an IPI, and clear it when we
write the new value.

Since an IPI invalidating the p2m may happen between
nvmx_switch_guest() and vmx_vmenter, but we can't perform the vmwrite
with interrupts disabled, check the flag just before entering the
guest and restart the vmentry if it's set.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli ec832dddc4 x86/np2m: simplify nestedhvm_hap_nested_page_fault()
There is a possibility for nested_p2m to became stale between
nestedhvm_hap_nested_page_fault() and nestedhap_fix_p2m().  At the moment
this is handled by detecting such a race inside nestedhap_fix_p2m() and
special-casing it.

Instead, introduce p2m_get_nestedp2m_locked(), which will returned a
still-locked p2m.  This allows us to call nestedhap_fix_p2m() with the
lock held and remove the code detecting the special-case.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli cd579578aa x86/np2m: remove np2m_base from p2m_get_nestedp2m()
Remove np2m_base parameter as it should always match the value of
np2m_base in VMCx12.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli 77690ea09a x86/np2m: flush all np2m objects on nested INVEPT
At the moment, nvmx_handle_invept() updates the current np2m just to
flush it.  Instead introduce a function, np2m_flush_base(), which will
look up the np2m base pointer and call p2m_flush_table() instead.

Unfortunately, since we don't know which p2m a given vcpu is using, we
must flush all p2ms that share that base pointer.

Convert p2m_flush_table() into p2m_flush_table_locked() in order not
to release the p2m_lock after np2m_base check.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli a08a9cd3af x86/np2m: refactor p2m_get_nestedp2m()
1. Add a helper function assign_np2m()
2. Remove useless volatile
3. Update function's comment in the header
4. Minor style fixes ('\n' and d)

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
2017-10-06 13:36:43 +01:00
Sergey Dyasli 664adc5cca x86/msr: introduce guest_wrmsr()
The new function is responsible for handling WRMSR from both HVM and PV
guests. Currently it handles only 2 MSRs:

    MSR_INTEL_PLATFORM_INFO
    MSR_INTEL_MISC_FEATURES_ENABLES

It has a different behaviour compared to the old MSR handlers: if MSR
is being handled by guest_wrmsr() then WRMSR will either succeed (if
a guest is allowed to access it and provided a correct value based on
its MSR policy) or produce a GP fault. A guest will never see
a successful WRMSR of some MSR unknown to this function.

guest_wrmsr() unifies and replaces the handling code from
vmx_msr_write_intercept() and priv_op_write_msr().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

This also fixes a bug on AMD hardware where a guest which tries to
enable CPUID faulting via a direct write to the MSR will observe it
appearing to succeed, but because Xen actually ignored the write.

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2017-09-25 10:56:52 +02:00
Sergey Dyasli 37f074a338 x86/msr: introduce guest_rdmsr()
The new function is responsible for handling RDMSR from both HVM and PV
guests. Currently it handles only 2 MSRs:

    MSR_INTEL_PLATFORM_INFO
    MSR_INTEL_MISC_FEATURES_ENABLES

It has a different behaviour compared to the old MSR handlers: if MSR
is being handled by guest_rdmsr() then RDMSR will either succeed (if
a guest is allowed to access it based on its MSR policy) or produce
a GP fault. A guest will never see a H/W value of some MSR unknown to
this function.

guest_rdmsr() unifies and replaces the handling code from
vmx_msr_read_intercept() and priv_op_read_msr().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>

This (along with the prep work in init_domain_msr_policy()) also fixes
a bug where Dom0 could probe and find CPUID faulting, even though it
couldn't actually use it.

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2017-09-25 10:56:13 +02:00
Sergey Dyasli e7a370733b x86: replace arch_vcpu::cpuid_faulting with msr_vcpu_policy
Since each vCPU now has struct msr_vcpu_policy, use cpuid_faulting bit
from there in current logic and remove arch_vcpu::cpuid_faulting.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2017-09-25 10:55:23 +02:00
Sergey Dyasli 4187f79dc7 x86/msr: introduce struct msr_vcpu_policy
The new structure contains information about guest's MSRs that are
unique to each vCPU. It starts with only 1 MSR:

    MSR_INTEL_MISC_FEATURES_ENABLES

Which currently has only 1 usable bit: cpuid_faulting.

Add 2 global policy objects: hvm_max and pv_max that are inited during
boot up. Availability of MSR_INTEL_MISC_FEATURES_ENABLES depends on
availability of MSR_INTEL_PLATFORM_INFO.

Add init_vcpu_msr_policy() which sets initial MSR policy for every vCPU
during domain creation with a special case for Dom0.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2017-09-25 10:54:09 +02:00
Sergey Dyasli 4098b092e1 x86/msr: introduce struct msr_domain_policy
The new structure contains information about guest's MSRs that are
shared between all domain's vCPUs. It starts with only 1 MSR:

    MSR_INTEL_PLATFORM_INFO

Which currently has only 1 usable bit: cpuid_faulting.

Add 2 global policy objects: hvm_max and pv_max that are inited during
boot up. It's always possible to emulate CPUID faulting for HVM guests
while for PV guests the H/W support is required.

Add init_domain_msr_policy() which sets initial MSR policy during
domain creation with a special case for Dom0.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
2017-09-25 10:53:00 +02:00
Sergey Dyasli 41d1fcb1c9 x86/vvmx: add hvm_intsrc_vector support to nvmx_intr_intercept()
Under the following circumstances:

    1. L1 doesn't enable PAUSE exiting or PAUSE-loop exiting controls
    2. L2 executes PAUSE in a loop with RFLAGS.IE == 0

L1's PV IPI through event channel will never reach the target L1's vCPU
which runs L2 because nvmx_intr_intercept() doesn't know about
hvm_intsrc_vector. This leads to infinite L2 loop without nested
vmexits and can cause L1 to hang.

The issue is easily reproduced with Qemu/KVM on CentOS-7-1611 as L1
and an L2 guest with SMP.

Fix nvmx_intr_intercept() by injecting hvm_intsrc_vector irq into L1
which will cause nested vmexit.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-09-20 17:17:21 +02:00
Sergey Dyasli 6b792e28bc vvmx: fix ept_sync() for nested p2m
If ept_sync_domain() is called for np2m, the following happens:

    1. *np2m*::ept_data::invalidate cpumask is updated
    2. IPIs are sent for CPUs in domain_dirty_cpumask forcing vmexits
    3. vmx_vmenter_helper() checks *hostp2m*::ept_data::invalidate
       and does nothing

Which is clearly a bug. Make ept_sync_domain() to update hostp2m's
invalidate mask in nested p2m case and make vmx_vmenter_helper() to
invalidate EPT translations for all EPTPs if nested virt is enabled.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-06-30 11:27:51 +01:00
Sergey Dyasli b22ee98c4e x86/vvmx: add a shadow vmcs check to vmlaunch
Intel SDM states that if the current VMCS is a shadow VMCS,
VMFailInvalid occurs and control passes to the next instruction.

Implement such behaviour for nested vmlaunch.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-03-14 12:25:47 +01:00
Sergey Dyasli dc05c0ceeb x86/vvmx: correct nested shadow VMCS handling
Currently xen always sets the shadow VMCS-indicator bit on nested
vmptrld and always clears it on nested vmclear.  This behavior is
wrong when the guest loads a shadow VMCS: shadow bit will be lost
on nested vmclear.

Fix this by checking if the guest has provided a shadow VMCS.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-03-14 12:25:14 +01:00
Sergey Dyasli 7ecd11c90a x86/vvmx: add mov-ss blocking check to vmentry
Intel SDM states that if there is a current VMCS and there is MOV-SS
blocking, VMFailValid occurs and control passes to the next instruction.

Implement such behaviour for nested vmlaunch and vmresume.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-03-14 12:24:38 +01:00
Sergey Dyasli e3f6493827 x86/vvmx: add vmcs id check into vmptrld emulation
If a guest will do vmptrld with an incorrect vmcs id:

(XEN) Xen BUG at .../git/upstream/xen/xen/include/asm/hvm/vmx/vmx.h:333
(XEN) ----[ Xen-4.9-unstable  x86_64  debug=y   Tainted:    H ]----
(XEN) Xen call trace:
(XEN)    [<ffff82d0801f925e>] vmcs.c#arch/x86/hvm/vmx/vmcs.o.unlikely+0x28/0x19a
(XEN)    [<ffff82d0801f602c>] virtual_vmcs_vmread+0x11/0x2c
(XEN)    [<ffff82d0802002cc>] vvmx.c#_map_io_bitmap+0x86/0x88
(XEN)    [<ffff82d080202399>] nvmx_handle_vmptrld+0xf0/0x1fb
(XEN)    [<ffff82d0801fe93c>] vmx_vmexit_handler+0x132b/0x1c49
(XEN)    [<ffff82d080203e6c>] vmx_asm_vmexit_handler+0x3c/0x120

Fix this by adding appropriate checks for vmcs id during vmptrld
emulation.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-03-03 11:59:22 +01:00
Sergey Dyasli a013e1b9e9 x86/vvmx: check vmcs address in vmread/vmwrite
If nested vmcs's address is invalid, virtual_vmcs_enter() will fail
during vmread/vmwrite:

(XEN) Xen BUG at .../git/upstream/xen/xen/include/asm/hvm/vmx/vmx.h:333
(XEN) ----[ Xen-4.9-unstable  x86_64  debug=y   Tainted:    H ]----
(XEN) Xen call trace:
(XEN)    [<ffff82d0801f925e>] vmcs.c#arch/x86/hvm/vmx/vmcs.o.unlikely+0x28/0x19a
(XEN)    [<ffff82d0801f60e3>] virtual_vmcs_vmwrite_safe+0x16/0x52
(XEN)    [<ffff82d080202cb2>] nvmx_handle_vmwrite+0x70/0xfe
(XEN)    [<ffff82d0801fe98a>] vmx_vmexit_handler+0x1379/0x1c49
(XEN)    [<ffff82d08020427c>] vmx_asm_vmexit_handler+0x3c/0x120

Fix this by emulating VMfailInvalid if the address is invalid.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-03-03 11:58:47 +01:00
Sergey Dyasli d6e9f8d4f3 x86/vmx: fix vmentry failure with TSX bits in LBR
During VM entry, H/W will automatically load guest's MSRs from MSR-load
area in the same way as they would be written by WRMSR.

However, under the following conditions:

    1. LBR (Last Branch Record) MSRs were placed in the MSR-load area
    2. Address format of LBR includes TSX bits 61:62
    3. CPU has TSX support disabled

VM entry will fail with a message in the log similar to:

    (XEN) [   97.239514] d1v0 vmentry failure (reason 0x80000022): MSR loading (entry 3)
    (XEN) [   97.239516]   msr 00000680 val 1fff800000102e60 (mbz 0)

This happens because of the following behaviour:

    - When capturing branches, LBR H/W will always clear bits 61:62
      regardless of the sign extension
    - For WRMSR, bits 61:62 are considered the part of the sign extension

This bug affects only certain pCPUs (e.g. Haswell) with vCPUs that
use LBR.  Fix it by sign-extending TSX bits in all LBR entries during
VM entry in affected cases.

LBR MSRs are currently not Live Migrated. In order to implement such
functionality, the MSR levelling work has to be done first because
hosts can have different LBR formats.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-27 10:22:24 +00:00
Sergey Dyasli 7f11aa4b2b x86/vmx: optimize vmx_read/write_guest_msr()
Replace linear scan with vmx_find_msr().  This way the time complexity
of searching for required MSR reduces from linear to logarithmic.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2017-02-27 10:22:20 +00:00
Sergey Dyasli 9b93c6b369 x86/vmx: introduce vmx_find_msr()
Modify vmx_add_msr() to use a variation of insertion sort algorithm:
find a place for the new entry and shift all subsequent elements before
insertion.

The new vmx_find_msr() exploits the fact that MSR list is now sorted
and reuses the existing code for binary search.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-27 10:22:12 +00:00
Sergey Dyasli 62c7b99a10 x86/vvmx: correctly emulate VMREAD
There is an issue with the original __vmread() in nested vmx mode:
emulation of a guest's VMREAD with invalid arguments leads to BUG().

Fix this by using vmread_safe() and reporting any kind of VMfail back
to the guest.

A new safe versions of get_vvmcs() macro and related functions are
introduced because of new function signatures and lots of existing
users.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-14 10:25:27 +00:00
Sergey Dyasli d18216a0c0 x86/vvmx: correctly emulate VMWRITE
There is an issue with the original __vmwrite() in nested vmx mode:
emulation of a guest's VMWRITE with invalid arguments leads to BUG().

Fix this by using vmwrite_safe() and reporting any kind of VMfail back
to the guest.

A new safe versions of set_vvmcs() macro and related functions are
introduced because of new function signatures and lots of existing
users.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-14 10:25:18 +00:00
Sergey Dyasli 195ca0e1de x86/vmx: introduce VMX_INSN_SUCCEED
The new value corresponds to VMsucceed status of VMX instructions.
This will replace usage of literal zeroes in related functions.

Update vmfail(), vmread_safe() and vmwrite_safe().

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-14 10:25:05 +00:00
Sergey Dyasli 1edbf34e63 x86/vmx: improve vmread_safe()
The original function doesn't distinguish between Valid and Invalid
VMfails.  Improved function returns error code depending on the outcome:

        VMsucceed: 0
      VMfailValid: VM Instruction Error Number
    VMfailInvalid: VMX_INSN_FAIL_INVALID (~0)

Existing users of __vmread_safe() are updated and double underscore
prefix is removed from the function's name because such prefixes are
reserved to a compiler.

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-09 11:07:31 +01:00
Sergey Dyasli d4a24c64b6 x86/vmx: introduce vmwrite_safe()
Any fail during the original __vmwrite() leads to BUG() which can be
easily exploited from a guest in the nested vmx mode.

The new function returns error code depending on the outcome:

          VMsucceed: 0
        VMfailValid: VM Instruction Error Number
      VMfailInvalid: a new VMX_INSN_FAIL_INVALID

A new macro GAS_VMX_OP is introduced in order to improve the
readability of asm.  Existing ASM_FLAG_OUT macro is reused and copied
into asm_defns.h

Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
2017-02-09 11:07:01 +01:00