From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from AM0PR83CU005.outbound.protection.outlook.com (mail-westeuropeazon11020119.outbound.protection.outlook.com [52.101.69.119]) by lore.virtuozzo.com (Postfix) with ESMTPS id E4BBA802A7 for ; Tue, 6 Oct 2026 10:34:45 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VR+/4vRYvlUdNQ+sE/91u994yPMKoQxZlJIv2GaEZlCpTPBT6VtuqoIXMeZAs5qaZgRuCS8C16dFcYkBS9u1YirnRutLdp1olIURYgJzu29WRMl6wDkgcdMN02VhFhF0X/FlPRIe+b37D4chl2xJmPJ0kFr79GNzEbPVg4I6TjjvpvR9H3mYoMTIdP4d1VMnCmRHYEJmC4/sz+/BGP12O6wUkzHaj4G5Ieeq1G4J1NhVS7No2FwXLsMoYkmJnGMtDnTbwd5Fi7EJibPvjV1KZdXdPhu9G5diVe5HLU4HjiPh/d61dzBCBBie3AxouwkWTTeLYEMGwzP1oBrSvOKRXg== 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=iCNpEE8vVc5GsF3DWQYBWElFW1Erpv+YOdJQSqn8Mlo=; b=n+GJ9l15KgPB2h4pjt87q7fDZNPZIVYR9NK/6i4qHJs8zdYDNhjPsdZTtvSsSYbzejYZrAxZ9+M1AN8/2nNr9MzxLXAsTfCbEtZiBGgYKf+tqGPrK7q03cU1xPRwo5qMOpK0/X2L/PKN1U8/abG8dLkXdPiluGnZAaKp6JMq0fn4WV4ZKRCRtU+kwfkHiGUdmT5wv8XBvJslYt8tUEnFeEBIDGrR3SIzYhnAVpckdGC5NNJtLMLXchgrElCVDZznaxIyW7HRertaMfWu4CJuZZlc26JPk0+KSQYFMGLjkS2rQYI2JDdHcqdV3S/CfiZjHc2EXPomfHnSzsHYMmQs6Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=virtuozzo.com; dmarc=pass action=none header.from=virtuozzo.com; dkim=pass header.d=virtuozzo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=iCNpEE8vVc5GsF3DWQYBWElFW1Erpv+YOdJQSqn8Mlo=; b=arBfn2sSLllpEr5LHW0dXcOizdEs+zYqOq9oqWJr7n2nJzQkmO7s7aCm1wR7EwVgxb9ztcayayk5LZf0OpjUrFoDrs5KgAZ3kSBJ5PCLWqWCj6iExXgzGTLRE1v71rF83FtzBYIOfJEwsjnmpwLaa2taxcY2YprVnYRf553VJILHvxe5jhuMZt7BOrj+SeM4UUn93WpJtyoUGgiKEu9EIgx7WSgyf3hZBaaRTZtLtZP8hCPl9nt74gmeCbU8rDfgoLJwngna+0dUmdJUeyt2Dz8H6BMxaqBNZsLpcNCJA3VTFD9szq+Z07N2FR9eCD0ojeVt+p/KNskS70HtIEZ4RA== Authentication-Results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=virtuozzo.com; Received: from VI0PR08MB10656.eurprd08.prod.outlook.com (2603:10a6:800:20a::12) by GV1PR08MB8692.eurprd08.prod.outlook.com (2603:10a6:150:86::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.496.14; Tue, 6 Oct 2026 10:34:43 +0000 Received: from VI0PR08MB10656.eurprd08.prod.outlook.com ([fe80::4e37:b189:ddcd:3dd8]) by VI0PR08MB10656.eurprd08.prod.outlook.com ([fe80::4e37:b189:ddcd:3dd8%7]) with mapi id 15.21.0496.010; Tue, 6 Oct 2026 10:34:43 +0000 From: Andrey Drobyshev Date: Tue, 06 Oct 2026 13:34:34 +0300 Subject: [PATCH QEMU HCI-8.0 v6 10/12] usb-host: reconfigure endpoints on CPR incoming #VSTOR-137800 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261006-usb-host_v3-v6-10-8688ec9576d1@virtuozzo.com> References: <20261006-usb-host_v3-v6-0-8688ec9576d1@virtuozzo.com> In-Reply-To: <20261006-usb-host_v3-v6-0-8688ec9576d1@virtuozzo.com> To: svt-core@virtuozzo.com Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org X-Mailer: b4 0.16.0 X-ClientProxiedBy: VI1PR09CA0115.eurprd09.prod.outlook.com (2603:10a6:803:78::38) To VI0PR08MB10656.eurprd08.prod.outlook.com (2603:10a6:800:20a::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI0PR08MB10656:EE_|GV1PR08MB8692:EE_ X-MS-Office365-Filtering-Correlation-Id: bcd290ac-6b51-4cf0-17f3-08df23956a76 X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr List-Id: svt-core@virtuozzo.com X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|52116014|376014|23010399003|1800799024|366016|10067099003|56012099006|5113699003|5023799004|6133799003|22082099003|18002099003|38350700014; X-Microsoft-Antispam-Message-Info: W26Ctx+Kc0dsQV14s912syJY2KqizDYR7rT3pWAk4jDqb+iyX3ysStlMWBUTGnh4GEhj0rU9Zl18gvAZy/m7TbxSCoNnG/caMTLcMhMVK8YF+QYQUiYN59eoJiR/C80irG+5GoBCI2TVdUE+0c0W35Sm0ug7+b8HJYlPZb+uBU/5lMFKvcr5z83Gh/Ud0PgLo0B/FV+Fj+i52Gncv6CQ7yfHlJVDoZz0bvBSC6wMWwHS2XeZJ0veOS1dPd51Gi3JdxsaczwkCIPnp9pMxy9f38Gjh5EJ1yIBrNy7+DV9vBuXXxyB08BiOJ/Yaz2fLokNyDAZcuz/YB4hz+OKQlIvQ5TAVWGRkkC6CU6LQMYpjgWG4BD7PuLhZIxl+hDNVFgxIkdN+l+MFsNmKsuW8iiKjpiRLVXXJnOyCHMDXipL+zK79gKjjyfusqGVEPbcGnQJ4kh9Ic9mIin+3/kEPu+gKuxx2LCMJTYiJ/6pTMklBMVCTbvKX62MPl1E642VdpO1fvV+GuGzMWpg/mAFqddyrdwkazSNqpbjKlPzZY5D2DFKsS7twJIdQO5PgFFMQAG9zPQJ1MuWuJoXyV6phP4su+Aypp4mfhaL/HpF4rU9oFd4VWwnCQwApL6JuCenGzp/E7MSf1/KF9SPu2foqA0dcdJylV/93FjdEdoAwOHkP05FOo8QwkEb74oobJyz9YLhZlfVzbzGDg+jHXJwidkD6/aBfzlB3pTII8YI3zi12C8= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI0PR08MB10656.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(52116014)(376014)(23010399003)(1800799024)(366016)(10067099003)(56012099006)(5113699003)(5023799004)(6133799003)(22082099003)(18002099003)(38350700014);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?TnlrRW9XNmo5eUtiVUVNRDFMR0cvM2ZZL2RCNVg0aTYxOWpydEM1dEdZa1Nw?= =?utf-8?B?VGRFRmFYTWdIeEJvbFA4MDFpRWdmaEYyUENIWFhWU0Nyd09GcGw0cDRXcnhZ?= =?utf-8?B?cWVqRGZRRkdZY2g2V1MvRU90TnNpMFhjS0Z6MTVMQ2pIKzNmcGZoeHR4a1oz?= =?utf-8?B?bWRTM01RTjd6MFJqNHB6ZUd5OEp0Z0tTUFU3amhhRFpTRm10OXQya1BhT2xs?= =?utf-8?B?d1NtRVpJcU5sdmdCa25oLzM1NDNjUzRsbmozWTVrR2xaS2RVclh6ZytVN20x?= =?utf-8?B?TVJXdTh2ZFpHU0FjNUZjSmt5TXg0eVEyWnRXNzdtTHcvdUtpc3NJVFoxL2xX?= =?utf-8?B?cVVFUmo0aWhSeEJuL2xBU093RHQycXcxbko4U09zQWdVMEtCZzk2c0JCYjNr?= =?utf-8?B?NEVxbGRWUXZZcWUwaDJaSStTdG9KT25VOHVlQ3QwYjBSUEtwQzJVZ3BxaC9o?= =?utf-8?B?NWhwZ3pCZStpcjQwSXpvVFNsN2IwV3RJcjRaN3RSaXBsQ1FqNTh4R1RYK1JK?= =?utf-8?B?UDZSa1hhdS8vbHh1eEN1UFFxTU1abTh2bHNRdUc2eEwzU0pVRFMydXZSNkVE?= =?utf-8?B?L29NelY4eC8wa0N4M1VEWEZyNkRuYUNSYzRGS3VydXRaNVlYR29Pd3Rrdnkw?= =?utf-8?B?d2t5cHJnbVVjMnNZM0RHai8wWGdDaDJIVDlNUFpqMFFsdWNSaDZEN0VJZ09L?= =?utf-8?B?OWJYMGhoZ1lVTDQwaVhGcTdvWm1TUVJHYmNmZ25MUkJ5R0ExT2R2Uk0xNGNt?= =?utf-8?B?c3dxWHhMa1V0RVdRR2ExQTF4SXhiK0RZaFl2dHZjUHJjMkhHRTc5MVdWSzdL?= =?utf-8?B?S1FLejlZWWdxbGdVQTIwQjBIRGRTTDZmMWE2WUZDYlNHUTBncHIwSjJydU5l?= =?utf-8?B?dkZXTUJ2SmsrbloxU29KS2JwWENnR3JTSmRTRW9wM1FnS3JpY2dkcXBTMita?= =?utf-8?B?Vk52NVR6aVRoQ01vN0RZcitCb0dkMS8xQUJQdVdYZUwxczZQcE5aS25uWjl1?= =?utf-8?B?U1ppY01VNXVVTkIzZklEVmEyOTc3SnFFM2N5c2d1YU83V0Y1b01kVkgyazFV?= =?utf-8?B?cWFyZi9oUE45blhCM3dHcEcwRFBsV1NDVTV0blNCbnNyZytKcEE1c21BRHgx?= =?utf-8?B?aGxZaWRNdTMra2tUL3dYRFVEdmNMTGRVek9pdXNSNk1PYUllYlhoc1VyS1hl?= =?utf-8?B?aWJoVGhIRmx5MHV6VThLWFFXVmMveXB2THpiS045SFFzWlhQYWF0VTZZOUxy?= =?utf-8?B?ZlFSYkVEWFh0dFBXZHBQekxBSXVVUHZ0OFlkUWxoZk5mTVBTMXhRcWgvb1ZQ?= =?utf-8?B?QkNaNjYrbjZHMXQ3NkVPbm1TVk9RdDdGYUVHMDNhb0NNUzNlU1VYVmVydTJj?= =?utf-8?B?Qjd1Sy9hYjZ2dEFDUDFKblNZYUl0ZWI2Nk9IR3doSStCd1pwSFp2QWU5djhh?= =?utf-8?B?akdRVFJMK1lReFVMU3NUWW9sSXp6R0VDWDFXREI4QkNxQTdUZndmSlF0NUZW?= =?utf-8?B?VENpeUJWMGYzVitmbm9sRXJSdTRKYnNKci9XS2xFdmg1Qmw1MWZ1WFBFMUc2?= =?utf-8?B?U2FieGU1c2NjaWxVbDZjajVXamFiKzB6MDNTQXJDK3ZJcjZvYTg5ZGREaXFD?= =?utf-8?B?Q0RrNW1tRzVtN0wwSVBUV1daZ3d6V0Rxa0htM1ZvZ2V5RDBUT254UUd3NVl4?= =?utf-8?B?ZDJWQXhDT2Z2MXQyOWhpQWxSSFBLbXk0MjA4eDN1TWhDRlNXM1hPL1M3akNQ?= =?utf-8?B?SzVYMmQ4WFdscWpJMEJ1bWxrN0FSN2U3OTl5Z1RiR1hmRlZVUFV2eHpUc25F?= =?utf-8?B?Rk0vcG9uU2FRRDNleW04bnE0b04ycXRWUVJvcmw2Zm1FTTE2ZE5XUWE2NVpO?= =?utf-8?B?Rkk5bTFySGpkMHVwSGtRdFRlQVAralZ1WFAyOXJlNWhFdDVvTzdETVpDdXJL?= =?utf-8?B?aTZJQnhCVlAwSmZMY0ZXYzdaT3VUaE9MZmloNW85VXNtRWNzUkhTaDRsUUts?= =?utf-8?B?M1FyWk1CZVdaWFBnNlBheXVYQ3RXU280NENIQWMrSFhMNmNRQzRBTFFDZ2dq?= =?utf-8?B?c0gwN24wMjVENlVZM2dsbXJ3L09ZTFpseVRhV2N6dWFxcnRGNEJNYWx6SjVE?= =?utf-8?B?NzdjeG9ZMURBbnZISlI4QldiNmM4TTlhRWk5ZjJHU0NHTXc0U21GSWZ5WnJE?= =?utf-8?B?NTFqRnQ1SXpCZzRTdDNjU1NXNTlySE94N1RLSDlDNWsyT05JdkFIUHord2Jq?= =?utf-8?B?bUFheEVjZi9KdXRTdzZZcGhXSSt0U2hGME1kK2F1bmJnTVI0R21nQmt4QnJL?= =?utf-8?B?R2ZQQkJ5YVFWSno1KzNWWHZtUHlLK1RuZE5ZK3cybFV6NHZJR3ZXZDVhdzBK?= =?utf-8?Q?HFpwEid8OWt+s0Tw=3D?= X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: bcd290ac-6b51-4cf0-17f3-08df23956a76 X-MS-Exchange-CrossTenant-AuthSource: VI0PR08MB10656.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2026 10:34:35.4027 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: z7j9ugzJQ7XwASLIbz08vjHhtzrCZByvbVZQbY1HbbUtP6kmzRvGjhpxenLSJasl2Q6Phjxn+fK87FKvBNojDxZUxCQL/HjRu1CwHSyTwcU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR08MB8692 On CPR incoming we skip the usb_host_open() rescan, so libusb only sets up the endpoints from the device's default configuration. If the guest had enabled an endpoint by selecting a non-zero altsetting (e.g. an isochronous streaming endpoint), that endpoint is now missing, and the guest's transfers to it simply stall. The altsetting itself is restored by vmload now, so let's call usb_host_ep_update() on the CPR target to rebuild the endpoints out of it. The kernel claims are still there on the preserved FD, but libusb's own handle knows nothing about them, so a later SET_INTERFACE would fail with LIBUSB_ERROR_NOT_FOUND. Let's re-claim the interfaces on the target as well to bring libusb's view back in sync - on the preserved FD this is a no-op at the usbfs level anyway. Signed-off-by: Andrey Drobyshev --- hw/usb/host-libusb.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 492f0442974..b3c46aa8de0 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -946,7 +946,7 @@ static void usb_host_ep_update(USBHostDevice *s) alt = udev->altsetting[intf->bInterfaceNumber]; if (alt != 0) { - assert(alt < conf->interface[i].num_altsetting); + assert(alt >= 0 && alt < conf->interface[i].num_altsetting); intf = &conf->interface[i].altsetting[alt]; } @@ -2033,6 +2033,53 @@ static void usb_host_post_load_bh(void *opaque) usb_host_auto_check(NULL); } +/* + * Reconfigure the CPR target after vmload: reject a migrated altsetting the + * device can't honour, then re-claim the interfaces so libusb's view matches + * the preserved fd (which already holds the claims). + */ +static int usb_host_cpr_reclaim_interfaces(USBHostDevice *s) +{ + USBDevice *udev = USB_DEVICE(s); + struct libusb_config_descriptor *conf; + int n, rc; + + rc = libusb_get_active_config_descriptor(s->dev, &conf); + if (rc != 0) { + usb_host_libusb_error("libusb_get_active_config_descriptor", rc); + return -1; + } + + for (int i = 0; i < conf->bNumInterfaces; i++) { + int ifnum = conf->interface[i].altsetting[0].bInterfaceNumber; + int alt = udev->altsetting[ifnum]; + + if (alt < 0 || alt >= conf->interface[i].num_altsetting) { + error_report("usb-host: migrated altsetting %d out of range for " + "interface %d", alt, ifnum); + libusb_free_config_descriptor(conf); + return -1; + } + } + + n = MIN(conf->bNumInterfaces, USB_MAX_INTERFACES); + for (int i = 0; i < n; i++) { + rc = libusb_claim_interface(s->dh, i); + if (rc != 0) { + usb_host_libusb_error("libusb_claim_interface", rc); + libusb_free_config_descriptor(conf); + return -1; + } + s->ifs[i].claimed = true; + } + + udev->ninterfaces = conf->bNumInterfaces; + udev->configuration = conf->bConfigurationValue; + libusb_free_config_descriptor(conf); + + return 0; +} + static int usb_host_post_load(void *opaque, int version_id) { USBHostDevice *dev = opaque; @@ -2042,6 +2089,14 @@ static int usb_host_post_load(void *opaque, int version_id) * rescan in usb_host_post_load_bh() -- those are for cross-host migration. */ if (cpr_is_incoming()) { + /* + * The device stayed open, so rebuild libusb's claims and endpoints, + * and start reaping now that the source has handed the fd off. + */ + if (usb_host_cpr_reclaim_interfaces(dev) < 0) { + return -1; + } + usb_host_ep_update(dev); usb_host_cpr_restart_events(); return 0; } -- 2.47.1