Commit Graph
14 Commits
Author SHA1 Message Date
Mykola Kvach 3322c7355b xen/arm: propagate vGIC vCPU init failures
The vGIC per-vCPU init callback can fail. In particular, GICv3 rejects
a vCPU when the domain's redistributor layout has no MMIO slot covering
that vCPU. However, the generic vGIC init path ignored the callback
return value, so vcpu_create() could succeed with an invalid vGICv3
per-vCPU state.

This can be reproduced on FVP Base RevC by exposing a 2 MiB GICv3
redistributor region to Dom0 and booting Xen with:

    maxcpus=1 dom0_max_vcpus=64

The host GICv3 redistributor range is:

    region 0: 0x0000002f100000 - 0x0000002f300000

With Xen's guest redistributor frame size of 128 KiB, that range covers
16 guest redistributors. vCPU16 and above have no corresponding
redistributor slot.

Before this fix, Xen detected the missing redistributors:

    d0: Unable to find a re-distributor for VCPU 16
    ...
    d0: Unable to find a re-distributor for VCPU 63

but ignored the error and continued as if the secondary vCPUs had been
created correctly. Dom0 then saw 64 possible CPUs and could hang during
secondary CPU bring-up:

    smp: Bringing up secondary CPUs ...
    d0v15: vGICR: SGI: unhandled word write ... to ICACTIVER0

Propagate the vGIC vcpu_init() error so the caller can stop creating
secondary vCPUs. With this fix, Dom0 construction reports:

    d0: Unable to find a re-distributor for VCPU 16
    Failed to allocate d0v16

and the guest continues booting with the vCPUs created before the
failure:

    smp: Brought up 1 node, 16 CPUs

Free the private IRQ rank allocated by vcpu_vgic_init() on this error
path. The caller will still run the generic vCPU creation cleanup, but
XFREE() clears the pointer so that cleanup remains idempotent.

Also fix the host-layout redistributor region count for the case where
the requested vCPU count is larger than the capacity of all host
redistributor regions. The old code always stored i + 1 after the loop.
That is correct when the loop stops inside a valid region because the
requested vCPU count is covered. If the loop exits after consuming all
hardware regions, i is already equal to the number of allocated regions,
so i + 1 records one region too many.

In the same FVP setup, that off-by-one made Xen describe host-layout
GICR state beyond the populated redistributor region list. Dom0 then
accessed the GICR MMIO window described in its device tree, but Xen could
not match the access to a valid emulated redistributor frame. During
debugging this was seen as an unexpected vGICR access followed by a
guest panic:

    d0v0: vGICR: unknown gpa read address 000000002f10ffe8
    pc : gic_iterate_rdists+0x4c/0x104
    Kernel panic - not syncing: Attempted to kill the idle task!

Keep the existing construct_domain() policy used by Dom0 and dom0less
domain construction: a failure to create a secondary vCPU stops the
secondary vCPU creation loop, but does not fail the whole domain
construction.

Fixes: ea37fd2111 ("xen/arm: split vgic driver into generic and vgic-v2 driver")
Fixes: 54ec59f6b0 ("xen/arm: vgic-v3: Don't create empty re-distributor regions")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
(cherry picked from commit 961cc8cc0f)
2026-07-15 09:46:50 +02:00
Mykola Kvach 20c5792dc9 xen/arm: gic-v3: Preserve ARE_NS when disabling the distributor
gicv3_dist_init() disables the distributor before reprogramming the
global interrupt state. It used to do this by writing 0 to GICD_CTLR.

On a system where firmware has already enabled Non-secure affinity
routing, a zero write clears the Non-secure view's GICD_CTLR.ARE_NS bit.
Arm IHI 0069H.b, section 2.3.3 ("Changing affinity routing enables"),
states that changing GICD_CTLR.ARE_NS from 1 to 0 is UNPREDICTABLE. The
GICD_CTLR register description in section 12.9.4 carries the same rule
for the ARE_NS field.

Preserve ARE_NS while clearing the group enable bits. If firmware left
ARE_NS clear, the value written is still 0, preserving the existing
initialization flow.

Fixes: bc183a0235 ("xen/arm: Add support for GIC v3")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Release-Acked-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
(cherry picked from commit e63ba93511)
2026-07-15 09:46:50 +02:00
Mykola Kvach 08156620f1 xen/arm: gic-v3: Wait for redistributor RWP using the right bit
gicv3_do_wait_for_rwp() is used for both distributor and
redistributor writes. The CTLR register is at offset 0 for both,
but the RWP bit is not in the same position.

For GICD_CTLR, RWP is bit 31. For GICR_CTLR, bit 31 is UWP,
while RWP is bit 3. The redistributor wait path was therefore
polling UWP instead of RWP.

UWP covers upstream writes, including Generate SGI packets, and is
not a substitute for redistributor register write completion. The
existing redistributor callers need RWP semantics for redistributor
register writes such as GICR_ICENABLER0 and GICR_CTLR updates.

Add GICR_CTLR_RWP and pass the expected RWP bit to the shared
helper.

Fixes: bc183a0235 ("xen/arm: Add support for GIC v3")
Reported-by: Luca Fancellu <luca.fancellu@arm.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
(cherry picked from commit d86cf3cbd4)
2026-07-15 09:46:50 +02:00
Mykola Kvach 715bf77ce1 xen/arm: gic-v2: disable interrupt bypass on CPU shutdown
The GICv2 CPU shutdown path currently writes 0 to GICC_CTLR.

Per IHI0048B.b section 2.3.1, clearing the architected bypass-disable
bits selects bypass rather than deasserted interrupt outputs when the
CPU interface stops driving them. Tables 2-2 and 2-3 show that a zeroed
GICC_CTLR can fall back to the legacy IRQ/FIQ inputs instead of fully
disabling the interface.

Fix this by reading GICC_CTLR, then setting the bypass-disable bits and
clearing the group-enable bits that are architecturally defined for the
current GICC_CTLR view before writing the value back. When Security
Extensions are implemented Xen accesses the Non-secure copy of
GICC_CTLR, where IRQBypDisGrp1 and FIQBypDisGrp1 are at bits [6:5] and
bits [8:7] are reserved.

Without Security Extensions (GICD_CTLR.DS=1), GICD_IGROUPR is RAZ/WI
and all interrupts are Group 0, so clearing EnableGrp0 alone is
sufficient to stop interrupt delivery through the CPU interface.

Section 2.3.2 also states that wakeup event signals remain available
even when both GIC interrupt signaling and interrupt bypass are
disabled, so disabling bypass does not break the power-management use
case, i.e. suspend modes.

Fixes: 5e40a1b435 ("arm: SMP CPU shutdown")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
(cherry picked from commit 6f00fd9d6c)
2026-07-15 09:46:50 +02:00
Mykola Kvach 0927c7f348 xen/arm: gic-v3: disable Group 1 before CPU power-down
gicv3_cpu_disable() currently writes 0 to ICC_CTLR_EL1. Unlike
GICC_CTLR in the GICv2 path, ICC_CTLR_EL1 does not enable or disable
physical Group 1 interrupt signalling, so this write only clears
EOImode.

The GICv3 power management rules require the physical group enables in
the CPU interface to be cleared before the redistributor is driven into
ProcessorSleep, otherwise behaviour is UNPREDICTABLE. Xen only enables
Group 1 interrupts on this path, so disable the interface by clearing
ICC_IGRPEN1_EL1 instead.

This appears to be a copy of the GICv2 pattern where the enable control
lives in CTLR, but for GICv3 the enable moved to ICC_IGRPEN1_EL1.

Fixes: bc183a0235 ("xen/arm: Add support for GIC v3")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
(cherry picked from commit 18b718b6af)
2026-07-15 09:46:50 +02:00
Mykola Kvach 76dc2d6071 systemd: fall back to default system-sleep dir without systemd-devel
Keep the pkg-config lookup for SYSTEMD_SLEEP_DIR, but fall back to
"$(prefix)/lib/systemd/system-sleep/" if the variable remains unset.
This avoids reintroducing a build-time dependency on systemd-devel while
still honoring the path provided by pkg-config when present.

Fixes: e54a6cd6a1 ("systemd: Add hooks to stop/start xen-watchdog on suspend/resume")
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
(cherry picked from commit b34bde262c)
2026-03-06 14:42:24 +01:00
Mykola Kvach 4c3aa6e93d xen/arm: irq: add missing spin_unlock() in init_local_irq_data() error path
If init_one_irq_desc() fails, init_local_irq_data() returns without
releasing local_irqs_type_lock, leading to a possible deadlock.

Release the lock before returning to ensure proper cleanup.

Fixes: 2bb32b8092 ("xen/irq: Propagate the error from init_one_desc_irq() in init_*_irq_data()")
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Denis Mukhin <dmukhin@ford.com>
Acked-by: Julien Grall <jgrall@amazon.com>
2025-08-12 12:04:41 +01:00
Mykola Kvach e54a6cd6a1 systemd: Add hooks to stop/start xen-watchdog on suspend/resume
This patch adds a systemd sleep hook script to stop the xen-watchdog
service before system suspend and start it again after resume.

Stopping the watchdog before a system suspend operation may look unsafe.
Let's imagine the following situation: 'systemctl suspend' does not
interact with the running service at all. In such a case, the Xen
watchdog daemon freezes just before suspend. If this happens, for
example, right before sending a ping, and Xen has not yet marked the
domain as suspended (is_shutting_down), the Xen watchdog timer may
trigger a false alert.

This is an almost impossible situation, because typically:
    ping time = watchdog timeout / 2

and the watchdog timeout is usually set to a relatively large value
(dozens of seconds).

Still, this is more likely with very short watchdog timeouts. It may
happen in the following scenarios:
    * Significant delays occur between freezing Linux tasks and
      triggering the ACPI or PSCI sleep request or handler.
    * Long delays happen inside Xen between the entrance to the sleep
      trigger and the actual forwarding of the sleep request further.

A similar situation may occur on resume with short timeouts. During the
resume operation, Xen restores timers and the domain context. The Xen
watchdog timer also resumes. If it schedules the domain right before the
watchdog timeout expires, and the daemon responsible for pinging is not
yet running, a timeout might occur.

Both scenarios are rare and typically require very small watchdog
timeouts combined with significant delays in Xen or the Linux kernel
during suspend/resume flows.

Conceptually, however, if activating and pinging the Xen watchdog is the
responsibility of the domain and its services, then the domain should
also manage the watchdog service/daemon lifecycle. This is similar to
what is already done by the Xen watchdog driver inside the Linux kernel.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Denis Mukhin <dmukhin@ford.com>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
2025-08-01 15:36:02 +02:00
Mykola Kvach 7fc5a47322 SUPPORT.md: Document guest PSCI support
Add a new entry under "Virtual Hardware, Hypervisor" for guest PSCI
support on ARM. This documents support for all mandatory functions of
PSCI 1.1, and separately lists the supported optional functions.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
2025-07-07 15:08:05 -07:00
Mykola Kvach 3e5f9674c0 xen/char: wrap suspend/resume console callbacks with CONFIG_SYSTEM_SUSPEND
This patch wraps the suspend/resume console callbacks and related code within
CONFIG_SYSTEM_SUSPEND blocks. This ensures that these functions and their
calls are only included in the build when CONFIG_SYSTEM_SUSPEND is enabled.

This addresses Misra Rule 2.1 violations.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
2025-06-26 14:57:22 +02:00
Mykola Kvach bee20891d3 xen/common: Guard freeze/thaw_domains functions with CONFIG_SYSTEM_SUSPEND
This patch adds CONFIG_SYSTEM_SUSPEND guards around freeze_domains
and thaw_domains functions.

This ensures they are only compiled into the hypervisor when the system
suspend functionality is enabled, aligning their inclusion with their
specific use case.

This addresses two Misra Rule 2.1 violations.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
2025-06-24 14:56:02 +02:00
Mykola Kvach e6ac1b2b01 xen/arm64: head: document missing input registers for MMU functions
Add missing input register descriptions to enable_secondary_cpu_mm
and enable_boot_cpu_mm functions. This update improves code clarity
and consistency in comments.

No functional changes are introduced by this patch.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2025-06-09 08:48:42 +02:00
Mykola Kvach d7d55c27cc xen/arm: vpsci: Fix typo in comment (SCCC changed to SSSC)
Corrected a typo in a comment within vpsci.c:
  replaced "SCCC_SMCCC_*_REVISION" with the correct "SSSC_SMCCC_*_REVISION".

This change improves clarity but does not affect functionality.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2025-05-30 08:47:29 +02:00
Mykola Kvach 1099bdd24f x86/ACPI: Move scheduler enable/disable calls out of {freeze,thaw}_domains()
... and into their parent, enter_state().  This change addresses the concern
about misleading function semantics, as the scheduler operations are not
directly related to the domain pausing/resuming implied by the freeze/thaw
naming.

Suggested-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
2025-05-28 12:29:33 +01:00