From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from GVXPR05CU001.outbound.protection.outlook.com (mail-swedencentralazon11023092.outbound.protection.outlook.com [52.101.83.92]) by lore.virtuozzo.com (Postfix) with ESMTPS id 275A78017D for ; Tue, 6 Oct 2026 15:57:51 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=lHn5B6ueTZirgAWXni3jTC2PqO6Fs8zVFnEd80AQ7z4lNHMN4Pq/qaaW/s0+ZzQzLCS7KHO6R4iYNqtDNC093zu8LJrwF5MY94pXGCHIS1mJ0wlGuZ3JbgNVy/Z/fdFLaHtIn6sS9lW0CozUTTrA4xdNggo4XMgL6L3ZVHLarPvQOOy+Keb6ZMb9KNMCFG2c7F77QotpiGx03z5DVGLBe/FBk0zeOjaQKXrSxSojMHFMIoq2+ipYDHwsHj+mENroLk/ZEYwW7nLbfP8vCEEfxLgVJ0cAwNJXHFyLbbHULLnmIqxdacJuOuqEM0TOLCHdtrbk+kGhMFqmYxGMgtj8rA== 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=UWHjvrGPUoibOnjIWXboKGO13NM/pSA/d6J/cVlRD2Q=; b=h3v+o6Kg5wUN/SF/vf5TH/9o/f/+5juoC3ZKZXDSttIxh2b50o4yAW4pR/3ZZzk3taHDofdBK5JNAYqQdGp8QrsivieDaZ++dat11lwHZhcAtbiq3SjfHR5W/6YgqQnkrtxqQtuCDiwO2n7X7IG6dVFVFmdXm8Bcwfu37z6k9y0M3dVQ2DKpU7WMjRH2ITtU5L8n4ibFzWIqOdnN7s7p9nVPZCUKdKDaa6jmrABHUhMSLDLnc7Ss8SVwciCCOSmkiMTNICOh20hOwXKCFisE5Dl+IgkqcHF9dEI8Dj43/YYXcwNElKm0SdFdzm/ZI8Y0WGTdXRn11VLqzlmSVjL1EQ== 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=UWHjvrGPUoibOnjIWXboKGO13NM/pSA/d6J/cVlRD2Q=; b=fyYzm3hUaSZJekvWH5RsyzL96anrHaXajn3CFEMfqs80jSc9YMV+fMus4ak6sDd+yWBYVOmw8u7PqcSwYl7LJhYp/246aKDqXaEnT+uIWeIWf4geEca+dg1sJc3wl69Ol6I+bRmdyzLdtDnnIs3Vy99QV1705FO1NG5FY4Wzn8o= Received: from DUZPR01CA0141.eurprd01.prod.exchangelabs.com (2603:10a6:10:4bd::28) by DB9PR08MB6441.eurprd08.prod.outlook.com (2603:10a6:10:252::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.472.15; Tue, 6 Oct 2026 15:57:45 +0000 Received: from DU2PEPF00028D09.eurprd03.prod.outlook.com (2603:10a6:10:4bd:cafe::7b) by DUZPR01CA0141.outlook.office365.com (2603:10a6:10:4bd::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.472.21 via Frontend Transport; Tue, 6 Oct 2026 15:57:44 +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 DU2PEPF00028D09.mail.protection.outlook.com (10.167.242.169) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.496.14 via Frontend Transport; Tue, 6 Oct 2026 15:57:44 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=23yjbh4k34hwzfubhuiim7m4inbd3ick; d=sashiko.virtuozzo.com; t=1791302264; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date:Message-ID; bh=ekOio7LphWqunzaqgQ7fSAwchwk3dLKgrGpDG3LOtgY=; b=I1kdTccVns0c+SnQ+aOLv79OJQtbTtMpWc2QYQn1Ol/u31Iur6e1t5nYdZEUQZV9 zxZWXcaSVjPq680TDdbg0pFifQSf1venw8JUUs0Nx4AX6kXSIqxU8JuuwY5XQfpVkF8 BNxGzAS8rnQdTqJZvd/5+gQjcxgbptIOLx+JhJmOsFTtsJTLm5I0+Ezyhq3JnVWpx+c aqga0Wv1udASFSZMgsSCgD+VvaeYU8Ue1WKrJXJs5q/7BHZRsdT/0MI8Vx71qWf7EsA 9EJp6+mnuH0A5ugg/OO9j/NHC4FQGFn3AwWeExRDrGss1G+VOSFWKjWyeDkouPUC35+ HVY4Y7/DGg== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=sokbgaaqhfgd6qjht2wmdajpuuanpimv; d=amazonses.com; t=1791302264; h=From:Subject:To:Cc:In-Reply-To:References:Content-Type:Content-Transfer-Encoding:Date:Message-ID:Feedback-ID; bh=ekOio7LphWqunzaqgQ7fSAwchwk3dLKgrGpDG3LOtgY=; b=ADGqiGuS60QkQwhhTC7fF1LT5+f8u7kK9G2UA/fFaoTUGGNbSn+XfujnbBAzdGcj yvYZ+ltnf5dDDy+PV1ZcIKm6kg7apd68QEzsVi2BVf8soycJ2dtXOfqRa+VWLaMPmxm 26Xs651mB+/c5HrkRcFoJN+DqWd3DDJjDtWeGnDU= From: no-reply@sashiko.virtuozzo.com Subject: Re: [PATCH QEMU HCI-8.0 v7 12/14] usb-host: reconfigure endpoints on CPR incoming #VSTOR-137800 To: svt-core@virtuozzo.com, Andrey Drobyshev Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org In-Reply-To: <20261006-usb-host_v3-v7-12-044f668789a1@virtuozzo.com> References: <20261006-usb-host_v3-v7-0-044f668789a1@virtuozzo.com> <20261006-usb-host_v3-v7-12-044f668789a1@virtuozzo.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Date: Tue, 6 Oct 2026 15:57:44 +0000 Message-ID: <010701a111ef64d7-70ed69c3-6036-445d-90de-70722b7b8580-000000@eu-central-1.amazonses.com> Feedback-ID: ::1.eu-central-1.2wRQJBpg9g1fGRYexx3dUuYGS25Bux+2TEOx72/m6U4=:AmazonSES X-SES-Outgoing: 2026.10.06-69.169.224.2 X-EOPAttributedMessage: 0 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF00028D09:EE_|DB9PR08MB6441:EE_ MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 6c6adb70-4dff-4eef-9895-08df23c28f65 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|48200799018|9140799003|376014|61400799027|32142699015|13003099007|4143699003|5023799004|5063699009|56012099006|10067099003|55112099003|18002099003|22082099003|6133799003|4113699003|5113699003|16102099003; X-Microsoft-Antispam-Message-Info: e9K/9IgCTLqKdhNDcGHm40zOmaGludzliNnZofDG9/n6f8W+wtw/e/kLsoqNo2SuydMH4t0sbQ1KFiIQFMLzOMfwWrjSyE0blOt/xguGj6K6FCmuC5q+LVbGnIfvQtZ/RYhopGS9F2z8jS03pB7GujyR/ecJvMt9RnQl7imaVDpSvFaWtXbKWOXXhf6IqovhP5dwTr4QQSBf+vLVy4JynTRQN3jfzpzjYkzjMrzTrMjxcVHYveK043uiuIB7ICcEj2dqdvruT3Q2UXGIjLXPW64WrVnV4CYsrDrahX6Gulfo8b/ThxTUuX8oFARjO1dVivDHWTVZVVisvXyW1Od6rejP3PyNYYKNaTjiTrgN2i0dC6R2ky6h13TgWANwRyvqC2PlKfv/1UvkIaDZzNFCsN3UsatOLOXzBxyPDvfhxHa0ivSVxhhTvD21WRe1zTFWLpEGTlwo/xqyCFHbxGNNdJd2J4tuv0Kh1o9k73CNnaD4r//hpnlhKt36jFqZQZYBxolmrYclSyYOQiLbdTn7fe87mr+Ewr4kp1Byc8riQIs9VX4gSGyNCks3xu0NMQu0pswUObUy1aPaMxnZhnAB1QUFrerb5v1zLHhpimeyDg5DSrJfYQ2kd694wXnxqK59NGp0kUOLk+yfppSvkdJA6l0MUZF8zB9l1NX8Twn4xjYW3IuHSh2/0WvuxlNz+sQXIShHM4UqzFcfThsl2wo+IFrgrc+it6FafmXD2NrGLZwqDdRd3Xpsg92Fk2Uj4mnExwb22j72qDW1fZ8emE8Epr6s9QCWa7h2t3A8E+Fm5RV/SxuGDqTJbtY83306Me2AVryDL54p4P05RoM2xq9KUw== 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)(48200799018)(9140799003)(376014)(61400799027)(32142699015)(13003099007)(4143699003)(5023799004)(5063699009)(56012099006)(10067099003)(55112099003)(18002099003)(22082099003)(6133799003)(4113699003)(5113699003)(16102099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: VT9TembgEr1R/GfUNxd5hMzMYGc5XoWD0IqEg1lSsEQRpoSLms8g4cDnKBT7/Oih2kdOnmOzpVOk/A/JECN0MCj8GzIUlEh4uE5mjA2whuB4crcigxulJjjGiGhKg+S1WO8NgZU0Sn/CNmVuOLDmzc9xzN055AWmBS9n7zflAVafxQ/dxn/P8gaMebvk7QhUoxcQnc5IfH31wDBCNL/YFgPTYvjuyQiH8TYSRBH+11PFBiHaVVXxtMzUYfyfbE21G3+HsefkmAYiYyN56FSkcf7fLRjuv09kp+ImnE2RXxogR0Jb0lSjRfZOhsn/dClzHb95jsniVcdfI32LXXlj5F1F28Ep/hWcdpn8laR0uj1NmDkRKRJRmXQGSJrd7nrat1KIh2Sz1pOMp/Pd4FMLfJ16iW5U/XU0N4rQTKHqUNARDXzrKul0SYnE+Zxk+MS7 X-ExternalRecipientOutboundConnectors: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2026 15:57:44.5437 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6c6adb70-4dff-4eef-9895-08df23c28f65 X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: DU2PEPF00028D09.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR08MB6441 Thank you for your contribution! Sashiko AI review found 5 potential issue(= s) to consider: - [Medium] usb-host: failed CPR post_load makes target exit notifier reset = the shared device - [Medium] usb-host: CPR reclaim claims all interfaces and sets configurati= on even if guest never configured - [Medium] usb-host: CPR post_load dereferences NULL dev/dh when device was= not opened - [Low] usb-host: usb_host_ep_update() on CPR target resets endpoint halt s= tate - [Low] usb-host: reclaim comment claims no half-claimed state but claim lo= op can fail midway -- commit 557f801d929f427a0cdb08c818b08fd2db0316df Author: Andrey Drobyshev usb-host: reconfigure endpoints on CPR incoming #VSTOR-137800 This patch makes the CPR target call usb_host_ep_update() after vmload, so endpoints for a non-zero altsetting are rebuilt. It also re-claims the interfaces through libusb so libusb's view matches the preserved fd. The new helper usb_host_cpr_reclaim_interfaces() validates the migrated altsetting values before claiming. > diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c > --- a/hw/usb/host-libusb.c > +++ b/hw/usb/host-libusb.c [ ... ] > +static int usb_host_cpr_reclaim_interfaces(USBHostDevice *s) > +{ > + USBDevice *udev =3D USB_DEVICE(s); > + struct libusb_config_descriptor *conf; > + int rc; > + > + rc =3D libusb_get_active_config_descriptor(s->dev, &conf); [Severity: Medium] Can s->dev (and later s->dh in libusb_claim_interface()) be NULL here? usb_host_post_load() takes the CPR branch whenever cpr_is_incoming(), and neither usb_host_cpr_reclaim_interfaces() nor usb_host_ep_update() checks dev->dh or dev->dev first. On the target, only the hostdevice=3D path opens the device in realize(). With autoscan (hostvendor/hostproduct/hostport), usb_host_auto_check() only calls usb_host_open() under runstate_is_running(). If the target command line differs from the source's, a NULL pointer would be passed to libusb. This is somewhat speculative. Would an "if (!dev->dh)" guard make sense? [ ... ] > + /* Data is sane: claim each interface on the fd and record it. */ > + for (int i =3D 0; i < conf->bNumInterfaces; i++) { > + int ifnum =3D conf->interface[i].altsetting[0].bInterfaceNumber; > + > + rc =3D libusb_claim_interface(s->dh, ifnum); > + if (rc !=3D 0) { > + usb_host_libusb_error("libusb_claim_interface", rc); > + libusb_free_config_descriptor(conf); > + return -1; > + } > + s->ifs[ifnum].claimed =3D true; > + } > + > + udev->ninterfaces =3D conf->bNumInterfaces; > + udev->configuration =3D conf->bConfigurationValue; [Severity: Medium] Does this claim every interface and set udev->configuration even when the guest never configured the device on the source? On the source, claims are only made in usb_host_claim_interfaces(), which is reached from usb_host_set_config(). usb_host_open() only detaches kernel drivers. If the guest had not issued SET_CONFIGURATION at CPR time, libusb_get_active_config_descriptor() can still succeed for a kernel-autoconfigured device. The target would then create claims the source never made. It would also set configuration and ninterfaces from the host's active config, so the guest would see a configured device. If migration fails and the source resumes, its ifs[].claimed flags and configuration would disagree with the kernel state. The commit message says the re-claim is "a no-op at the usbfs level anyway". Does that hold when the source never claimed the interfaces? I could not confirm that this case is reachable in practice. > + libusb_free_config_descriptor(conf); > + > + return 0; > +} [Severity: Low] The comment above this function and the one in the validation loop say validation happens first so "garbage migration data can't leave it half-claimed". However, the claim loop can still fail partway through libusb_claim_interface(). In that case the function returns -1 with the earlier interfaces claimed and marked in s->ifs[].claimed, and nothing rolls that back. Could the comment be adjusted, or the claims be undone on failure? > static int usb_host_post_load(void *opaque, int version_id) > { > USBHostDevice *dev =3D opaque; [ ... ] > if (cpr_is_incoming()) { > + /* > + * The device stayed open, so rebuild libusb's claims and endpoi= nts, > + * and start reaping now that the source has handed the fd off. > + */ > + if (usb_host_cpr_reclaim_interfaces(dev) < 0) { > + return -1; > + } [Severity: Medium] Can this new failure return cause the target's exit notifier to reset the shared device? If usb_host_cpr_reclaim_interfaces() returns -1, the incoming migration fails and the target process exits through usb_host_exit_notifier(). On the target, s->dh is set and s->cpr_handed_off is false, because it is only set by usb_host_cpr_quiesce() on the source: usb_host_exit_notifier() { ... if (!s->cpr_handed_off) { usb_host_abort_xfers(s); usb_host_release_interfaces(s); libusb_reset_device(s->dh); usb_host_attach_kernel(s); } ... } That would reset and release a device on an fd that the still-live source expects to keep. Any s->ifs[].claimed flags set by a partial reclaim also feed usb_host_release_interfaces(). The notifier still gates this only on cpr_handed_off, and the later patch "usb-host: make CPR migration blocker conditional" does not change that. Should the target be marked as not owning the device when post_load fails? > + usb_host_ep_update(dev); [Severity: Low] Does usb_host_ep_update() here reset per-endpoint runtime state that the guest changed on the source? It calls usb_ep_reset() and then usb_ep_set_halted(udev, pid, ep, 0) for every endpoint, and the vmstate carries only the altsetting. A halted endpoint would be un-halted without CLEAR_FEATURE(ENDPOINT_HALT), and max_streams would be rebuilt in default form. > usb_host_start_events(); > return 0; > } --=20 Sashiko AI review =C2=B7 https://sashiko.vzint.dev/#/patchset/20261006-usb-= host_v3-v7-0-044f668789a1@virtuozzo.com?part=3D12