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>,
	"Oliver Upton" <oupton@kernel.org>,
	kvm@vger.kernel.org, kvmarm@lists.linux.dev
Subject: Re: [PATCH v3 09/40] KVM: arm64: gic-v5: Create and manage VM and VPE tables
Date: Fri, 03 Jul 2026 16:31:48 +0000	[thread overview]
Message-ID: <20260703163148.80DCD1F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260703154811.3355680-10-sascha.bischoff@arm.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Hardware-modified VMT and VPET tables are allocated as Cacheable memory and managed with CPU cache maintenance, leading to false sharing and loss of hardware writes on systems with a non-coherent IRS.
- [High] Incorrect calculation of `vpe_id_bits` tells the hardware the VPET is twice its actual size, allowing a guest to trigger out-of-bounds IRS memory accesses.
- [High] Failure to check if `vped_size` is zero before allocation leads to `ZERO_SIZE_PTR` usage, resulting in bogus physical addresses and a kernel panic during cache maintenance.
- [High] The L1 Virtual Machine Table and linear VMT allocations lack the 4KB page alignment required by the GICv5 hardware for `IRS_VMT_BASER`.
- [Medium] Error paths in `vgic_v5_vmte_release` return early after freeing VPE tracking pointers, leaving dangling pointers in the globally reachable `vmi` structure.
--

commit f0a39157639262cdd2140f7a3d5512f31e4004d2
Author: Sascha Bischoff <Sascha.Bischoff@arm.com>
KVM: arm64: gic-v5: Create and manage VM and VPE tables

This patch adds support for allocating the Virtual Machine Table (VMT) and
Virtual PE Table (VPET) to track VM state for GICv5. It introduces lifecycle
management and tracking for unused VMTEs via an IDA.

> diff --git a/arch/arm64/kvm/vgic/vgic-v5-tables.c b/arch/arm64/kvm/vgic/vgic-v5-tables.c
> index db8cb6a384994..xxxxxxxxxxxxx 100644
> --- a/arch/arm64/kvm/vgic/vgic-v5-tables.c
> +++ b/arch/arm64/kvm/vgic/vgic-v5-tables.c
[ ... ]
> static int vgic_v5_alloc_vmt_linear(unsigned int num_entries)
> {
> 	vmt_info->linear.vmt_base = kzalloc_objs(*vmt_info->linear.vmt_base,
> 						 num_entries);

[Severity: High]
Does this allocation guarantee the 4KB alignment required by the GICv5
hardware for IRS_VMT_BASER?

When the base address is written to VMT_BASER in vgic_v5_irs_assign_vmt(),
the lower 12 bits are stripped:

vmt_baser = FIELD_PREP(...) | (vmt_base & GICV5_IRS_VMT_BASER_ADDR);

Since kzalloc_objs() only guarantees SLUB alignment (e.g., 8 or 16 bytes
for small allocations), won't the truncation of the lower bits cause the
hardware to read from the wrong address at the start of the 4KB page?

[ ... ]
> static int vgic_v5_alloc_vmt_two_level(unsigned int num_entries)
> {
[ ... ]
> 	vmt_info->l2.vmt_base = kzalloc_objs(*vmt_info->l2.vmt_base,
> 					     vmt_info->l2.num_l1_ents);

[Severity: High]
Should these hardware-modified tables be allocated from Non-Cacheable memory
instead of standard Cacheable memory (via kzalloc_objs)?

For systems with a non-coherent IRS, vgic_v5_clean_inval() uses
dcache_clean_inval_poc() which executes DC CIVAC. Because VMT and VPET
entries are tightly packed, multiple entries can share a single 64-byte
cache line.

If the hardware writes to these tables (like setting VALID bits) and the
CPU later invalidates or cleans an adjacent entry, could the CIVAC operation
write back the CPU's stale cache state and silently overwrite concurrent
hardware updates?

[ ... ]
> int vgic_v5_vmte_init(struct kvm *kvm)
> {
[ ... ]
> 	/*
> 	 * Allocate and assign the VPE Table. Round up the number of CPUs to a
> 	 * whole power of two as we cannot describe non-powers-of-two in the
> 	 * VMTE field as it conveys the number of ID bits used and not the
> 	 * number of vPEs.
> 	 *
> 	 * The IRS encodes the number of IAFFID bits as N - 1, so a VM with a
> 	 * single vCPU must still allocate two VPET entries and expose 1 bit.
> 	 */
> 	nr_cpus = max(2UL, roundup_pow_of_two(nr_cpus));
> 	vmi->vpe_id_bits = fls(nr_cpus) - 1;

[Severity: High]
Is there an off-by-one calculation error here for vmi->vpe_id_bits?

The hardware expects the number of ID bits to be encoded as N - 1 for a
table of 2^N entries. Since nr_cpus is already rounded up to a power of 2,
fls(nr_cpus) - 1 evaluates to ilog2(nr_cpus), which is N rather than N - 1.

By writing N into the VPE_ID_BITS field, does this instruct the hardware
that the VPET has 2^(N+1) entries instead of 2^N? A guest could potentially
trigger out-of-bounds IRS memory accesses by targeting an interrupt at a
VPE ID in the non-existent upper half.

[ ... ]
> int vgic_v5_vmte_release(struct kvm *kvm)
> {
[ ... ]
> 	for (int i = 0; i < BIT(vmi->vpe_id_bits); i++)
> 		kfree(vmi->vped_ptrs[i]);
> 	kfree(vmi->vped_ptrs);
> 	kfree(vmi->vpet_base);
> 	kfree(vmi->vmd_base);
> 
> 	/* Unlikely, but possible. Avoid leaking the memory. */
> 	vgic_v5_drain_pending_irqs(kvm, vmi, false);
> 
> 	/* If we have an LPI IST, free it */
> 	if (vmi->h_lpi_ist) {
> 		ret = vgic_v5_lpi_ist_free(kvm);
> 		if (ret)
> 			return ret;
> 	}

[Severity: Medium]
Does returning early here leave dangling pointers in the globally reachable
vmi structure?

The pointers for vped_ptrs, vpet_base, and vmd_base are unconditionally
freed just above this check. If vgic_v5_lpi_ist_free() (or
vgic_v5_spi_ist_free() below it) fails, the function returns immediately
without erasing the vmi object from the vm_info XArray or setting the
freed pointers to NULL.

If the teardown is retried, will this result in a double-free of these
pointers when vgic_v5_vmte_release() runs again?

[ ... ]
> int vgic_v5_vmte_alloc_vpe(struct kvm_vcpu *vcpu)
> {
[ ... ]
> 	/* Alloc VPE Descriptor. Only used by IRS. */
> 	vped = kzalloc(vmt_info->vped_size, GFP_KERNEL);
> 	if (!vped)
> 		return -ENOMEM;

[Severity: High]
Could vmt_info->vped_size be zero here, leading to a ZERO_SIZE_PTR
allocation?

Unlike the VM descriptor allocation which explicitly checks if
vmt_info->vmd_size != 0, this allocation proceeds unconditionally. If the
IRS does not require a VPE descriptor and specifies a size of 0, kzalloc()
will return the non-null ZERO_SIZE_PTR (0x10).

If that happens, won't virt_to_phys() generate a bogus physical address for
the hardware, and won't the subsequent vgic_v5_clean_inval(vped, ...)
cause a kernel panic when dcache_clean_inval_poc() executes a cache
maintenance instruction on the unmapped 0x10 address?

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

  reply	other threads:[~2026-07-03 16:31 UTC|newest]

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