In virtual-8086 mode with IOPL < 3, INT n raises #GP(0). INT1, INT3
and INTO are not affected. They are delivered normally.
svm_emul_swint_injection() applies the check to all of them, so an ICEBP
raises #GP instead of #DB. It also reports the IDT entry in the #GP
error code instead of 0.
Move the check earier prior to setting up ec, and limit it to INT n only.
Fixes: 897d59a426 ("x86/svm: Introduce svm_emul_swint_injection()")
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This is overly agressive. The APM says:
The hypervisor must clear the entire VMCB field to 0 for a guest, under the
following circumstances:
* The hypervisor executes the guest on a different CPU core than one used
the last time that guest was executed.
Clear the cleanbits only when the VMCB is used on a different pCPU rather than
on every context switch to the vCPU.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
... as building and interpreting Ocaml objects in C is rather fragile.
For C producing objects for Ocaml to consume, one trick to check validity is
Gc.compact() which forces a major sweep, walking all objects. If this doesn't
segfault, then we at least got the pointer <-> integer aspects right.
For now, start with a very simple version call. (Re)introduce
tools/ocaml/tests and add test-ocaml-bindings which is installed into
$(DESTDIR)$(LIBEXEC)/tests to be picked up automatically with the other dom0
tests.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Andrii Sultanov <andriy.sultanov@vates.tech>
... rather than editing them after the fact.
This capability exists from Ocaml 4.05 which is also our minimum supported
version.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Andrii Sultanov <andriy.sultanov@vates.tech>
psci_init_0_2() stores the value returned by PSCI_VERSION in the global
psci_ver before checking that Xen supports it. When the firmware reports
a version other than 0.2 or 1.x, the function prints "Unrecognized PSCI
version" and returns -EOPNOTSUPP, but psci_ver keeps the rejected value
and psci_cpu_on_nr stays 0.
psci_init() then tries the PSCI 0.1 fallback, which overwrites psci_ver
on success. When the fallback fails as well (the /psci node is not
compatible with "arm,psci", it has no "cpu_on" property, or Xen boots
with ACPI), psci_init() returns an error that smp_init_cpus() ignores,
and psci_ver still holds the rejected version. All the users of
psci_ver then consider PSCI as available:
- on arm64, smp_psci_init() installs call_psci_cpu_on() as the method
to bring up the secondary CPUs;
- on arm32, platform_cpu_up() calls call_psci_cpu_on() instead of the
platform specific cpu_up() callback;
- call_psci_cpu_off(), call_psci_system_off() and
call_psci_system_reset() issue their PSCI calls.
As a result, Xen brings up each secondary CPU with an SMC using function
ID 0. An SMCCC compliant firmware refuses it, and Xen reports "Failed to
bring up CPU<n> (error -1)" for each secondary CPU.
Fix it by setting psci_ver back to 0 before returning the error.
Fixes: 4d3d72c014 ("xen/arm: Initial support for PSCI-0.2")
Signed-off-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This part of the comment is actually about VCPUOP_register_runstate_phys_area
and not VCPUOP_register_runstate_memory_area.
Fixes: d5df44275e ("domain: introduce GADDR based runstate area registration alternative")
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
Acked-by: Jan Beulich <jbeulich@suse.com>
On Arm, the hardware domain does not use the P2M pool. Its P2M pages are
allocated directly from the heap, without any limit. However, when the
hardware domain is created using dom0less, we still allocate a P2M pool
for it, either of the default size or the one given in
xen,domain-p2m-mem-mb. This memory is never used and is simply wasted.
The same applies when the pool size is set for the hardware domain using
XEN_DOMCTL_set_paging_mempool_size.
Don't create the pool for a hardware domain. Make the get/set paging
mempool domctls return -EOPNOTSUPP, skip the pool teardown and reject
xen,domain-p2m-mem-mb for a hardware domain in dom0less.
The dom0less check is Arm specific, because on RISC-V the hardware domain
does use the P2M pool.
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
The DT dma-noncoherent property describes the bus coherency of the
device represented by the node. On an ITS subnode, that is memory
accessed by that ITS. Add GICV3_QUIRK_MEM_NC_NS to the corresponding
host_its and use it when programming GITS_CBASER and GITS_BASER<n>.
On the top-level GIC node, the property describes the Redistributor side
of the LPI path. Collect it in gicv3_lpi_init_host_lpis() and apply it
only to the host LPI policy used when allocating the property and
pending tables and when programming GICR_PROPBASER and GICR_PENDBASER.
Mark the function init-only because firmware attributes are collected
only during boot.
Do not inherit the property between parent and child nodes: ITS-node
non-coherency does not change the global host LPI policy, and GIC-node
non-coherency does not change per-ITS quirk_flags.
ACPI is unchanged; this patch only consumes the DT dma-noncoherent
property.
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
ITS quirks are matched only by IIDR and mask fields stored in each table
entry. That is too coarse when the same GIC IP block appears on several
platforms but a workaround is valid only for some of them.
Replace the fixed IIDR fields with a generic match(hw_its, data)
callback and an opaque data pointer. Add an IIDR matcher as a reusable
building block and use it from the R-Car Gen4 matcher after checking the
Renesas machine compatibles.
This intentionally narrows the R-Car Gen4 quirk. Previously every ITS
with IIDR 0x0201743b matched. Now it matches only a DT-discovered ITS on
an r8a779f0 or r8a779g0 machine. ACPI-discovered ITSes and the same IIDR
on other platforms no longer match.
Keep first-match semantics explicit. Use BUG_ON() if a non-sentinel
entry has no matcher or the IIDR matcher receives no data. A broken
entry must stop Xen in both debug and release builds, as skipping a
required workaround could cause a failure later. Place the matcher data
and table in init-only read-only sections.
The matched entry still supplies separate ITS and LPI flags; this patch
only changes how the entry is selected.
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
ITS quirks can impose restrictions on memory accessed by the ITS itself
and on shared host LPI/Redistributor state. These scopes are not
identical, so a single global ITS quirk state makes the host LPI policy
depend implicitly on the quirks seen while initializing host ITSes.
Add per-ITS quirk_flags to struct host_its and keep a separate
host_lpi_flags state in the LPI code. The quirk table now records the
ITS-private and host LPI scopes explicitly through its_flags and
lpi_flags. The R-Car Gen4 quirk applies the same memory restrictions to
both scopes, preserving the existing R-Car memory policy without relying
on an implicit aggregation step.
This also removes the assumption that all host ITSes must expose the
same quirk state. ITS-derived host LPI restrictions are accumulated only
from quirk entries that explicitly set lpi_flags.
Use per-ITS quirk_flags for GITS_CBASER, GITS_BASER<n>, and ITT
allocations. Use host_lpi_flags when allocating the property and pending
tables and when programming GICR_PROPBASER and GICR_PENDBASER.
Memory-related quirk bits are named GICV3_QUIRK_MEM_* and are translated
by shared gicv3_mem_get_*() helpers.
Collect both scopes during the ITS preparation pass, before host LPI
state is allocated. Keep init-only annotations and includes in the
implementation files rather than the public header.
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
The boot CPU pending table must use the memory attributes selected by
ITS quirks. gicv3_lpi_init_host_lpis() is therefore called after
gicv3_its_init(). However, gicv3_its_init() also programs and enables
each ITS before host LPI state is allocated. No ITS commands are
submitted at that point, but this ordering relies on that implementation
detail.
Split per-ITS initialization into preparation and activation phases.
First map and disable every ITS and collect its quirks. Then initialize
host LPI state. Only after that, allocate and program the ITS tables and
command queue, and enable each ITS.
The subsequent gicv3_cpu_init() sequence remains unchanged: it programs
the Redistributor LPI tables, enables LPIs, and then submits the first
MAPC and SYNC commands.
Drop the now unreachable stub for gicv3_lpi_init_host_lpis().
Suggested-by: Julien Grall <julien@xen.org>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
When the removal spans several ranges, the last one is trimmed by
setting its start to e + 1, and destroyed if that leaves it empty. For
e == ~0UL, e + 1 wraps to 0, so the range is kept as [0, end] and the
removal adds everything below it.
This is hit by pv_shim_shutdown(), whose iomem_deny_access(d, 0, ~0UL)
on resume turns the guest's grant frame permissions into [0, highest
grant frame]. arch_iommu_hwdom_init() can hit it too, for a PVH
hardware domain with an E820 entry above its 48-bit iomem_caps.
Destroy the range when it ends within [s, e] instead.
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
Per the IVMD Flags definition, bit 1 is IR and bit 2 is IW, matching
ACPI_IVMD_READ and ACPI_IVMD_WRITE. parse_ivmd_block() takes iw from
the former and ir from the latter, so a unity range firmware declares
read-only is mapped write-only, and vice versa.
Ranges with both permissions, including Xen's own, are unaffected.
Fixes: e941abd7ca ("ACPI: eliminate duplicate IVRS definitions")
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Acked-by: Roger Pau Monné <roger@xenproject.org>
hvmemul_write_cr() updates guest_cr[2] but, unlike every other writer of
it, doesn't call hvm_update_guest_cr(). On SVM, CR2 is loaded from
the VMCB, so the emulated write never reaches the guest, and the next
VMExit overwrites guest_cr[2] with the stale VMCB value.
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
stub_xc_domain_create() fails unconditionally with "Unhandled: ARM" for
the ARM variant of arch_domainconfig, so no OCaml toolstack (e.g.
xenopsd) can create an ARM domain.
To fix this, convert the two fields of xen_arm_arch_domainconfig,
gic_version and nr_spis, into the corresponding fields of struct
xen_arch_domainconfig and reject values that do not fit, as is already
done for other parameters. The remaining fields (sve_vl, tee_type,
arm_sci_type and v8r_el1_msa) aren't exposed to OCaml yet, so they stay
zero.
Also add a BUILD_BUG_ON() on the size of the createdomain struct, just
like the x86 case, to catch future ABI changes.
Signed-off-by: Andrii Sultanov <andriy.sultanov@vates.tech>
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Between writing MSR_S_CET.SHSTK_EN and establishing SSP using RSTORSSP or
SETSSBSY, there must not be any CALL or RET instructions.
Building Xen with -fno-early-inlining causes wrmsr() to become out-of-line,
and thus suffers #DF during boot.
Make the MSR and shstk helpers always_inline. They ought to have been this
way all along.
Fixes: b60ab42db2 ("x86/shstk: Activate Supervisor Shadow Stacks")
Fixes: 3037d8b7eb ("x86/boot: Use RSTORSSP to establish SSP")
Reported-by: Stefano Stabellini <sstabellini@kernel.org>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Reviewed-by: Roger Pau Monné <roger@xenproject.org>
If the memory region to be mapped does not start at the page boundary
and its end spans over the page boundary, map_range_to_domain() passes
a number of pages that is short by one to map_regions_p2mt(). Domain's
attempt to access memory within that page will fail. Fix it by calculating
the number of pages to be mapped taking into account the start offset.
Fixes: 88c10b0d6e ("arch/arm: let map_mmio_regions() use start and count")
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Acked-by: Julien Grall <julien@xen.org>
Per the binding (docs/misc/arm/device-tree/guest.txt), region 0 for
mapping grant table is large enough to map the whole grant table. Xen
never checks that this holds:
- enhanced dom0less domUs are given GUEST_GNTTAB_SIZE (4096 frames),
while their limit comes from the max_grant_frames DT property or, if
absent, from the gnttab_max_frames command line option or default,
neither of which is bounded by the region size,
- a dom0less hardware domain is given gnttab_dom0_frames() frames,
while the max_grant_frames DT property can raise its limit above
that.
A guest growing its grant table past the end of the region ends up
mapping grant frames over whatever follows it in its address space,
e.g. the magic pages at GUEST_MAGIC_BASE for a domU.
Validate that the configured max frames can actually fit in the region
Xen exposes in make_hypervisor_node().
Fix find_gnttab_region() logic of setting the gnttab_size for hardware
domain to allow the max frames up until the size of the text section.
Otherwise, the DT setting would only allow to shrink it from the
default.
Fixes: 79eb2871f2 ("xen/arm: configure dom0less domain for enabling xenstore after boot")
Fixes: df68a4cb7e ("xen/arm: Add capabilities to dom0less")
Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
The device tree Xen builds for dom0/hwdom or for a dom0less domain is
only ever consumed by the guest, so a mistake in it surfaces as an
obscure failure inside the domain, far away from the code which
produced the tree.
Add device_tree_dump(). The output follows dtc's format so that a dump
can be diffed against the source DTS or fed back to dtc; the value
formatting heuristics are ported from dtc's utilfdt_print_data() for
that reason. The walk itself goes through libfdt rather than decoding
the tag stream by hand as dtc's fdtdump does.
Dumping a whole tree is only useful while debugging and costs both code
size and a lot of console output, so it is put under its own option,
CONFIG_DEVICE_TREE_DUMP. It is separate from CONFIG_DEVICE_TREE_DEBUG
because the generated tree is often all that is needed, without the rest
of the device tree debug messages.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
arch_sanitise_domain_config() validates the configuration requested by
the toolstack, and should not fill anything in. The config struct passed
to createdomain is supposed to be pure input. ARM used to abuse this
(GIC_NATIVE resolution, now removed) to smuggle output back to the
toolstack. Making the parameter const stops that type of abuse from
happening on any architecture.
The x86 implementation turned out to have its own instance of the same
issue. It set XEN_DOMCTL_CDF_oos_off into config->flags for non-HVM
guests. Since The sanitisation runs before the function domain_create()
copies config->flags into d->options, this relied on mutating the
toolstack's config to take effect. Move the default onto d->options
directly in arch_domain_create() (which runs after d->options is
populated), where all the remaining domain options are resolved. This
has the same effect and no mutation of the input config is required.
ARM, PPC and RISC-V need no equivalent change, Their implementations
were already read-only.
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Jan Beulich <jbeulich@suse.com> # x86
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Baptiste Le Duc <baptiste.le-duc@vates.tech> # riscv
The xen_arch_domainconfig.clock_frequency value is populated in
domain_vtimer_init() during XEN_DOMCTL_createdomain from the global
timer_dt_clock_frequency, which comes from the host's DT timer node and
has nothing to do with the domain being created. Like now removed
GIC_NATIVE resolution, this is a host-wide system property being
smuggled out through a domain-creation IN struct.
Expose it instead as a new arm_clock_frequency_hz field in
XEN_SYSCTL_physinfo, populated via arch_do_physinfo(), and mirroring how
the GIC capability bits were already moved there.
Rather than making the field dependant on DT boot, make Xen always
report the timer frequency, either via the DT "clock-frequency" node, or
directly via CNTFRQ_EL0. preinit_xen_time() already computes cpu_khz for
every boot path. The renamed timer_clock_frequency_hz now captures
whichever of the two produced that value, in full Hz precision, instead
of only recording the DT case. So, ACPI guests get a real value too,
allowing to drop the special case.
The DT "clock-frequency" property exists because firmware might leave
CNTFRQ_EL0 wrong, and since CNTFRQ_EL0 cannot be trapped the only fix is
to replicate the correct value into the guest DT. To keep that signal, a
new XEN_SYSCTL_PHYSCAP_ARM_TIMER_DT_FREQ capability bit records whether
arm_clock_frequency_hz came from the DT property. Then libxl only emits
a "clock-frequency" property into the guest timer node when that bit is
set. A guest whose CNTFRQ_EL0 is already correct keeps an unmodified
timer node, exactly as before.
Although the CNTFRQ_EL0 register is 64 bits wide, and some current timer
implementations run at 1GHz, a 32bit value is sufficient to store the
timer value, because it only mirrors the DT 'clock-frequency' property,
which the bindings define as a single 32-bit cell.
In struct xen_sysctl_physinfo the new field just reuses the former pad
word, so sysctl consumers are unaffected. struct xen_arch_domainconfig
however loses clock_frequency from its middle, which shrinks the struct
and shifts every field after it, so bump XEN_DOMCTL_INTERFACE_VERSION.
The xen_arch_domainconfig parameter passed to domain_vtimer_init() is no
longer needed, so drop that parameter entirely. libxl now fetches the
frequency via libxl_get_physinfo() in libxl__arch_domain_save_config()
instead of reading it back out of the createdomain reply. The OCaml
xen_arch_domainconfig mirror drops the field too.
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Now that the toolstack always resolves a concrete GIC_V2 or GIC_V3
before calling createdomain, nothing on the Xen side needs to resolve
GIC_NATIVE either:
* A new gic_domctl_hw_version() helper returns the
XEN_DOMCTL_CONFIG_GIC_* value matching the host's gic_hw_version().
* arch_sanitise_domain_config() uses it to validate the requested
version against the hardware, rather than resolving GIC_NATIVE and
writing the result back into config->arch.gic_version. A guest must
use the host's GIC version, except that a GICv3 host with the GICv2
compatibility mode enabled may also run GICv2 guests. This is the
same information that XEN_SYSCTL_physinfo reports to the toolstack.
* create_dom0() and arch_parse_dom0less_node(), which both always want
a vGIC that exactly matches the hardware, use the same helper instead
of GIC_NATIVE.
With nothing left resolving or relying on it, drop
XEN_DOMCTL_CONFIG_GIC_NATIVE from the public ABI. Every caller must now
request a concrete GIC_V2 or GIC_V3.
This is an incompatible change for any toolstack still passing 0
(formerly GIC_NATIVE) expecting Xen to auto-select a version. Add a
CHANGELOG.md entry, noting that available GIC versions can be queried
via XEN_SYSCTL_physinfo.
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
XEN_DOMCTL_CONFIG_GIC_NATIVE lets the toolstack ask Xen to silently
resolve the domain's GIC version to whatever the host hardware has. Xen
then writes the resolved value back into the same in/out
xen_arch_domainconfig the toolstack used as input, which is the kind of
API abuse we're trying to get rid of. The struct passed to createdomain
should only be an input parameter.
Move the "pick the best available GIC version" decision to the
toolstack, using the XEN_SYSCTL_PHYSCAP_ARM_GIC_V2/V3 capability bits
already exposed via XEN_SYSCTL_physinfo:
* libxl__arch_domain_build_info_setdefault() resolves the GIC version
against those bits before the config is built. An unspecified version
becomes v3 if available, else v2, else fails. An explicitly requested
v2/v3 is validated against the same bits, so a version the host
cannot provide is directly rejected in the toolstack.
* The Python xc.domain_create() binding does the same via a call to
xc_physinfo().
* libxl__arch_domain_prepare_config() therefore only ever sees a
concrete v2/v3 request and just validates it. The GIC_NATIVE case is
dropped since setdefault() always resolves it first.
LIBXL_GIC_VERSION_DEFAULT keeps its name and value: xl.cfg still accepts
"default" as the C<gic_version> keyword, and setdefault() resolves it to
a concrete v2/v3 before anything else can observe it.
This guarantees no toolstack path can still produce
XEN_DOMCTL_CONFIG_GIC_NATIVE, in preparation for removing it from the
Xen side and from the ABI entirely.
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Acked-by: Michal Orzel <michal.orzel@amd.com>
Acked-by: Anthony PERARD <anthony.perard@vates.tech>
In preparation to simplify the domain creation logic surrounding GIC
version.
On a GICv3 host, also report support for GICv2-compatible guests when
the hardware's vGICv2 compatibility mode is enabled, rather than just
the native GIC version.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Include PCI IDs of UART ports on Intel RPL - PTL. Based on Linux driver
and hwdata, they all share the same parameters.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
There's a potential 32bit left-shift (when size is 4) to a 32bit value,
which would trigger UB and tickle UBSAN the wrong way. Shifting right an
all-ones mask fixes the issue.
Fixes: 4609fc8eb0 ("x86/hvm: Improve error information in handle_pio()")
Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
As of the referenced commit v won't be returned from the function anymore.
Yet that was the sole reason for it to not be pointer-to-const. curr,
which was introduced by that change, had no reason to be pointer-to-non-
const from the start.
Amends: 622c9a5ba9 ("x86/mm: accurately track which vCPU page-tables are loaded")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
memcpy_to_guest_ring() bounds the copy against the ring size with
if ( len + offset > XEN_ARGO_MAX_RING_SIZE )
where len and offset are unsigned int. offset is masked below
PAGE_SIZE just above, but a len close to UINT_MAX makes len + offset
wrap below XEN_ARGO_MAX_RING_SIZE and pass the check. The head_len
computation in the loop wraps the same way, so the copy length is no
longer bounded.
All current callers bound len via iov_count(), so this is not
reachable in practice.
No functional change for in-range inputs.
Signed-off-by: Weiqi Wang <weiqi.wang-2@postgrad.manchester.ac.uk>
Acked-by: Jan Beulich <jbeulich@suse.com>
MISRA C Rule 10.1 states: "Operands shall not be of an inappropriate
essential type".
bar_write() and guest_mem_bar_write() added the boolean 'hi' to a
pointer difference when printing the ignored BAR index. These handlers
are registered only for the memory BAR registers, so print
(reg - PCI_BASE_ADDRESS_0) / 4 instead. The expression has type
unsigned int, so use %u.
No functional changes.
Suggested-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger@xenproject.org>
Due to a typo the state record for a watch specifying a depth is
written only partially. Instead of using the correct length of the
xs_state_watch_ext structure only the length of the xs_state_watch
structure was used when writing the data.
Fix that by using the correct length.
This is XSA-514 / CVE-2026-79607
Fixes: db98de120c ("tools/xenstored: add depth information to watches")
Reported-by: Andrii Sultanov <andriy.sultanov@vates.tech>
Signed-off-by: Juergen Gross <jgross@suse.com>
Grants can be offered read-only by the owning domain. While a domain mapping
a RO grant may have a need to invalidate the cache, it must not modify the
other-guests data while doing so. Force-upgrade to a clean operation in this
case.
This is CVE-2026-102702, part of XSA-519.
Fixes: 18e8d22fe7 ("introduce GNTTABOP_cache_flush")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
When the start address is not cacheline aligned, the bytes covered by
the first, partial cacheline are subtracted from 'size'. Nothing checks
that the region actually extends beyond that cacheline, so if it does
not, the unsigned subtraction underflows and the loop that follows walks
practically the entire address space.
For example, with a 64-byte cacheline, p = 0x40000001 and size = 1:
p & cacheline_mask -> 1, so the partial head is taken
size -= 64 - 1 -> 1 - 63 underflows to 0xffffffffffffffc2
Instead of a single "dc civac" at 0x40000000, the loop then runs
288230376151711743 times, issuing "dc ivac" from 0x40000040 upwards.
Invalidating without cleaning discards dirty cachelines, so this
corrupts whatever is mapped along the way until Xen takes a data abort.
Moreover, _cache_flush() in common/grant_table.c, reachable from a guest
via GNTTABOP_cache_flush, bounds 'offset' and 'length' against the page
size but requires no alignment, so GNTTAB_CACHE_INVAL with offset = 1
and length = 1 is enough to trigger this. Note that the page may belong
to a different domain (the d != owner path), so the data being discarded
is not necessarily the caller's own.
The subtraction dates back to the fix for XSA-437, so this is a regression
in that change.
Fix this by detecting the underflow instead of letting it happen: if the
region ends inside the first cacheline, there is nothing left to flush
and the function bails out right after cleaning it. Partially covered
cachelines are still cleaned as well as invalidated, so that data outside
of the region is not discarded.
Additionally, drop 'idx' and advance 'p' directly instead. It simplifies
the logic while using fewer variables and less arithmetic.
Note that the partial head is now cleaned using the unaligned start of the
region instead of the start of its cacheline. This is permitted by the
architecture; the Arm ARM (DDI 0487) states:
"When a DC instruction requires an address argument this takes the form
of a 64-bit register that holds the VA argument. No alignment
restrictions apply for this address."
The same applies on Arm32.
Also, switch the asm() in the loop to asm_inline, like the neighbouring
ones: the wrapper expands to a single instruction with a trailing
semicolon, which GCC counts as two statements, overestimating the size
of the function when deciding whether to inline it.
This is CVE-2026-102699, part of XSA-519.
Fixes: 9a216e92de ("xen/arm: page: Handle cache flush of an element at the top of the address space")
Signed-off-by: Leonid Komarianskyi <leonid_komarianskyi@epam.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Julien Grall <julien@xen.org>
The consistency checks in effect when Blocked-by-STI/MovSS are active includes
DEBUGCTL.BTF too. Take this into account when editing PENDING_DBG.BS.
This ends up narrowing the cases where PENDING_DBG is modified. Rework the
comment to be more precise.
This is XSA-518 / CVE-2026-79611.
Fixes: 1d3eb82598 ("x86/vtx: Work around SingleStep + STI/MovSS VMEntry failures")
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
A v1 -> v2 change isn't the only scenario where "status" may go stale in
map_grant_ref(). Across a v2 -> v1 -> v2 change the status pages would
have been freed and re-populated, possibly changing the pages used for the
array. Check the pointer against the expected version-dependent value.
This is XSA-517 / CVE-2026-79610.
Fixes: 96dfeb4177 ("gnttab: cope with version changes racing other operations")
Assisted-by: Claude
Reported-by: Teddy Astie <teddy.astie@vates.tech>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
For XPTI enabled VMs, restore_all_guest() copies most of the active L4
pagetable into the per-CPU root_pgt. The L4 is read via the
directmap.
Unfortunately, there was no accounting for the fact that PV guests
have short directmaps. For an L4 living beyond the 5T boundary (3.5T
for CONFIG_BIGMEM), Xen will copy arbitrary data from guest-controlled
virtual address space into the per-CPU root_pgt, instead of the
intended L4.
Xen has per-domain mappings for the LDT and GDT, with two pages
reserved for Xen's use in the GDT but only one in use. Reuse GDT page
15 to map the effective L4. The GDT limit keeps implicit accesses out
of this page.
We update this mapping in make_cr3(), the only place a non-empty value
of v->arch.cr3 is written into a guest's vcpu struct, for two reasons.
First is reference counting: this makes it easier to argue that the
reference for v->arch.cr3 itself covers the reference for the mapping.
Secondly, this guarantees that all updates, even updates made in
shadow mode, result in an update to the mapping. During live
migration, it's possible for guest_get_eff_kern_l1e() to result in a
modified value of v->arch.cr3 (sketch below); placing the mapping
update at make_cr3() catches this, while other candidate locations
like write_ptbase() and toggle_guest_mode() don't.
Note that we introduce the idea of an "effective L4" here, to mean
"guest L4 after any transformations": XPTI copies either the actual
guest L4 if not shadowed, or the shadow L4 (transformed) if shadowed.
Sketch: guest_get_eff_kern_l1e() has a pair of toggle_guest_pt() calls
which happen if the guest is in user mode. During live migration, a
log-dirty clean will do a domain_pause and then call
shadow_blow_tables(), unpinning the shadow of the guest user root
pagetable. After execution resumes, the first toggle_guest_pt() could
then cause that page to become unshadowed. The second
toggle_guest_pt() would then re-shadow it, possibly with a different
backing shadow page.
This is XSA-516 / CVE-2026-79609.
Fixes: 5784de3e20 ("x86: Meltdown band-aid against malicious 64-bit PV guests")
Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: George Dunlap <gwd@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
The identified commit inverted the condition under which Xen chooses
to set the Zenbleed chickenbit.
Undo that, and leave a better comment explaining why.
Found by AI review of the referenced commit.
This is XSA-515 / CVE-2026-79608.
Fixes: d0c75dc4c0 ("x86/amd: Fix race editing DE_CFG")
Assisted-by: Sashiko + Opus 5.0
Reported-by: George Dunlap <dunlapg@umich.edu>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Error path of failed sidtab_map() leaves global sidtab in shutdown state and
from that point system is unable to allocate new SIDs in sidtab_context_to_sid().
To restore sidtab state new function sidtab_cancel_shutdown() is introduced,
which only resets shutdown flag, rewinding effect of sidtab_shutdown().
Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik@epam.com>
Acked-by: Daniel P. Smith <dpsmith@apertussoutions.com>
We already have two instances of this, and we're about to gain a third.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: George Dunlap <gwd@xenproject.org>
As of the referenced commit there's no reason to open-code the loop
anymore. With that replaced by a single call, there's then also no point
in using the local "mfn" in this code.
Amends: 5260e8fb93 ("xen: re-define assign_pages and introduce a new function assign_page")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: George Dunlap <gwd@xenproject.org>
NextRIP is consumed on VMRUN as the return address pushed onto the
stack for injected soft exceptions/interrupts. nsvm_vmcb_prepare4vmrun()
builds n2vmcb from the virtual VMCB on every entry to the L2 guest, but
never copied this field, leaving n2vmcb->nextrip stale. Injecting an
event in this state can wedge the L2 vCPU, as the APM does not define
behaviour for a VMRUN with a garbage NextRIP.
Nested virt is only offered on NRIPS-capable hardware, and NRIPS is
required to be advertised to L1 (see start_nested_svm()), so the L1
hypervisor is required to keep NextRIP correct. Therefore no
conditional logic is needed here; an unconditional sync suffices.
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Chunjie Zhu <chunjie.zhu@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Do not wait indefinitely for XHCI to configure console connection. If
the cable is not plugged in, timeout after about 1s and continue boot.
If the cable is plugged in later, the console will be activated then
(see final part of dbc_ensure_running()). When timeout occurs, print a
warning message - it will be saved in the console ring buffer, to be
later retrieved from dom0, or possibly later printed when the cable is
finally connected. But, do not print the warning when waiting after
controller reset, as that may have been called from from console
dbc_putc() and printing here would result in (possibly infinite)
recursion.
Try the timeout to be about 1s, which is way above time needed for
configuring already connected cable. But, since this part runs very
early in the Xen startup, time is not calibrated yet, and functions like
NOW() do not work yet. Use raw TSC and estimate needed time to be at
least 1s on a fast CPU (5GHz), and possibly longer on a slower one. This
is not very accurate method, but fortunately it doesn't need to be.
This also helps with similar situation on resuming from suspend - if
cable got unplugged in the meantime, system will not hang waiting for
the console anymore. And finally, on some systems, when dom0 is also
allowed to access the USB controller, it may put the device into low
power mode that in some older controllers (for example Kaby Lake)
disables also debug capability. In such a case, adding a timeout allows
the system to resume, then dom0 can wake up the controller and Xen will
resume XHCI console.
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Valgrind reports that 21 bytes are "still reachable" from the (XEN_LOG_DIR "/console") allocation:
HEAP SUMMARY:
in use at exit: 21 bytes in 1 blocks
total heap usage: 9 allocs, 8 frees, 4,799 bytes allocated
Since the dynamic memory allocation for the default log directory path happens before the process
forks into the background, the parent and intermediate processes exit during daemonize()
with the memory still reachable.
Move the strdup() allocation down below the daemonize() block. This ensures only the final
background daemon allocates the default path, matching the lifetime of the free(log_dir)
cleanup loop at the exit of main().
With this change, Valgrind reports a clean heap summary
HEAP SUMMARY:
in use at exit: 0 bytes in 0 blocks
total heap usage: 8 allocs, 8 frees, 4,778 bytes allocated
Signed-off-by: Andrew Mbugua <andrewprecious388@gmail.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
xentop parses -d/--delay and -i/--iterations with atoi(), so invalid
input is silently accepted with surprising results: a fractional delay
such as "-d 2.5" is truncated to 2; "-d abc" parses as 0, which in
batch mode turns the output loop into a busy loop; "-d -1" wraps to an
effective delay of about 136 years; and "-i 0" (or any unparsable
iterations count) decrements an unsigned counter from zero, running
for about 2^32 iterations. atoi() also has undefined behaviour on
out-of-range input.
Parse both options with strtoull() instead, and reject anything that
is not a plain decimal integer in range: a sign, a fractional part,
trailing junk or overflow now produce an error and exit rather than a
silently wrong value.
Compatibility considerations: "--delay 0" remains accepted, since
updating as fast as possible is a plausible deliberate choice and
works today; "--iterations 0" is rejected, since running the loop
2^32 times cannot be what the caller meant. The interactive 'D'
prompt already validates its input and is unchanged. The only
previously useful invocation this breaks is a fractional delay, which
now fails loudly instead of silently rounding down - which is the
point of the change.
A patch documenting the --delay truncation was posted in 2010 but
never applied:
Link: https://lore.kernel.org/xen-devel/01ea26d2420e3562eb30.1292604768@chilopoda.uk.xensource.com/
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
xenstat_collect_networks() looks for a Linux bridge (a
/sys/class/net/*/bridge directory) so that, with bonding, dom0 can be
given the bridge's counters. When there is none, as on hosts using Open
vSwitch (the XCP-ng default), routed networking or only libvirt's
virbr0 (which is excluded on purpose), getBridge() leaves devBridge
empty. strstr(iface, "") then matches every interface, and devNoBridge
is just "p", so every VIF with a standard name (vifN.M, vifN.M-emu)
takes the bridge branch instead of being attached to its domain. Every
domain ends up with zero networks, and xentop shows NETS 0.
Only take the bridge branch when a bridge was actually found.
Fixes: 1fd93d4f8c ("xenstat: Linux dom0 statistics for case we use network bonding")
Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Olivier Lambert <olivier.lambert@vates.tech>
Tested-by: Jason Andryuk <jason.andryuk@amd.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
Acked-by: Anthony PERARD <anthony.perard@vates.tech>
Add a new directory linux-bridge-vlan with example files showing
how to configure systemd-networkd to support a bridge VLAN
configuration.
Signed-off-by: Leigh Brown <leigh@solinno.co.uk>
Acked-by: Anthony PERARD <anthony.perard@vates.tech>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
Update add_to_bridge shell function to read the vlan parameter from
xenstore and set the bridge VLAN configuration for the VID.
Add additional helper functions to parse the vlan specification,
which consists of one or more of the following:
a) single VLAN (e.g. 10).
b) contiguous range of VLANs (e.g. 10-15).
c) discontiguous range with base, increment and count
(e.g. 100+10x9 which gives VLAN IDs 100, 110, ... 190).
A single VLAN can be suffixed with "p" to indicate the PVID, or
"u" to indicate untagged. A range of VLANs can be suffixed with
"u" to indicate untagged. A complex example would be:
vlan=1p/10-15/20-25u
This capability requires the iproute2 bridge command to be
installed. An error will be generated if the vlan parameter is
set and the bridge command is not available.
Signed-off-by: Leigh Brown <leigh@solinno.co.uk>
Acked-by: Anthony PERARD <anthony.perard@vates.tech>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
RFC 791 sets the minimum acceptable mtu to 68:
Every internet module must be able to forward a datagram of 68
octets without further fragmentation. This is because an internet
header may be up to 60 octets, and the minimum fragment is 8 octets.
In the Linux kernel source:
include/net/ip.h:#define IPV4_MIN_MTU 68 /* RFC 791 */
While there is no reason to expect a value <68 to be read from xenstore or
from the bridge make the value test require a number >= this minimum.
Signed-off-by: James Dingwall <james@dingwall.me.uk>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
The set_mtu() function of xen-network-common.sh currently has this code:
if [ ${type_if} = vif ]
then
local dev_=${dev#vif}
local domid=${dev_%.*}
local devid=${dev_#*.}
local FRONTEND_PATH="/local/domain/$domid/device/vif/$devid"
xenstore_write "$FRONTEND_PATH/mtu" ${mtu}
fi
This works fine if the device has its default name but if the xen config
defines the vifname parameter the FRONTEND_PATH is incorrectly constructed.
Learn the frontend path by reading the appropriate value from the backend.
Also change use of `...` to $(...) for a consistent style in the script.
Signed-off-by: James Dingwall <james@dingwall.me.uk>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>