Incrementing ->sched_index between bounds check and array access may
result in accessing one past the array when that is fully filled
(->num_schedule_entries == ARINC653_MAX_DOMAINS_PER_SCHEDULE).
Fixes: 22787f2e10 ("ARINC 653 scheduler")
Reported-by: Kamil Frankowicz <kamil.frankowicz@cert.pl>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Stewart Hildebrand <stewart@stew.dk>
When that code still lived in a653sched_init(), it was redundant with the
earlier memset() / xzalloc(). Once moved, the full structure field needs
setting, as dom_handle_cmp() uses memcmp() and arinc653_sched_set() may
have clobbered entries. Rather than implying the handle to be all zero,
copy the handle out of the domain structure.
Fixes: 9f0c658bae ("arinc: add cpu-pool support to scheduler")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Stewart Hildebrand <stewart@stew.dk>
MCE init for APs was broken when CPU feature re-checking was added. At the
same time make sure we don't bypass setup_doitm() (and whatever else may
be added to the bottom of identify_cpu()).
Fixes: bb502a8ca5 ("x86: check feature flags after resume")
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
Most (if not all) Intel CPUs starting from Sandy Bridge have up to 8
event selectors per core, which could be halved per hyperthread.
However, current PV emulation logic doesn't support up to 8 event selector,
leading to errors when trying to access them, hence, preventing Linux from
driving the vPMU correctly.
Make sure up to MSR_P6_EVNTSEL(7) is usable, which is the same upper bound as
used in VMX code.
The check if the event selector actually exist for the hardware is done in
core2_vpmu_do_{rdmsr,wrmsr}, hence we're not allowing to access non-existent
MSRs.
Fixes: 27c5541986 ("x86/VPMU: add support for PMU register handling on PV guests")
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Having two spellings of the constants makes following the code unnecessarily
difficult. Reduce it to one spelling.
This is an API change in the public headers, but one for the better.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
MISRA C:2012 Rule 5.3 states as following: An identifier declared in an
inner scope shall not hide an identifier declared in an outer scope.
Inside the 'if' block, the inner 'i' shadows the outer 'i'.
Reuse the outer variable and remove the inner declaration to fix that.
No functional change.
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Like the EPT code, defer TLB flushes for NPT to reduce the number of
flushes and avoid holding the P2M lock while flushing. This can
substantially improve performance in some scenarios.
The cases where the TLB needs to be flushed without deferring are
already handled by the call to p2m_tlb_flush_sync() in p2m_free_ptp().
Suggested-by: Roger Pau Monne <roger.pau@citrix.com>
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Many machines fails to boot if this option is disabled.
It's off by default as it was deemed too risky for being enabled
by default late in the Xen 4.13 cycle, but found out to be safe.
As there are no known drawback by having this option on, enable
it by default.
Signed-off-by: Teddy Astie <teddy.astie@vates.tech>
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
struct cpuinfo_x86
.x86 => .family
.x86_vendor => .vendor
.x86_model => .model
.x86_mask => .stepping
No functional change.
This work is part of making Xen safe for Intel family 18/19.
Signed-off-by: Kevin Lampis <kevin.lampis@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
struct cpuinfo_x86
.x86 => .family
.x86_vendor => .vendor
.x86_model => .model
.x86_mask => .stepping
No functional change.
This work is part of making Xen safe for Intel family 18/19.
Signed-off-by: Kevin Lampis <kevin.lampis@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
These checks were guarding against non-64 bit CPU models but they are
not supported by Xen anymore so the checks are no longer needed.
The switch statement was removed from mcheck_init()
to support Intel family 18/19.
Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Kevin Lampis <kevin.lampis@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
FF-A v1.2 defines PARTITION_INFO_GET_REGS for register-based partition
info retrieval, but Xen currently only supports the buffer-based GET
path for guests.
Implement GET_REGS using the cached SP list and VM entries, including
the register window layout and input validation. Track VM list changes
via the partinfo tag and use it to validate GET_REGS tag inputs. Ensure
that when a non-Nil UUID is specified, the UUID fields in both GET and
GET_REGS results are MBZ as required by the specification.
PARTITION_INFO_GET_REGS is available to v1.2 guests, returning cached SP
entries and VM entries with UUIDs zeroed for non-Nil UUID queries.
Also publish VM membership updates (VM count, ctx list, and partinfo
tag) under the same write-locked section so GET_REGS sees coherent state
and concurrent changes are reliably reported via RETRY.
Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Julien Grall <julien@xen.org>
The init-time SP cache already contains partition properties, but the
code still builds separate subscriber arrays for VM created/destroyed
notifications. That duplicates state and allocation.
Use the cached SP list directly to:
- decide which SPs receive created/destroyed notifications
- build the per-domain destroy bitmap
- skip destroy notifications for SPs not notified on create
Also switch cached SP entry field reads in VM create/destroy
notification paths to unaligned-safe helpers, as cache entries are
variable-size and should not be dereferenced via struct pointers.
No functional changes.
Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Julien Grall <julien@xen.org>
FFA_PARTITION_INFO_GET currently queries the SPMC on each call and walks the
RX buffer every time. The SP list is expected to be static, so repeated
firmware calls and validation are unnecessary.
Cache the SPMC partition-info list at init time, keeping only secure
endpoints, and reuse the cached entries for SP count and partition-info
responses. Initialize the VM create/destroy subscriber lists from the cached
list and free the cache on init failure.
SP partition info now reflects the init-time snapshot and will not change.
Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Julien Grall <julien@xen.org>
Windowed GET_REGS retrieval needs to emit VM entries starting from an
arbitrary index, but ffa_get_vm_partinfo() always starts from index 0.
Add a start_index parameter to ffa_get_vm_partinfo() and skip entries
until the local index reaches start_index. Update
ffa_handle_partition_info_get() to pass start_index=0 to preserve
existing behavior.
No functional changes.
Signed-off-by: Bertrand Marquis <bertrand.marquis@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Julien Grall <julien@xen.org>
Family 0x1a covers both Zen5 and Zen6, but the latter is not believed to be
vulnerable to entrysign.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
With the GCC toolchain baseline now at 5.1, gcc_3_4.o (covering 3.4 through
4.6) will never get chosen. Drop it.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Michal Orzel <michal.orzel@amd.com>
The setting of errno in canonicalize() is rather fragile and seems to
be even wrong in one corner case: when the invalid path "/local/domain/"
is passed, sscanf() will set errno to 0, resulting in canonicalize() to
return NULL with errno being 0. This can result in triggering the
assert(conn->in == NULL) in consider_message().
Don't assume the initial setting of errno to "EINVAL" will stay valid
in all cases and set it to EINVAL only when returning NULL due to an
invalid path.
This is XSA-481/CVE-2026-23555
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Julien Grall <julien@xen.org>
In the EPT implementation, the defer flushing logic is used
unconditionally, and that would lead to paging memory being returned to the
paging pool before its references had been flushed.
Issue any pending flushes before freeing the paging memory back to the
pool.
Note AMD (NPT) and Shadow paging are not affected, as they don't implement
the deferred flushing logic.
This is XSA-480 / CVE-2026-23554
Fixes: 4a59e6bb3a ("x86/EPT: squash meaningless TLB flush")
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
When calling "xenstore-list -p /" it will prepend all listed keys
with "//" instead of "/".
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
The usage information of xenstore-exists is just wrong, as the "-p"
option is not supported by xenstore-exists.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
The "-h" parameter of the xenstore-* programs is explicitly meant to
show the usage information of the programs. This use case should not
result in an error of the program's exit code.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
The "-h" parameter is missing in the man pages of the xenstore-*
programs.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
MISRA C Rule 20.12 states: "A macro parameter used as an operand to
the # or ## operators, which is itself subject to further macro replacement,
shall only be used as an operand to these operators".
In this case the 'FFA_*' macros are used both as a regular macro argument and
as an operand for '#' stringification in the expansion of 'FW_ABI()'.
This is deviated using a SAF-x-safe comment.
No functional changes.
Signed-off-by: Dmytro Prokopchuk <dmytro_prokopchuk1@epam.com>
Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
For the ARM build only, Eclair reports a R8.4 violation because do_argo_op()
cannot see its declaration. This means that x86 is picking hypercall-defs.h
up transitively while ARM is not. Include xen/hypercall.h explicitly.
Eclair also reports a R8.3 violation because of arg3 and arg4 differing in
name with a raw_ prefix. Because hypercall-defs.h generates both do_argo_op()
and compat_argo_op() from a single description, it's not possible to simply
rename to raw_ in the declaration, as that would force doing the same rename
in compat_argo_op().
In do_argo_op(), drop the split parameter handling, and perform the 32bit
range check via an explicit cast. While adjusting the surrounding logic, drop
unnecessary casts to void * for already pointer arguments in argo_printk().
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
In FRED mode, ERET is stricter than IRET about flags. Notably this means:
* The vm86 bit (bit 17) and IOPL (bits 12,13) must be clear.
* The sticky-1 reserved bit (bit 2) must be set, so dom0_construct() needs to
set X86_EFLAGS_MBS in order for a PV dom0 to start.
* All other reserved bits must be clear.
Xen has been overly lax with reserved bit handling. Adjust
arch_set_info_guest*() and hypercall_iret() which consume flags to clamp the
reserved bits for all guest types.
This is a minor ABI change, but by the same argument as commit
9f892f84c2 ("x86/domctl: Stop using XLAT_cpu_user_regs()"); the reserved
bits would get clamped like this naturally by hardware when the vCPU is run.
The handling of vm86 is also different. Guests under 32bit Xen really could
use vm86 mode, but Long Mode disallows vm86 mode and IRET simply ignores the
bit. Xen's behaviour for a PV32 guest trying to use vm86 mode under a 64bit
Xen is to arrange to deliver #GP at the target of the IRET, rather than to
fail the IRET itself.
However there's no filtering in arch_set_info_guest() itself, and it can't
arrange to queue a #GP at the target, so do the next best thing and fail the
hypercall. This is not expected to create an issue for PV guests, as the
result of such an arch_set_info_guest() previously would be to run supposedly
Real Mode code as Protected Mode code.
This allows PV guests to start when Xen is using FRED mode.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
The limitation of which tests can be build on 32bit is too strict. Move
some tests out of the 64bit explicit region, as they can also be built on
32bits.
Fixes: cb50e40337 ("test/pdx: add PDX compression unit tests")
Reported-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
When building the PDX test harness as a 32bit executable the page shifts
done on unsigned long types can overflow. Instead use pfn_to_paddr(),
which casts the values to paddr_t previous to doing the shift.
Fixes: cb50e40337 ("test/pdx: add PDX compression unit tests")
Reported-by: Edwin Török <edwin.torok@citrix.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Since 4dbcb06536, the vGICv2 CPU interface is mapped in a deferred
manner. On domains with XEN_DOMCTL_CDF_trap_unmapped_accesses unset on
GICv2 hardware, the vGICv2 CPU interface fails to be mapped. A visible
symptom is that a domU gets stuck at:
[ 0.177983] smp: Bringing up secondary CPUs ...
Move the 2nd check_p2m earlier so it's prioritized over try_handle_mmio.
Fixes: 980aff4e8f ("xen/arm: Add way to disable traps on accesses to unmapped addresses")
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@amd.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
struct cpuinfo_x86
.x86 => .family
.x86_vendor => .vendor
.x86_model => .model
.x86_mask => .stepping
No functional change.
This work is part of making Xen safe for Intel family 18/19.
Signed-off-by: Kevin Lampis <kevin.lampis@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This NR_CPUS-dimensioned array is likely unused on most installations.
Therefore it is especially wasteful for it to consume more space than
really needed. Allocate it dynamically ahead of registering the hooks.
Further the array having all fields set to -1 is actually useless. Nothing
relies on it, and core_parking_remove() doesn't restore the sentinel for
vacated slots. Drop the initializers altogether, rather than replacing
them.
Also take the opportunity and update an adjacent variable's type, where
a fixed-width type was pretty clearly inappropriate to use.
Finally drop the redundant initializer from core_parking_init().
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Under FRED, entry_from_pv() handles everything, even system call instructions.
This means more of our logic is written in C now, rather than assembly.
In order to facilitate this, introduce pv_inject_callback(), which reuses
struct trap_bounce infrastructure to inject the syscall/sysenter callbacks.
This in turns requires some !PV compatibility for pv_inject_callback() and
pv_hypercall() which can both be ASSERT_UNREACHABLE().
For each of INT $N, SYSCALL and SYSENTER, FRED gives us interrupted context
which was previously lost. As the guest can't see FRED, Xen has to lose state
in the same way to maintain the prior behaviour.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
ERETU can fault for guest reasons, and like IRET needs special handling to
forward the error into the guest.
As this is largely written in C, take the opportunity to better classify the
sources of error, and in particular, not forward errors that are actually
Xen's fault into the guest, opting for a domain crash instead.
Because ERETU does not enable NMIs if it faults, a corner case exists if an
NMI was taken while in guest context, and the ERETU back out faults. Recovery
must involve an ERETS with the interrupted context's NMI flag.
See the comments for full details.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Under FRED, entry_from_pv() handles everything. To start with, implement
exception handling in the same manner as entry_from_xen(), although we can
unconditionally enable interrupts after the async/fatal events.
After entry_from_pv() returns, test_all_events() needs to run to perform
exception and interrupt injection. Split entry_FRED_R3() into two and
introduce eretu_exit_to_guest() as the latter half, coming unilaterally from
restore_all_guest().
For all of this, there is a slightly complicated relationship with CONFIG_PV.
entry_FRED_R3() must exist irrespective of CONFIG_PV, because it's the
entrypoint registered with hardware. For simplicity, entry_from_pv() is
always called, but it collapses into fatal_trap() in the !PV case.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
When FRED is active, hardware automatically swaps GS when changing privilege,
and the SWAPGS instruction is disallowed.
For native OSes using GS as the thread local pointer this is a massive
improvement on the pre-FRED architecture, but under Xen it makes handling PV
guests more complicated. Specifically, it means that GS_BASE and GS_SHADOW
are the opposite way around in FRED mode, as opposed to IDT mode.
This leads to the following changes:
* In load_segments(), we already load both GSes. Account for FRED in the
SWAP() condition and avoid the path with SWAGS.
* In save_segments(), we need to read GS_SHADOW rather than GS_BASE.
* In toggle_guest_mode(), we need to emulate SWAPGS.
* In {read,write}_msr() which access the live registers, GS_SHADOW and
GS_BASE need swapping.
* In do_set_segment_base(), merge the SEGBASE_GS_{USER,KERNEL} cases and
take FRED into account when choosing which base to update.
SEGBASE_GS_USER_SEL was already an LKGS invocation (decades before FRED)
so under FRED needs to be just a MOV %gs. Simply skip the SWAPGSes.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
clang would duplicate the loop body and end up with a double definition
of the symbol:
```
/tmp/test_x86_emulator-0f3576.s:27823: Error: symbol `vmovsh_to_mem' is already defined
/tmp/test_x86_emulator-0f3576.s:27825: Error: symbol `.Lvmovsh_to_mem_end' is already defined
```
Until a better solution is found: reduce optimizations in the test runner.
Using -Os might also work, but we can't rely on the size optimization
always avoiding the duplication of asm blocks.
This is test code, not performance critical code, and -O0 is more future
proof.
However for debugging -Og is recommended over -O0, and this still avoids
the duplicate label problem.
Signed-off-by: Edwin Török <edwin.torok@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
The scheduler may call this function to force synchronization of given
vCPU's state. RISC-V does not support lazy context switching, so nothing
is done in sync_vcpu_execstate() and sync_local_execstate().
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
As the tasklet subsystem is now initialized, it is necessary to implement
sync_local_execstate(), since it is invoked when something calls
tasklet_softirq_action(), which is registered in tasklet_subsys_init().
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Introduce timer_interrupt() to process IRQ_S_TIMER interrupts.
The handler disables further timer interrupts by clearing
SIE.STIE and raises TIMER_SOFTIRQ so the generic timer subsystem
can perform its processing.
Update do_trap() to dispatch IRQ_S_TIMER to this new handler.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Implement reprogram_timer() on RISC-V using the standard SBI timer call.
The privileged architecture only defines machine-mode timer interrupts
(using mtime/mtimecmp). Therefore, timer services for S/HS/VS mode must
be provided by M-mode via SBI calls. SSTC (Supervisor-mode Timer Control)
is optional and is not supported on the boards available to me, so the
only viable approach today is to program the timer through SBI.
reprogram_timer() enables/disables the supervisor timer interrupt and
programs the next timer deadline using sbi_set_timer(). If the SBI call
fails, the code panics, because sbi_set_timer() is expected to return
either 0 or -ENOSUPP (this has been stable from early OpenSBI versions to
the latest ones). The SBI spec does not define a standard negative error
code for this call, and without SSTC there is no alternative method to
program the timer, so the SBI timer call must be available.
reprogram_timer() currently returns int for compatibility with the
existing prototype. While it might be cleaner to return bool, keeping the
existing signature avoids premature changes in case sbi_set_timer() ever
needs to return other values (based on which we could try to avoid
panic-ing) in the future.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Introduce a function pointer for sbi_set_timer(), since different OpenSBI
versions may implement the TIME extension with different extension IDs
and/or function IDs.
If the TIME extension is not available, fall back to the legacy timer
mechanism. This is useful when Xen runs as a guest under another Xen,
because the TIME extension is not currently virtualised and therefore
will not appear as available.
Despite of the fact that sbi_set_timer_v01 is introduced and used as
fall back, SBI v0.1 still isn't fully supported (with the current SBI
calls usage, sbi_rfence_v01 should be introduced too), so panic()
in sbi_init() isn't removed.
The sbi_set_timer() pointer will be used by reprogram_timer() to program
Xen’s physical timer as without SSTC extension there is no any other
option except SBI call to do that as only M-timer is available for us.
Use dprintk() for all the cases to print that a speicifc SBI extension
is available as it isn't really necessary in case of release builds.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Add handling of the SBI_EXT_0_1_SET_TIMER function ID to the legacy
extension ecall handler. The handler now programs the vCPU’s virtual
timer via vtimer_set_timer() and returns SBI_SUCCESS.
This enables guests using the legacy SBI timer interface to schedule
timer events correctly.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
Introduce vtimer_ctxt_switch_from() and vtimer_ctxt_switch_to() to handle
virtual timer state across vCPU context switches.
At present, vtimer_ctxt_switch_from() is a no-op because the RISC-V SSTC
extension, which provides a virtualization-aware timer, is not yet
supported. Xen therefore relies the virtual (SBI-based) timer.
The virtual timer uses Xen's internal timer infrastructure and must be
associated with the pCPU on which the vCPU is currently running so that
timer events can be delivered efficiently. As a result, vtimer_ctxt_switch_to()
migrates the timer to the target pCPU when a vCPU is scheduled in.
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>