From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.openvz.org (mail.openvz.org [69.168.225.77]) by lore.virtuozzo.com (Postfix) with ESMTPS id 5BF088017D for ; Mon, 2 Nov 2026 10:56:34 +0000 (UTC) Received: from mail.openvz.org (localhost [127.0.0.1]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6A2AtGiM023680; Mon, 2 Nov 2026 13:55:17 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6A2AtGiM023680 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=default; t=1793616919; bh=AnPUZ86TGokB8+uqGUw+/1LEIcmmAydAI+B17t7joOo=; h=From:To:Date:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe; b=PLMyBRg9+oSdKXP5/w235eZcj65nMAKEFgcsH3exH+WkcTF5MOCUebdjMetkXk5/A +tLf6w2AkUx225GR6+7aJWkVZJOxBX/wKgM1U7IwuMsg8h/S8FJ/Bx4v1xUW/VwMKM 7CgZW/atyKHZTrFfcjICgREN9aZFrii+803uMYUafzw+j2wyz6FffL8MMD5fiisqPI Lt76pZ6ACnojM021XWce0MXhaCGeLfle68L8Kw40/MtBT98DgPtrR+8ExGKhL1h92k FHHiijvGIUFPalIpbwAfp0G5aO13XOMFyPPQ8KsdtwlP36zV416959OvmMSNrJH/o6 qABTuektq92Jg== Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by mail.openvz.org (8.14.4/8.14.4) with ESMTP id 6A2AtFSP023676 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=FAIL) for ; Mon, 2 Nov 2026 13:55:15 +0300 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.openvz.org 6A2AtFSP023676 Authentication-Results: mail.openvz.org; dkim=pass (2048-bit key) header.d=openvz.org header.i=@openvz.org header.b="ZnhnzXCg" Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-48e0fc747a7so2421476f8f.1 for ; Mon, 02 Nov 2026 02:55:15 -0800 (PST) X-Forwarded-Encrypted: i=2; AKwUvBxIr2+QRp5tUsSs2DFOsIfWb3FKbqISA81tEitMsYD2WLN9tjNmwlMvDAQcekmzQDL3peY9hw==@openvz.org X-Gm-Message-State: APuU4Z/6GK/UTrRqDSrc9+oX47l8xaFSIPSoTSd/U4rLje8ayihGsXSx 1c3lTZ9JN3og0b4tgNn08ffxc+9YzjNY3fZ0JhxJET9uyKL+aBtstZW2eG0DRAIDQqU9x0IyjhJ VQC0kaHwi6W55mcr/oO5b8MJgfHugzVyq9ZiRUMIFmglGMrCaedXU/Q== X-Gm-Gg: AYBFou2Rk8nJxYkWMbprLge0VjjnqpgCg1UQ74CzPrP6RnWCwscOHB10vWaUW+UlFun gOeHZmlONGhaZfAP/SiIdOL65Y0IzWLOf9AFJjqM7bdmnq2Qfd8XPGyoe64vGFiWIrS/7FxC/yW IcfCvJ/cGhmla9h1dqnu88SKMaGDNnwE2nYyoyPxfQ3/rKVj6xaui+GNkQLyTKeVIK9QB2EYK1C nNeQcz2K8/HPUG5zz+5cEhkNPAgGop10/x5r4DsgXPUjGA8GXzpfiw9NX2Lu9NWzDV25ooh5onN cvecoZO7Bg== X-Received: by 2002:a05:6000:2288:b0:48a:f404:6960 with SMTP id ffacd0b85a97d-48e6e2e76a5mr21235616f8f.9.1793616914669; Mon, 02 Nov 2026 02:55:14 -0800 (PST) X-Received: by 2002:a05:6000:2288:b0:48a:f404:6960 with SMTP id ffacd0b85a97d-48e6e2e76a5mr21235565f8f.9.1793616914143; Mon, 02 Nov 2026 02:55:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1793616914; cv=none; d=google.com; s=arc-20260327; b=VJhdnee1rWrYVGjku47fBXpqegCcNr1XecPZKHlm4qafoO44BXA+l2u/YcDN3JstVd WHaqUEAUbYzFz6q8sI+gZzVLFXtEv7TaCKxxf3hmqKqZFLnV1vvbCAn28Ss1j/EltqP9 8ZC1BslR70WZHMUAot4YceUHryCLqmsmVKjVOdI7Y/vTnEGlzyBkFwuuqT9B4BylIzj8 uD7YJmI/UlzSmUxk8JYEtLm4STSKOX96V0fCIvkyudiHxGRENcznwCgTXZZocN69msbJ uTt+HvCl5a1NvyZeDA82UpYVJSSbBdj1SGVEJtZk7ayLDGa1ZsJ1cd+PtfMw8LA9bmKk RD/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dkim-signature; bh=OsQf7xpMiPoRuVBQT/JMlM0kwvQdQAdaFJf/UGjme34=; fh=zcSBoxR+VufMptY+TIoFkCyUbRhi/PgnS5jWRP7vzwY=; b=Lg6gD80FXBPYv8E+aw00u7/xh9SQEFm8fyD/aPXqJFIlWFkUoEYQxcdpcO+tJkcU+f yceFVV+HB/mkC980XIXLbVVcwhfHx8843IOnA8j3wYGobDx+IWcO8Q9rvwZ7NSumgoXp GBdgKlCTm7zFoEd8QtnzMv8dzxHWw15ncUSpGmFNbBI+j0cT6hIRTvIIaJkwOtUBbVU1 8m17TOXA+D/WQ5yJRA25D/acZhkQD1WQLD2ZQRLhwDjvgLKEdixc+mCd4df+iJpW2pVq XmopeZ6ylVUx1Ig5kkiuDLVaFR0E3odey3xpbvxtWNWDcbuVKPHxl9mrZXQUQ5Z8ZMWL PdBQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@openvz.org header.s=google header.b=ZnhnzXCg; spf=softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:91db:48d7:7451:652a as permitted sender) smtp.mailfrom=den@openvz.org; dara=neutral header.i=@openvz.org Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41]) by mx.google.com with SMTPS id ffacd0b85a97d-48e6ebc476asor2012524f8f.11.2026.11.02.02.55.13 for (Google Transport Security); Mon, 02 Nov 2026 02:55:14 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:91db:48d7:7451:652a as permitted sender) client-ip=2a06:5b06:b600:300:91db:48d7:7451:652a; Authentication-Results: mx.google.com; dkim=pass header.i=@openvz.org header.s=google header.b=ZnhnzXCg; spf=softfail (google.com: domain of transitioning den@openvz.org does not designate 2a06:5b06:b600:300:91db:48d7:7451:652a as permitted sender) smtp.mailfrom=den@openvz.org; dara=neutral header.i=@openvz.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1793616913; x=1794221713; darn=openvz.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=OsQf7xpMiPoRuVBQT/JMlM0kwvQdQAdaFJf/UGjme34=; b=ZnhnzXCgQDtQ0VSMC++rYAPZmCFbAOBqbLEhv9jEiorXj57JcvKxDJ/0yAmjHudnN2 U8jO6A8T/K9zlcw5FbE4bucOLF0WGU61ePnoegpKuV1Vd72rFTE2lRuGyV7BShbjc8Mb bL5v9+kXWUQbZBt5fM84sxUvltv3/50cw2VVTtI3t6VOGxTVbUByMxebtfw6ta1MIVI3 or09MtJWkywx+cU8CY3m8oUXL5TbK8edKZIFBwv3DfeMXNZ+8qxAKDCcBYa9ZJCCZgj+ D1YC7Li1lSKF31pEX/bkHpOZsAyN/lP67lcd1PdZltnP4oZ8COHuRflOtsARyt0vAv1D YQaQ== X-Forwarded-Encrypted: i=1; AKwUvBxDCOev4LQwQ98nMHrNdpxqoeZpCI/51aR/PnEcaUCHrHerN0Pjo1zQM66poERlkxGhFB3RZg==@openvz.org X-Received: by 2002:a05:6000:4a13:b0:48b:9d2:1a6a with SMTP id ffacd0b85a97d-48e6e2b9ce9mr21656161f8f.1.1793616913487; Mon, 02 Nov 2026 02:55:13 -0800 (PST) Received: from athena.sw.ru ([2a06:5b06:b600:300:91db:48d7:7451:652a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48e71b81c74sm18936093f8f.36.2026.11.02.02.55.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Nov 2026 02:55:13 -0800 (PST) From: "Denis V. Lunev" To: Date: Mon, 2 Nov 2026 11:55:05 +0100 Message-ID: <20261102105510.3330185-1-den@openvz.org> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 X-OZ-Fwd: true Cc: devel@openvz.org Subject: [Devel] [PATCH hci-8.1] ms/KVM: x86: Fix lost EOI when unmasking a pending level IOAPIC pin X-BeenThere: devel@openvz.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: OpenVZ development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: devel-bounces@openvz.org Errors-To: devel-bounces@openvz.org When the guest unmasks a level-triggered redirection entry whose line is already asserted, ioapic_write_indirect() injects the pending interrupt first and only then asks the destination vCPUs to rescan their ioapic_handled_vectors and EOI exit bitmaps. If the same write also set the vector or the trigger mode, a destination vCPU can take the interrupt and EOI it before the rescan. A posted interrupt reaches a running vCPU without a VM exit, and the EOI is then either virtualized without an exit or dropped by kvm_ioapic_send_eoi() because the vector is not in ioapic_handled_vectors yet. Remote IRR stays set and the pin delivers no more interrupts until the guest reprograms it. Linux programs the entry masked and unmasks it with a separate write, so the vector is scanned before anything can be injected. Windows writes the vector, the trigger mode and the mask bit in one go. A virtio balloon on INTx whose line is already up when the driver connects its interrupt then stops receiving interrupts for the rest of the boot, and the guest ignores every later balloon target. Make the scan request before servicing the pending IRR. The request waits for the destination vCPUs to leave guest mode, and each of them rescans the routes and reloads its EOI exit bitmap before it can enter the guest and take the interrupt. Fixes: c7c9c56ca26f ("x86, apicv: add virtual interrupt delivery support") Fixes: 3bb345f387dd ("KVM: x86: store IOAPIC-handled vectors in each VCPU") Link: https://lore.kernel.org/kvm/20261029-kvm-ioapic-eoi-v1-den@openvz.org/ https://virtuozzo.atlassian.net/browse/VSTOR-151727 Feature: fix ms/kvm Signed-off-by: Denis V. Lunev --- Posted upstream, with a kvm-unit-tests reproducer in the same thread: https://lore.kernel.org/kvm/20261029-kvm-ioapic-eoi-v1-den@openvz.org/ https://lore.kernel.org/kvm/20261029200214.1241130-1-den@openvz.org/ Tested on sqvm2-4061 (nested Intel, APICv) with kvm.ko and kvm-intel.ko built out of tree from 6.12.0-211.52.1.22.9 plus this patch; ioapic.c is the same in 22.14. The ioapic_eoi_race test lost 4587 of 5000 EOIs in the single-write case on the stock modules and none with the patch; the masked-write case lost none on either. x86/ioapic.flat passes, in-kernel and split irqchip. Mainline 7.2.13 behaves the same, stock and patched. arch/x86/kvm/ioapic.c | 66 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 2c2783296aed..546414dcf1df 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -388,39 +388,6 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) mask_after = e->fields.mask; if (mask_before != mask_after) kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after); - if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG && - ioapic->irr & (1 << index) && !e->fields.mask && !e->fields.remote_irr) { - /* - * Pending status in irr may be outdated: the IRQ line may have - * already been deasserted by a device while the IRQ was masked. - * This occurs, for instance, if the interrupt is handled in a - * Linux guest as a oneshot interrupt (IRQF_ONESHOT). In this - * case the guest acknowledges the interrupt to the device in - * its threaded irq handler, i.e. after the EOI but before - * unmasking, so at the time of unmasking the IRQ line is - * already down but our pending irr bit is still set. In such - * cases, injecting this pending interrupt to the guest is - * buggy: the guest will receive an extra unwanted interrupt. - * - * So we need to check here if the IRQ is actually still pending. - * As we are generally not able to probe the IRQ line status - * directly, we do it through irqfd resampler. Namely, we clear - * the pending status and notify the resampler that this interrupt - * is done, without actually injecting it into the guest. If the - * IRQ line is actually already deasserted, we are done. If it is - * still asserted, a new interrupt will be shortly triggered - * through irqfd and injected into the guest. - * - * If, however, it's not possible to resample (no irqfd resampler - * registered for this irq), then unconditionally inject this - * pending interrupt into the guest, so the guest will not miss - * an interrupt, although may get an extra unwanted interrupt. - */ - if (kvm_notify_irqfd_resampler(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index)) - ioapic->irr &= ~(1 << index); - else - ioapic_service(ioapic, index, false); - } if (e->fields.delivery_mode == APIC_DM_FIXED) { struct kvm_lapic_irq irq; @@ -455,6 +422,39 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) } else { kvm_make_scan_ioapic_request(ioapic->kvm); } + if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG && + ioapic->irr & (1 << index) && !e->fields.mask && !e->fields.remote_irr) { + /* + * Pending status in irr may be outdated: the IRQ line may have + * already been deasserted by a device while the IRQ was masked. + * This occurs, for instance, if the interrupt is handled in a + * Linux guest as a oneshot interrupt (IRQF_ONESHOT). In this + * case the guest acknowledges the interrupt to the device in + * its threaded irq handler, i.e. after the EOI but before + * unmasking, so at the time of unmasking the IRQ line is + * already down but our pending irr bit is still set. In such + * cases, injecting this pending interrupt to the guest is + * buggy: the guest will receive an extra unwanted interrupt. + * + * So we need to check here if the IRQ is actually still pending. + * As we are generally not able to probe the IRQ line status + * directly, we do it through irqfd resampler. Namely, we clear + * the pending status and notify the resampler that this interrupt + * is done, without actually injecting it into the guest. If the + * IRQ line is actually already deasserted, we are done. If it is + * still asserted, a new interrupt will be shortly triggered + * through irqfd and injected into the guest. + * + * If, however, it's not possible to resample (no irqfd resampler + * registered for this irq), then unconditionally inject this + * pending interrupt into the guest, so the guest will not miss + * an interrupt, although may get an extra unwanted interrupt. + */ + if (kvm_notify_irqfd_resampler(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index)) + ioapic->irr &= ~(1 << index); + else + ioapic_service(ioapic, index, false); + } break; } } -- 2.53.0 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel