From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from AM0PR02CU008.outbound.protection.outlook.com (mail-westeuropeazon11023111.outbound.protection.outlook.com [52.101.72.111]) by lore.virtuozzo.com (Postfix) with ESMTPS id E0B028017D for ; Tue, 3 Nov 2026 14:21:24 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bRAN1rf4Dzk5F3lUe+gvLeRsNjb9gF3xy7w2d0EklHQGVFnKn5/cPKfXveRZibeqXpyo/tsAnJf242RNbiboG6jbiMKDQ2ABWPXuCJitqGUbQa9fVqC05O9jLBOKcDFFdDwXFUYiPEMAVWHOQhf5susn0YEuFleQES+dvIUasJ6YUYYwQSn/VIGFhJB+5vbBTZLswTnLweWFThMXVJU6IJbl7CcYErDJfWue/tipAhG9wExoHtlGbJvvSQYt6Mb05Fhtud1clCR7DQ/twSMMWBt49MnDJj+88ROMMpWiF2yjpo1rw48Lze2/xVDtgT0mvJXoh9Yc0i+eeqp1NfjGlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=94VKpbIMLuxU/7uhPneWhhPjt2J8Q2c2WaD1eMrhA8c=; b=mCAGRi5Q+2oTlcDpH/OLkc78s8q8VSyWPOa/jl7WaGxAQmF5RHyFmQFV6hWapgkXpknJK9AQUAbSyZpWeq+tTCkKPlb7qt6NppZ9OLgWgKJEqbhpKwSMOS9xiRahexC2vGuRPmz2hPAu/DfWIPc+QsqjbQtEbanffR6cwEuwelBJFdRIfIZ0kYaB5wdcvsI0+DqQsNLLRPu4g9sBw9RIVMkCUm+2UwmzMeqIvyQvil5/ehSS+TPStK0aepUOauscKyw/bijOFm6yBvtWbF8CSZ8njfCCp5Dn/VSp2fPYuj6ACO2ehRjMu//YY6E9uP8IYcQV9/DvWPpMgMnnEGLxRw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 69.169.224.2) smtp.rcpttodomain=virtuozzo.com smtp.mailfrom=eu-central-1.amazonses.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=sashiko.virtuozzo.com; dkim=pass (signature was verified) header.d=sashiko.virtuozzo.com; dkim=pass (signature was verified) header.d=amazonses.com; arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.onmicrosoft.com; s=selector2-virtuozzo-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=94VKpbIMLuxU/7uhPneWhhPjt2J8Q2c2WaD1eMrhA8c=; b=YuCBNMszGU12U0HvSv/4lnDsVLUMVsNZH67WQi8L94OxnaMAgtalZLy81/hwLXVo54GXlnBcgoifjH6lyU9KEhq+Ge0HtjciItLSVSAzXxt1BYthlygtBrk8DGbOzZRGHf7jbrCgX1314sHvGSEk+SSApN5rbVcjWevXz4D8DNM= Received: from FR4P281CA0150.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:b8::16) by DU0PR08MB9052.eurprd08.prod.outlook.com (2603:10a6:10:474::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.592.8; Tue, 3 Nov 2026 14:21:22 +0000 Received: from MI3PEPF00008499.eurprd03.prod.outlook.com (2603:10a6:d10:b8:cafe::46) by FR4P281CA0150.outlook.office365.com (2603:10a6:d10:b8::16) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.592.8 via Frontend Transport; Tue, 3 Nov 2026 14:21:21 +0000 Authentication-Results: mx.microsoft.com 1; spf=pass (sender IP is 69.169.224.2) smtp.mailfrom=eu-central-1.amazonses.com; dkim=pass (signature was verified) header.d=sashiko.virtuozzo.com;dkim=pass (signature was verified) header.d=amazonses.com;dmarc=pass action=none header.from=sashiko.virtuozzo.com; Received-SPF: Pass (protection.outlook.com: domain of eu-central-1.amazonses.com designates 69.169.224.2 as permitted sender) receiver=protection.outlook.com; client-ip=69.169.224.2; helo=b224-2.smtp-out.eu-central-1.amazonses.com; pr=C Received: from b224-2.smtp-out.eu-central-1.amazonses.com (69.169.224.2) by MI3PEPF00008499.mail.protection.outlook.com (10.167.240.184) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.592.5 via Frontend Transport; Tue, 3 Nov 2026 14:21:21 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=23yjbh4k34hwzfubhuiim7m4inbd3ick; d=sashiko.virtuozzo.com; t=1793715681; h=Message-ID:From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date; bh=FQ/JRgHExP0q9DwtUjG5Nr6/zQJZ333MEpGU9h5XZac=; b=bDeaJQjEoIf34GljbmZr7zlMQTqVg0eV7PYzs0x+T6F58HyQf+oUzpAOvW2Y6Qav M0SM9GGG+Ug0f5jBubFMa9JP1Da8T4kGFgpU+Ms7DbAw5gGji1YxmcOJRdUcdzPhXgJ eGs705jlcZYGNffSDXQTPhg5mEOMp57WY058Xxre7A+oooCNTx3XtUbTfAR/D8BfNLY +xJkjJpDDXGnHwHwMOLs5Wll68AY5jBPp+tLtJLFlF7U9g7AUmAfnF6bMYa4ozYcg7h LgSlh2ZJ9SqPxC2KMPiRsyvnDAeBsQ+0YnDGzDx4uS96YqgvlNND/9IcgI6+nTUlRIl B4LAUbo/YA== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=qftdzk2dqsatjnlrq4r5brjbihpfcrsh; d=amazonses.com; t=1793715681; h=Message-ID:From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date:Feedback-ID; bh=FQ/JRgHExP0q9DwtUjG5Nr6/zQJZ333MEpGU9h5XZac=; b=CUmopppUbcE0izzoW4WZib6v0Cxc5CK8EwwhYXjIiUx5RM7VF0ffP9iaRxXFJFHA jsgNkK3F9qDnVkggCLf9IcXrazSjKLsYmluWK29eFHZxJSk1npp2LQ2tRarKr+VcAOk 1LyV+a4hTiNU6K0sQLfk6ZaAa0RnMlq980kccMVg= Message-ID: <010701a1a1c936da-43fc3a47-1f29-447a-863a-994b4a6dee45-000000@eu-central-1.amazonses.com> From: no-reply@sashiko.virtuozzo.com Subject: Re: [PATCH QEMU HCI-8.1 v7 23/35] kvm: tolerate ioctls after kvm_close() To: svt-core@virtuozzo.com, Andrey Drobyshev Cc: andrey.drobyshev@virtuozzo.com In-Reply-To: <20261103-vfio_v1-v7-23-4467fdccbbe6@virtuozzo.com> References: <20261103-vfio_v1-v7-0-4467fdccbbe6@virtuozzo.com> <20261103-vfio_v1-v7-23-4467fdccbbe6@virtuozzo.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Tue, 3 Nov 2026 14:21:20 +0000 Feedback-ID: ::1.eu-central-1.2wRQJBpg9g1fGRYexx3dUuYGS25Bux+2TEOx72/m6U4=:AmazonSES X-SES-Outgoing: 2026.11.03-69.169.224.2 X-EOPAttributedMessage: 0 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MI3PEPF00008499:EE_|DU0PR08MB9052:EE_ MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 389ccddf-19b3-4903-c836-08df39b5bbed X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr X-MS-Exchange-AtpMessageProperties: SA List-Id: svt-core@virtuozzo.com X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|704161411799003|32142699015|376014|48200799018|61400799027|9140799003|6133799003|4113699003|5113699003|10067099003|22082099003|16102099003|18002099003|55112099003|3023799007|56012099006|5063699009|5023799004|4143699003|261022105027099003|261102123227099003|261021121427099003|261028144727099003|261026140227099003|261026121527099003|261009223027099003; X-Microsoft-Antispam-Message-Info: f0rwW2M5bRQQGCGKzEObEY1oWRNkyUGJBR3LkKezVgMnGyzyfqvwR8BSWd1DxG/ukNotLN0V+iumLw2MjexV0uICG2cVEZOhVss76nD40o3G4e2Sky5uo4pIk8weAx5CkSzfJB/2HA+fDdp4plRNnnMjlTfEH6baD31E5Iu+xLWw1XjnxbhtEwGKimPK9fMINu9jRh9fYWS6FCKAyYlkexWbeiTA/vn2dq8r0iyng+WYdkcM2hG30HhXSOLyKt2um3uFG6qFyN2s1XFAuWBVsp9BxQAF7Y8PPIzZlUiKbHf9+e6/wA/feIQExjkQQfAyq7FsEXJ8B18Oo2p9HYyvPI6Or8r7Fc4N0LZkzhKXTZHkFn1jKRC0OreupHboJeqIdzE0uYDas07yYzs/Pw7GZ7vcCElIbB8DSq+j43AHFyGOanxFTYOFURFb4/bDOO0MPpTok99YOWk8G07G3AfbEOK1I4C7c+OzClcFjBJSIg1ekBaMBOpfssRm09uP8MTIWlGlG+l0SNBk5AbHjW9GEKIIkzbACDbAQHj7bruqW49ii526bAIF6rfleB3VN4OyAr0nS/Mc5myudT4yeauW4CJxy2ZrQigJ+eiWbYdoFygUAk48C6uf31+mhoLLeCZpc1Dw1Bgbz6a0zUcr+DVHURKJRSAJW61h8pI6VnFlGqrPwwvGwMHM/wjvHuruAEzy4+zvco8GrrdJ5HM/GZuJrJAAvG9grMSAmYxyAx/9u+HoAG7N/fc8LuC+EP/a6zT5lqd+M3a/DrspyD6ibnH/udwU43mhN68a9x3yhQIkDnD3nyCpNNgccI+NOzYalXkrLoM56HxPSnRUCJE4g3muzw== X-Forefront-Antispam-Report: CIP:69.169.224.2;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:b224-2.smtp-out.eu-central-1.amazonses.com;PTR:b224-2.smtp-out.eu-central-1.amazonses.com;CAT:NONE;SFS:(13230040)(704161411799003)(32142699015)(376014)(48200799018)(61400799027)(9140799003)(6133799003)(4113699003)(5113699003)(10067099003)(22082099003)(16102099003)(18002099003)(55112099003)(3023799007)(56012099006)(5063699009)(5023799004)(4143699003)(261022105027099003)(261102123227099003)(261021121427099003)(261028144727099003)(261026140227099003)(261026121527099003)(261009223027099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: kF/FZ7hDWfXzCmeAxyj62VRaePRbh8CdwFpusH+989mudAWHeVcJshll96G+BSvjRFRvKrQEzitHADmvkAP+FOa64gy874hYg22nJNbBMQYSb+8NH3tswclzL5XjhrGrtpzd/BV0jua5+QPLAKkLyLzgZeFew2iAOLZAacPvMdE5NXyW9sC+0VIcX3p5OwyioX8i0/5j0xxe7sK8kFmUCPyRjPw0RbK9Rbs/dLNERbkw2by+ZaGQ65Q/+Fyw9Ly0ikbO8f1JRcLnCQc6jN+zP060TWcnKreRtvifc4nWRfwMfEALPnUOARbIXjWTTsXKAen9EKK6e+6U3nKeCR6ZoNihd8xhtre4ojxK51cyGXXsV4lc44UzGHTrjDF40ppl50ycWaQafDjM5fpnD646jFy4ueeIV5jC5bDbOBVglfPjWKwL9VqtGUc+jcSxzLIN X-ExternalRecipientOutboundConnectors: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Nov 2026 14:21:21.3984 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 389ccddf-19b3-4903-c836-08df39b5bbed X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: MI3PEPF00008499.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0PR08MB9052 Thank you for your contribution! Sashiko AI review found 4 potential issue(= s) to consider: - [Medium] kvm: kvm_vm_ioctl() returns 0 after kvm_close() for fd-returning= ioctls, yielding fd 0 - [Medium] kvm: ioctl wrappers return 0 after kvm_close() without filling o= utputs - [Medium] kvm: ioctl wrappers return 0 after kvm_close(), callers treat it= as a valid fd - [Low] kvm: closed-state checks in ioctl wrappers race with kvm_close() -- commit e7e22762666ee0142be58442e3f90a44a9a53d12 Author: Andrey Drobyshev kvm: tolerate ioctls after kvm_close() This patch keeps kvm_state allocated after kvm_close() instead of setting it to NULL. It makes kvm_ioctl(), kvm_vm_ioctl() and kvm_vcpu_ioctl() return 0 once the file descriptors have been closed. The aim is to stop a retired cpr-transfer source from crashing on late interrupts. > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c > --- a/accel/kvm/kvm-all.c > +++ b/accel/kvm/kvm-all.c [ ... ] > @@ -644,7 +644,6 @@ void kvm_close(void) > close(kvm_state->fd); > kvm_state->fd =3D -1; > } > - kvm_state =3D NULL; > } [Severity: Low] Can the closed-state checks added below race with kvm_close()? kvm_close() stores -1 into kvm_state->vmfd and kvm_state->fd with plain stores after close(). It does not call accel_ioctl_inhibit_begin(), so it does not wait for in-flight ioctls from threads that don't hold the BQL. A thread without the BQL could pass the new s->vmfd =3D=3D -1 test in kvm_vm_ioctl(). kvm_close() could then close the descriptor. The first thread would re-read s->vmfd for ioctl() and either get -EBADF or issue the ioctl on a recycled descriptor number. kvm_set_irq() and the ioeventfd callers treat that error as fatal. Is there any synchronization that excludes this? Also, kvm_enabled() and kvm_dirty_ring_enabled() keep reporting a live KVM now that kvm_state is no longer set to NULL. Only the three ioctl wrappers check for the closed state. > @@ -3371,6 +3370,11 @@ int kvm_ioctl(KVMState *s, unsigned long type, ...) > arg =3D va_arg(ap, void *); > va_end(ap); > =20 > + /* kvm_close() has been called: there is no KVM to talk to any more = */ > + if (s->fd =3D=3D -1) { > + return 0; > + } > + [Severity: Medium] Is returning 0 here safe for callers that read output from the ioctl? This stub never writes the caller's output buffers or return value. KVM_CHECK_EXTENSION, KVM_GET_VCPU_MMAP_SIZE and KVM_GET_SUPPORTED_* all report success with no data. kvm_check_extension() would read the 0 as "extension unsupported". > trace_kvm_ioctl(type, arg); > ret =3D ioctl(s->fd, type, arg); [ ... ] > @@ -3389,6 +3393,11 @@ int kvm_vm_ioctl(KVMState *s, unsigned long type, = ...) > arg =3D va_arg(ap, void *); > va_end(ap); > =20 > + /* kvm_close() has been called: there is no VM to talk to any more */ > + if (s->vmfd =3D=3D -1) { > + return 0; > + } > + [Severity: Medium] Can this return 0 be mistaken for a valid file descriptor? Several VM ioctls return a new fd as their result: KVM_GET_STATS_FD, KVM_CREATE_GUEST_MEMFD, KVM_CREATE_VCPU and KVM_CREATE_DEVICE (through cd.fd). After kvm_close() these now return 0, and the callers take that as fd 0, which is stdin. The most reachable case is query_stats_cb(): stats_fd =3D kvm_vm_ioctl(s, KVM_GET_STATS_FD, NULL); if (stats_fd =3D=3D -1) { error_setg_errno(errp, errno, "KVM stats: ioctl failed"); return; } query_stats(result, target, names, stats_fd, NULL, errp); close(stats_fd); The check for -1 passes, so a QMP query-stats reads from fd 0 and then calls close(0). query_stats_schemas_cb() has the same pattern. Other callers: kvm_create_guest_memfd(): fd =3D kvm_vm_ioctl(kvm_state, KVM_CREATE_GUEST_MEMFD, &guest_memfd= ); if (fd < 0) { kvm_create_vcpu(): kvm_fd =3D kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id); if (kvm_fd < 0) { kvm_create_guest_memfd() accepts 0 as a guest_memfd. kvm_create_vcpu() sets cpu->kvm_fd =3D 0. In hw/vfio/helpers.c, vfio_kvm_device_add_fd() has this: if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) { ... } vfio_kvm_device_fd =3D cd.fd; cd.fd is only initialised for .type, so it stays 0. vfio_kvm_device_fd becomes 0, and a later vfio_kvm_device_close() calls close(0). It can also be reached after vfio_kvm_device_close() has reset vfio_kvm_device_fd to -1, because kvm_enabled() is still true after kvm_close(). openpic_kvm.c and s390_flic_kvm.c use cd.fd after a zero-initialised KVM_CREATE_DEVICE call in the same way. kvm_create_device() sets create_dev.fd =3D -1, but it would still return success with -1 as the fd. Before this patch these calls dereferenced a NULL kvm_state. Should the fd-returning requests return an error instead? Also, for requests that fill an output struct, KVM_GET_CLOCK, KVM_GET_IRQCHIP, KVM_GET_PIT2 and KVM_GET_DIRTY_LOG return success with the buffer untouched. Can kvm_update_clock() in hw/i386/kvm/clock.c then read data.clock from an uninitialised stack struct? Can kvm_pic_get() and kvm_ioapic_get() copy uninitialised stack data into device state? kvm_get_current_ns() in target/i386/kvm/xen-emu.c has the same pattern as kvm_update_clock(). The commit message justifies the 0 only for the interrupt, irqfd and ioeventfd callers. Does it cover callers that use the return value as a handle or read the output buffer? > trace_kvm_vm_ioctl(type, arg); > accel_ioctl_begin(); > ret =3D ioctl(s->vmfd, type, arg); [ ... ] > @@ -3409,6 +3418,11 @@ int kvm_vcpu_ioctl(CPUState *cpu, unsigned long ty= pe, ...) > arg =3D va_arg(ap, void *); > va_end(ap); > =20 > + /* kvm_close() has been called: the vCPU fds are gone */ > + if (cpu->kvm_fd =3D=3D -1) { > + return 0; > + } > + [Severity: Medium] Does the same issue apply to kvm_vcpu_ioctl()? KVM_GET_STATS_FD on a closed vCPU returns 0, and kvm_init_vcpu() stores that result in cpu->kvm_vcpu_stats_fd. The vCPU GET_* ioctls also return success without writing any data. KVM_RUN returns without running. If kvm_get_msrs() were reached through a stale CPUState, it would hit assert(ret =3D=3D nmsrs). cpu_remove_sync() takes the CPUs off CPU_FOREACH = in kvm_close(), so this is probably only reachable through a stale CPUState pointer. > trace_kvm_vcpu_ioctl(cpu->cpu_index, type, arg); > accel_cpu_ioctl_begin(cpu); > ret =3D ioctl(cpu->kvm_fd, type, arg); --=20 Sashiko AI review =C2=B7 https://sashiko.vzint.dev/#/patchset/20261103-vfio= _v1-v7-0-4467fdccbbe6@virtuozzo.com?part=3D23