Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Sascha Bischoff" <Sascha.Bischoff@arm.com>
Cc: "Marc Zyngier" <maz@kernel.org>,
	kvm@vger.kernel.org, kvmarm@lists.linux.dev,
	"Oliver Upton" <oupton@kernel.org>
Subject: Re: [PATCH v4 10/48] KVM: arm64: gic-v5: Introduce guest IST alloc and management
Date: Fri, 24 Jul 2026 11:22:39 +0000	[thread overview]
Message-ID: <20260724112240.4FD981F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260724104819.1296803-11-sascha.bischoff@arm.com>

Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [Critical] Missing hardware invalidation commands allow DMA Use-After-Free.
- [Critical] Integer truncation in `l1sz` calculation leads to zero-sized IST allocation and host memory corruption.
- [High] VPE descriptor pointer is published to hardware before its initialization is visible.
- [High] Null pointer dereference of `vcpu0` in `vgic_v5_vmte_assign_ist`.
- [High] Missing `GICV5_VMTEL2E_IST_VALID` bit leaves IST configurations invalid.
- [High] Unsafe DMA buffer allocations using `kzalloc()` cause cacheline sharing and lost hardware updates.
- [Medium] Missing `WRITE_ONCE` when zeroing the hardware-shared VMTE entry.
--

--- Patch [10]: [PATCH v4 10/48] KVM: arm64: gic-v5: Introduce guest IST alloc and management ---
commit 014722137813a4073b0da36f6aceff4c3e396990
Author: Sascha Bischoff <Sascha.Bischoff@arm.com>

KVM: arm64: gic-v5: Introduce guest IST alloc and management

GICv5 guests use Interrupt State Tables (ISTs) to track and manage the
interrupt state for SPIs and LPIs. These ISTs are provided to the host's
IRS via the VMTE.

> diff --git a/arch/arm64/kvm/vgic/vgic-v5-tables.c b/arch/arm64/kvm/vgic/vgic-v5-tables.c
> index 22cd03e0f1963..aa737972f525c 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5-tables.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5-tables.c

[ ... ]

> @@ -628,3 +671,500 @@ int vgic_v5_vmte_free_vpe(struct kvm_vcpu *vcpu)
>  
>  	return 0;
>  }
> +
> +/*
> + * Assign an already allocated IST to the VM by populating the fields in the
> + * corresponding VMTE. We re-use this code for both an SPI IST and LPI IST, even
> + * if the paths to reach it might be vastly different.
> + */
> +static int vgic_v5_vmte_assign_ist(struct kvm *kvm, phys_addr_t ist_base,
> +				   bool two_level, unsigned int id_bits,
> +				   unsigned int l2sz, unsigned int istsz,
> +				   bool spi_ist)
> +{
> +	struct kvm_vcpu *vcpu0 = kvm_get_vcpu(kvm, 0);

[Severity: High]
Could kvm_get_vcpu(kvm, 0) return NULL here if userspace performs VGIC
initialization operations before any vCPUs have been created?

> +	u32 vm_id = vgic_v5_vm_id(kvm);
> +	enum gicv5_vcpu_cmd cmd;
> +	struct vmtl2_entry *vmte;
> +	unsigned int section;
> +	u64 tmp;
> +	int ret;

[ ... ]

> +	tmp = FIELD_PREP(GICV5_VMTEL2E_IST_L2SZ, l2sz);
> +	tmp |= FIELD_PREP(GICV5_VMTEL2E_IST_ADDR,
> +			ist_base >> GICV5_VMTEL2E_IST_ADDR_SHIFT);
> +	tmp |= FIELD_PREP(GICV5_VMTEL2E_IST_ISTSZ, istsz);
> +	tmp |= FIELD_PREP(GICV5_VMTEL2E_IST_ID_BITS, id_bits);
> +	if (two_level)
> +		tmp |= GICV5_VMTEL2E_IST_STRUCTURE;
> +
> +	WRITE_ONCE(vmte->val[section], cpu_to_le64(tmp));

[Severity: High]
Is the GICV5_VMTEL2E_IST_VALID bit missing when constructing this IST entry?

It appears the valid bit is never set in tmp before it is written to the VMTE,
which might leave the configuration architecturally invalid and break interrupt
routing.

> +	vgic_v5_clean_inval(vmte, sizeof(*vmte));
> +
> +	/* Finally, mark the entry as valid */
> +	cmd = spi_ist ? SPI_VIST_MAKE_VALID : LPI_VIST_MAKE_VALID;
> +	ret = irq_set_vcpu_affinity(vgic_v5_vpe_db(vcpu0), &cmd);

[Severity: High]
If kvm_get_vcpu(kvm, 0) returned NULL above, does passing it directly to
vgic_v5_vpe_db() here cause a NULL pointer dereference?

> +
> +	return ret;
> +}
> +
> +/*
> + * Allocate a Linear IST - always used for SPIs and potentially LPIs.
> + *
> + * The calculation for n has been taken from section 11.2.2 of the GICv5 EAC0
> + * spec.
> + *
> + * NOTE: istsz is the FIELD used by GICv5, not the actual size (or log2() of the
> + * size).
> + */
> +static int vgic_v5_alloc_linear_ist(struct kvm *kvm, bool spi_ist,
> +				    unsigned int id_bits, unsigned int istsz)
> +{
> +	const size_t n = id_bits + 1 + istsz;
> +	u32 vm_id = vgic_v5_vm_id(kvm);
> +	struct vgic_v5_vm_info *vmi;
> +	__le64 *ist;
> +	u32 l1sz;
> +
> +	vmi = xa_load(&vm_info, vm_id);
> +	if (!vmi)
> +		return -EINVAL;
> +
> +	/*
> +	 * Allocate the IST. We only have one level, so we just use the L2 ISTE.
> +	 */
> +	l1sz = BIT(n + 1);

[Severity: Critical]
Could the 32-bit truncation of l1sz evaluate to zero for large values of n
(such as when a guest requests a large LPI ID space)?

If n + 1 >= 32, the 64-bit BIT() macro result will be truncated to exactly 0
when assigned to the u32 l1sz. This would result in a zero-sized allocation
that returns ZERO_SIZE_PTR, potentially leading to host memory corruption.

> +	ist = kzalloc(l1sz, GFP_KERNEL_ACCOUNT);

[Severity: High]
Is this memory structure modified by the non-coherent GIC hardware?

If so, does allocating it with kzalloc() risk cacheline sharing with adjacent
slab objects, potentially causing lost hardware updates during CPU cache
eviction?

[ ... ]

> +/*
> + * Free a Linear IST. Can only happen once the VM is dead.
> + */
> +static int vgic_v5_linear_ist_free(struct kvm *kvm, bool spi)
> +{

[ ... ]

> +	/* The VM should be dead here, so we can just zero the VMT section */
> +	vmte->val[section] = cpu_to_le64(0);

[Severity: Critical]
Does freeing the backing memory and zeroing the VMTE without first issuing
hardware invalidation commands allow the hardware to continue DMAing into
freed slab objects?

[Severity: Medium]
Additionally, since this is a hardware-shared data structure, does clearing
the VMTE entry with a plain assignment risk store tearing? Should this use
WRITE_ONCE() to ensure an atomic 64-bit write?

> +	vgic_v5_clean_inval(vmte, sizeof(*vmte));
> +
> +	return 0;
> +}
> +
> +/*
> + * Free a Two-Level IST. Can only happen once the VM is dead.
> + */
> +static int vgic_v5_two_level_ist_free(struct kvm *kvm, bool spi)
> +{

[ ... ]

> +	/* The VM must be dead, so we can just zero the VMT section */
> +	vmte->val[section] = cpu_to_le64(0);

[Severity: Critical]
Does freeing the backing memory and zeroing the VMTE without first issuing
hardware invalidation commands allow the hardware to continue DMAing into
freed slab objects?

[Severity: Medium]
Similarly, does clearing the VMTE entry with a plain assignment risk store
tearing here?

> +	vgic_v5_clean_inval(vmte, sizeof(*vmte));
> +
> +	return 0;
> +}

Looking at vgic_v5_vmte_alloc_vpe() from the broader context of this file:

vgic_v5_vmte_alloc_vpe() {
    ...
    vped = kzalloc(vmt_info->vped_size, GFP_KERNEL);
    ...
    tmp = FIELD_PREP(GICV5_VPED_ADDR, virt_to_phys(vped) >> GICV5_VPED_ADDR_SHIFT);
    WRITE_ONCE(vpet_base[vpe_id], cpu_to_le64(tmp));

    vgic_v5_clean_inval(vped, vmt_info->vped_size);
    ...
}

[Severity: High]
Is it possible for the hardware to observe the VPE descriptor pointer before
the zeroed memory of the descriptor is flushed to the Point of Coherency?

If a CPU cache eviction writes the pointer to main memory before the cache
clean, non-coherent hardware might consume uninitialized memory.

[Severity: High]
Additionally, since vped is allocated with kzalloc(), does this risk cacheline
sharing with adjacent objects, potentially leading to lost hardware updates?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724104819.1296803-1-sascha.bischoff@arm.com?part=10

  reply	other threads:[~2026-07-24 11:22 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-24 10:48 [PATCH v4 00/48] KVM: arm64: Add GICv5 IRS support Sascha Bischoff
2026-07-24 10:48 ` [PATCH v4 01/48] irqchip/gic-v5: Allow KVM setup without a maintenance IRQ Sascha Bischoff
2026-07-24 11:21   ` sashiko-bot
2026-07-24 10:48 ` [PATCH v4 02/48] irqchip/gic-v5: Provide OF IRS config frame attrs to KVM Sascha Bischoff
2026-07-24 11:10   ` sashiko-bot
2026-07-24 10:49 ` [PATCH v4 03/48] irqchip/gic-v5: Set up gic_kvm_info on ACPI hosts Sascha Bischoff
2026-07-24 11:19   ` sashiko-bot
2026-07-24 10:49 ` [PATCH v4 04/48] KVM: arm64: gic-v5: Define remaining IRS MMIO registers Sascha Bischoff
2026-07-24 10:49 ` [PATCH v4 05/48] arm64/sysreg: Add GICv5 GIC VDPEND encoding Sascha Bischoff
2026-07-24 10:49 ` [PATCH v4 06/48] arm64/sysreg: Update ICC_CR0_EL1 with LINK and LINK_IDLE fields Sascha Bischoff
2026-07-24 11:14   ` sashiko-bot
2026-07-24 10:50 ` [PATCH v4 07/48] KVM: arm64: gic-v5: Extract host IRS caps from IRS config frame Sascha Bischoff
2026-07-24 11:19   ` sashiko-bot
2026-07-24 10:50 ` [PATCH v4 08/48] KVM: arm64: gic-v5: Add VPE doorbell domain Sascha Bischoff
2026-07-24 11:11   ` sashiko-bot
2026-07-24 10:50 ` [PATCH v4 09/48] KVM: arm64: gic-v5: Create and manage VM and VPE tables Sascha Bischoff
2026-07-24 11:19   ` sashiko-bot
2026-07-24 10:50 ` [PATCH v4 10/48] KVM: arm64: gic-v5: Introduce guest IST alloc and management Sascha Bischoff
2026-07-24 11:22   ` sashiko-bot [this message]
2026-07-24 10:51 ` [PATCH v4 11/48] KVM: arm64: gic-v5: Implement VMT/vIST IRS MMIO Ops Sascha Bischoff
2026-07-24 11:20   ` sashiko-bot
2026-07-24 10:51 ` [PATCH v4 12/48] KVM: arm64: gic-v5: Keep GICv5 vCPU limit model-specific Sascha Bischoff
2026-07-24 10:51 ` [PATCH v4 13/48] KVM: arm64: gic-v5: Implement VPE IRS MMIO Ops Sascha Bischoff
2026-07-24 11:21   ` sashiko-bot
2026-07-24 10:52 ` [PATCH v4 14/48] KVM: arm64: gic-v5: Set up VMTEs and VPE doorbells Sascha Bischoff
2026-07-24 11:27   ` sashiko-bot
2026-07-24 10:52 ` [PATCH v4 15/48] KVM: arm64: gic-v5: Add resident/non-resident hyp calls Sascha Bischoff
2026-07-24 11:26   ` sashiko-bot
2026-07-24 10:52 ` [PATCH v4 16/48] KVM: arm64: gic-v5: Request doorbells when VPEs enter WFI Sascha Bischoff
2026-07-24 11:41   ` sashiko-bot
2026-07-24 10:52 ` [PATCH v4 17/48] KVM: arm64: gic-v5: Introduce struct vgic_v5_irs and IRS base address Sascha Bischoff
2026-07-24 10:53 ` [PATCH v4 18/48] KVM: arm64: gic-v5: Add IRS IODEV support to MMIO handlers Sascha Bischoff
2026-07-24 10:53 ` [PATCH v4 19/48] KVM: arm64: gic-v5: Add KVM_VGIC_V5_ADDR_TYPE_IRS to UAPI Sascha Bischoff
2026-07-24 11:30   ` sashiko-bot
2026-07-24 10:53 ` [PATCH v4 20/48] KVM: arm64: gic-v5: Add GICv5 IRS IODEV and MMIO emulation Sascha Bischoff
2026-07-24 11:45   ` sashiko-bot
2026-07-24 10:53 ` [PATCH v4 21/48] KVM: arm64: gic-v5: Initialise per-VM IRS state Sascha Bischoff
2026-07-24 10:54 ` [PATCH v4 22/48] KVM: arm64: gic-v5: Register the IRS IODEV Sascha Bischoff
2026-07-24 11:33   ` sashiko-bot
2026-07-24 10:54 ` [PATCH v4 23/48] KVM: arm64: gic-v5: Set IRICHPPIDIS based on IRS enable state Sascha Bischoff
2026-07-24 11:41   ` sashiko-bot
2026-07-24 10:54 ` [PATCH v4 24/48] KVM: arm64: selftests: Update vGICv5 selftest to set IRS address Sascha Bischoff
2026-07-24 10:54 ` [PATCH v4 25/48] KVM: arm64: gic-v5: Add GIC VDPEND hyp call Sascha Bischoff
2026-07-24 11:34   ` sashiko-bot
2026-07-24 10:55 ` [PATCH v4 26/48] KVM: arm64: gic: Introduce set_pending_state() to irq_op Sascha Bischoff
2026-07-24 11:39   ` sashiko-bot
2026-07-24 10:55 ` [PATCH v4 27/48] KVM: arm64: gic-v5: Support SPI injection Sascha Bischoff
2026-07-24 11:48   ` sashiko-bot
2026-07-24 10:55 ` [PATCH v4 28/48] Documentation: KVM: Extend VGICv5 device attribute docs Sascha Bischoff
     [not found] ` <20260724104819.1296803-35-sascha.bischoff@arm.com>
2026-07-24 11:46   ` [PATCH v4 34/48] KVM: arm64: gic-v5: Add VGICv5 IST save/restore UAPI sashiko-bot
     [not found] ` <20260724104819.1296803-31-sascha.bischoff@arm.com>
2026-07-24 11:52   ` [PATCH v4 30/48] KVM: arm64: gic-v5: Mask per-vcpu PPI state in vgic_v5_finalize_ppi_state() sashiko-bot
     [not found] ` <20260724104819.1296803-36-sascha.bischoff@arm.com>
2026-07-24 12:02   ` [PATCH v4 35/48] KVM: arm64: gic-v5: Implement save/restore mechanisms for ISTs sashiko-bot
     [not found] ` <20260724104819.1296803-42-sascha.bischoff@arm.com>
2026-07-24 12:02   ` [PATCH v4 41/48] KVM: selftests: Add VGICv5 NR_IRQS attribute tests sashiko-bot
     [not found] ` <20260724104819.1296803-33-sascha.bischoff@arm.com>
2026-07-24 12:05   ` [PATCH v4 32/48] KVM: arm64: gic-v5: Handle userspace accesses to IRS MMIO region sashiko-bot
     [not found] ` <20260724104819.1296803-43-sascha.bischoff@arm.com>
2026-07-24 12:06   ` [PATCH v4 42/48] KVM: selftests: Add VGICv5 IRS_REGS attribute tests sashiko-bot
     [not found] ` <20260724104819.1296803-32-sascha.bischoff@arm.com>
2026-07-24 12:09   ` [PATCH v4 31/48] KVM: arm64: gic-v5: Add GICv5 EL1 sysreg userspace accessors sashiko-bot
     [not found] ` <20260724104819.1296803-47-sascha.bischoff@arm.com>
2026-07-24 12:15   ` [PATCH v4 46/48] KVM: selftests: Add VGICv5 SPI injection tests sashiko-bot
     [not found] ` <20260724104819.1296803-48-sascha.bischoff@arm.com>
2026-07-24 12:18   ` [PATCH v4 47/48] KVM: selftests: Add VGICv5 LPI delivery tests sashiko-bot
     [not found] ` <20260724104819.1296803-38-sascha.bischoff@arm.com>
2026-07-24 12:19   ` [PATCH v4 37/48] Documentation: KVM: Add KVM_DEV_ARM_VGIC_GRP_IRS_REGS to VGICv5 docs sashiko-bot
     [not found] ` <20260724104819.1296803-30-sascha.bischoff@arm.com>
2026-07-24 12:19   ` [PATCH v4 29/48] KVM: arm64: gic-v5: Add GICv5 SPI injection to irqfd sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260724112240.4FD981F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Sascha.Bischoff@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=maz@kernel.org \
    --cc=oupton@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox