Commit Graph
50735 Commits
Author SHA1 Message Date
Juergen Gross fce27a1fd0 docs: clarify tag sequence in sending-patches
Make clear what an "Assisted-by:" tag relates to in
sending-patches.pandoc.

Add the possibility to clarify how AI was used.

Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Julien Grall <julien@xen.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:49:38 +02:00
Oleksii Kurochko 60004aa6da xen/riscv: add missing APLIC register offsets, masks to asm/aplic.h
These definitions are required for correct decoding of APLIC MMIO
accesses and target configuration, and will be used by both the
physical and virtual APLIC implementations.

While adding them, rearrange the header in the style of x86's
asm/msr-index.h: a register's offset is immediately followed by the
definitions of that register's fields, with the blocks sorted by
offset.  This makes the relation between a register and its fields
obvious from the layout alone, so no comment is needed to express it.

No functional change is intended by this patch; it only centralises
hardware definitions that were previously missing.

Co-developed-by: Romain Caritey <Romain.Caritey@microchip.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:43:00 +02:00
Furkan Caliskan 04584da792 xen/sched: rtds: make admission control cpupool-wide toggleable
Add a per-cpupool on/off switch for RTDS admission control via
XEN_SYSCTL_scheduler_op, enabled by default, so an operator can
disable/enable enforcement for a pool

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-21 10:43:00 +02:00
Furkan Caliskan 5f7bfb20cd xen/sched: rtds: report utilization and cap via debug key
Print a cpupool's admitted utilization against its capacity in the
'r' debug ky (xl debug-keys r), so an operator can see the total
usage of a cpupool.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-21 10:43:00 +02:00
Furkan Caliskan 38e3acece2 xen/sched: rtds: enforce admission control in xl sched-rtds
Now that we have introduced admission control for new and
removed units. Extend it to XEN_DOMCTL_SCHEDOP_putinfo and
putvcpuinfo, so growing an existing reservation via
xl sched-rtds is checked too.

putinfo sets the same (period, budget) for every unit of a
domain at once, so it tests the whole domain's utilization
delta atomically, rather than unit-by-unit, which could
spuriously reject an overall-acceptable change depending on
iteration order.

putvcpuinfo changes one unit at a time, so it just calls
rt_try_set_utilization() directly.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-21 10:43:00 +02:00
Furkan Caliskan 5772eaafe3 xen/sched: rtds: add global-EDF utilization admission control
RTDS has no admission control: nothing stops the sum of all admitted
units' (budget/period) reservations in a cpupool from exceeding
what its pCPUs can actually provide. Once that happens, none of the
EDF deadline guarantees this scheduler is built around still hold
for the units sharing that pool.

Introduce admission control to prevent this: reject a reservation
whenever admitting it would push a cpupool's units over its capacity.
Track a running utilization total per cpupool, and enforce it in
rt_alloc_udata()/rt_free_udata(), the paired lifecycle hooks for a
unit's creation and destruction. This catches the default
period/budget every new unit gets.

Utilization is represented as a fixed-point value: budget is
left shifted by RTDS_UTIL_SHIFT (20 bits) and divided by period.
A plain "(budget << RTDS_UTIL_SHIFT) / period" risks overflowing
the multiply for large enough budgets. Rather than widen the
arithmetic to tolerate any input, the input itself is bounded:
rt_validate_params() rejects any budget above RTDS_MAX_BUDGET,
chosen as the largest value that can be left-shifted by
RTDS_UTIL_SHIFT without overflowing 64 bits, so the shift in
rt_unit_utilization() can never overflow.

A cpupool's capacity rt_utilization_cap() scales with the number of
scheduling resources in it. It is calculated as:
(number of sched_resources * RTDS_UTIL_SCALE * RTDS_UTIL_CAP_PCT / 100),
where RTDS_UTIL_CAP_PCT controls how much of that capacity can
actually be reserved; at 100% (its current value), all of it can be.

Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-21 10:43:00 +02:00
Ross Lagerwall 1b2f3cbc09 x86/svm: Intercept CR0 writes selectively
Since 3356d685db ("x86/svm: Remove lazy FPU support"), Xen does not
need to track when the TS or MP bits change so opt to intercept CR0
writes selectively. Aside from potentially reducing a few VMEXITs, this
fixes a nested virt bug where L1 intercepts CR0_SEL_WRITE and L0
intercepts CR0_WRITE. The hardware prioritizes CR0_WRITE and so L1 never
sees any CR0 writes.

Since CR0 TS/MP bits may now change behind Xen's back, sync CR0 on
VMEXIT so that the emulator sees the correct values.

Shadow mode continues to use the full CR0_WRITE intercept since with
Shadow the CR0 in the VMCB is not the same as the value Xen tracks on
behalf of the guest and allowing the guest to change one of them
directly would be fragile.

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:11:27 +02:00
Ross Lagerwall d60f9e94af x86/viridian: Implement synthetic timer direct mode
In direct mode, the timer asserts an interrupt on expiration rather than
using a SynIC message. It is useful to implement this since Windows 11's
Hyper-V can only use synthetic timers in direct mode.

To avoid changing behaviour in existing guests, add a new Viridian flag,
stimer_direct, to control whether this feature is visible and usable.

At the same time, check that the reserved bits are zero and the APIC
vector is only set when using direct mode since this is enforced by
Hyper-V (although not mentioned in the spec).

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:11:04 +02:00
Ross Lagerwall 33829ead9a x86/viridian: Workaround Hyper-V GP fault writing to MSR
The Viridian spec requires the vector to be >= 0x10 when writing to the
SINTx MSR, otherwise it should #GP fault.
The spec-defined initial value is 0x10000, i.e. the vector is 0. On
startup, for some reason Windows 11 Hyper-V tries to set the MSR to
the spec-defined initial value and since the vector is 0, it GP faults.
Fix this by doing as Hyper-V does and only fault if the SINT is
unmasked.

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:10:22 +02:00
Jan Beulich a401b5c9dc Eclair: re-enable scanning of the (almost) final linking step
The real final binaries are now no longer created by a linker invocation,
but by renaming an intermediate file (each). Arrange for linking pass 2
outputs to be scanned instead, yet continue to exclude the auxiliary
.xen.efi.alt.* binaries.

Fixes: da944a72fd ("x86: split xen-syms/xen.efi linking rules"))
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Nicola Vetrini <nicola.vetrini@bugseng.com>
2026-09-21 10:09:45 +02:00
Oleksii Kurochko 3ecc6da8d6 xen/riscv: create APLIC DT node for guest domains
Guests require a Device Tree description of the interrupt controller
topology. Add support for creating an APLIC node when building the
guest DT.

Provide stub for imsic_make_dt_node() it will be introduced properly
in follow-up patch.

The value chosen for GUEST_APLIC_S_BASE is based on QEMU one.

DT-building functions are marked __init because domain creation happens at
boot time, before the init sections are freed. In a typical deployment
libxl creates the interrupt controller node in userspace and hands the
complete FDT to Xen, so these functions are only called during early
domain construction.

Co-developed-by: Romain Caritey <Romain.Caritey@microchip.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:09:06 +02:00
Oleksii Kurochko 3559e12585 xen/riscv: generate IMSIC DT node for guest domains
Guests using the IMSIC interrupt controller require a corresponding
Device Tree description.

Add support for generating an IMSIC node when building the guest DT.
This allows guests to discover and use the IMSIC interrupt controller.

The value choosen for GUEST_IMSIC_S_BASE is an address which is typically
used for IMSIC and QEMU.

DT-building functions are marked __init because domain creation happens at
boot time, before the init sections are freed. In a typical deployment
libxl creates the interrupt controller node in userspace and hands the
complete FDT to Xen, so these functions are only called during early
domain construction.

Co-developed-by: Romain Caritey <Romain.Caritey@microchip.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:09:00 +02:00
Oleksii Kurochko 68ca2185e0 xen/riscv: introduce (de)initialization helpers for vINTC
Add common helpers domain_vintc_init() and domain_vintc_deinit() to
allocate and deallocate a virtual interrupt controller (vINTC)
structure and initialize basic virtual interrupt controller registers.

domain_vintc_deinit() isn't called at the moment as arch_domain_destroy()
is implemented as stub at the moment.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:08:47 +02:00
Oleksii Kurochko 9164a97efb xen/riscv: introduce minimal virtual APLIC (vAPLIC) infrastructure
At the current development stage, only domain vINTC init and deinit
operations are required, so implement those first.

Initialize vAPLIC's domaincfg to with the interrupt-enable bit set and
MSI delivery mode selected as the current solution is exepcted to have
always IMSIC, and initialize vintc->ops.

Other operations such as emulate_load(), emulate_store(), and is_access()
will be needed once guests are running and MMIO accesses to APLIC MMIO
range must be handled. These will be introduced separately later.

Introduce a structure to describe a virtual interrupt controller (vINTC)
and a vintc_ops structure, which provides operations to emulate load and
store accesses to interrupt controller MMIOs and to check whether a given
address falls within the MMIO range of a specific virtual interrupt
controller.
Note that already existed init_ops field in struct vintc will be init-ed
for APLIC in the follow up patch.

The vAPLIC implementation of these operations will be provided later
once guests can be run and these operations are actually needed.

Introduce these structures here as they are required for the implementation
of domain_vaplic_init() and domain_vaplic_alloc(). Also, introduce
vaplic_init() and init vintc_ops->vcpu_init() with it.

Co-developed-by: Romain Caritey <Romain.Caritey@microchip.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:08:35 +02:00
Oleksii Kurochko bbbe70852a xen/riscv: introduce per-vCPU IMSIC state
Each vCPU interacting with the IMSIC requires state to track the
associated guest interrupt file and its backing context.

Introduce a per-vCPU structure to hold IMSIC-related state, including
the guest interrupt file identifier and the CPU providing the backing
VS-file. Access to the guest file identifier is protected by a lock.

Initialize this structure during vCPU setup and store it in arch_vcpu.
The initial state marks the VS-file as software-backed until it becomes
associated with a physical CPU.

Add helper to retrieve the guest interrupt file identifier:
- vcpu_guest_file_id() is going to be used during update of APLIC's
  target register with the pair of information <guest_file_id, cpu_id>
  (to have MSI delivery mode work properly) when guest is trying to
  access vAPLIC's target register.
It will be used in the follow up patches.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:08:21 +02:00
Oleksii Kurochko 24a61ce264 xen/riscv: introduce aia_init() and aia_usable()
aia_init() is going to contain all the logic related to AIA initialization.

At the moment, it only checks whether the SSAIA extension is available,
and if so, sets is_aia_usable (which  indicates more than just the
availability of the extension) to true; it also signifies that the necessary
components (to be introduced in follow-up patches) have been initialized.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:08:09 +02:00
Oleksii Kurochko ff930346ef xen/riscv: implement make_intc_domU_node()
Introduce a RISC-V specific function to create an interrupt controller
Device Tree node for DomU domains during dom0less build.

Add make_intc_domU_node() to the dom0less build path and wire it to
a new generic helper, intc_make_domu_dt_node(), which delegates DT
node creation to the active interrupt controller implementation via
vintc_init_ops.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:07:55 +02:00
Oleksii Kurochko c91771c85c xen/riscv: introduce init interrupt controller operations
Introduce intc_hw_init_ops structure to avoid risky mix of init
function and non-init function.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:07:42 +02:00
Oleksii Kurochko 7e4be8d8eb xen/riscv: implement make_arch_nodes()
No RISC-V-specific nodes need to be created at the moment,
so make_arch_nodes() is implemented to simply return 0.

It is placed in dom0less-build.c as make_arch_nodes() is
only used in the dom0less code path. In the future, it will
be extended to create an emulated UART node.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:07:24 +02:00
Oleksii Kurochko 913cf380cf xen/riscv: implement make_timer_node()
Generally, in DT for RISC-V there is a document which describes a timer
node (riscv,timer.yaml or sifive,clint.yaml), but the Linux timer driver
is declared with TIMER_OF_DECLARE(riscv_timer, "riscv", ...).
It matches the CPU node (compatible "riscv"), not the timer node itself.
It then calls of_find_compatible_node(NULL, NULL, "riscv,timer") only to
read the optional riscv,timer-cannot-wake-cpu property.

Since Xen does not care about that property for now, make_timer_node() is
implemented to return 0, as no timer node needs to be created for RISC-V
guests.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:07:11 +02:00
Oleksii Kurochko 213ca210ff xen/riscv: implement make_cpus_node()
Implement make_cpus_node() to create cpus node for a guest domain.

This function is going to be use by common dom0less code during
construction domain.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:06:57 +02:00
Oleksii Kurochko 282bbc3cab xen/riscv: introduce guest riscv,isa string
Introduce build_guest_isa_str() to generate the riscv,isa string to be
passed to the guest via the Device Tree riscv,isa property.

Introduce the per-domain guest ISA bitmap, populated during domain
creation by calling init_guest_isa().

Introduce struct riscv_isa_ext_entry with a new guest_flags field
to filter out ISA extensions that should not be exposed to guests:

- f/d/q/v: FPU and vector context save/restore are not yet implemented
  for guests.
- Z*inx are not exposed either: they aren't in riscv_isa_ext[], so they
  can never be set in riscv_isa and thus never reach a guest, and no
  current hardware/guest-OS advertises or expects them. Supporting them
  would be cheaper than F/D/Q (FP values stay in integer registers Xen
  already context-switches), but is left as future work.
- h: Nested virtualisation is not supported.
- sstc: Xen owns the supervisor timer; guests must use SBI.
- svade: Xen manages hardware A/D bit updates in stage-2 page tables.
- svpbmt: Page-based memory types are not yet wired up in stage-2 code.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:06:37 +02:00
Oleksii Kurochko a83e5b41c4 xen/riscv: Implement construct_domain()
Implement construct_domain() function for RISC-V, which performs initial setup
for the domain's first vCPU, loads the kernel, initrd, and device tree,
and sets up guest CPU registers for boot.

It also creates additional vCPUs up to max_vcpus and assigns the device tree
address and boot cpuid in registers.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-21 10:06:12 +02:00
Oleksii Kurochko 31fb44f8c0 xen: introduce CONFIG_HAS_SHARED_INFO for archs without a shared page
On architectures that run guests in dom0less mode without the PV ABI
(currently RISC-V), no shared_info page is allocated and d->shared_info
remains NULL throughout the domain lifetime.  Several places in common
code access d->shared_info through the shared_info() macro or directly,
causing UBSAN null-pointer errors on such architectures.

Rather than adding runtime NULL guards that are logically unreachable
on x86 and Arm (where shared_info is always allocated), introduce a new
Kconfig symbol CONFIG_HAS_SHARED_INFO selected by x86 and Arm.

On !HAS_SHARED_INFO the shared_info() macro expands to a dereference
of shared_info_absent, an extern pointer that is declared but
intentionally never defined.  Any use of shared_info() that is not
dead-code-eliminated will therefore cause a link-time failure, making
missed guards impossible to overlook.

The 2L event-channel ops call shared_info() and must not be compiled on
architectures without a shared_info page, so event_2l.o is gated on
CONFIG_HAS_SHARED_INFO.  On such architectures evtchn_init() installs the
FIFO ops as a placeholder instead, so that a later guest opt-in to the
FIFO ABI via EVTCHNOP_init_control has no special-casing to do; if FIFO
support itself is also unavailable (!CONFIG_EVTCHN_FIFO), a dedicated
no-op evtchn_port_ops_none table is installed instead, so that
d->evtchn_port_ops is never NULL.  evtchn_fifo_word_from_port() is
guarded against uninitialised d->evtchn_fifo so the FIFO ops are safe
before evtchn_fifo_init_control() is called by the guest.

With CONFIG_HAS_SHARED_INFO=n all vCPUs fall back to the global
dummy_vcpu_info, so writes through vcpu_info() could leak data between
vCPUs. Reviewing the write paths in common code: the write in
map_guest_area() stores the constant ~0 so nothing serious would happen
if it were leaked; the event_2l.c paths are not compiled on
!HAS_SHARED_INFO, as event_2l.o is gated on CONFIG_HAS_SHARED_INFO; the
write in vcpu_info_populate() targets the new mapping buffer, not
dummy_vcpu_info.

Outside common code, the remaining writes are x86 PV-specific, for which
CONFIG_HAS_SHARED_INFO=y. No code changes are needed.

Finally, struct domain's shared_info field itself is gated on
CONFIG_HAS_SHARED_INFO, as it would otherwise be a permanently NULL
pointer: every user of it is either arch code for an architecture that
selects HAS_SHARED_INFO, or common code already guarded by the same
Kconfig symbol.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Michal Orzel <michal.orzel@amd.com> #Arm
2026-09-21 10:05:20 +02:00
Jan Beulich 68c3f7fb3a Eclair: relax long <-> function-pointer conversion deviation
What is true for unsigned long is also true for plain/signed long, thus
also taking care of two instances of __x86_return_thunk() being cast to
long.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Nicola Vetrini <nicola.vetrini@bugseng.com>
2026-09-21 09:59:08 +02:00
Jan Beulich 9fd71d2257 x86/domain: address Misra rule 11.1 violation in reset_stack_and_call_ind()
Eclair dislikes both sides of the comparison to differ in noreturn
attributes, thus deeming this a violation of "Conversions shall not be
performed between a pointer to a function and any other type". Since gcc
doesn't permit use of "noreturn" types used in a typecast, resort to
typeof().

No functional change intended.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Nicola Vetrini <nicola.vetrini@bugseng.com>
2026-09-21 09:58:31 +02:00
Jan Beulich b0597289eb x86: always park offline CPUs
While on AMD (or Hygon) CPUs the situation isn't as bad wrt broadcasting
of #MC, some "multicast" can still happen. Therefore the reasoning to park
CPUs rather than fully offlining them applies everywhere.

Don't retain the dependency on the "mce=" cmdline option either: That
option may best be dropped as well, as not enabling MCE will result in a
shutdown when #MC would otherwise be raised.

Drop the global variable, using a #define (just like common code does)
instead. Outside of common code, simplify expressions / code accordingly.
(In common code we still have to cater for x86 wanting it different from
everyone else.)

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-21 09:57:22 +02:00
Furkan Caliskan 4835c078e5 xen/sched: core: skip missing vcpu slots in sched_move_domain()
sched_move_domain() derives the number of units to rebuild from
d->max_vcpus, which is fixed at domain creation and never rolled
back if vcpu_create() fails partway through building a domain. So
d->vcpu[i] can be NULL for some i even though max_vcpus still
counts it - this happens if sched_alloc_udata() returns NULL.

The per-unit loop doesn't check for this: it sets
unit->vcpu_list = d->vcpu[unit_id] (NULL) and hands that broken
unit straight to the destination scheduler's alloc_udata(),
which assumes vcpu_list is always valid and crashes Xen when
it is not.

Reproduced by building a domain in a non-default cpupool where
vcpu creation fails partway through, then destroying it.
domain_kill() moves the domain back to the default cpupool via
sched_move_domain() before actually destroying it, crashing
inside the destination scheduler's alloc_udata() (seen in
Credit2's csched2_alloc_udata() -> is_idle_unit() -> NULL deref).

Before building a unit in sched_move_domain(), check whether all
vpcu slots belonging to that unit are populated. If any of its
vpcus is missing:
 - For a dying domain, skip the unit allocation.
 - For an active domain, abort the move and return -EINVAL to
   prevent running with dropped vCPUs.

Fixes: 70fadc4163 ("xen/cpupool: support moving domain between cpupools with different granularity")
Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-21 09:54:12 +02:00
Julian Vetter adbbbd47a1 xen/arm: report proper GIC version via XEN_DOMCTL_getdomaininfo
When creating a domain on ARM, and passing XEN_DOMCTL_CONFIG_GIC_NATIVE
for the gic_version field in the struct xen_arch_domainconfig,
arch_sanitise_domain_config() resolves this to the approrpiate GIC_V2 or
GIC_V3 version the domain actually has, based on the host's
gic_hw_version(). That value is stored in the domain as
d->arch.vgic.version, but can't be queried through any other domctl
later. Toolstacks that create and build a domain in the same call
already have this info from the createdomain reply and never need to ask
again.

Toolstacks that create a domain and build it later from a separate
process do need to ask again. But, the ARM implementation only fills in
info->flags and info->gpaddr_bits. info->arch_config is left zeroed, so
XEN_DOMCTL_getdomaininfo always reports gic_version as
XEN_DOMCTL_CONFIG_GIC_NATIVE (0) regardless of what was actually
configured earlier.

Signed-off-by: Julian Vetter <julian.vetter@vates.tech>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2026-09-15 17:13:02 +02:00
Michal Orzel 20ee984e1d drivers/char: Panic when the requested UART fails to initialise
uart_init() cannot tell its caller that the UART the user asked for did
not come up: every failure path only printks. Arm and RISC-V carry on
into console_init_preirq() and boot without a console, rather than
refusing to boot as they do elsewhere when a user request cannot be met.

Return an error from dt_uart_init() and panic in start_xen(). An
explicit request Xen cannot satisfy should stop the boot rather than
silently degrade it, which is what start_xen() already does for the rest
of the boot configuration.

Only a path given on the command line counts as a request we have to
satisfy. Falling back to /chosen/stdout-path or acpi_uart_init()
therefore never fails. SPCR is firmware provided, the analogue of
stdout-path, and there is no ACPI equivalent of dtuart= to make an
explicit request with.

While here, decide whether the SPCR table was found from the returned
acpi_status rather than from the table pointer, which was only NULL
because the caller initialised it - acpi_get_table() writes it solely
on success.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
2026-09-15 17:13:02 +02:00
Michal Orzel 12b136a965 drivers/char: Check if console=dtuart for ACPI SPCR serial bring up
dtuart denotes a generic UART parsed from a device tree (back then it
was the only method, hence dt prefix) or ACPI SPCR table (they all use
the SERHND_DTUART serial handle). Currently we only check if console= is
set to dtuart in the DT flow and not in the ACPI flow. This means that
even if we set console=none we would still bring up ACPI parsed
serial device for nothing. Move the check to uart_init() to cover both
paths.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2026-09-15 17:13:02 +02:00
Michal Orzel 422484e55c cmdline: Document console=dtuart option
Document the default console= option on Arm and RISC-V that is
"dtuart" indicating a generic UART parsed from a device tree or
ACPI SPCR table. This serial utilizes SERHND_DTUART handle.

Take the opportunity to:
 - fix documented x86 default to vga to match OPT_CONSOLE_STR,
 - mark dtuart option as available on RISC-V,
 - document fall back to /chosen/stdout-path.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-15 17:13:02 +02:00
Baptiste Le Duc 4830ddbee3 Add basic b4 config file
b4[1] is a convenient tool for mail-based contribution. A config file[2]
tracked in the tree lets the project ship a few defaults that match the Xen
patch submission rules.

This aims to help new contributors who have never used a mailing list avoid
mistakes when sending their patch series.

The tree has no scripts/checkpatch.pl or equivalent, so there is nothing
for b4 to run per patch. Disable the needs-checking pre-flight check so a
series can be sent without first running b4 prep --check.

[1] https://pypi.org/project/b4/
[2] https://b4.docs.kernel.org/en/latest/config.html

Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-15 11:46:07 +02:00
Andrew Cooper 5838665ef1 x86/build: Remove leading space in xen.efi.S rule
It happens to be benign, but it causes emacs to ask:

  Suspicious line 194. Save anyway? (y or n)

whenever saving the file.

Fixes: da944a72fd ("x86: split xen-syms/xen.efi linking rules")
Acked-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-15 11:46:07 +02:00
Andrew Cooper 6bdb8d45b7 xen: Use __has_include() in xen/percpu.h
Only x86 has an asm/percpu.h.  Have the compiler only include it if it's
present, rather than symlinking an empty file.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2026-09-11 18:24:25 +01:00
Ross Lagerwall 221f87ad39 nestedsvm: Fix multi-byte IO port intercept check
For multi-byte IO port accesses, the APM says that SVM should intercept
if any of the corresponding permission bits are set. However, the code
has this backwards and only intercepts if all the permission bits are
set. Fix this and at the same time, make things safer by handling
mapping failures as intercepted. Also rename the 'enabled' variable to
make it clearer what it does.

This affects Hyper-V which for the root partition intercepts 0xcf8 and
0xcfc-0xcff. L2 issues 4 byte CFG index writes to 0xcf8 which are incorrectly
permitted and update the L1 CFG index. The subsequent L2 CFG data read at 0xcfc
is intercepted by L1, then resubmitted as a CFG index write followed by CFG
data read to L0. Since L1 doesn't see the CFG index write by L2, it uses the
wrong index and gets garbage back, ultimately leading to a failure to boot
since it cannot access its NVMe disk.

Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-11 18:24:25 +01:00
Andrew Cooper 73df85da4f x86: Rename X86_ET_EXT_INTR to X86_ET_INTR and fix function names
The name X86_ET_EXT_INTR came from the VT-x code originally, but it's not
really correct.

The SDM doesn't give a concrete name, and only describes the fields as
"external interrupts".  The APM does give a concrete name of INTR, and both
Intel and AMD use the name INTR for related purposes elsewhere; the name
derives originally from #INTR which was a real pin on early processors.

Very importantly, this is distinct from ExtINT which is a type of maskable
interrupt which can be sent in an x86 system.

Therefore rename all {svm,vmx}_*_extint() to {svm,vmx}_*_intr(), as they
pertain to all maskable interrupts, not only to ExtINT interrupts.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
2026-09-11 18:24:25 +01:00
Jan Beulich acd87f99ac sched/core: avoid use of "current" in initializer lists
TRACE_TIME() uses an initializer list and hence is covered by Misra C:2012
rule 13.1 ("Initializer lists shall not contain persistent side effects").
Use intermediate variables to address this.

In vcpu_yield() take the opportunity to rename the existing variable which
better would have been used already before.

In do_sched_op() extend the scope of and rename an existing variable. Also
drop a pointless (and slightly malformed, style-wise) cast there, and
adjust to other one to by style conformant.

No functional change intended.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
2026-09-11 08:55:16 +02:00
Jan Beulich 0c8460766a x86/nSVM: address Misra 2.1 rule violation
The 16-bit range of "port" is fully handled by the switch(). Therefore the
default: case is reported unreachable by Eclair. Insert BUILD_ERROR() to
annotate this for Eclair.

No functional change.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
2026-09-11 08:54:53 +02:00
Jan Beulich bc24cc6b72 x86/HVM: address Misra 2.1 rule violations
In hvm_set_cr3() the "bad_cr3" label is reachable only with
SHADOW_PAGING=y; the code being there is therefore a Misra rule 2.1
(unreachable code) violation when SHADOW_PAGING=n.

Similarly code past the initial switch() in hvm_debug_op() is reachable
only when CONFIG_INTEL_VMX=y.

No functional change.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
2026-09-11 08:53:58 +02:00
Jan Beulich 7fc89f9649 x86/shadow: eliminate unused forms of sh_map_and_validate_gl<N>e()
The L2H, L3, and L4 forms only have GUEST_PAGING_LEVELS=4 call sites, i.e.
their 2- and 3-level forms are unreachable, violating Misra rule 2.1. The
L2H form additionally is unused (call site DCE-d) with PV32=n.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
2026-09-11 08:53:19 +02:00
Jan Beulich 4fcd42a958 x86/mm: pagetable_dying() is HVM+SHADOW_PAGING only
The referenced commit didn't go far enough, leaving a Misra rule 2.1
(unreachable code) violation: The function lacks "noreturn" in this
configuration. Since with SHADOW_PAGING=n paging_mode_shadow() is compile-
time-constant false, the compiler can DCE the call site. Hence we can
avoid building the function itself altogether.

No functional change.

Fixes: 2fb2dee1ac ("x86/mm: pagetable_dying() is HVM-only")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
2026-09-11 08:52:40 +02:00
Roger Pau Monne d7bf1b8ea2 x86/mm: limit deferred TLB flushing to PV domain support
The current logic on x86 will mark all domain owned pages as needing a TLB
flush before being re-used.  However such TLB flushing is only strictly
needed when the pages might have been mapped by a PV domain, as those can
keep a reference to the page in the TLB after it has been freed.

Limit the flushing to builds with PV domain support, as tracking whether a
page might have been mapped by a PV domain is not trivial (and possibly not
worth the extra logic).

Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2026-09-10 11:54:12 +02:00
Roger Pau Monne 0ea57a11f5 xen/rcu: sort includes
Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-10 11:54:12 +02:00
Roger Pau Monne fff00f1826 xen/rcu: fix types
Adjust some types: int -> bool, int -> unsigned int. Also fix a couple of
typos plus trailing white space.

No functional change intended.

Signed-off-by: Roger Pau Monné <roger@xenproject.org>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-10 11:54:12 +02:00
Oleksii Kurochko 2f73bc7c06 xen/dom0less: turn max_init_domid into a common variable
Until now every architecture carried its own notion of max_init_domid:
Arm defined a real variable (declared in asm/setup.h, defined in
setup.c), while ppc, riscv and x86 each provided a "#define
max_init_domid (0)" stub in their asm/setup.h. This duplicated the same
declaration across all arches and placed a purely dom0less concept in
arch setup headers.

Now that the dom0less build code lives in common (xen/common/
device-tree/dom0less-build.c sets max_init_domid, and the console
serial-input switcher reads it), there is no reason for the symbol to be
per-arch. Provide a single declaration in <xen/dom0less-build.h>, with
the !CONFIG_DOM0LESS_BOOT stub kept there as well, so there is one source
of truth and the arch headers no longer need to mention it. Update
console.c to include <xen/dom0less-build.h> for the declaration instead
of relying on asm/setup.h, and drop the now unneeded <asm/setup.h>
include.

Place the definition in xen/common/domid.c rather than in dom0less-
build.c. The latter is built as dom0less-build.init.o, i.e. the whole
object is relocated into the .init.* sections and freed after boot,
whereas max_init_domid must outlive boot because it is read at runtime
by the console serial-input switcher. domid.c is always linked (obj-y)
and resides in regular (non-init) sections, so it is a correct home for
the variable. It is marked __ro_after_init since it is only updated
while creating boot-time domains and read-only afterwards, and guarded
by CONFIG_DOM0LESS_BOOT as domid.c itself is unconditional.

While at it, make <xen/dom0less-build.h> self-contained: it includes
<public/xen.h>, which uses the fixed-width types provided by
<xen/types.h>, so include the latter explicitly rather than relying on
the includer having pulled it in first. This becomes necessary as soon
as <xen/dom0less-build.h> comes first in an alphabetically sorted
include list, as it now does in domid.c.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2026-09-10 09:02:08 +02:00
Jan Beulich 04d4312440 x86/EFI: adjust efi_multiboot2_prelude() to comply to Misra rule 18.2
While casting to pointer types may be more natural there, the subtraction
then ends up violating "Subtraction between pointers shall only be applied
to pointers that address elements of the same array". Use unsigned long
arithmetic instead.

No functional change intended.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
2026-09-10 09:01:30 +02:00
Jan Beulich c3b570e1b5 x86/PCI: use pci_sbdf_t also for pci_dev_base()
No need to pass three arguments when both callers already hold SBDF in
their hands.

No functional change.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger@xenproject.org>
Reviewed-by: Teddy Astie <teddy.astie@vates.tech>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
2026-09-10 09:00:55 +02:00
Jan Beulich 1b12a20631 PPC: split xen-syms linking rule
Doing so, besides (hopefully) adding clarity (not the least by way of
[re-]using pattern rules where possible), also avoids explicit recursive
$(MAKE) invocations.

By re-using the generic rules introduced when the respective x86 rule was
split,
- the .map file now isn't created after the final binary anymore,
- --strip-debug is passed to $(LD) during early linking passes (for
  consistency the option is also explicitly added to the optional linking
  pass rule),
- CONFIG_{SUPPRESS_DUPLICATE_SYMBOL_WARNINGS,ENFORCE_UNIQUE_SYMBOLS} are
  now properly respected.
Orphan section checking, otoh, is getting suppressed for now, until the
about a dozen warnings which would result have been taken care of.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
2026-09-10 09:00:16 +02:00
Jan Beulich da944a72fd x86: split xen-syms/xen.efi linking rules
Doing so, besides (hopefully) adding clarity (not the least by way of
using pattern rules where possible), also avoids explicit recursive
$(MAKE) invocations. For xen-syms move re-usable helper rules to a new
scripts/Makefile.link.

While doing so, re-order .map file creation (which can in principle fail)
and check-endbr.sh invocation ahead of putting in place the final image
(which is now the result of a simple rename).

Also drop --source-name= from the tools/symbols invocation which has
--empty passed, for being meaningless there.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
2026-09-10 08:59:50 +02:00