From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782311; cv=none; d=zohomail.com; s=zohoarc; b=C8jnoCUnjCP3mwKZB9StrXKXPxd9K28M+3Dwg1D3e19QM+Lcsdxm0hzKk+0JiloEDpvhQBI3qwPxUHu8hV10x5Sx38ibjuIzznvkvnLSeLfwTa1Dz36c4U4GVh115lbQKwJOxzuZecjowwvX+gqEjAe1lRmgkTplos009kr/tg0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782311; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=TBqwkdTRqUwsY27EiP5YbesMgj7n7qTjOsQBFo8GYrE=; b=PEsOkdrak453aMBaq46syZ7hccn/HkXHaxHVVIEhaIG2fb9kDn0Nf2rYMgtGspNpFU0EwjyOkwFDRh9uiyFCEJsg5BiyfF9WCUNdmzBCKe5ysO7aycESFdwqWehqdzoGh/GvqnIoq8C45nEPhTvVjymBPdO1Ca5EBubv71o0TNc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782311351966.45373128857; Sun, 15 Jan 2023 03:31:51 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477858.740753 (Exim 4.92) (envelope-from ) id 1pH1EN-0004jp-QG; Sun, 15 Jan 2023 11:31:19 +0000 Received: by outflank-mailman (output) from mailman id 477858.740753; Sun, 15 Jan 2023 11:31:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EN-0004j8-Lz; Sun, 15 Jan 2023 11:31:19 +0000 Received: by outflank-mailman (input) for mailman id 477858; Sun, 15 Jan 2023 11:31:18 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EM-0004co-En for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:18 +0000 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [2a00:1450:4864:20::636]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 1f70f17e-94c8-11ed-b8d0-410ff93cb8f0; Sun, 15 Jan 2023 12:31:16 +0100 (CET) Received: by mail-ej1-x636.google.com with SMTP id u19so61973708ejm.8 for ; Sun, 15 Jan 2023 03:31:16 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:15 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 1f70f17e-94c8-11ed-b8d0-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TBqwkdTRqUwsY27EiP5YbesMgj7n7qTjOsQBFo8GYrE=; b=QwaIpJdnEWMrDV9ZVxPKuUyl7Pi8ECOWt8hyB4G2cSC+mNK0H+LMpIrDm2cl90+hbU FFJOD2E7WpDSliUnmb/Dno2Af+sHkwT7PBW0UjtFKHQBC6b/twmJ4C9M1A5JqRUsAu5l TRJJ4MGHYIiCRTZCKsT/2ueklyDo5xRdUHW4dGQgrAOxcqYckEAqT+oFDYbtZpkHJPyU +ppjHBSSKJzCM6T4WY74pT6ivefE3azDHm1XOqDF96/RcwYPNnbE10fS6L39V8gSbUrC t35/J+zp1j4PHLmdh2isTy1sLJ6LpQRrP7kySnCnHmBmGQw07ag6qnzT6r3S2fuRbX8O gnqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TBqwkdTRqUwsY27EiP5YbesMgj7n7qTjOsQBFo8GYrE=; b=mlwivffz3BUF05TY7GwQYHoOK1EFyknsEHzrmZkOGEmmHQzF9I3rz+oFylMAvF6g3Q Sdv7Crn0GITZt8dXp4cw/sYcdy5kjbXZgDAqWThe/s6q9FclEsnBYhJSK2SWiQEKR7w/ jxayyi403g9mnK8FFCkEV532/IC913lsifyIY2R+DRgs342TWo3C0Qq1imhy3aWZt64g fr6gQzI9pFn6CTK7P8iwqqbFUqR1DC0bzaYFDLM/ZtmG4Gsse5BzpVxJ9DvoQCqxyFN7 v807fx4FEO1zfsJwYkpxO9cUfDO+EBCuY77ZP+GbihL3YIN4OZg9iwZRE4Nd9cLPHtab J2jA== X-Gm-Message-State: AFqh2kpvFdx4piZ1C8JBS7V6pNM/yR7X+i8HO4F9w4wwpZwIgP2wmMxK HVrf3wiWbtmTEDNeTV0SWkhRrT9LaX0d+2bQ X-Google-Smtp-Source: AMrXdXvZ32YsPLgOdTO+otsGGHFp+YCDuOV+0rKNF6of4w6hnrg24wnd22SuHOKktSTOClOxf4TYPw== X-Received: by 2002:a17:906:2816:b0:7c0:d452:2e74 with SMTP id r22-20020a170906281600b007c0d4522e74mr75892077ejc.4.1673782275466; Sun, 15 Jan 2023 03:31:15 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Oleksandr Andrushchenko , Wei Liu , Anthony PERARD , Juergen Gross , Dmytro Semenets Subject: [RFC PATCH v3 01/10] tools: allow vchan XenStore paths more then 64 bytes long Date: Sun, 15 Jan 2023 13:31:02 +0200 Message-Id: <20230115113111.1207605-2-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782312830100011 Content-Type: text/plain; charset="utf-8" From: Oleksandr Andrushchenko Current vchan implementation, while dealing with XenStore paths, allocates 64 bytes buffer on the stack which may not be enough for some use-cases. Make the buffer longer to respect maximum allowed XenStore path of XENSTORE_ABS_PATH_MAX. Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Dmytro Semenets --- tools/libs/vchan/init.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/libs/vchan/init.c b/tools/libs/vchan/init.c index 9195bd3b98..fec650dc32 100644 --- a/tools/libs/vchan/init.c +++ b/tools/libs/vchan/init.c @@ -249,7 +249,7 @@ static int init_xs_srv(struct libxenvchan *ctrl, int do= main, const char* xs_base int ret =3D -1; struct xs_handle *xs; struct xs_permissions perms[2]; - char buf[64]; + char *buf; char ref[16]; char* domid_str =3D NULL; xs_transaction_t xs_trans =3D XBT_NULL; @@ -259,6 +259,10 @@ static int init_xs_srv(struct libxenvchan *ctrl, int d= omain, const char* xs_base if (!ctrl->xs_path) return -1;=20 =20 + buf =3D malloc(XENSTORE_ABS_PATH_MAX); + if (!buf) + return -1; + xs =3D xs_open(0); if (!xs) goto fail; @@ -280,14 +284,14 @@ retry_transaction: goto fail_xs_open; =20 snprintf(ref, sizeof ref, "%d", ring_ref); - snprintf(buf, sizeof buf, "%s/ring-ref", xs_base); + snprintf(buf, XENSTORE_ABS_PATH_MAX, "%s/ring-ref", xs_base); if (!xs_write(xs, xs_trans, buf, ref, strlen(ref))) goto fail_xs_open; if (!xs_set_permissions(xs, xs_trans, buf, perms, 2)) goto fail_xs_open; =20 snprintf(ref, sizeof ref, "%d", ctrl->event_port); - snprintf(buf, sizeof buf, "%s/event-channel", xs_base); + snprintf(buf, XENSTORE_ABS_PATH_MAX, "%s/event-channel", xs_base); if (!xs_write(xs, xs_trans, buf, ref, strlen(ref))) goto fail_xs_open; if (!xs_set_permissions(xs, xs_trans, buf, perms, 2)) @@ -303,6 +307,7 @@ retry_transaction: free(domid_str); xs_close(xs); fail: + free(buf); return ret; } =20 @@ -419,13 +424,20 @@ struct libxenvchan *libxenvchan_client_init(struct xe= ntoollog_logger *logger, { struct libxenvchan *ctrl =3D malloc(sizeof(struct libxenvchan)); struct xs_handle *xs =3D NULL; - char buf[64]; + char *buf; char *ref; int ring_ref; unsigned int len; =20 if (!ctrl) - return 0; + return NULL; + + buf =3D malloc(XENSTORE_ABS_PATH_MAX); + if (!buf) { + free(ctrl); + return NULL; + } + ctrl->ring =3D NULL; ctrl->event =3D NULL; ctrl->gnttab =3D NULL; @@ -436,8 +448,9 @@ struct libxenvchan *libxenvchan_client_init(struct xent= oollog_logger *logger, if (!xs) goto fail; =20 + // find xenstore entry - snprintf(buf, sizeof buf, "%s/ring-ref", xs_path); + snprintf(buf, XENSTORE_ABS_PATH_MAX, "%s/ring-ref", xs_path); ref =3D xs_read(xs, 0, buf, &len); if (!ref) goto fail; @@ -445,7 +458,7 @@ struct libxenvchan *libxenvchan_client_init(struct xent= oollog_logger *logger, free(ref); if (!ring_ref) goto fail; - snprintf(buf, sizeof buf, "%s/event-channel", xs_path); + snprintf(buf, XENSTORE_ABS_PATH_MAX, "%s/event-channel", xs_path); ref =3D xs_read(xs, 0, buf, &len); if (!ref) goto fail; @@ -475,6 +488,7 @@ struct libxenvchan *libxenvchan_client_init(struct xent= oollog_logger *logger, out: if (xs) xs_close(xs); + free(buf); return ctrl; fail: libxenvchan_close(ctrl); --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782310; cv=none; d=zohomail.com; s=zohoarc; b=JjFzveO1tZBBn8d34MNstaT23ttzOq8dLl2YfYOkMUEt5GWSHerOVqOeLIVB9Seph4483fudbz2y8hh2CBxLemVxF02OepxVppExd0Xf02FsB+1fm1Tf3+DZ1R+LdcufsEjHMjoyMHZF2371sMXOpYHr8qrSRRhuGavHP+6Imtw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782310; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=03O/96QsOqq4aLYpGvEXu2Bk6X9D5zYH6rdH2Rhto3Q=; b=dqC1c80Yf93VzEEXz1iJSyC8ZAHjd911It3IplUrQ3L121zOb6AFRMCJAVzAeD0vPbHFQBS2f+OzlUPY8gdu3Of7QkK/naEOthA11J9UnzsG9vCUXkg4jnPGXDSDsU5v9p1OPL35Q/BbwvJs34Q49EWhdhkC9tu+k49QUfwvEHQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782310227414.44851703114773; Sun, 15 Jan 2023 03:31:50 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477859.740769 (Exim 4.92) (envelope-from ) id 1pH1EP-00057b-2g; Sun, 15 Jan 2023 11:31:21 +0000 Received: by outflank-mailman (output) from mailman id 477859.740769; Sun, 15 Jan 2023 11:31:21 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EO-00057Q-VE; Sun, 15 Jan 2023 11:31:20 +0000 Received: by outflank-mailman (input) for mailman id 477859; Sun, 15 Jan 2023 11:31:19 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EN-0004ci-6R for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:19 +0000 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [2a00:1450:4864:20::62a]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 204756f6-94c8-11ed-91b6-6bf2151ebd3b; Sun, 15 Jan 2023 12:31:17 +0100 (CET) Received: by mail-ej1-x62a.google.com with SMTP id bk15so4531259ejb.9 for ; Sun, 15 Jan 2023 03:31:17 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:16 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 204756f6-94c8-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=03O/96QsOqq4aLYpGvEXu2Bk6X9D5zYH6rdH2Rhto3Q=; b=GjzY+W7G5a/MctJVU7CBCLUw9wATIetZIrBiEbrCoWfdM4C5Xx4AQ+5oCPnJqxnJ8Y lMxpnHXt+q6wsWEZpjHNqpxCj3ujMJ+9Rx+doJP2ijRd2SjwHL8E8tz7u7cm+whw1Jgq XZK/G4Asx6nRXjw5A+OZVjHZY15XRjsIWV6N/CwVM95WfIcpfEG0wmywFnuwn0qH6Uk9 vKGSodzrl7SME9bv/hCB/YGmjdaoGkuXRxBjgjVUVc8KG9wvEWdhDoVB5tp8bcvVlw2R WVdtN7/L2c3SU8/QH32B2pYtJOEx5IeKY6wgvwBN7TZsf48r8a0pldoel4zqO9yyt975 8t2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=03O/96QsOqq4aLYpGvEXu2Bk6X9D5zYH6rdH2Rhto3Q=; b=jxwtBWZMbrinlQf/fsJ3CU4VOMM9F4MAlM0wyD05bLIBrHY4ri1BDVkGWDIrQwaHYR z5jgztyOLk1II0NRSDC8IPP6naDKKrDFH4bZczceohQeEbXWKzJxjGvTIkuVGWW8uaje tEJdtFgjyGCH40R0e5nMy0bqk3IRNtZRQU1aXynlvyjRgBQV4mca8QsVP/wAXyo+ZhBn 7+Tw473JlOCLGatSo8PfPyi0dmgMcIn5N/vkgaEHXTvE3Mrzkenztlk7jtjfUTGXWmFg WBAfxErVEKEp1suH0mGwfW18SnjcknTbo5SJFM4KQMomeffRREtbDMhP4rg1B2Lj8Rbv tLng== X-Gm-Message-State: AFqh2kphWD8lWnPhzds5umrJcMEy0qze8ACisq8epyGMXyR9WmC15LWr apec6yfpfQLNBP7cAaM6eX0oZIGpbv6R30K3 X-Google-Smtp-Source: AMrXdXs1MGroZp8qjceei9NllSlJPHzb4YXfmzo63afyVz0Tkk0Cxgv03c1A8+LUozMTfi+OtgAAAw== X-Received: by 2002:a17:906:edb0:b0:84d:3623:bf5e with SMTP id sa16-20020a170906edb000b0084d3623bf5emr27799097ejb.24.1673782276552; Sun, 15 Jan 2023 03:31:16 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross , Oleksandr Andrushchenko , Anastasiia Lukianenko Subject: [RFC PATCH v3 02/10] tools/libs/light: Add vchan support to libxl Date: Sun, 15 Jan 2023 13:31:03 +0200 Message-Id: <20230115113111.1207605-3-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782310810100003 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Add possibility to send commands from libxl and execute them on server side. Libxl vchan adds support for JSON messages processing. The using of libxl vchan is preventing the client from libxl from reading and writing from / to the local sysfs directly.To do this, the libxl vchan was added - instead of working with the read and write functions from / to the sysfs, functionality allows to send requests to the server, then receive and process the response. Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko Signed-off-by: Dmytro Semenets --- tools/helpers/Makefile | 4 +- tools/libs/light/Makefile | 7 +- tools/libs/light/libxl_vchan.c | 488 +++++++++++++++++++++++++++++++++ tools/libs/light/libxl_vchan.h | 92 +++++++ tools/xl/Makefile | 3 +- 5 files changed, 588 insertions(+), 6 deletions(-) create mode 100644 tools/libs/light/libxl_vchan.c create mode 100644 tools/libs/light/libxl_vchan.h diff --git a/tools/helpers/Makefile b/tools/helpers/Makefile index 09590eb5b6..2bf52d055d 100644 --- a/tools/helpers/Makefile +++ b/tools/helpers/Makefile @@ -20,7 +20,7 @@ $(XEN_INIT_DOM0_OBJS): CFLAGS +=3D $(CFLAGS_libxentoollog) $(XEN_INIT_DOM0_OBJS): CFLAGS +=3D $(CFLAGS_libxenstore) $(XEN_INIT_DOM0_OBJS): CFLAGS +=3D $(CFLAGS_libxenlight) $(XEN_INIT_DOM0_OBJS): CFLAGS +=3D $(CFLAGS_libxenctrl) -xen-init-dom0: LDLIBS +=3D $(call xenlibs-ldlibs,ctrl toollog store light) +xen-init-dom0: LDLIBS +=3D $(call xenlibs-ldlibs,ctrl toollog store light = vchan) =20 INIT_XENSTORE_DOMAIN_OBJS =3D init-xenstore-domain.o init-dom-json.o $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS +=3D $(CFLAGS_libxentoollog) @@ -29,7 +29,7 @@ $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS +=3D $(CFLAGS_libxen= ctrl) $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS +=3D $(CFLAGS_libxenstore) $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS +=3D $(CFLAGS_libxenlight) $(INIT_XENSTORE_DOMAIN_OBJS): CFLAGS +=3D -include $(XEN_ROOT)/tools/confi= g.h -init-xenstore-domain: LDLIBS +=3D $(call xenlibs-ldlibs,toollog store ctrl= guest light) +init-xenstore-domain: LDLIBS +=3D $(call xenlibs-ldlibs,toollog store ctrl= guest light vchan) =20 INIT_DOM0LESS_OBJS =3D init-dom0less.o init-dom-json.o $(INIT_DOM0LESS_OBJS): CFLAGS +=3D $(CFLAGS_libxentoollog) diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index 4fddcc6f51..0941ad2cf4 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -71,6 +71,7 @@ OBJS-y +=3D libxl.o OBJS-y +=3D libxl_create.o OBJS-y +=3D libxl_dm.o OBJS-y +=3D libxl_pci.o +OBJS-y +=3D libxl_vchan.o OBJS-y +=3D libxl_dom.o OBJS-y +=3D libxl_exec.o OBJS-y +=3D libxl_xshelp.o @@ -170,7 +171,7 @@ LDLIBS-y +=3D $(PTHREAD_LIBS) LDLIBS-y +=3D -lyajl LDLIBS +=3D $(LDLIBS-y) =20 -$(OBJS-y) $(PIC_OBJS) $(LIBXL_TEST_OBJS): CFLAGS +=3D $(CFLAGS_LIBXL) -inc= lude $(XEN_ROOT)/tools/config.h +$(OBJS-y) $(PIC_OBJS) $(LIBXL_TEST_OBJS): CFLAGS +=3D $(CFLAGS_LIBXL) $(CF= LAGS_libxenevtchn) -include $(XEN_ROOT)/tools/config.h $(ACPI_OBJS) $(ACPI_PIC_OBJS): CFLAGS +=3D -I. -DLIBACPI_STDUTILS=3D\"$(CU= RDIR)/libxl_x86_acpi.h\" $(TEST_PROG_OBJS) _libxl.api-for-check: CFLAGS +=3D $(CFLAGS_libxentoollog= ) $(CFLAGS_libxentoolcore) libxl_dom.o libxl_dom.opic: CFLAGS +=3D -I$(XEN_ROOT)/tools # include lib= acpi/x86.h @@ -241,13 +242,13 @@ libxenlight_test.so: $(PIC_OBJS) $(LIBXL_TEST_OBJS) $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB= _LDFLAGS) -o $@ $^ $(LDLIBS) $(APPEND_LDFLAGS) =20 test_%: test_%.o test_common.o libxenlight_test.so - $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenli= ght)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) -lyajl $(APPEND_LDFL= AGS) + $(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenli= ght)) $(LDLIBS_libxentoollog) $(LDLIBS_libxentoolcore) $(LDLIBS_libxenvchan= ) -lyajl $(APPEND_LDFLAGS) =20 libxl-save-helper: $(SAVE_HELPER_OBJS) libxenlight.so $(CC) $(LDFLAGS) -o $@ $(SAVE_HELPER_OBJS) $(LDLIBS_libxentoollog) $(LDLI= BS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxentoolcore) $(APPEND_LDFL= AGS) =20 testidl: testidl.o libxenlight.so - $(CC) $(LDFLAGS) -o $@ testidl.o $(LDLIBS_libxenlight) $(LDLIBS_libxentoo= llog) $(LDLIBS_libxentoolcore) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ testidl.o $(LDLIBS_libxenlight) $(LDLIBS_libxentoo= llog) $(LDLIBS_libxentoolcore) $(LDLIBS_libxenvchan) $(APPEND_LDFLAGS) =20 install:: $(LIBHEADERS) libxl-save-helper $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC_BIN) diff --git a/tools/libs/light/libxl_vchan.c b/tools/libs/light/libxl_vchan.c new file mode 100644 index 0000000000..7611816f52 --- /dev/null +++ b/tools/libs/light/libxl_vchan.c @@ -0,0 +1,488 @@ +/* + * Vchan support for JSON messages processing + * + * Copyright (C) 2021 EPAM Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" +#include "libxl_vchan.h" + +#define VCHAN_EOM "\r\n" +/* + * http://xenbits.xen.org/docs/unstable/misc/xenstore-paths.html + * 1.4.4 Domain Controlled Paths + * 1.4.4.1 ~/data [w] + * A domain writable path. Available for arbitrary domain use. + */ +#define VCHAN_SRV_DIR "/local/domain" + +struct vchan_state { + struct libxenvchan *ctrl; + + /* Server domain ID. */ + libxl_domid domid; + + /* XenStore path of the server with the ring buffer and event channel.= */ + char *xs_path; + + int select_fd; + + /* GC used for state's lifetime allocations, such as rx_buf. */ + libxl__gc *gc; + /* Receive buffer. */ + char *rx_buf; + /* Current allocated size. */ + size_t rx_buf_size; + /* Actual data in the buffer. */ + size_t rx_buf_used; + + /* YAJL generator used to parse and create requests/replies. */ + yajl_gen gen; +}; + +int libxl__vchan_field_add_string(libxl__gc *gc, yajl_gen gen, + const char *field, char *val) +{ + libxl__json_object *result; + + libxl__yajl_gen_asciiz(gen, field); + result =3D libxl__json_object_alloc(gc, JSON_STRING); + result->u.string =3D val; + return libxl__json_object_to_yajl_gen(gc, gen, result); +} + +static libxl__json_object *libxl__vchan_arg_new(libxl__gc *gc, + libxl__json_node_type type, + libxl__json_object *args, + char *key) +{ + libxl__json_map_node *arg; + libxl__json_object *obj; + + obj =3D libxl__json_object_alloc(gc, type); + + GCNEW(arg); + + arg->map_key =3D key; + arg->obj =3D obj; + + flexarray_append(args->u.map, arg); + + return obj; +} + +void libxl__vchan_arg_add_string(libxl__gc *gc, libxl__json_object *args, + char *key, char *val) +{ + libxl__json_object *obj =3D libxl__vchan_arg_new(gc, JSON_STRING, args= , key); + + obj->u.string =3D val; +} + +void libxl__vchan_arg_add_bool(libxl__gc *gc, libxl__json_object *args, + char *key, bool val) +{ + libxl__json_object *obj =3D libxl__vchan_arg_new(gc, JSON_BOOL, args, = key); + + obj->u.b =3D val; +} + +static void reset_yajl_generator(struct vchan_state *state) +{ + yajl_gen_clear(state->gen); + yajl_gen_reset(state->gen, NULL); +} + +void vchan_dump_gen(libxl__gc *gc, yajl_gen gen) +{ + const unsigned char *buf =3D NULL; + size_t len =3D 0; + + yajl_gen_get_buf(gen, &buf, &len); + LOG(DEBUG, "%s\n", buf); +} + +void vchan_dump_state(libxl__gc *gc, struct vchan_state *state) +{ + vchan_dump_gen(gc, state->gen); +} + +/* + * Find a JSON object and store it in o_r. + * return ERROR_NOTFOUND if no object is found. + */ +static int vchan_get_next_msg(libxl__gc *gc, struct vchan_state *state, + libxl__json_object **o_r) +{ + size_t len; + char *end =3D NULL; + const size_t eoml =3D sizeof(VCHAN_EOM) - 1; + libxl__json_object *o =3D NULL; + + if (!state->rx_buf_used) + return ERROR_NOTFOUND; + + /* Search for the end of a message which is CRLF. */ + end =3D memmem(state->rx_buf, state->rx_buf_used, VCHAN_EOM, eoml); + if (!end) + return ERROR_NOTFOUND; + + len =3D (end - state->rx_buf) + eoml; + + LOGD(DEBUG, state->domid, "parsing %zuB: '%.*s'", len, (int)len, + state->rx_buf); + + /* Replace \r by \0 so that libxl__json_parse can use strlen */ + state->rx_buf[len - eoml] =3D '\0'; + + o =3D libxl__json_parse(gc, state->rx_buf); + state->rx_buf_used -=3D len; + if (!o) { + LOGD(ERROR, state->domid, "Parse error"); + /* + * In case of parsing error get back to a known state: + * reset the buffer and continue reading. + */ + return ERROR_INVAL; + } + + memmove(state->rx_buf, state->rx_buf + len, state->rx_buf_used); + + LOGD(DEBUG, state->domid, "JSON object received: %s", JSON(o)); + + *o_r =3D o; + + return 0; +} + +static int vchan_process_packet(libxl__gc *gc, struct vchan_info *vchan, + libxl__json_object **resp_result) +{ + while (true) { + struct vchan_state *state =3D vchan->state; + int rc; + ssize_t r; + + if (!libxenvchan_is_open(state->ctrl)) + return ERROR_FAIL; + + /* Check if the buffer still has space or increase its size. */ + if (state->rx_buf_size - state->rx_buf_used < vchan->receive_buf_s= ize) { + size_t newsize =3D state->rx_buf_size * 2 + vchan->receive_buf= _size; + + if (newsize > vchan->max_buf_size) { + LOGD(ERROR, state->domid, + "receive buffer is too big (%zu > %zu)", + newsize, vchan->max_buf_size); + return ERROR_NOMEM; + } + + state->rx_buf_size =3D newsize; + state->rx_buf =3D libxl__realloc(state->gc, state->rx_buf, + state->rx_buf_size); + } + + do { + libxl__json_object *msg; + + r =3D libxenvchan_read(state->ctrl, + state->rx_buf + state->rx_buf_used, + state->rx_buf_size - state->rx_buf_used); + + if (r < 0) { + LOGED(ERROR, state->domid, "error reading"); + return ERROR_FAIL; + } else if (r =3D=3D 0) + continue; + + LOG(DEBUG, "received %zdB: '%.*s'", r, + (int)r, state->rx_buf + state->rx_buf_used); + + state->rx_buf_used +=3D r; + assert(state->rx_buf_used <=3D state->rx_buf_size); + + /* parse rx buffer to find one json object */ + rc =3D vchan_get_next_msg(gc, state, &msg); + if ((rc =3D=3D ERROR_INVAL) || (rc =3D=3D ERROR_NOTFOUND)) + continue; + if (rc) + return rc; + + if (resp_result) + return vchan->handle_response(gc, msg, resp_result); + else { + reset_yajl_generator(state); + return vchan->handle_request(gc, state->gen, msg); + } + } while (libxenvchan_data_ready(state->ctrl)); + } + + return 0; +} + +static int vchan_write(libxl__gc *gc, struct vchan_state *state, char *cmd) +{ + size_t len; + int ret; + + len =3D strlen(cmd); + while (len) { + ret =3D libxenvchan_write(state->ctrl, cmd, len); + if (ret < 0) { + LOGE(ERROR, "vchan write failed"); + return ERROR_FAIL; + } + cmd +=3D ret; + len -=3D ret; + } + return 0; +} + +libxl__json_object *vchan_send_command(libxl__gc *gc, struct vchan_info *v= chan, + char *cmd, libxl__json_object *args) +{ + libxl__json_object *result; + char *request; + int ret; + + reset_yajl_generator(vchan->state); + request =3D vchan->prepare_request(gc, vchan->state->gen, cmd, args); + if (!request) + return NULL; + + ret =3D vchan_write(gc, vchan->state, request); + if (ret < 0) + return NULL; + + ret =3D vchan_write(gc, vchan->state, VCHAN_EOM); + if (ret < 0) + return NULL; + + ret =3D vchan_process_packet(gc, vchan, &result); + if (ret < 0) + return NULL; + + return result; +} + +int vchan_process_command(libxl__gc *gc, struct vchan_info *vchan) +{ + char *json_str; + int ret; + + ret =3D vchan_process_packet(gc, vchan, NULL); + if (ret) + return ret; + + json_str =3D vchan->prepare_response(gc, vchan->state->gen); + if (!json_str) + return ERROR_INVAL; + + ret =3D vchan_write(gc, vchan->state, json_str); + if (ret) + return ret; + + return vchan_write(gc, vchan->state, VCHAN_EOM); +} + +static libxl_domid vchan_find_server(libxl__gc *gc, char *xs_dir, char *xs= _file) +{ + char **domains; + unsigned int i, n; + libxl_domid domid =3D DOMID_INVALID; + + domains =3D libxl__xs_directory(gc, XBT_NULL, xs_dir, &n); + if (domains =3D=3D NULL) + goto out; + + for (i =3D 0; i < n; i++) { + const char *tmp; + int d; + + if (sscanf(domains[i], "%d", &d) !=3D 1) + continue; + + tmp =3D libxl__xs_read(gc, XBT_NULL, + GCSPRINTF("%s/%d/data/%s", xs_dir, d, xs_file= )); + /* Found the domain where the server lives. */ + if (tmp) { + domid =3D d; + break; + } + } + +out: + return domid; +} + +static int vchan_init_client(libxl__gc *gc, struct vchan_state *state, + bool is_server) +{ + if (is_server) { + state->ctrl =3D libxenvchan_server_init(NULL, state->domid, + state->xs_path, 0, 0); + if (!state->ctrl) { + perror("Couldn't initialize vchan server"); + exit(1); + } + + } else { + state->ctrl =3D libxenvchan_client_init(CTX->lg, state->domid, + state->xs_path); + if (!state->ctrl) { + LOGE(ERROR, "Couldn't initialize vchan client"); + return ERROR_FAIL; + } + } + + state->ctrl->blocking =3D 1; + state->select_fd =3D libxenvchan_fd_for_select(state->ctrl); + if (state->select_fd < 0) { + LOGE(ERROR, "Couldn't read file descriptor for vchan client"); + return ERROR_FAIL; + } + + LOG(DEBUG, "Initialized vchan %s, XenSore at %s", + is_server ? "server" : "client", state->xs_path); + + return 0; +} + +struct vchan_state *vchan_init_new_state(libxl__gc *gc, libxl_domid domid, + char *vchan_xs_path, bool is_serv= er) +{ + struct vchan_state *state; + yajl_gen gen; + int ret; + + gen =3D libxl_yajl_gen_alloc(NULL); + if (!gen) { + LOGE(ERROR, "Failed to allocate yajl generator"); + return NULL; + } + +#if HAVE_YAJL_V2 + /* Disable beautify for data */ + yajl_gen_config(gen, yajl_gen_beautify, 0); +#endif + + state =3D libxl__zalloc(gc, sizeof(*state)); + state->domid =3D domid; + state->xs_path =3D vchan_xs_path; + state->gc =3D gc; + ret =3D vchan_init_client(gc, state, is_server); + if (ret) { + state =3D NULL; + yajl_gen_free(gen); + } + + state->gen =3D gen; + + return state; +} + +char *vchan_get_server_xs_path(libxl__gc *gc, libxl_domid domid, char *srv= _name) +{ + return GCSPRINTF(VCHAN_SRV_DIR "/%d/data/%s", domid, srv_name); +} + +/* + * Wait for the server to create the ring and event channel: + * since the moment we create a XS folder to the moment we start + * watching it the server may have already created the ring and + * event channel entries. Thus, we cannot watch reliably here without + * races, so poll for both entries to be created. + */ +static int vchan_wait_server_available(libxl__gc *gc, const char *xs_path) +{ + char *xs_ring, *xs_evt; + int timeout_ms =3D 5000; + + xs_ring =3D GCSPRINTF("%s/ring-ref", xs_path); + xs_evt =3D GCSPRINTF("%s/event-channel", xs_path); + + while (timeout_ms) { + unsigned int len; + void *file; + int entries =3D 0; + + file =3D xs_read(CTX->xsh, XBT_NULL, xs_ring, &len); + if (file) { + entries++; + free(file); + } + + file =3D xs_read(CTX->xsh, XBT_NULL, xs_evt, &len); + if (file) { + entries++; + free(file); + } + + if (entries =3D=3D 2) + return 0; + + timeout_ms -=3D 10; + usleep(10000); + } + + return ERROR_TIMEDOUT; +} + +struct vchan_state *vchan_new_client(libxl__gc *gc, char *srv_name) +{ + libxl_domid domid; + char *xs_path, *vchan_xs_path; + libxl_uuid uuid; + libxl_ctx *ctx =3D libxl__gc_owner(gc); + + domid =3D vchan_find_server(gc, VCHAN_SRV_DIR, srv_name); + if (domid =3D=3D DOMID_INVALID) { + LOGE(ERROR, "Can't find vchan server"); + return NULL; + } + + xs_path =3D vchan_get_server_xs_path(gc, domid, srv_name); + LOG(DEBUG, "vchan server at %s\n", xs_path); + + /* Generate unique client id. */ + libxl_uuid_generate(&uuid); + + vchan_xs_path =3D GCSPRINTF("%s/" LIBXL_UUID_FMT, xs_path, + LIBXL_UUID_BYTES((uuid))); + + if (!xs_mkdir(ctx->xsh, XBT_NULL, vchan_xs_path)) { + LOG(ERROR, "Can't create xs_dir at %s", vchan_xs_path); + return NULL; + } + + if (vchan_wait_server_available(gc, vchan_xs_path)) { + LOG(ERROR, "Failed to wait for the server to come up at %s", + vchan_xs_path); + return NULL; + } + + return vchan_init_new_state(gc, domid, vchan_xs_path, false); +} + +void vchan_fini_one(libxl__gc *gc, struct vchan_state *state) +{ + if (!state) + return; + + LOG(DEBUG, "Closing vchan"); + libxenvchan_close(state->ctrl); + + yajl_gen_free(state->gen); +} diff --git a/tools/libs/light/libxl_vchan.h b/tools/libs/light/libxl_vchan.h new file mode 100644 index 0000000000..0968875298 --- /dev/null +++ b/tools/libs/light/libxl_vchan.h @@ -0,0 +1,92 @@ +/* + Common definitions for JSON messages processing by vchan + Copyright (C) 2021 EPAM Systems Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; If not, see . +*/ + +#ifndef LIBXL_VCHAN_H +#define LIBXL_VCHAN_H + +#include + +struct vchan_state; + +struct vchan_info { + struct vchan_state *state; + + /* Process request and produce the result by adding json-objects to ge= n .*/ + int (*handle_request)(libxl__gc *gc, yajl_gen gen, + const libxl__json_object *request); + /* Convert the prepared response into JSON string. */ + char *(*prepare_response)(libxl__gc *gc, yajl_gen gen); + + /* Prepare request as JSON string which will be sent. */ + char *(*prepare_request)(libxl__gc *gc, yajl_gen gen, char *request, + libxl__json_object *args); + /* Handle response and produce the output suitable for the requester. = */ + int (*handle_response)(libxl__gc *gc, const libxl__json_object *respon= se, + libxl__json_object **result); + + /* Handle new client connection on the server side. */ + int (*handle_new_client)(libxl__gc *gc); + + /* Buffer info. */ + size_t receive_buf_size; + size_t max_buf_size; +}; + +int libxl__vchan_field_add_string(libxl__gc *gc, yajl_gen hand, + const char *field, char *val); + +static inline libxl__json_object *libxl__vchan_start_args(libxl__gc *gc) +{ + return libxl__json_object_alloc(gc, JSON_MAP); +} + +void libxl__vchan_arg_add_string(libxl__gc *gc, libxl__json_object *args, + char *key, char *val); +void libxl__vchan_arg_add_bool(libxl__gc *gc, libxl__json_object *args, + char *key, bool val); + +libxl__json_object *vchan_send_command(libxl__gc *gc, struct vchan_info *v= chan, + char *cmd, libxl__json_object *args= ); + +void vchan_reset_generator(struct vchan_state *state); + +int vchan_process_command(libxl__gc *gc, struct vchan_info *vchan); + +char *vchan_get_server_xs_path(libxl__gc *gc, libxl_domid domid, char *srv= _name); + +struct vchan_state *vchan_init_new_state(libxl__gc *gc, libxl_domid domid, + char *vchan_xs_path, bool is_serv= er); + +struct vchan_state *vchan_new_client(libxl__gc *gc, char *srv_name); + +void vchan_fini_one(libxl__gc *gc, struct vchan_state *state); + +void vchan_dump_state(libxl__gc *gc, struct vchan_state *state); +void vchan_dump_gen(libxl__gc *gc, yajl_gen gen); + +#endif /* LIBXL_VCHAN_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "linux" + * indent-tabs-mode: t + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/tools/xl/Makefile b/tools/xl/Makefile index 5f7aa5f46c..da4591b6a9 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -15,6 +15,7 @@ LDFLAGS +=3D $(PTHREAD_LDFLAGS) CFLAGS_XL +=3D $(CFLAGS_libxenlight) CFLAGS_XL +=3D $(CFLAGS_libxenutil) CFLAGS_XL +=3D -Wshadow +CFLAGS_XL +=3D $(CFLAGS_libxenvchan) =20 XL_OBJS-$(CONFIG_X86) =3D xl_psr.o XL_OBJS =3D xl.o xl_cmdtable.o xl_sxp.o xl_utils.o $(XL_OBJS-y) @@ -33,7 +34,7 @@ $(XL_OBJS): CFLAGS +=3D -include $(XEN_ROOT)/tools/config= .h # libxl_json.h needs i all: xl =20 xl: $(XL_OBJS) - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlig= ht) $(LDLIBS_libxentoollog) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlig= ht) $(LDLIBS_libxentoollog) $(LDLIBS_libxenvchan) -lyajl $(APPEND_LDFLAGS) =20 .PHONY: install install: all --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782311; cv=none; d=zohomail.com; s=zohoarc; b=cYiUq5t7HI1kbCUe2QSUpZ8SnysejEdiKRYhndB552ri/Da6yqVIhNlM1DNs2fuHSgl9W1ebvvransvFwMnPUycKWqnfXWG22X8NAABpWZrIUcUBMi7ta8g8G7/eOcmnhY8aJSwcBkFPBtS1oB2B1eJtFoTze6f6vExrAU6yia8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782311; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=OoECGyweNl38ENJbt1BJclW8weoldKxLjvYMq4gaQIY=; b=OWQ/+Xo8o9laY/7nhgD1mNL+RbkBw9y808v6ZD1k0uWOux6C800p03JvLFLDdm8ev/HkVwB4SEgRsfizJ4WpPO56apruXMEVhSkbtGHp9nyaMxVioi9WxO9qiSubntxjFJaEDRpappaZzQBdkMZKfAafXJG5SEO9+K21XscvOYc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782311389432.592379601959; Sun, 15 Jan 2023 03:31:51 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477860.740780 (Exim 4.92) (envelope-from ) id 1pH1ER-0005Qk-G4; Sun, 15 Jan 2023 11:31:23 +0000 Received: by outflank-mailman (output) from mailman id 477860.740780; Sun, 15 Jan 2023 11:31:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ER-0005QY-BP; Sun, 15 Jan 2023 11:31:23 +0000 Received: by outflank-mailman (input) for mailman id 477860; Sun, 15 Jan 2023 11:31:21 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EP-0004ci-BU for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:21 +0000 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [2a00:1450:4864:20::631]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 211d3372-94c8-11ed-91b6-6bf2151ebd3b; Sun, 15 Jan 2023 12:31:18 +0100 (CET) Received: by mail-ej1-x631.google.com with SMTP id u9so62072714ejo.0 for ; Sun, 15 Jan 2023 03:31:18 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:17 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 211d3372-94c8-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=OoECGyweNl38ENJbt1BJclW8weoldKxLjvYMq4gaQIY=; b=FdIGONtJ4A0wRis3AMTpplLlFdc1lrp2/W8tLHS9CpuC5oF63GuUNQkKMR9MoMawsr N1BLSlUWHG73eDAO5bVunbosrofKFfsthEC98hMurnKW8YqodK3S6+sgvHIko9zmvI1z s+yLsbpIE4uR5/g6AUS8HMBDox0iSRe57dQr7SqtIWdDcOpWABe5xddna/s64mmBLjx0 Q/AKZt+GBGX/LbwgS4b/7qbawBPBHpK3R32GEt+5S3votqxN9cHKn2mm5wSwtcbjBrtx Eiy4Y996dZTmMQA4GwgfTF7Q8grNH5K8YFR9R6JFcgz+J5VdMPgEMmrHSOffrMBajLgo FJrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OoECGyweNl38ENJbt1BJclW8weoldKxLjvYMq4gaQIY=; b=Nn3d7ZEGlUmxkyd7+PSdBb3Be8/uBx5V5Un/vibi8D0cdOtXBDCQJW+xm9HEVBHTGm PKNTczsnTETPR+PbJNh3MnLbgv20VD7pW2bkNndd8NBJ715bHV2BF7ntQKiQzzgDtNpz eBYj6P9M1ozT4nw2YwfEybAcPbu95S6PKKRARpyn7o4n0djeG7Q7IJyqieYqCH6tGcy7 Ic3mV/atOkbegop456Ft3Bojus+937fyp1aKUR89tpZcqR7Svuy+ZG2O9d7g08m8+/gN rgB6U4u3Zj+nWoXzN6hHwuBudgdIK81TND7yM+Z1FIf/+F0LM/FSaPCl5Bfh5OWiPMc0 qwBQ== X-Gm-Message-State: AFqh2kqFQBki/1ojvA0BPp8b35ENTnxi4/Q2TxHDvKfcc25l/RzIx1Y3 L0fuhxbPMEfpshGqZliwrJsx04y4ikyEpEZl X-Google-Smtp-Source: AMrXdXvvnmtSD9Recy2etH1LSWO8CG/k2xh1sEFNtstEDPuGMLLxqEl1vIXxpIxSdIOBGAlN9jyX6A== X-Received: by 2002:a17:907:900d:b0:84d:4e9b:ace5 with SMTP id ay13-20020a170907900d00b0084d4e9bace5mr17021518ejc.67.1673782277723; Sun, 15 Jan 2023 03:31:17 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross , Oleksandr Andrushchenko , Anastasiia Lukianenko Subject: [RFC PATCH v3 03/10] tools/xl: Add pcid daemon to xl Date: Sun, 15 Jan 2023 13:31:04 +0200 Message-Id: <20230115113111.1207605-4-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782312840100012 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Add draft version of pcid server (based on vchan-node2), which can receive messages from the client. Add essential functionality to handle pcid protocol: - define required constants - prepare for handling remote requests - prepare and send an error packet Signed-off-by: Dmytro Semenets Signed-off-by: Oleksandr Andrushchenko Signed-off-by: Anastasiia Lukianenko --- tools/configure | 8 +- tools/configure.ac | 1 + tools/hotplug/FreeBSD/rc.d/xlpcid.in | 75 +++ tools/hotplug/Linux/init.d/xlpcid.in | 76 ++++ tools/hotplug/Linux/systemd/Makefile | 1 + .../hotplug/Linux/systemd/xenpcid.service.in | 10 + tools/hotplug/NetBSD/rc.d/xlpcid.in | 75 +++ tools/include/pcid.h | 94 ++++ tools/libs/light/Makefile | 1 + tools/libs/light/libxl_pci.c | 128 ++++++ tools/libs/light/libxl_pcid.c | 428 ++++++++++++++++++ tools/xl/Makefile | 4 +- tools/xl/xl.h | 1 + tools/xl/xl_cmdtable.c | 7 + tools/xl/xl_pcid.c | 81 ++++ 15 files changed, 986 insertions(+), 4 deletions(-) create mode 100644 tools/hotplug/FreeBSD/rc.d/xlpcid.in create mode 100644 tools/hotplug/Linux/init.d/xlpcid.in create mode 100644 tools/hotplug/Linux/systemd/xenpcid.service.in create mode 100644 tools/hotplug/NetBSD/rc.d/xlpcid.in create mode 100644 tools/include/pcid.h create mode 100644 tools/libs/light/libxl_pcid.c create mode 100644 tools/xl/xl_pcid.c diff --git a/tools/configure b/tools/configure index dae377c982..0cd6edb6ca 100755 --- a/tools/configure +++ b/tools/configure @@ -2455,7 +2455,7 @@ ac_compiler_gnu=3D$ac_cv_c_compiler_gnu =20 =20 =20 -ac_config_files=3D"$ac_config_files ../config/Tools.mk hotplug/common/hotp= lugpath.sh hotplug/FreeBSD/rc.d/xencommons hotplug/FreeBSD/rc.d/xendriverdo= main hotplug/Linux/init.d/sysconfig.xencommons hotplug/Linux/init.d/sysconf= ig.xendomains hotplug/Linux/init.d/xen-watchdog hotplug/Linux/init.d/xencom= mons hotplug/Linux/init.d/xendomains hotplug/Linux/init.d/xendriverdomain h= otplug/Linux/launch-xenstore hotplug/Linux/vif-setup hotplug/Linux/xen-hotp= lug-common.sh hotplug/Linux/xendomains hotplug/NetBSD/rc.d/xencommons hotpl= ug/NetBSD/rc.d/xendriverdomain ocaml/libs/xs/paths.ml ocaml/xenstored/paths= .ml ocaml/xenstored/oxenstored.conf" +ac_config_files=3D"$ac_config_files ../config/Tools.mk hotplug/common/hotp= lugpath.sh hotplug/FreeBSD/rc.d/xencommons hotplug/FreeBSD/rc.d/xendriverdo= main hotplug/FreeBSD/rc.d/xlpcid hotplug/Linux/init.d/sysconfig.xencommons = hotplug/Linux/init.d/sysconfig.xendomains hotplug/Linux/init.d/xlpcid hotpl= ug/Linux/init.d/xen-watchdog hotplug/Linux/init.d/xencommons hotplug/Linux/= init.d/xendomains hotplug/Linux/init.d/xendriverdomain hotplug/Linux/launch= -xenstore hotplug/Linux/vif-setup hotplug/Linux/xen-hotplug-common.sh hotpl= ug/Linux/xendomains hotplug/NetBSD/rc.d/xencommons hotplug/NetBSD/rc.d/xend= riverdomain hotplug/NetBSD/rc.d/xlpcid ocaml/libs/xs/paths.ml ocaml/xenstor= ed/paths.ml ocaml/xenstored/oxenstored.conf" =20 ac_config_headers=3D"$ac_config_headers config.h" =20 @@ -10081,7 +10081,7 @@ fi =20 if test "x$systemd" =3D "xy"; then : =20 - ac_config_files=3D"$ac_config_files hotplug/Linux/systemd/proc-xen.mou= nt hotplug/Linux/systemd/xen-init-dom0.service hotplug/Linux/systemd/xen-qe= mu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hot= plug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.ser= vice hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xe= nstored.service" + ac_config_files=3D"$ac_config_files hotplug/Linux/systemd/proc-xen.mou= nt hotplug/Linux/systemd/xen-init-dom0.service hotplug/Linux/systemd/xen-qe= mu-dom0-disk-backend.service hotplug/Linux/systemd/xen-watchdog.service hot= plug/Linux/systemd/xenconsoled.service hotplug/Linux/systemd/xendomains.ser= vice hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xe= nstored.service hotplug/Linux/systemd/xenpcid.service" =20 =20 fi @@ -10946,8 +10946,10 @@ do "hotplug/common/hotplugpath.sh") CONFIG_FILES=3D"$CONFIG_FILES hotplug= /common/hotplugpath.sh" ;; "hotplug/FreeBSD/rc.d/xencommons") CONFIG_FILES=3D"$CONFIG_FILES hotpl= ug/FreeBSD/rc.d/xencommons" ;; "hotplug/FreeBSD/rc.d/xendriverdomain") CONFIG_FILES=3D"$CONFIG_FILES = hotplug/FreeBSD/rc.d/xendriverdomain" ;; + "hotplug/FreeBSD/rc.d/xlpcid") CONFIG_FILES=3D"$CONFIG_FILES hotplug/F= reeBSD/rc.d/xlpcid" ;; "hotplug/Linux/init.d/sysconfig.xencommons") CONFIG_FILES=3D"$CONFIG_F= ILES hotplug/Linux/init.d/sysconfig.xencommons" ;; "hotplug/Linux/init.d/sysconfig.xendomains") CONFIG_FILES=3D"$CONFIG_F= ILES hotplug/Linux/init.d/sysconfig.xendomains" ;; + "hotplug/Linux/init.d/xlpcid") CONFIG_FILES=3D"$CONFIG_FILES hotplug/L= inux/init.d/xlpcid" ;; "hotplug/Linux/init.d/xen-watchdog") CONFIG_FILES=3D"$CONFIG_FILES hot= plug/Linux/init.d/xen-watchdog" ;; "hotplug/Linux/init.d/xencommons") CONFIG_FILES=3D"$CONFIG_FILES hotpl= ug/Linux/init.d/xencommons" ;; "hotplug/Linux/init.d/xendomains") CONFIG_FILES=3D"$CONFIG_FILES hotpl= ug/Linux/init.d/xendomains" ;; @@ -10958,6 +10960,7 @@ do "hotplug/Linux/xendomains") CONFIG_FILES=3D"$CONFIG_FILES hotplug/Linu= x/xendomains" ;; "hotplug/NetBSD/rc.d/xencommons") CONFIG_FILES=3D"$CONFIG_FILES hotplu= g/NetBSD/rc.d/xencommons" ;; "hotplug/NetBSD/rc.d/xendriverdomain") CONFIG_FILES=3D"$CONFIG_FILES h= otplug/NetBSD/rc.d/xendriverdomain" ;; + "hotplug/NetBSD/rc.d/xlpcid") CONFIG_FILES=3D"$CONFIG_FILES hotplug/Ne= tBSD/rc.d/xlpcid" ;; "ocaml/libs/xs/paths.ml") CONFIG_FILES=3D"$CONFIG_FILES ocaml/libs/xs/= paths.ml" ;; "ocaml/xenstored/paths.ml") CONFIG_FILES=3D"$CONFIG_FILES ocaml/xensto= red/paths.ml" ;; "ocaml/xenstored/oxenstored.conf") CONFIG_FILES=3D"$CONFIG_FILES ocaml= /xenstored/oxenstored.conf" ;; @@ -10970,6 +10973,7 @@ do "hotplug/Linux/systemd/xendomains.service") CONFIG_FILES=3D"$CONFIG_FI= LES hotplug/Linux/systemd/xendomains.service" ;; "hotplug/Linux/systemd/xendriverdomain.service") CONFIG_FILES=3D"$CONF= IG_FILES hotplug/Linux/systemd/xendriverdomain.service" ;; "hotplug/Linux/systemd/xenstored.service") CONFIG_FILES=3D"$CONFIG_FIL= ES hotplug/Linux/systemd/xenstored.service" ;; + "hotplug/Linux/systemd/xenpcid.service") CONFIG_FILES=3D"$CONFIG_FILES= hotplug/Linux/systemd/xenpcid.service" ;; =20 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac diff --git a/tools/configure.ac b/tools/configure.ac index 3a2f6a2da9..d2b22e94a9 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -489,6 +489,7 @@ AS_IF([test "x$systemd" =3D "xy"], [ hotplug/Linux/systemd/xendomains.service hotplug/Linux/systemd/xendriverdomain.service hotplug/Linux/systemd/xenstored.service + hotplug/Linux/systemd/xenpcid.service ]) ]) =20 diff --git a/tools/hotplug/FreeBSD/rc.d/xlpcid.in b/tools/hotplug/FreeBSD/r= c.d/xlpcid.in new file mode 100644 index 0000000000..2817bfaeed --- /dev/null +++ b/tools/hotplug/FreeBSD/rc.d/xlpcid.in @@ -0,0 +1,75 @@ +#! /bin/bash +# +# xlpcid +# +# description: Run xlpcid daemon +### BEGIN INIT INFO +# Provides: xlpcid +# Short-Description: Start/stop xlpcid +# Description: Run xlpcid daemon +### END INIT INFO +# + +. @XEN_SCRIPT_DIR@/hotplugpath.sh + +xencommons_config=3D@CONFIG_DIR@/@CONFIG_LEAF_DIR@ + +test -f $xencommons_config/xencommons && . $xencommons_config/xencommons + +XLPCID_PIDFILE=3D"@XEN_RUN_DIR@/xlpcid.pid" + +# Source function library. +if [ -e /etc/init.d/functions ] ; then + . /etc/init.d/functions +elif [ -e /lib/lsb/init-functions ] ; then + . /lib/lsb/init-functions + success () { + log_success_msg $* + } + failure () { + log_failure_msg $* + } +else + success () { + echo $* + } + failure () { + echo $* + } +fi + +start() { + echo Starting xl pcid... + ${sbindir}/xl pcid --pidfile=3D$XLPCID_PIDFILE $XLPCID_ARGS +} + +stop() { + echo Stopping xl pcid... + if read 2>/dev/null <$XLPCID_PIDFILE pid; then + kill $pid + while kill -9 $pid >/dev/null 2>&1; do sleep 1; done + rm -f $XLPCID_PIDFILE + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + ;; + condrestart) + stop + start + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart}" + exit 1 +esac diff --git a/tools/hotplug/Linux/init.d/xlpcid.in b/tools/hotplug/Linux/ini= t.d/xlpcid.in new file mode 100644 index 0000000000..dce660098c --- /dev/null +++ b/tools/hotplug/Linux/init.d/xlpcid.in @@ -0,0 +1,76 @@ +#! /bin/bash +# +# xlpcid +# +# description: Run xlpcid daemon +### BEGIN INIT INFO +# Provides: xlpcid +# Short-Description: Start/stop xlpcid +# Description: Run xlpcid daemon +### END INIT INFO +# + +. @XEN_SCRIPT_DIR@/hotplugpath.sh + +xencommons_config=3D@CONFIG_DIR@/@CONFIG_LEAF_DIR@ + +test -f $xencommons_config/xencommons && . $xencommons_config/xencommons + +XLPCID_PIDFILE=3D"@XEN_RUN_DIR@/xlpcid.pid" + +# Source function library. +if [ -e /etc/init.d/functions ] ; then + . /etc/init.d/functions +elif [ -e /lib/lsb/init-functions ] ; then + . /lib/lsb/init-functions + success () { + log_success_msg $* + } + failure () { + log_failure_msg $* + } +else + success () { + echo $* + } + failure () { + echo $* + } +fi + +start() { + echo Starting xl pcid... + ${sbindir}/xl pcid --pidfile=3D$XLPCID_PIDFILE $XLPCID_ARGS +} + +stop() { + echo Stopping xl pcid... + if read 2>/dev/null <$XLPCID_PIDFILE pid; then + kill $pid + while kill -9 $pid >/dev/null 2>&1; do sleep 1; done + rm -f $XLPCID_PIDFILE + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + ;; + condrestart) + stop + start + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart}" + exit 1 +esac + diff --git a/tools/hotplug/Linux/systemd/Makefile b/tools/hotplug/Linux/sys= temd/Makefile index e29889156d..49f0f87296 100644 --- a/tools/hotplug/Linux/systemd/Makefile +++ b/tools/hotplug/Linux/systemd/Makefile @@ -12,6 +12,7 @@ XEN_SYSTEMD_SERVICE +=3D xendomains.service XEN_SYSTEMD_SERVICE +=3D xen-watchdog.service XEN_SYSTEMD_SERVICE +=3D xen-init-dom0.service XEN_SYSTEMD_SERVICE +=3D xendriverdomain.service +XEN_SYSTEMD_SERVICE +=3D xenpcid.service =20 ALL_XEN_SYSTEMD :=3D $(XEN_SYSTEMD_MODULES) \ $(XEN_SYSTEMD_MOUNT) \ diff --git a/tools/hotplug/Linux/systemd/xenpcid.service.in b/tools/hotplug= /Linux/systemd/xenpcid.service.in new file mode 100644 index 0000000000..49c57f635a --- /dev/null +++ b/tools/hotplug/Linux/systemd/xenpcid.service.in @@ -0,0 +1,10 @@ +[Unit] +Description=3DXen PCI host daemon +ConditionVirtualization=3Dxen + +[Service] +Type=3Dforking +ExecStart=3D@sbindir@/xl pcid + +[Install] +WantedBy=3Dmulti-user.target diff --git a/tools/hotplug/NetBSD/rc.d/xlpcid.in b/tools/hotplug/NetBSD/rc.= d/xlpcid.in new file mode 100644 index 0000000000..2817bfaeed --- /dev/null +++ b/tools/hotplug/NetBSD/rc.d/xlpcid.in @@ -0,0 +1,75 @@ +#! /bin/bash +# +# xlpcid +# +# description: Run xlpcid daemon +### BEGIN INIT INFO +# Provides: xlpcid +# Short-Description: Start/stop xlpcid +# Description: Run xlpcid daemon +### END INIT INFO +# + +. @XEN_SCRIPT_DIR@/hotplugpath.sh + +xencommons_config=3D@CONFIG_DIR@/@CONFIG_LEAF_DIR@ + +test -f $xencommons_config/xencommons && . $xencommons_config/xencommons + +XLPCID_PIDFILE=3D"@XEN_RUN_DIR@/xlpcid.pid" + +# Source function library. +if [ -e /etc/init.d/functions ] ; then + . /etc/init.d/functions +elif [ -e /lib/lsb/init-functions ] ; then + . /lib/lsb/init-functions + success () { + log_success_msg $* + } + failure () { + log_failure_msg $* + } +else + success () { + echo $* + } + failure () { + echo $* + } +fi + +start() { + echo Starting xl pcid... + ${sbindir}/xl pcid --pidfile=3D$XLPCID_PIDFILE $XLPCID_ARGS +} + +stop() { + echo Stopping xl pcid... + if read 2>/dev/null <$XLPCID_PIDFILE pid; then + kill $pid + while kill -9 $pid >/dev/null 2>&1; do sleep 1; done + rm -f $XLPCID_PIDFILE + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + status) + ;; + condrestart) + stop + start + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart}" + exit 1 +esac diff --git a/tools/include/pcid.h b/tools/include/pcid.h new file mode 100644 index 0000000000..6506b18d25 --- /dev/null +++ b/tools/include/pcid.h @@ -0,0 +1,94 @@ +/* + Common definitions for Xen PCI client-server protocol. + Copyright (C) 2021 EPAM Systems Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; If not, see . +*/ + +#ifndef PCID_H +#define PCID_H + +#define PCID_SRV_NAME "pcid" +#define PCID_XS_TOKEN "pcid-token" + +#define PCI_RECEIVE_BUFFER_SIZE 4096 +#define PCI_MAX_SIZE_RX_BUF MB(1) + +/* + *************************************************************************= ****** + * Common request and response structures used be the pcid remote protocol= are + * described below. + *************************************************************************= ****** + * Request: + * +-------------+--------------+-----------------------------------------= -----+ + * | Field | Type | Comment = | + * +-------------+--------------+-----------------------------------------= -----+ + * | cmd | string | String identifying the command = | + * +-------------+--------------+-----------------------------------------= -----+ + * + * Response: + * +-------------+--------------+-----------------------------------------= -----+ + * | Field | Type | Comment = | + * +-------------+--------------+-----------------------------------------= -----+ + * | resp | string | Command string as in the request = | + * +-------------+--------------+-----------------------------------------= -----+ + * | error | string | "okay", "failed" = | + * +-------------+--------------+-----------------------------------------= -----+ + * | error_desc | string | Optional error description string = | + * +-------------+--------------+-----------------------------------------= -----+ + * + * Notes. + * 1. Every request and response must contain the above mandatory structur= es. + * 2. In case if a bad packet or an unknown command received by the server= side + * a valid reply with the corresponding error code must be sent to the cli= ent. + * + * Requests and responses, which require SBDF as part of their payload, mu= st + * use the following convention for encoding SBDF value: + * + * pci_device object: + * +-------------+--------------+-----------------------------------------= -----+ + * | Field | Type | Comment = | + * +-------------+--------------+-----------------------------------------= -----+ + * | sbdf | string | SBDF string in form SSSS:BB:DD.F = | + * +-------------+--------------+-----------------------------------------= -----+ + */ + +#define PCID_MSG_FIELD_CMD "cmd" + +#define PCID_MSG_FIELD_RESP "resp" +#define PCID_MSG_FIELD_ERR "error" +#define PCID_MSG_FIELD_ERR_DESC "error_desc" + +/* pci_device object fields. */ +#define PCID_MSG_FIELD_SBDF "sbdf" + +#define PCID_MSG_ERR_OK "okay" +#define PCID_MSG_ERR_FAILED "failed" +#define PCID_MSG_ERR_NA "NA" + +#define PCID_SBDF_FMT "%04x:%02x:%02x.%01x" + +int libxl_pcid_process(libxl_ctx *ctx); + +#endif /* PCID_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "linux" + * indent-tabs-mode: t + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index 0941ad2cf4..72997eaac9 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -71,6 +71,7 @@ OBJS-y +=3D libxl.o OBJS-y +=3D libxl_create.o OBJS-y +=3D libxl_dm.o OBJS-y +=3D libxl_pci.o +OBJS-y +=3D libxl_pcid.o OBJS-y +=3D libxl_vchan.o OBJS-y +=3D libxl_dom.o OBJS-y +=3D libxl_exec.o diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index f4c4f17545..b0c6de88ba 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -18,6 +18,10 @@ =20 #include "libxl_internal.h" =20 +#include + +#include "libxl_vchan.h" + #define PCI_BDF "%04x:%02x:%02x.%01x" #define PCI_BDF_SHORT "%02x:%02x.%01x" #define PCI_BDF_VDEVFN "%04x:%02x:%02x.%01x@%02x" @@ -25,6 +29,130 @@ #define PCI_BDF_XSPATH "%04x-%02x-%02x-%01x" #define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x" =20 +static int pci_handle_response(libxl__gc *gc, + const libxl__json_object *response, + libxl__json_object **result) +{ + const libxl__json_object *command_obj; + const libxl__json_object *err_obj; + char *command_name; + int ret =3D 0; + + *result =3D NULL; + + command_obj =3D libxl__json_map_get(PCID_MSG_FIELD_RESP, response, JSO= N_STRING); + if (!command_obj) { + /* This is an unsupported or bad response. */ + return 0; + } + + err_obj =3D libxl__json_map_get(PCID_MSG_FIELD_ERR, response, JSON_STR= ING); + if (!err_obj) { + /* Bad packet without error code field. */ + return 0; + } + + if (strcmp(err_obj->u.string, PCID_MSG_ERR_OK) !=3D 0) { + const libxl__json_object *err_desc_obj; + + /* The response may contain an optional error string. */ + err_desc_obj =3D libxl__json_map_get(PCID_MSG_FIELD_ERR_DESC, + response, JSON_STRING); + if (err_desc_obj) + LOG(ERROR, "%s", err_desc_obj->u.string); + else + LOG(ERROR, "%s", err_obj->u.string); + return ERROR_FAIL; + } + + command_name =3D command_obj->u.string; + LOG(DEBUG, "command: %s", command_name); + + return ret; +} + +#define CONVERT_YAJL_GEN_TO_STATUS(gen) \ + ((gen) =3D=3D yajl_gen_status_ok ? yajl_status_ok : yajl_status_error) + +static char *pci_prepare_request(libxl__gc *gc, yajl_gen gen, char *cmd, + libxl__json_object *args) +{ + const unsigned char *buf; + libxl_yajl_length len; + yajl_gen_status sts; + yajl_status ret; + char *request =3D NULL; + int rc; + + ret =3D CONVERT_YAJL_GEN_TO_STATUS(yajl_gen_map_open(gen)); + if (ret !=3D yajl_status_ok) + return NULL; + + rc =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_CMD, cmd); + if (rc) + return NULL; + + if (args) { + int idx =3D 0; + libxl__json_map_node *node =3D NULL; + + assert(args->type =3D=3D JSON_MAP); + for (idx =3D 0; idx < args->u.map->count; idx++) { + if (flexarray_get(args->u.map, idx, (void**)&node) !=3D 0) + break; + + ret =3D CONVERT_YAJL_GEN_TO_STATUS(libxl__yajl_gen_asciiz(gen,= node->map_key)); + if (ret !=3D yajl_status_ok) + return NULL; + ret =3D libxl__json_object_to_yajl_gen(gc, gen, node->obj); + if (ret !=3D yajl_status_ok) + return NULL; + } + } + ret =3D CONVERT_YAJL_GEN_TO_STATUS(yajl_gen_map_close(gen)); + if (ret !=3D yajl_status_ok) + return NULL; + + sts =3D yajl_gen_get_buf(gen, &buf, &len); + if (sts !=3D yajl_gen_status_ok) + return NULL; + + request =3D libxl__sprintf(gc, "%s", buf); + + vchan_dump_gen(gc, gen); + + return request; +} + +struct vchan_info *pci_vchan_get_client(libxl__gc *gc); +struct vchan_info *pci_vchan_get_client(libxl__gc *gc) +{ + struct vchan_info *vchan; + + vchan =3D libxl__zalloc(gc, sizeof(*vchan)); + if (!vchan) + goto out; + vchan->state =3D vchan_new_client(gc, PCID_SRV_NAME); + if (!(vchan->state)) { + vchan =3D NULL; + goto out; + } + + vchan->handle_response =3D pci_handle_response; + vchan->prepare_request =3D pci_prepare_request; + vchan->receive_buf_size =3D PCI_RECEIVE_BUFFER_SIZE; + vchan->max_buf_size =3D PCI_MAX_SIZE_RX_BUF; + +out: + return vchan; +} + +void pci_vchan_free(libxl__gc *gc, struct vchan_info *vchan); +void pci_vchan_free(libxl__gc *gc, struct vchan_info *vchan) +{ + vchan_fini_one(gc, vchan->state); +} + static unsigned int pci_encode_bdf(libxl_device_pci *pci) { unsigned int value; diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c new file mode 100644 index 0000000000..958fe387f9 --- /dev/null +++ b/tools/libs/light/libxl_pcid.c @@ -0,0 +1,428 @@ +/* + Utils for xl pcid daemon + + Copyright (C) 2021 EPAM Systems Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; If not, see . + */ + +#define _GNU_SOURCE // required for strchrnul() + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" +#include "libxl_vchan.h" + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#define DOM0_ID 0 + +struct vchan_client { + XEN_LIST_ENTRY(struct vchan_client) list; + + /* This is the watch entry fired for this client. */ + char **watch_ret; + /* Length of the watch_ret[XS_WATCH_PATH]. */ + size_t watch_len; + + struct vchan_info info; + + /* + * This context is used by the processing loop to create its own gc + * and use it while processing commands, so we do not get OOM. + */ + libxl_ctx *ctx; + /* This gc holds all allocations made for the client needs itself. */ + libxl__gc gc[1]; + pthread_t run_thread; +}; + +static XEN_LIST_HEAD(clients_list, struct vchan_client) vchan_clients; + +static pthread_mutex_t vchan_client_mutex; + +static int make_error_reply(libxl__gc *gc, yajl_gen gen, char *desc, + char *command_name) +{ + int rc; + + rc =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_RESP, + command_name); + if (rc) + return rc; + + rc =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_ERR, + PCID_MSG_ERR_FAILED); + if (rc) + return rc; + + rc =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_ERR_DESC,= desc); + if (rc) + return rc; + + return 0; +} + +static int pcid_handle_request(libxl__gc *gc, yajl_gen gen, + const libxl__json_object *request) +{ + const libxl__json_object *command_obj; + libxl__json_object *command_response =3D NULL; + char *command_name; + int ret =3D 0; + + yajl_gen_map_open(gen); + + command_obj =3D libxl__json_map_get(PCID_MSG_FIELD_CMD, request, JSON_= STRING); + if (!command_obj) { + /* This is an unsupported or bad request. */ + ret =3D make_error_reply(gc, gen, "Unsupported request or bad pack= et", + PCID_MSG_ERR_NA); + goto out; + } + + command_name =3D command_obj->u.string; + + /* + * This is an unsupported command: make a reply and proceed over + * the error path. + */ + ret =3D make_error_reply(gc, gen, "Unsupported command", + command_name); + if (!ret) + ret =3D ERROR_NOTFOUND; + + if (ret) { + /* + * The command handler on error must provide a valid response, + * so we don't need to add any other field below. + */ + ret =3D 0; + goto out; + } + + if (command_response) { + ret =3D libxl__json_object_to_yajl_gen(gc, gen, command_response); + if (ret) + goto out; + } + + ret =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_RESP, + command_name); + if (ret) + goto out; + + ret =3D libxl__vchan_field_add_string(gc, gen, PCID_MSG_FIELD_ERR, + PCID_MSG_ERR_OK); +out: + yajl_gen_map_close(gen); + + vchan_dump_gen(gc, gen); + + return ret; +} + +static char *pcid_prepare_response(libxl__gc *gc, yajl_gen gen) +{ + const unsigned char *buf; + libxl_yajl_length len; + yajl_gen_status sts; + char *reply =3D NULL; + + sts =3D yajl_gen_get_buf(gen, &buf, &len); + if (sts !=3D yajl_gen_status_ok) + goto out; + + reply =3D libxl__sprintf(gc, "%s", buf); + + vchan_dump_gen(gc, gen); + +out: + return reply; +} + +static void server_fini_one(libxl__gc *gc, struct vchan_client *client) +{ + pthread_mutex_lock(&vchan_client_mutex); + XEN_LIST_REMOVE(client, list); + pthread_mutex_unlock(&vchan_client_mutex); + + GC_FREE; + free(client->watch_ret); + free(client); +} + +static bool is_vchan_exist(libxl_ctx *ctx, char *watch_dir) +{ + char **dir =3D NULL; + unsigned int nb; + bool ret =3D false; + + dir =3D xs_directory(ctx->xsh, XBT_NULL, watch_dir, &nb); + if (dir) { + free(dir); + ret =3D true; + } + return ret; +} + +static void *client_thread(void *arg) +{ + struct vchan_client *client =3D arg; + + while (true) { + int ret; + /* + * libvchan uses garbage collector for processing requests, + * so we create a new one each time we process a packet and + * dispose it right away to prevent OOM. + */ + GC_INIT(client->ctx); + ret =3D vchan_process_command(gc, &client->info); + GC_FREE; + + if ((ret =3D=3D ERROR_NOTFOUND) || (ret =3D=3D ERROR_INVAL)) + continue; + if (ret < 0) + break; + } + vchan_fini_one(client->gc, client->info.state); + server_fini_one(client->gc, client); + return NULL; +} + +#define DEFAULT_THREAD_STACKSIZE (24 * 1024) +/* NetBSD doesn't have PTHREAD_STACK_MIN. */ +#ifndef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 +#endif + +#define READ_THREAD_STACKSIZE \ + ((DEFAULT_THREAD_STACKSIZE < PTHREAD_STACK_MIN) ? \ + PTHREAD_STACK_MIN : DEFAULT_THREAD_STACKSIZE) + +static bool init_client_thread(libxl__gc *gc, struct vchan_client *new_cli= ent) +{ + + sigset_t set, old_set; + pthread_attr_t attr; + static size_t stack_size; +#ifdef USE_DLSYM + size_t (*getsz)(pthread_attr_t *attr); +#endif + + if (pthread_attr_init(&attr) !=3D 0) + return false; + if (!stack_size) { +#ifdef USE_DLSYM + getsz =3D dlsym(RTLD_DEFAULT, "__pthread_get_minstack"); + if (getsz) + stack_size =3D getsz(&attr); +#endif + if (stack_size < READ_THREAD_STACKSIZE) + stack_size =3D READ_THREAD_STACKSIZE; + } + if (pthread_attr_setstacksize(&attr, stack_size) !=3D 0) { + pthread_attr_destroy(&attr); + return false; + } + + sigfillset(&set); + pthread_sigmask(SIG_SETMASK, &set, &old_set); + + if (pthread_create(&new_client->run_thread, &attr, client_thread, + new_client) !=3D 0) { + pthread_sigmask(SIG_SETMASK, &old_set, NULL); + pthread_attr_destroy(&attr); + return false; + } + pthread_sigmask(SIG_SETMASK, &old_set, NULL); + pthread_attr_destroy(&attr); + + return true; +} + +static void init_new_client(libxl_ctx *ctx, libxl__gc *gc, + struct clients_list *list, char **watch_ret) +{ + struct vchan_client *new_client; + char *xs_path =3D watch_ret[XS_WATCH_PATH]; + + LOG(DEBUG, "New client at \"%s\"", xs_path); + + new_client =3D malloc(sizeof(*new_client)); + if (!new_client) { + LOGE(ERROR, "Failed to allocate new client at \"%s\"", xs_path); + return; + } + + memset(new_client, 0, sizeof(*new_client)); + + new_client->watch_ret =3D watch_ret; + new_client->watch_len =3D strlen(xs_path); + new_client->ctx =3D ctx; + /* + * Remember the GC of this client, so we can dispose its memory. + * Use it from now on. + */ + LIBXL_INIT_GC(new_client->gc[0], ctx); + + new_client->info.state =3D vchan_init_new_state(new_client->gc, DOM0_I= D, + xs_path, true); + if (!(new_client->info.state)) { + LOGE(ERROR, "Failed to add new client at \"%s\"", xs_path); + server_fini_one(new_client->gc, new_client); + return; + } + + new_client->info.handle_request =3D pcid_handle_request; + new_client->info.prepare_response =3D pcid_prepare_response; + new_client->info.receive_buf_size =3D PCI_RECEIVE_BUFFER_SIZE; + new_client->info.max_buf_size =3D PCI_MAX_SIZE_RX_BUF; + + if (!init_client_thread(new_client->gc, new_client)) { + LOGE(ERROR, "Failed to create client's thread for \"%s\"", xs_path= ); + server_fini_one(new_client->gc, new_client); + return; + } + + pthread_mutex_lock(&vchan_client_mutex); + XEN_LIST_INSERT_HEAD(&vchan_clients, new_client, list); + pthread_mutex_unlock(&vchan_client_mutex); +} + +static void terminate_clients(void) +{ + struct vchan_client *client; + + pthread_mutex_lock(&vchan_client_mutex); + XEN_LIST_FOREACH(client, &vchan_clients, list) { + pthread_join(client->run_thread, NULL); + } + pthread_mutex_unlock(&vchan_client_mutex); +} + +int libxl_pcid_process(libxl_ctx *ctx) +{ + GC_INIT(ctx); + char *xs_path, *str; + char **watch_ret; + unsigned int watch_num; + libxl_domid domid; + int ret; + + pthread_mutex_init(&vchan_client_mutex, NULL); + + str =3D xs_read(ctx->xsh, 0, "domid", NULL); + if (!str) { + LOGE(ERROR, "Can't read own domid\n"); + ret =3D -ENOENT; + goto out; + } + + ret =3D sscanf(str, "%d", &domid); + free(str); + if (ret !=3D 1) + { + LOGE(ERROR, "Own domid is not an integer\n"); + ret =3D -EINVAL; + goto out; + } + + xs_path =3D vchan_get_server_xs_path(gc, domid, PCID_SRV_NAME); + + /* Recreate the base folder: remove all leftovers. */ + ret =3D libxl__xs_rm_checked(gc, XBT_NULL, xs_path); + if (ret) + goto out; + + if (!xs_mkdir(CTX->xsh, XBT_NULL, xs_path)) + { + LOGE(ERROR, "xenstore mkdir failed: `%s'", xs_path); + ret =3D ERROR_FAIL; + goto out; + } + + /* Wait for vchan client to create a new UUID under the server's folde= r. */ + if (!xs_watch(CTX->xsh, xs_path, PCID_XS_TOKEN)) { + LOGE(ERROR, "xs_watch (%s) failed", xs_path); + ret =3D ERROR_FAIL; + goto out; + } + + while ((watch_ret =3D xs_read_watch(CTX->xsh, &watch_num))) { + struct vchan_client *client; + size_t len; + bool found; + + /* + * Any change under the base directory will fire an event, so we n= eed + * to filter if this is indeed a new client or it is because vchan + * server creates nodes under its UUID. + * + * Never try to instantiate a vchan server right under xs_path. + */ + if (!strcmp(watch_ret[XS_WATCH_PATH], xs_path)) + continue; + + found =3D false; + len =3D strlen(watch_ret[XS_WATCH_PATH]); + + pthread_mutex_lock(&vchan_client_mutex); + XEN_LIST_FOREACH(client, &vchan_clients, list) { + str =3D client->watch_ret[XS_WATCH_PATH]; + + if (strstr(watch_ret[XS_WATCH_PATH], str)) { + /* + * Base path is a substring of the current path, so it can= be: + * - a new node with different name, but starting with str + * - a subnode under str, so it will have '/' after str + * - same string + */ + if (len =3D=3D client->watch_len) { + found =3D true; + break; + } + if (len > client->watch_len) { + if (watch_ret[XS_WATCH_PATH][client->watch_len] =3D=3D= '/') { + found =3D true; + break; + } + } + } + } + pthread_mutex_unlock(&vchan_client_mutex); + + if (!found && is_vchan_exist(ctx, watch_ret[XS_WATCH_PATH])) + init_new_client(ctx, gc, &vchan_clients, watch_ret); + } + + xs_unwatch(CTX->xsh, xs_path, PCID_XS_TOKEN); + +out: + terminate_clients(); + GC_FREE; + pthread_mutex_destroy(&vchan_client_mutex); + return ret; +} diff --git a/tools/xl/Makefile b/tools/xl/Makefile index da4591b6a9..e17550e678 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -22,7 +22,7 @@ XL_OBJS =3D xl.o xl_cmdtable.o xl_sxp.o xl_utils.o $(XL_O= BJS-y) XL_OBJS +=3D xl_parse.o xl_cpupool.o xl_flask.o XL_OBJS +=3D xl_vtpm.o xl_block.o xl_nic.o xl_usb.o XL_OBJS +=3D xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o -XL_OBJS +=3D xl_info.o xl_console.o xl_misc.o +XL_OBJS +=3D xl_info.o xl_console.o xl_misc.o xl_pcid.o XL_OBJS +=3D xl_vmcontrol.o xl_saverestore.o xl_migrate.o XL_OBJS +=3D xl_vdispl.o xl_vsnd.o xl_vkb.o =20 @@ -34,7 +34,7 @@ $(XL_OBJS): CFLAGS +=3D -include $(XEN_ROOT)/tools/config= .h # libxl_json.h needs i all: xl =20 xl: $(XL_OBJS) - $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenutil) $(LDLIBS_libxenlig= ht) $(LDLIBS_libxentoollog) $(LDLIBS_libxenvchan) -lyajl $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $(XL_OBJS) $(LDLIBS_libxenstore) $(LDLIBS_libxenut= il) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(LDLIBS_libxenvchan) -ly= ajl $(APPEND_LDFLAGS) =20 .PHONY: install install: all diff --git a/tools/xl/xl.h b/tools/xl/xl.h index 72538d6a81..98a44c12e9 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -201,6 +201,7 @@ int main_loadpolicy(int argc, char **argv); int main_remus(int argc, char **argv); #endif int main_devd(int argc, char **argv); +int main_pcid(int argc, char **argv); #if defined(__i386__) || defined(__x86_64__) int main_psr_hwinfo(int argc, char **argv); int main_psr_cmt_attach(int argc, char **argv); diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index 35182ca196..54574a7ed3 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -545,6 +545,13 @@ const struct cmd_spec cmd_table[] =3D { "-F Run in the foreground.\n" "-p, --pidfile [FILE] Write PID to pidfile when daemonizing.", }, + { "pcid", + &main_pcid, 0, 1, + "Daemon that acts as a server for the client in the libxl PCI", + "[options]", + "-f Run in the foreground.\n" + "-p, --pidfile [FILE] Write PID to pidfile when daemonizing.", + }, #if defined(__i386__) || defined(__x86_64__) { "psr-hwinfo", &main_psr_hwinfo, 0, 1, diff --git a/tools/xl/xl_pcid.c b/tools/xl/xl_pcid.c new file mode 100644 index 0000000000..a5d38e672f --- /dev/null +++ b/tools/xl/xl_pcid.c @@ -0,0 +1,81 @@ +/* + Pcid daemon that acts as a server for the client in the libxl PCI + + Copyright (C) 2021 EPAM Systems Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; If not, see . + */ + +#define _GNU_SOURCE // required for strchrnul() + +#include +#include + +#include "xl.h" +#include "xl_utils.h" +#include "xl_parse.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * TODO: Running this code in multi-threaded environment + * Now the code is designed so that only one request to the server + * from the client is made in one domain. In the future, it is necessary + * to take into account cases when from different domains there can be + * several requests from a client at the same time. Therefore, it will be + * necessary to regulate the multithreading of processes for global variab= les. + */ + +int main_pcid(int argc, char *argv[]) +{ + int opt =3D 0, daemonize =3D 1, ret; + const char *pidfile =3D NULL; + static const struct option opts[] =3D { + {"pidfile", 1, 0, 'p'}, + COMMON_LONG_OPTS, + {0, 0, 0, 0} + }; + + SWITCH_FOREACH_OPT(opt, "fp:", opts, "pcid", 0) { + case 'f': + daemonize =3D 0; + break; + case 'p': + pidfile =3D optarg; + break; + } + + if (daemonize) { + ret =3D do_daemonize("xlpcid", pidfile); + if (ret) { + ret =3D (ret =3D=3D 1) ? 0 : ret; + goto out_daemon; + } + } + + libxl_pcid_process(ctx); + + ret =3D 0; + +out_daemon: + exit(ret); +} --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782309; cv=none; d=zohomail.com; s=zohoarc; b=Mj7p7rxUohzTVtaWyTe7GB+tF057letwO/s8/FxuSlA9CtCdYrEEWU1/0iF81KJWE/QwJ1JRhUgfooaelJYhDPkWGxrFE79xOT/ft1eGYkLb1s2/yT437xrZzEQSM2q57bV6CCKJyZKVdi0O8MEb1QNUTjkksj3eKUqGOlAgNbU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782309; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ylOSlAAsRMSF13m/WxnF31oV8wjlQEFnbS1C2vMhAmQ=; b=kzhoIVmZbYgrIbz3KmwwJrtXjNpoiRcTKXMdmaJ4rWDOUW6ySw8A3nmb/SGz0gMLNwvGU7wudhlwICus/wXxHDe9dR8b4b3zaROCcJ/GmxPRoSFjJbx5GbESNjip7O3TfGHh6Htrmv0zGOFIHv/t1QB6+agY1DvL19RDJiROKzc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 167378230949640.76110981442173; Sun, 15 Jan 2023 03:31:49 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477861.740786 (Exim 4.92) (envelope-from ) id 1pH1ER-0005Ug-TY; Sun, 15 Jan 2023 11:31:23 +0000 Received: by outflank-mailman (output) from mailman id 477861.740786; Sun, 15 Jan 2023 11:31:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ER-0005U4-Lv; Sun, 15 Jan 2023 11:31:23 +0000 Received: by outflank-mailman (input) for mailman id 477861; Sun, 15 Jan 2023 11:31:22 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EP-0004co-R9 for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:21 +0000 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [2a00:1450:4864:20::636]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 2199714c-94c8-11ed-b8d0-410ff93cb8f0; Sun, 15 Jan 2023 12:31:19 +0100 (CET) Received: by mail-ej1-x636.google.com with SMTP id ud5so62065038ejc.4 for ; Sun, 15 Jan 2023 03:31:19 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:18 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 2199714c-94c8-11ed-b8d0-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ylOSlAAsRMSF13m/WxnF31oV8wjlQEFnbS1C2vMhAmQ=; b=lNcXXQ3WpawuLh/3f81jyVto3aISNpKmjWDl2wwuXCSiF50o2NMnWn7KtAjgsQrvtn eUxjNtPh3n3a5xm9Ye+1RcPav1lc0xnmNfBlcMaJ1wep8J/4+qWp4g2FJSRLzfo8NIEI LmEDxgjlSF5fv9yuEL8zh52CeWoi94A83N8F690NQpkLQBSxvipQDDShNi1CQSV2GGmK 1V+WNt8En85YvYRFqDA9tdMX5oCHvUt+s7xrrjVlcqZ5iz5+D4YSnKlxO/W2EIZF/+YQ M6D0ma60Oc37VMjd0bPATOlvCHiLUI+Htq79FS0jt0Ad84IJYRb+urcLGMxaIaxN4M0v rR6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ylOSlAAsRMSF13m/WxnF31oV8wjlQEFnbS1C2vMhAmQ=; b=wELnWtLn5uInqtjvBe7r0kyB1h89C8DvWO3DAbrk/F/aeWgkNXKDPmexfoIOjfxJa3 E90KuVGyifwdZNrvzk6OZcJ4Ac4+nX7rPAaoV7fIM8uVLf3Ki3ovyNF9gM6akpqwZuha z+J6L1AZKAhOgvu1ofc+fx9uNu/YgUYwm1lJOVScprWAE/JuTjMDIt6tc2OyR3E6ciTf zS4Rya5GiTea6wyhQMrVXZ5RcoZtGeg+szCVSvcgmlofZAoRm9snc+58BUdOg34OqrIr m4uidKloeLYbKyBvmTP2yiZSFYltTEZa3wgfTBHt6nZxs2SKz7wkf6ljTKvGHt3gyfpx Va8A== X-Gm-Message-State: AFqh2kpg/SSTChQVR+da/R/adXB7IIySBdR3e6VTI9GzYnwTgqrGf2wz 4ahdHYkG5So/vTyZGGSELzJ5VZBTvbNtu3Ud X-Google-Smtp-Source: AMrXdXt1PVXJzXqXXv1CjLnjGLuod88mQki1Do5dmGNVJqTG1BuQUjE+az8UvXD8viFox25uMpExyQ== X-Received: by 2002:a17:907:7657:b0:7ff:727f:65cb with SMTP id kj23-20020a170907765700b007ff727f65cbmr9474933ejc.19.1673782279053; Sun, 15 Jan 2023 03:31:19 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Oleksandr Andrushchenko , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 04/10] tools/libs/light: pcid: implement list_assignable command Date: Sun, 15 Jan 2023 13:31:05 +0200 Message-Id: <20230115113111.1207605-5-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782310989100008 Content-Type: text/plain; charset="utf-8" From: Oleksandr Andrushchenko Signed-off-by: Oleksandr Andrushchenko --- tools/include/pcid.h | 19 ++++++++++++ tools/libs/light/libxl_pci.c | 54 ++++++++++++++++++++++----------- tools/libs/light/libxl_pcid.c | 56 ++++++++++++++++++++++++++++++----- 3 files changed, 103 insertions(+), 26 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 6506b18d25..452bdc11cf 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -79,6 +79,25 @@ =20 #define PCID_SBDF_FMT "%04x:%02x:%02x.%01x" =20 +/* + *************************************************************************= ****** + * List assignable devices + * + * This command lists PCI devices that can be passed through to a guest do= main. + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "list_assignable". + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "list_assignable". + * Command specific response data: + * +-------------+--------------+-----------------------------------------= -----+ + * | devices | list | List of of pci_device objects = | + * +-------------+--------------+-----------------------------------------= -----+ + */ +#define PCID_CMD_LIST_ASSIGNABLE "list_assignable" +#define PCID_MSG_FIELD_DEVICES "devices" + int libxl_pcid_process(libxl_ctx *ctx); =20 #endif /* PCID_H */ diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index b0c6de88ba..321543f5bf 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -29,6 +29,18 @@ #define PCI_BDF_XSPATH "%04x-%02x-%02x-%01x" #define PCI_PT_QDEV_ID "pci-pt-%02x_%02x.%01x" =20 +static int process_list_assignable(libxl__gc *gc, + const libxl__json_object *response, + libxl__json_object **result) +{ + *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIELD_D= EVICES, + response, JSON_ARR= AY); + if (!*result) + return ERROR_INVAL; + + return 0; +} + static int pci_handle_response(libxl__gc *gc, const libxl__json_object *response, libxl__json_object **result) @@ -68,6 +80,9 @@ static int pci_handle_response(libxl__gc *gc, command_name =3D command_obj->u.string; LOG(DEBUG, "command: %s", command_name); =20 + if (strcmp(command_name, PCID_CMD_LIST_ASSIGNABLE) =3D=3D 0) + ret =3D process_list_assignable(gc, response, result); + return ret; } =20 @@ -124,8 +139,7 @@ static char *pci_prepare_request(libxl__gc *gc, yajl_ge= n gen, char *cmd, return request; } =20 -struct vchan_info *pci_vchan_get_client(libxl__gc *gc); -struct vchan_info *pci_vchan_get_client(libxl__gc *gc) +static struct vchan_info *pci_vchan_get_client(libxl__gc *gc) { struct vchan_info *vchan; =20 @@ -147,8 +161,7 @@ out: return vchan; } =20 -void pci_vchan_free(libxl__gc *gc, struct vchan_info *vchan); -void pci_vchan_free(libxl__gc *gc, struct vchan_info *vchan) +static void pci_vchan_free(libxl__gc *gc, struct vchan_info *vchan) { vchan_fini_one(gc, vchan->state); } @@ -561,26 +574,29 @@ libxl_device_pci *libxl_device_pci_assignable_list(li= bxl_ctx *ctx, int *num) { GC_INIT(ctx); libxl_device_pci *pcis =3D NULL, *new; - struct dirent *de; - DIR *dir; + struct vchan_info *vchan; + libxl__json_object *result, *dev_obj; + int i; =20 *num =3D 0; =20 - dir =3D opendir(SYSFS_PCIBACK_DRIVER); - if (NULL =3D=3D dir) { - if (errno =3D=3D ENOENT) { - LOG(ERROR, "Looks like pciback driver not loaded"); - } else { - LOGE(ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER); - } + vchan =3D pci_vchan_get_client(gc); + if (!vchan) goto out; - } =20 - while((de =3D readdir(dir))) { + result =3D vchan_send_command(gc, vchan, PCID_CMD_LIST_ASSIGNABLE, NUL= L); + if (!result) + goto vchan_free; + + for (i =3D 0; (dev_obj =3D libxl__json_array_get(result, i)); i++) { + const char *sbdf_str =3D libxl__json_object_get_string(dev_obj); unsigned int dom, bus, dev, func; - char *name; + const char *name; + + if (!sbdf_str) + continue; =20 - if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) !=3D 4) + if (sscanf(sbdf_str, PCID_SBDF_FMT, &dom, &bus, &dev, &func) !=3D = 4) continue; =20 new =3D realloc(pcis, ((*num) + 1) * sizeof(*new)); @@ -602,7 +618,9 @@ libxl_device_pci *libxl_device_pci_assignable_list(libx= l_ctx *ctx, int *num) (*num)++; } =20 - closedir(dir); +vchan_free: + pci_vchan_free(gc, vchan); + out: GC_FREE; return pcis; diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index 958fe387f9..bab08b72cf 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -84,6 +84,41 @@ static int make_error_reply(libxl__gc *gc, yajl_gen gen,= char *desc, return 0; } =20 +static int process_list_assignable(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + struct dirent *de; + DIR *dir =3D NULL; + + dir =3D opendir(SYSFS_PCI_DEV); + if (dir =3D=3D NULL) { + make_error_reply(gc, gen, strerror(errno), command_name); + return ERROR_FAIL; + } + + libxl__yajl_gen_asciiz(gen, PCID_MSG_FIELD_DEVICES); + + *response =3D libxl__json_object_alloc(gc, JSON_ARRAY); + + while ((de =3D readdir(dir))) { + unsigned int dom, bus, dev, func; + + if (sscanf(de->d_name, PCID_SBDF_FMT, &dom, &bus, &dev, &func) != =3D 4) + continue; + + struct libxl__json_object *node =3D + libxl__json_object_alloc(gc, JSON_STRING); + node->u.string =3D de->d_name; + flexarray_append((*response)->u.array, node); + } + + closedir(dir); + + return 0; +} + static int pcid_handle_request(libxl__gc *gc, yajl_gen gen, const libxl__json_object *request) { @@ -104,14 +139,19 @@ static int pcid_handle_request(libxl__gc *gc, yajl_ge= n gen, =20 command_name =3D command_obj->u.string; =20 - /* - * This is an unsupported command: make a reply and proceed over - * the error path. - */ - ret =3D make_error_reply(gc, gen, "Unsupported command", - command_name); - if (!ret) - ret =3D ERROR_NOTFOUND; + if (strcmp(command_name, PCID_CMD_LIST_ASSIGNABLE) =3D=3D 0) + ret =3D process_list_assignable(gc, gen, command_name, + request, &command_response); + else { + /* + * This is an unsupported command: make a reply and proceed over + * the error path. + */ + ret =3D make_error_reply(gc, gen, "Unsupported command", + command_name); + if (!ret) + ret =3D ERROR_NOTFOUND; + } =20 if (ret) { /* --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782306; cv=none; d=zohomail.com; s=zohoarc; b=k+pVYO5TfS3E4jSjlNuHfJ0U7nlHmrZ9Gae4J+QHNLlsR99e4R3IbQpsBdd7+eB8fYNk51UW631YMrtZxw/lEnuG8t0tqgvnWQvXrX9Oz2nIp3sfLRYA2UTPZaVdRP4SNtUm0FTIofuKbFtrDbU/D95c0UV9NDyNaHb98MHh3Uw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782306; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=RBd+hmBQgXZkrJPkk2A6G6FhZeqNtc7f2zf0tt6B+Y4=; b=G2s4iwHat0J5Agr76m1tnGyw88osT2R/gaDJ9dr95+pR9jNk9JEstM6fc2sVsv52zPgv7mSo/FWPFAEfbubeXrmS8vHs2uFdbf1UMF6/IQqsdromtrW0qPPPklaQAfioOpw9fkfHp3FZjb+KLKaFLKYqc0Fh7yarsN1hpsw8saw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782306493243.36923041827356; Sun, 15 Jan 2023 03:31:46 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477862.740790 (Exim 4.92) (envelope-from ) id 1pH1ES-0005cC-EJ; Sun, 15 Jan 2023 11:31:24 +0000 Received: by outflank-mailman (output) from mailman id 477862.740790; Sun, 15 Jan 2023 11:31:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ES-0005aq-7m; Sun, 15 Jan 2023 11:31:24 +0000 Received: by outflank-mailman (input) for mailman id 477862; Sun, 15 Jan 2023 11:31:22 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EQ-0004ci-BW for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:22 +0000 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [2a00:1450:4864:20::633]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 22474e46-94c8-11ed-91b6-6bf2151ebd3b; Sun, 15 Jan 2023 12:31:20 +0100 (CET) Received: by mail-ej1-x633.google.com with SMTP id cf18so55655629ejb.5 for ; Sun, 15 Jan 2023 03:31:20 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:19 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 22474e46-94c8-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RBd+hmBQgXZkrJPkk2A6G6FhZeqNtc7f2zf0tt6B+Y4=; b=A6g4LBmvHkUjz9gzJSTm8njOCHRcxbwKot/vnTJEsRj2KBagbqA4nLR7ENR61+Kv4K ZIaflMDApL5DvuJO865GIau25biBL5Vle+LSr0/P4rFK26j6uZjVEXxKXk7QMVie6doB t4Ope3jJK+eVqWJV9chTrR0/uH6lQFQge1zkxtIGKHib7vofe6zcBuG2xPN9B4rVAc2R uQ8RE/JmllneEKwOVLzxc8/cUL4lYQnrKx4sgs3InX07lSkxZfL9Wrw0FtEwa7v495If Z+Vcc7/ibHupzF0hurL4mpfEbWcWTYny7mz841/j/rEimBsv4tMCJA5SpjDEeZQNUXoq qwfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RBd+hmBQgXZkrJPkk2A6G6FhZeqNtc7f2zf0tt6B+Y4=; b=B+cumoEnK7mJ6mVDrDOJtSlG58sqvfHNR0NB5W9OQPDa53JcnAKMFwHAMlV2CSLUoQ IUxYkd4jj2Vw7jadY3/7k0UxHH/UG+eJi6WF5zW+lZsMwqC2qmtaUtjyUJal4pQQpmAD OtFNuhgfC//rjNbS0sgzv6n3s5AI6CUiVxtayTF2534sjHiVkMWYe0y2sT+bGA55k+Q/ UZXF1espRGPvhe5xT0um1almIHXyYvlCAYGAptaIWJit7wSQxJfNywf9gtU667bjEZLC NqgCZhbr4TnpWiWj5LWOp08kLrZrmDLB0A0AppjlD4PySwu5mw9q6ncGS+O86a97O6YA m+pQ== X-Gm-Message-State: AFqh2koabTYkHHIohMNP0MCHU9Jrp87IfKm1vcMqs92UamVGpJY2ODXT ol3AlwsnqiDKbDpVfBLVoNDOz4RvGV0QPeqx X-Google-Smtp-Source: AMrXdXszUm9sdvZugQmrnDnG84ZBeP8VU310ltdSm5Vq5MqV8JhaKIifUaao3soTTYzNSyY9yBG+jg== X-Received: by 2002:a17:906:2813:b0:829:59d5:e661 with SMTP id r19-20020a170906281300b0082959d5e661mr74258838ejc.29.1673782280151; Sun, 15 Jan 2023 03:31:20 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Wei Liu , Anthony PERARD Subject: [RFC PATCH v3 05/10] tools/light: pci: describe [MAKE|REVERT]_ASSIGNABLE commands Date: Sun, 15 Jan 2023 13:31:06 +0200 Message-Id: <20230115113111.1207605-6-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782307056100001 Content-Type: text/plain; charset="utf-8" From: Volodymyr Babchuk Add protocol for two more commands, one to make a PCI device assignable, and other - to revert its state back. Signed-off-by: Volodymyr Babchuk --- tools/include/pcid.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 452bdc11cf..118f8105cf 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -98,6 +98,44 @@ #define PCID_CMD_LIST_ASSIGNABLE "list_assignable" #define PCID_MSG_FIELD_DEVICES "devices" =20 +/* + *************************************************************************= ****** + * Make device assignable + * + * This command makes given device assignable by ensuring that OS + * will not try to access it. + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "make_assignable". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * - "rebind" =3D true if daemon needs to save original driver name, + * so device later can be rebound back. + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "make_assignable". + */ +#define PCID_CMD_MAKE_ASSIGNABLE "make_assignable" +#define PCID_MSG_FIELD_REBIND "rebind" + +/* + *************************************************************************= ****** + * Revert device from assignable state + * + * This command reverts effect of "make_assignable" command. Basically, + * now device can be used by OS again. + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "revert_assignable". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * - "rebind" =3D true if daemon needs to rebind device back to it's + * original driver, which name was saved by "make_assignable" command + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "revert_assignable". + */ +#define PCID_CMD_REVERT_ASSIGNABLE "revert_assignable" + + int libxl_pcid_process(libxl_ctx *ctx); =20 #endif /* PCID_H */ --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782313; cv=none; d=zohomail.com; s=zohoarc; b=UI15EBHWhql0N8Yy6n/q2crTcHNX56V67x2/ZTFeeC8zPyLVNFNAPKO4npfQtHcLNVhrgZyAUjVS4L1AqodGfuuvJNq+uj2AUprGeUUjvJt+8skEQGZo7WUruJyLHPcxdQABXa/QvQdGXqNdYtcuhtgId4GrLw8WUKf/iGT6YGc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782313; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=qQf6nMYZTsKyVSis1dtkaKRd/WNynJi6oS+H2pCRPK4=; b=aqyY4wdPFuFQhBkiNOtNBGopDBjrZ30g0nqE5P58/2xoaIDmFSvxsjdN/K3JbJRX7dp+qGAkyQm7CoWQGK5kdqVnqfDO0EBratT++5GjonRbcHUGhg48rdKCjPINEQO1kcRoBJQpw1nIdQ2c0hQ7VDDMVwBm2EGQqWW7hc7WbS0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782313088904.9822891469586; Sun, 15 Jan 2023 03:31:53 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477864.740822 (Exim 4.92) (envelope-from ) id 1pH1EV-0006TQ-1v; Sun, 15 Jan 2023 11:31:27 +0000 Received: by outflank-mailman (output) from mailman id 477864.740822; Sun, 15 Jan 2023 11:31:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EU-0006SY-Ty; Sun, 15 Jan 2023 11:31:26 +0000 Received: by outflank-mailman (input) for mailman id 477864; Sun, 15 Jan 2023 11:31:25 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ET-0004co-DB for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:25 +0000 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [2a00:1450:4864:20::62e]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 230e1483-94c8-11ed-b8d0-410ff93cb8f0; Sun, 15 Jan 2023 12:31:22 +0100 (CET) Received: by mail-ej1-x62e.google.com with SMTP id mp20so15434679ejc.7 for ; Sun, 15 Jan 2023 03:31:22 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:20 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 230e1483-94c8-11ed-b8d0-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qQf6nMYZTsKyVSis1dtkaKRd/WNynJi6oS+H2pCRPK4=; b=b1fWQURdMrLlTHhc7988e863g0gmdekRAYutqRUOdN7cPy7Sfb4P1c2FmKM5UqsfbS g0E1qVTXCwtotjcXHLtDOwcl8leftSP7cd8N5AUjN+opJPHyytKGsgd93TGhQzRXEOdJ oHc8YhzncL8xzpPNL+C1+sMxrmNoynlScFryOp2odfrc4cJaqQmOORSFLj5eiDeC64Dw clRgm1ZHjjUrM1YIqC2pwY+lGuKoHbQrDLHt5seQ1hl8GLHn+W56auWL1Wv3emVDtSad O8sF80wekUj08Onzt3XfJ+4wFUuH+guOY+PqFW00AQNn1K3jtniK+DPekeuXt47DIUIq kr2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qQf6nMYZTsKyVSis1dtkaKRd/WNynJi6oS+H2pCRPK4=; b=6Gq6iIggLxRuuR3/fC5E7IVUQCmbYcvyjw4jaag0VaMFK0VjuneA26u8tuYFKHoAzQ Xq4LqerL33hcLiMfXo85hRbmJt9OW4HgfzGYmbthXQTYUlrDo+uhNRMMGAMl0DdWVEpc 8Fnq+blmDLtQy/GVn4ChOK9Ovcoo4u6aa1fq/mTGfVS4+EyZTIEWOnyn/N6i4zc+v5nk Q76XYP4lOHWYspXorf+n3zPkrI7fDiDgo7iaRBaAxRbPsRMBFlmxS34ITwvVybIgRwZ4 MNig4HOI3G10Bj9MUqza4rzQcFSsQd3ZmSZm1IRG1UTUJxR1Oalblo67ynSNBFkUSDI0 58wA== X-Gm-Message-State: AFqh2kqOP2DCZRrTtZAKx22TRmcwYQ/1FYMkA0woX0GeFBUO04HaXv9v bdnMfOffb77thEUepsLFxfho6TWNl57H5m0v X-Google-Smtp-Source: AMrXdXvys0v7on+HORafcG2tSLqa7aLVQ7y7zFyuXcAIURFw/5cESvXLmPgsZxWNaTgSkvni09S3Og== X-Received: by 2002:a17:906:4f02:b0:86e:4067:b699 with SMTP id t2-20020a1709064f0200b0086e4067b699mr3656816eju.4.1673782281236; Sun, 15 Jan 2023 03:31:21 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 06/10] tools/light: pci: move assign/revert logic to pcid Date: Sun, 15 Jan 2023 13:31:07 +0200 Message-Id: <20230115113111.1207605-7-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782314819100016 Content-Type: text/plain; charset="utf-8" From: Volodymyr Babchuk Implement commands MAKE_ASSIGNABLE and REVERT_ASSIGNABLE in pcid in the same way as they were implemented in libxl_pci.c Replace original logic in libxl_pci.c by calling appropriate functions from pcid. This is quite huge patch, as lots of code were moved from lixbl_pci.c to libxl_pcid.c. Signed-off-by: Volodymyr Babchuk --- tools/libs/light/libxl_pci.c | 292 +++++-------------------- tools/libs/light/libxl_pcid.c | 396 ++++++++++++++++++++++++++++++++++ 2 files changed, 454 insertions(+), 234 deletions(-) diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 321543f5bf..0351a0d3df 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -82,6 +82,10 @@ static int pci_handle_response(libxl__gc *gc, =20 if (strcmp(command_name, PCID_CMD_LIST_ASSIGNABLE) =3D=3D 0) ret =3D process_list_assignable(gc, response, result); + else if (strcmp(command_name, PCID_CMD_MAKE_ASSIGNABLE) =3D=3D 0) + *result =3D libxl__json_object_alloc(gc, JSON_NULL); + else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) =3D=3D 0) + *result =3D libxl__json_object_alloc(gc, JSON_NULL); =20 return ret; } @@ -636,44 +640,6 @@ void libxl_device_pci_assignable_list_free(libxl_devic= e_pci *list, int num) free(list); } =20 -/* Unbind device from its current driver, if any. If driver_path is non-N= ULL, - * store the path to the original driver in it. */ -static int sysfs_dev_unbind(libxl__gc *gc, libxl_device_pci *pci, - char **driver_path) -{ - char * spath, *dp =3D NULL; - struct stat st; - - spath =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver", - pci->domain, - pci->bus, - pci->dev, - pci->func); - if ( !lstat(spath, &st) ) { - /* Find the canonical path to the driver. */ - dp =3D libxl__zalloc(gc, PATH_MAX); - dp =3D realpath(spath, dp); - if ( !dp ) { - LOGE(ERROR, "realpath() failed"); - return -1; - } - - LOG(DEBUG, "Driver re-plug path: %s", dp); - - /* Unbind from the old driver */ - spath =3D GCSPRINTF("%s/unbind", dp); - if ( sysfs_write_bdf(gc, spath, pci) < 0 ) { - LOGE(ERROR, "Couldn't unbind device"); - return -1; - } - } - - if ( driver_path ) - *driver_path =3D dp; - - return 0; -} - static uint16_t sysfs_dev_get_vendor(libxl__gc *gc, libxl_device_pci *pci) { char *pci_device_vendor_path =3D @@ -785,49 +751,6 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc, return false; } =20 -/* - * A brief comment about slots. I don't know what slots are for; however, - * I have by experimentation determined: - * - Before a device can be bound to pciback, its BDF must first be listed - * in pciback/slots - * - The way to get the BDF listed there is to write BDF to - * pciback/new_slot - * - Writing the same BDF to pciback/new_slot is not idempotent; it results - * in two entries of the BDF in pciback/slots - * It's not clear whether having two entries in pciback/slots is a problem - * or not. Just to be safe, this code does the conservative thing, and - * first checks to see if there is a slot, adding one only if one does not - * already exist. - */ - -/* Scan through /sys/.../pciback/slots looking for pci's BDF */ -static int pciback_dev_has_slot(libxl__gc *gc, libxl_device_pci *pci) -{ - FILE *f; - int rc =3D 0; - unsigned dom, bus, dev, func; - - f =3D fopen(SYSFS_PCIBACK_DRIVER"/slots", "r"); - - if (f =3D=3D NULL) { - LOGE(ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER"/slots"); - return ERROR_FAIL; - } - - while (fscanf(f, "%x:%x:%x.%d\n", &dom, &bus, &dev, &func) =3D=3D 4) { - if (dom =3D=3D pci->domain - && bus =3D=3D pci->bus - && dev =3D=3D pci->dev - && func =3D=3D pci->func) { - rc =3D 1; - goto out; - } - } -out: - fclose(f); - return rc; -} - static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci) { char * spath; @@ -856,133 +779,34 @@ static int pciback_dev_is_assigned(libxl__gc *gc, li= bxl_device_pci *pci) return -1; } =20 -static int pciback_dev_assign(libxl__gc *gc, libxl_device_pci *pci) -{ - int rc; - - if ( (rc =3D pciback_dev_has_slot(gc, pci)) < 0 ) { - LOGE(ERROR, "Error checking for pciback slot"); - return ERROR_FAIL; - } else if (rc =3D=3D 0) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot", - pci) < 0 ) { - LOGE(ERROR, "Couldn't bind device to pciback!"); - return ERROR_FAIL; - } - } - - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", pci) < 0 ) { - LOGE(ERROR, "Couldn't bind device to pciback!"); - return ERROR_FAIL; - } - return 0; -} - -static int pciback_dev_unassign(libxl__gc *gc, libxl_device_pci *pci) -{ - /* Remove from pciback */ - if ( sysfs_dev_unbind(gc, pci, NULL) < 0 ) { - LOG(ERROR, "Couldn't unbind device!"); - return ERROR_FAIL; - } - - /* Remove slot if necessary */ - if ( pciback_dev_has_slot(gc, pci) > 0 ) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot", - pci) < 0 ) { - LOGE(ERROR, "Couldn't remove pciback slot"); - return ERROR_FAIL; - } - } - return 0; -} - static int libxl__device_pci_assignable_add(libxl__gc *gc, libxl_device_pci *pci, int rebind) { libxl_ctx *ctx =3D libxl__gc_owner(gc); - unsigned dom, bus, dev, func; - char *spath, *driver_path =3D NULL; - const char *name; + struct vchan_info *vchan; int rc; - struct stat st; - - /* Local copy for convenience */ - dom =3D pci->domain; - bus =3D pci->bus; - dev =3D pci->dev; - func =3D pci->func; - name =3D pci->name; - - /* Sanitise any name that is set */ - if (name) { - unsigned int i, n =3D strlen(name); + libxl__json_object *args, *result; =20 - if (n > 64) { /* Reasonable upper bound on name length */ - LOG(ERROR, "Name too long"); - return ERROR_FAIL; - } - - for (i =3D 0; i < n; i++) { - if (!isgraph(name[i])) { - LOG(ERROR, "Names may only include printable characters"); - return ERROR_FAIL; - } - } - } - - /* See if the device exists */ - spath =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func); - if ( lstat(spath, &st) ) { - LOGE(ERROR, "Couldn't lstat %s", spath); - return ERROR_FAIL; - } - - /* Check to see if it's already assigned to pciback */ - rc =3D pciback_dev_is_assigned(gc, pci); - if ( rc < 0 ) { - return ERROR_FAIL; - } - if ( rc ) { - LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, fu= nc); - goto name; + vchan =3D pci_vchan_get_client(gc); + if (!vchan) { + rc =3D ERROR_NOT_READY; + goto out; } =20 - /* Check to see if there's already a driver that we need to unbind fro= m */ - if ( sysfs_dev_unbind(gc, pci, &driver_path ) ) { - LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver", - dom, bus, dev, func); - return ERROR_FAIL; - } + args =3D libxl__vchan_start_args(gc); =20 - /* Store driver_path for rebinding to dom0 */ - if ( rebind ) { - if ( driver_path ) { - pci_info_xs_write(gc, pci, "driver_path", driver_path); - } else if ( (driver_path =3D - pci_info_xs_read(gc, pci, "driver_path")) !=3D NULL )= { - LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %= s", - dom, bus, dev, func, driver_path); - } else { - LOG(WARN, PCI_BDF" not bound to a driver, will not be rebound.= ", - dom, bus, dev, func); - } - } else { - pci_info_xs_remove(gc, pci, "driver_path"); - } + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, pci->domain, + pci->bus, pci->dev, pci->func)); + libxl__vchan_arg_add_bool(gc, args, PCID_MSG_FIELD_REBIND, rebind); =20 - if ( pciback_dev_assign(gc, pci) ) { - LOG(ERROR, "Couldn't bind device to pciback!"); - return ERROR_FAIL; + result =3D vchan_send_command(gc, vchan, PCID_CMD_MAKE_ASSIGNABLE, arg= s); + if (!result) { + rc =3D ERROR_FAIL; + goto vchan_free; } =20 -name: - if (name) - pci_info_xs_write(gc, pci, "name", name); - else - pci_info_xs_remove(gc, pci, "name"); - /* * DOMID_IO is just a sentinel domain, without any actual mappings, * so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being @@ -990,12 +814,15 @@ name: */ rc =3D xc_assign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci), XEN_DOMCTL_DEV_RDM_RELAXED); - if ( rc < 0 ) { - LOG(ERROR, "failed to quarantine "PCI_BDF, dom, bus, dev, func); - return ERROR_FAIL; - } + if ( rc < 0 ) + LOG(ERROR, "failed to quarantine "PCI_BDF, pci->domain, pci->bus, + pci->dev, pci->func); =20 - return 0; +vchan_free: + pci_vchan_free(gc, vchan); + +out: + return rc; } =20 static int name2bdf(libxl__gc *gc, libxl_device_pci *pci) @@ -1038,13 +865,8 @@ static int libxl__device_pci_assignable_remove(libxl_= _gc *gc, { libxl_ctx *ctx =3D libxl__gc_owner(gc); int rc; - char *driver_path; - - /* If the device is named then we need to look up the BDF */ - if (pci->name) { - rc =3D name2bdf(gc, pci); - if (rc) return rc; - } + struct vchan_info *vchan; + libxl__json_object *args, *temp_obj, *result; =20 /* De-quarantine */ rc =3D xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci)); @@ -1054,41 +876,43 @@ static int libxl__device_pci_assignable_remove(libxl= __gc *gc, return ERROR_FAIL; } =20 - /* Unbind from pciback */ - if ( (rc =3D pciback_dev_is_assigned(gc, pci)) < 0 ) { - return ERROR_FAIL; - } else if ( rc ) { - pciback_dev_unassign(gc, pci); - } else { - LOG(WARN, "Not bound to pciback"); + vchan =3D pci_vchan_get_client(gc); + if (!vchan) { + rc =3D ERROR_NOT_READY; + goto out; } =20 - /* Rebind if necessary */ - driver_path =3D pci_info_xs_read(gc, pci, "driver_path"); + args =3D libxl__json_object_alloc(gc, JSON_MAP); + temp_obj =3D libxl__json_object_alloc(gc, JSON_STRING); + if (!temp_obj) { + rc =3D ERROR_NOMEM; + goto vchan_free; + } + temp_obj->u.string =3D GCSPRINTF(PCID_SBDF_FMT, pci->domain, pci->bus, + pci->dev, pci->func); + flexarray_append_pair(args->u.map, PCID_MSG_FIELD_SBDF, temp_obj); =20 - if ( driver_path ) { - if ( rebind ) { - LOG(INFO, "Rebinding to driver at %s", driver_path); + args =3D libxl__json_object_alloc(gc, JSON_MAP); + temp_obj =3D libxl__json_object_alloc(gc, JSON_BOOL); + if (!temp_obj) { + rc =3D ERROR_NOMEM; + goto vchan_free; + } =20 - if ( sysfs_write_bdf(gc, - GCSPRINTF("%s/bind", driver_path), - pci) < 0 ) { - LOGE(ERROR, "Couldn't bind device to %s", driver_path); - return -1; - } + temp_obj->u.b =3D rebind; + flexarray_append_pair(args->u.map, PCID_MSG_FIELD_REBIND, temp_obj); =20 - pci_info_xs_remove(gc, pci, "driver_path"); - } - } else { - if ( rebind ) { - LOG(WARN, - "Couldn't find path for original driver; not rebinding"); - } + result =3D vchan_send_command(gc, vchan, PCID_CMD_REVERT_ASSIGNABLE, a= rgs); + if (!result) { + rc =3D ERROR_FAIL; + goto vchan_free; } =20 - pci_info_xs_remove(gc, pci, "name"); +vchan_free: + pci_vchan_free(gc, vchan); =20 - return 0; +out: + return rc; } =20 int libxl_device_pci_assignable_add(libxl_ctx *ctx, libxl_device_pci *pci, diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index bab08b72cf..d8245195ee 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -38,6 +38,8 @@ =20 #define DOM0_ID 0 =20 +#define PCI_BDF "%04x:%02x:%02x.%01x" + struct vchan_client { XEN_LIST_ENTRY(struct vchan_client) list; =20 @@ -119,6 +121,394 @@ static int process_list_assignable(libxl__gc *gc, yaj= l_gen gen, return 0; } =20 +static int pciback_dev_is_assigned(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func) +{ + char * spath; + int rc; + struct stat st; + + if (access(SYSFS_PCIBACK_DRIVER, F_OK) < 0) { + if (errno =3D=3D ENOENT) { + LOG(ERROR, "Looks like pciback driver is not loaded"); + } else { + LOGE(ERROR, "Can't access "SYSFS_PCIBACK_DRIVER); + } + return -1; + } + + spath =3D GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF, + domain, bus, dev, func); + rc =3D lstat(spath, &st); + + if (rc =3D=3D 0) + return 1; + if (rc < 0 && errno =3D=3D ENOENT) + return 0; + LOGE(ERROR, "Accessing %s", spath); + return -1; +} + +#define PCID_INFO_PATH "pcid" +#define PCID_BDF_XSPATH "%04x-%02x-%02x-%01x" + +static char *pcid_info_xs_path(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, const char *node) +{ + return node ? + GCSPRINTF(PCID_INFO_PATH"/"PCID_BDF_XSPATH"/%s", + domain, bus, dev, func, node) : + GCSPRINTF(PCID_INFO_PATH"/"PCID_BDF_XSPATH, + domain, bus, dev, func); +} + + +static int pcid_info_xs_write(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, const char *node, + const char *val) +{ + char *path =3D pcid_info_xs_path(gc, domain, bus, dev, func, node); + int rc =3D libxl__xs_printf(gc, XBT_NULL, path, "%s", val); + + if (rc) LOGE(WARN, "Write of %s to node %s failed.", val, path); + + return rc; +} + +static char *pcid_info_xs_read(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, const char *node) +{ + char *path =3D pcid_info_xs_path(gc, domain, bus, dev, func, node); + + return libxl__xs_read(gc, XBT_NULL, path); +} + +static void pcid_info_xs_remove(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, const char *node) +{ + char *path =3D pcid_info_xs_path(gc, domain, bus, dev, func, node); + libxl_ctx *ctx =3D libxl__gc_owner(gc); + + /* Remove the xenstore entry */ + xs_rm(ctx->xsh, XBT_NULL, path); +} + + +/* Write the standard BDF into the sysfs path given by sysfs_path. */ +static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path, + unsigned int domain, unsigned int bus, + unsigned int dev, unsigned int func) +{ + int rc, fd; + char *buf; + + fd =3D open(sysfs_path, O_WRONLY); + if (fd < 0) { + LOGE(ERROR, "Couldn't open %s", sysfs_path); + return ERROR_FAIL; + } + + buf =3D GCSPRINTF(PCI_BDF, domain, bus, dev, func); + rc =3D write(fd, buf, strlen(buf)); + /* Annoying to have two if's, but we need the errno */ + if (rc < 0) + LOGE(ERROR, "write to %s returned %d", sysfs_path, rc); + close(fd); + + if (rc < 0) + return ERROR_FAIL; + + return 0; +} + + +/* Unbind device from its current driver, if any. If driver_path is non-N= ULL, + * store the path to the original driver in it. */ +static int sysfs_dev_unbind(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func, + char **driver_path) +{ + char * spath, *dp =3D NULL; + struct stat st; + + spath =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/driver", + domain, bus, dev, func); + if (!lstat(spath, &st)) { + /* Find the canonical path to the driver. */ + dp =3D libxl__zalloc(gc, PATH_MAX); + dp =3D realpath(spath, dp); + if ( !dp ) { + LOGE(ERROR, "realpath() failed"); + return -1; + } + + LOG(DEBUG, "Driver re-plug path: %s", dp); + + /* Unbind from the old driver */ + spath =3D GCSPRINTF("%s/unbind", dp); + if (sysfs_write_bdf(gc, spath, domain, bus, dev, func) < 0) { + LOGE(ERROR, "Couldn't unbind device"); + return -1; + } + } + + if (driver_path) + *driver_path =3D dp; + + return 0; +} + +/* + * A brief comment about slots. I don't know what slots are for; however, + * I have by experimentation determined: + * - Before a device can be bound to pciback, its BDF must first be listed + * in pciback/slots + * - The way to get the BDF listed there is to write BDF to + * pciback/new_slot + * - Writing the same BDF to pciback/new_slot is not idempotent; it results + * in two entries of the BDF in pciback/slots + * It's not clear whether having two entries in pciback/slots is a problem + * or not. Just to be safe, this code does the conservative thing, and + * first checks to see if there is a slot, adding one only if one does not + * already exist. + */ + +/* Scan through /sys/.../pciback/slots looking for pci's BDF */ +static int pciback_dev_has_slot(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func) +{ + FILE *f; + int rc =3D 0; + unsigned s_domain, s_bus, s_dev, s_func; + + f =3D fopen(SYSFS_PCIBACK_DRIVER"/slots", "r"); + + if (f =3D=3D NULL) { + LOGE(ERROR, "Couldn't open %s", SYSFS_PCIBACK_DRIVER"/slots"); + return ERROR_FAIL; + } + + while (fscanf(f, "%x:%x:%x.%d\n", + &s_domain, &s_bus, &s_dev, &s_func) =3D=3D 4) { + if (s_domain =3D=3D domain && + s_bus =3D=3D bus && + s_dev =3D=3D dev && + s_func =3D=3D func) { + rc =3D 1; + goto out; + } + } +out: + fclose(f); + return rc; +} + +static int pciback_dev_assign(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func) +{ + int rc; + + if ( (rc =3D pciback_dev_has_slot(gc, domain, bus, dev, func)) < 0 ) { + LOGE(ERROR, "Error checking for pciback slot"); + return ERROR_FAIL; + } else if (rc =3D=3D 0) { + if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/new_slot", + domain, bus, dev, func) < 0 ) { + LOGE(ERROR, "Couldn't bind device to pciback!"); + return ERROR_FAIL; + } + } + + if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/bind", + domain, bus, dev, func) < 0 ) { + LOGE(ERROR, "Couldn't bind device to pciback!"); + return ERROR_FAIL; + } + return 0; +} + +static int process_make_assignable(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + struct stat st; + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc; + bool rebind; + char *spath, *driver_path =3D NULL; + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_REBIND, request, JSON_BO= OL); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'rebind'", comma= nd_name); + return ERROR_FAIL; + } + + rebind =3D libxl__json_object_get_bool(json_o); + + /* See if the device exists */ + spath =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func); + if ( lstat(spath, &st) ) { + make_error_reply(gc, gen, strerror(errno), command_name); + LOGE(ERROR, "Couldn't lstat %s", spath); + return ERROR_FAIL; + } + + /* Check to see if it's already assigned to pciback */ + rc =3D pciback_dev_is_assigned(gc, dom, bus, dev, func); + if (rc < 0) { + make_error_reply(gc, gen, "Can't check if device is assigned", + command_name); + return ERROR_FAIL; + } + if (rc) { + LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, fu= nc); + goto done; + } + + /* Check to see if there's already a driver that we need to unbind fro= m */ + if (sysfs_dev_unbind(gc, dom, bus, dev, func, &driver_path)) { + LOG(ERROR, "Couldn't unbind "PCI_BDF" from driver", + dom, bus, dev, func); + return ERROR_FAIL; + } + + /* Store driver_path for rebinding back */ + if (rebind) { + if (driver_path) { + pcid_info_xs_write(gc, dom, bus, dev, func, "driver_path", + driver_path); + } else if ( (driver_path =3D + pcid_info_xs_read(gc, dom, bus, dev, func, + "driver_path")) !=3D NULL ) { + LOG(INFO, PCI_BDF" not bound to a driver, will be rebound to %= s", + dom, bus, dev, func, driver_path); + } else { + LOG(WARN, PCI_BDF" not bound to a driver, will not be rebound.= ", + dom, bus, dev, func); + } + } else { + pcid_info_xs_remove(gc, dom, bus, dev, func, "driver_path"); + } + + if (pciback_dev_assign(gc, dom, bus, dev, func)) { + LOG(ERROR, "Couldn't bind device to pciback!"); + return ERROR_FAIL; + } + +done: + return 0; +} + +static int pciback_dev_unassign(libxl__gc *gc, unsigned int domain, + unsigned int bus, unsigned int dev, + unsigned int func) +{ + /* Remove from pciback */ + if ( sysfs_dev_unbind(gc, domain, bus, dev, func, NULL) < 0 ) { + LOG(ERROR, "Couldn't unbind device!"); + return ERROR_FAIL; + } + + /* Remove slot if necessary */ + if ( pciback_dev_has_slot(gc, domain, bus, dev, func) > 0 ) { + if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/remove_slot", + domain, bus, dev, func) < 0 ) { + LOGE(ERROR, "Couldn't remove pciback slot"); + return ERROR_FAIL; + } + } + return 0; +} + +static int process_revert_assignable(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc; + bool rebind; + char *driver_path =3D NULL; + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_REBIND, request, JSON_BO= OL); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'rebind'", comma= nd_name); + return ERROR_FAIL; + } + + rebind =3D libxl__json_object_get_bool(json_o); + + /* Unbind from pciback */ + if ( (rc =3D pciback_dev_is_assigned(gc, dom, bus, dev, func)) < 0 ) { + make_error_reply(gc, gen, "Can't unbind from pciback", command_nam= e); + return ERROR_FAIL; + } else if ( rc ) { + pciback_dev_unassign(gc, dom, bus, dev, func); + } else { + LOG(WARN, "Not bound to pciback"); + } + + /* Rebind if necessary */ + driver_path =3D pcid_info_xs_read(gc, dom, bus, dev, func, "driver_pat= h"); + + if ( driver_path ) { + if ( rebind ) { + LOG(INFO, "Rebinding to driver at %s", driver_path); + + if ( sysfs_write_bdf(gc, + GCSPRINTF("%s/bind", driver_path), + dom, bus, dev, func) < 0 ) { + LOGE(ERROR, "Couldn't bind device to %s", driver_path); + return -1; + } + + pcid_info_xs_remove(gc, dom, bus, dev, func, "driver_path"); + } + } else { + if ( rebind ) { + LOG(WARN, + "Couldn't find path for original driver; not rebinding"); + } + } + + return 0; +} + static int pcid_handle_request(libxl__gc *gc, yajl_gen gen, const libxl__json_object *request) { @@ -142,6 +532,12 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen= gen, if (strcmp(command_name, PCID_CMD_LIST_ASSIGNABLE) =3D=3D 0) ret =3D process_list_assignable(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_MAKE_ASSIGNABLE) =3D=3D 0) + ret =3D process_make_assignable(gc, gen, command_name, + request, &command_response); + else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) =3D=3D 0) + ret =3D process_revert_assignable(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782309; cv=none; d=zohomail.com; s=zohoarc; b=TUbLJQjeZnnF/Exw/jDiZIQV/8bgP7BLObRPSS+vKvctREo/ZNY47FsBaLucvgD1paYmoJ3ClkFwnwz1/cJHznLs9WC6RweUcuC9LU8TkmWp6SUEAp4495XHkQFmA5b6ajTDsauW4Nxj3O38rwM99ZsVLBzNhrzhLKCDI+6zPm4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782309; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=X6pojTqohgbfc6HlNckJ9zlssPABsEQZhoi9N0xRTxw=; b=cH68x6PWlvB590IHbzxekLQUf+cUcdJuVO8V7I5/KrX+nU9fMAgrU/mqxHx6NNiAmzktqczy5bzk5R93wk7Ppc93mKp2YPDfuB6R3GausH9Z763IZeF1cyvq/Lj5tCEA3IdC0yPZfhmrav1BSxmqDdUhdkAUlg2U66kEiJsFJBM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782309907595.3175431138103; Sun, 15 Jan 2023 03:31:49 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477863.740810 (Exim 4.92) (envelope-from ) id 1pH1ET-00063t-QO; Sun, 15 Jan 2023 11:31:25 +0000 Received: by outflank-mailman (output) from mailman id 477863.740810; Sun, 15 Jan 2023 11:31:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ET-000630-HR; Sun, 15 Jan 2023 11:31:25 +0000 Received: by outflank-mailman (input) for mailman id 477863; Sun, 15 Jan 2023 11:31:24 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1ER-0004ci-SL for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:23 +0000 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [2a00:1450:4864:20::62a]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 239eae73-94c8-11ed-91b6-6bf2151ebd3b; Sun, 15 Jan 2023 12:31:23 +0100 (CET) Received: by mail-ej1-x62a.google.com with SMTP id bk15so4531517ejb.9 for ; Sun, 15 Jan 2023 03:31:23 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:21 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 239eae73-94c8-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=X6pojTqohgbfc6HlNckJ9zlssPABsEQZhoi9N0xRTxw=; b=BcMKaFa411QobFIhInxDjJUI8JkLC8GEhG0hTQH8KxYKVDH0SstOxoy9CFMAMbBH/R Xo48qU5Bf7Zghmb3isT6DkmMkSG2CYv5dZSGKJU5lg6jLESu8I5fQmWH/krF/D8s2VOB UszVy4v09Xpc2AfGnx1SF7OnjTRuUWZwPehpGBWnVk+cB1iGEIhmMTJkE5rb/O545w3a lr9w/hgGCMXc73EADqXkudFaP9L557UesX7qiuUv3iohljLoFDByox/qI8Ccvv6vQVPw g3R7fotNvFWJX4GUqLkBeO1+dfBOk64iXr48pDknJX1PKSqjXXDclGVTpF8S0Qs5qDVt Z3dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X6pojTqohgbfc6HlNckJ9zlssPABsEQZhoi9N0xRTxw=; b=WzpTkqOl2dG8XmOoZGvTtGe5NI+4lRTCxaMQAYNIXLYa769kpFN9QrnR9CcLJvJaz3 7YF5sQHPQ5Khsylq3+SkI/afoGwTdATpNTn1rrXG6cA+3KpvvdepdB/2f0Py66W/Hc5p OAyIgp4utvPW4CAOCf5FXbifTzn9iYWUH83H9iwqqlX4byWJcDaubTfXL7/gCepnJOx0 Zo2n2+bjxWFctHJJLrJRVRmOeOFkyxRCmzrfVvLdwm9yeECX/0TYIZ+lU9WPW351/BA6 Uy8tiVI0ubkhxcQiFfdMsu3Wo8TZ6katNsWRWscQYQpsHO4HK5ZQ0z49ep/9QK+Zozlc 1JvA== X-Gm-Message-State: AFqh2krgs44zzqBuy1nUiRuUEFwiuB2+tfdW4Jp9kVAQV2/UnLPnWw8t 0aq6CVRXytqeRp8Vo9Jd7iB655QhNVkvKFq6 X-Google-Smtp-Source: AMrXdXvOSIf8FV/MCs4zS31QZqNbKyoeuGhPIH8lGD3/tJRCRp+7UYM91FAowYKZ1MYzHrDOMgLtiw== X-Received: by 2002:a17:906:b053:b0:7ad:ca80:5669 with SMTP id bj19-20020a170906b05300b007adca805669mr89988229ejb.64.1673782282413; Sun, 15 Jan 2023 03:31:22 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 07/10] tools/libs/light: pcid: implement is_device_assigned command Date: Sun, 15 Jan 2023 13:31:08 +0200 Message-Id: <20230115113111.1207605-8-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782310802100002 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Signed-off-by: Dmytro Semenets --- tools/include/pcid.h | 19 ++++++++++++++++ tools/libs/light/libxl_pci.c | 43 +++++++++++++++++++---------------- tools/libs/light/libxl_pcid.c | 34 ++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 21 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 118f8105cf..983e067dfc 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -135,6 +135,25 @@ */ #define PCID_CMD_REVERT_ASSIGNABLE "revert_assignable" =20 +/* + *************************************************************************= ****** + * Check is device assigned + * + * This command checks device is assigned + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "is_device_assigned". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "is_device_assigned". + * Command specific response data: + * +-------------+--------------+-----------------------------------------= -----+ + * | result | bool | true if device assigned = | + * +-------------+--------------+-----------------------------------------= -----+ + */ +#define PCID_CMD_IS_ASSIGNED "is_device_assigned" +#define PCID_MSG_FIELD_RESULT "result" =20 int libxl_pcid_process(libxl_ctx *ctx); =20 diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 0351a0d3df..d68cb1986f 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -86,7 +86,9 @@ static int pci_handle_response(libxl__gc *gc, *result =3D libxl__json_object_alloc(gc, JSON_NULL); else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) =3D=3D 0) *result =3D libxl__json_object_alloc(gc, JSON_NULL); - + else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) =3D=3D 0) + *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIE= LD_RESULT, + response, JSON_B= OOL); return ret; } =20 @@ -753,30 +755,31 @@ bool libxl__is_igd_vga_passthru(libxl__gc *gc, =20 static int pciback_dev_is_assigned(libxl__gc *gc, libxl_device_pci *pci) { - char * spath; + struct vchan_info *vchan; int rc; - struct stat st; + libxl__json_object *args, *result; =20 - if ( access(SYSFS_PCIBACK_DRIVER, F_OK) < 0 ) { - if ( errno =3D=3D ENOENT ) { - LOG(ERROR, "Looks like pciback driver is not loaded"); - } else { - LOGE(ERROR, "Can't access "SYSFS_PCIBACK_DRIVER); - } - return -1; + vchan =3D pci_vchan_get_client(gc); + if (!vchan) { + rc =3D ERROR_NOT_READY; + goto out; } =20 - spath =3D GCSPRINTF(SYSFS_PCIBACK_DRIVER"/"PCI_BDF, - pci->domain, pci->bus, - pci->dev, pci->func); - rc =3D lstat(spath, &st); + args =3D libxl__vchan_start_args(gc); =20 - if( rc =3D=3D 0 ) - return 1; - if ( rc < 0 && errno =3D=3D ENOENT ) - return 0; - LOGE(ERROR, "Accessing %s", spath); - return -1; + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, pci->domain, + pci->bus, pci->dev, pci->func)); + + result =3D vchan_send_command(gc, vchan, PCID_CMD_IS_ASSIGNED, args); + if (!result) { + rc =3D ERROR_FAIL; + } + rc =3D result->u.b; + pci_vchan_free(gc, vchan); + +out: + return rc; } =20 static int libxl__device_pci_assignable_add(libxl__gc *gc, diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index d8245195ee..d72beed405 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -147,7 +147,7 @@ static int pciback_dev_is_assigned(libxl__gc *gc, unsig= ned int domain, if (rc < 0 && errno =3D=3D ENOENT) return 0; LOGE(ERROR, "Accessing %s", spath); - return -1; + return 0; } =20 #define PCID_INFO_PATH "pcid" @@ -335,6 +335,35 @@ static int pciback_dev_assign(libxl__gc *gc, unsigned = int domain, return 0; } =20 +static int process_pciback_dev_is_assigned(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc; + + libxl__yajl_gen_asciiz(gen, PCID_MSG_FIELD_RESULT); + *response =3D libxl__json_object_alloc(gc, JSON_BOOL); + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + rc =3D pciback_dev_is_assigned(gc, dom, bus, dev, func); + if (rc < 0) + return ERROR_FAIL; + (*response)->u.b =3D rc; + return 0; +} + static int process_make_assignable(libxl__gc *gc, yajl_gen gen, char *command_name, const struct libxl__json_object *reques= t, @@ -538,6 +567,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen = gen, else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) =3D=3D 0) ret =3D process_revert_assignable(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) =3D=3D 0) + ret =3D process_pciback_dev_is_assigned(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782309; cv=none; d=zohomail.com; s=zohoarc; b=aW+4uXrFBk2zJ4seHcHTEaC1vUbzTT3KFtR6hry6X8s+RzreF3IWirxm/dYBDducQRxPBUqP4EAiSiWSQ0p3R5EoYgO4aF2S0RXxTpoVMTwbOliVyITN9YNlVNimJkrbgqijTNzjztao+/Zc4WGN30N/+p+pNnpDOvgkLgXiSRE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782309; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Xrk/C/YZL5jbZac94OfOErvgSHJBWQ1xYVIaSMYUI8w=; b=RWbmULIcVHWVBKBsuZ1R0JjWergLA4R5mhUD6NjIxGsUDpt8o79UlBNLSvQd+SuIzouog4aou12nX3WctavRs5TLeBAZfxfw+NYfa8s/W/i2SccKcBw5qABbg26rsp8hfSHLluftfHZta3QdbnFTUsespXYGaniEQ0M5yLQWC2g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782309751891.4945258763486; Sun, 15 Jan 2023 03:31:49 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477865.740828 (Exim 4.92) (envelope-from ) id 1pH1EV-0006Xc-JO; Sun, 15 Jan 2023 11:31:27 +0000 Received: by outflank-mailman (output) from mailman id 477865.740828; Sun, 15 Jan 2023 11:31:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EV-0006Wr-8I; Sun, 15 Jan 2023 11:31:27 +0000 Received: by outflank-mailman (input) for mailman id 477865; Sun, 15 Jan 2023 11:31:26 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EU-0004co-DE for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:26 +0000 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [2a00:1450:4864:20::633]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 243543c7-94c8-11ed-b8d0-410ff93cb8f0; Sun, 15 Jan 2023 12:31:24 +0100 (CET) Received: by mail-ej1-x633.google.com with SMTP id vm8so62019600ejc.2 for ; Sun, 15 Jan 2023 03:31:24 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:23 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 243543c7-94c8-11ed-b8d0-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Xrk/C/YZL5jbZac94OfOErvgSHJBWQ1xYVIaSMYUI8w=; b=VtNcbBNxJQHL8qNJ13hjEKUccbTHIhsH+7PdDIVkx03I0dj93avNdZj2yMqZtplsxn 5Ka51TPEkoQFzU5mq9MAARaZxKlKsvrUE1ZB3bkacojsBZGVG7Oo0iMtSWBwWpSs7e5r gqtMo488X0izuIxDjKsaaBIFEXoT1ILUR92JfET09m2H2iofTap+Nq0rpHnxVZ6bUOSi URlvSfs4juLQJ6bd5PX0MbLCceDqEtCn/6hEF1wtcp3s+8k7Wc60BrsIYIQdt0DsurVL rXrPZvVNmDMF6fWbSsi03JUkHmo6N6NoX0pketo2xDhxsrjshJZ0OfRgIHMazYPS9TPO X05g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Xrk/C/YZL5jbZac94OfOErvgSHJBWQ1xYVIaSMYUI8w=; b=eaXn9WFkBNnIQU1pciyS8dmoG9KxWw0vCTeyMgJRgug6x0/Z6RtQodkMFhi4tuQqcq br4whrCyYUgYlHO6pdUqKGmSbu5A6lP48arSGNY2/ZIqroDrDCNAQU0enqzh9nLW3ApJ C7gPbCucKQBpJsln0GjVHd/gm97Hf+jrr16PkE1vdMiU4tyiQ0EdTgPNITloLsBu4psO a1CQbYswJmn59NoL8rAIb3lVvMfEXBa7ySrO/S91ie1THd6oks0+r6E5TRHqbjZTyDCU 63AuaKkVz3PZCX5FCbKghfP0fAh5qVew1Panp851Lu1NoypKMWCgxHxAiaQ/Vc5M0dDL hDEQ== X-Gm-Message-State: AFqh2koq+d0YPR2m74Hu4R2TdJ/1/JuuNcK9wHis/8LSTHMA1/vBAUbI NptuDgRFPp5ZouO4orFumCxf5Ovk6OiomjwP X-Google-Smtp-Source: AMrXdXsZ1NOKoKhI67d7/ClWLpVJASzmYxGSrjUO1bFyEb+E0FluHbskFeoq51YxQuaL0nxzmDBKVw== X-Received: by 2002:a17:906:eb09:b0:84d:34fa:f1a4 with SMTP id mb9-20020a170906eb0900b0084d34faf1a4mr25284731ejb.60.1673782283481; Sun, 15 Jan 2023 03:31:23 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 08/10] tools/libs/light: pcid: implement reset_device command Date: Sun, 15 Jan 2023 13:31:09 +0200 Message-Id: <20230115113111.1207605-9-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782310987100007 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Signed-off-by: Dmytro Semenets --- tools/include/pcid.h | 15 ++++++++ tools/libs/light/libxl_pci.c | 52 +++++++++++---------------- tools/libs/light/libxl_pcid.c | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 31 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 983e067dfc..63ac0bcac9 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -155,6 +155,21 @@ #define PCID_CMD_IS_ASSIGNED "is_device_assigned" #define PCID_MSG_FIELD_RESULT "result" =20 +/* + *************************************************************************= ****** + * Reset PCI device + * + * This command resets PCI device + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "reset_device". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "reset_device". + */ +#define PCID_CMD_RESET_DEVICE "reset_device" + int libxl_pcid_process(libxl_ctx *ctx); =20 #endif /* PCID_H */ diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index d68cb1986f..e9f0bad442 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -89,6 +89,8 @@ static int pci_handle_response(libxl__gc *gc, else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) =3D=3D 0) *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIE= LD_RESULT, response, JSON_B= OOL); + else if (strcmp(command_name, PCID_CMD_RESET_DEVICE) =3D=3D 0) + *result =3D libxl__json_object_alloc(gc, JSON_NULL); return ret; } =20 @@ -1518,38 +1520,26 @@ out: static int libxl__device_pci_reset(libxl__gc *gc, unsigned int domain, uns= igned int bus, unsigned int dev, unsigned int func) { - char *reset; - int fd, rc; - - reset =3D GCSPRINTF("%s/do_flr", SYSFS_PCIBACK_DRIVER); - fd =3D open(reset, O_WRONLY); - if (fd >=3D 0) { - char *buf =3D GCSPRINTF(PCI_BDF, domain, bus, dev, func); - rc =3D write(fd, buf, strlen(buf)); - if (rc < 0) - LOGD(ERROR, domain, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno !=3D ENOENT) - LOGED(ERROR, domain, "Failed to access pciback path %s", reset); - reset =3D GCSPRINTF("%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, = dev, func); - fd =3D open(reset, O_WRONLY); - if (fd >=3D 0) { - rc =3D write(fd, "1", 1); - if (rc < 0) - LOGED(ERROR, domain, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno =3D=3D ENOENT) { - LOGD(ERROR, domain, - "The kernel doesn't support reset from sysfs for PCI device "= PCI_BDF, - domain, bus, dev, func); - } else { - LOGED(ERROR, domain, "Failed to access reset path %s", reset); + struct vchan_info *vchan; + int rc =3D 0; + libxl__json_object *args, *result; + + vchan =3D pci_vchan_get_client(gc); + if (!vchan) { + rc =3D ERROR_NOT_READY; + goto out; } - return -1; + args =3D libxl__vchan_start_args(gc); + + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, domain, bus, dev, func)); + result =3D vchan_send_command(gc, vchan, PCID_CMD_RESET_DEVICE, args); + if (!result) + rc =3D ERROR_FAIL; + pci_vchan_free(gc, vchan); + + out: + return rc; } =20 int libxl__device_pci_setdefault(libxl__gc *gc, uint32_t domid, diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index d72beed405..80bcd3c63e 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -364,6 +364,69 @@ static int process_pciback_dev_is_assigned(libxl__gc *= gc, yajl_gen gen, return 0; } =20 +static int device_pci_reset(libxl__gc *gc, unsigned int domain, unsigned i= nt bus, + unsigned int dev, unsigned int func) +{ + char *reset; + int fd, rc; + + reset =3D GCSPRINTF("%s/do_flr", SYSFS_PCIBACK_DRIVER); + fd =3D open(reset, O_WRONLY); + if (fd >=3D 0) { + char *buf =3D GCSPRINTF(PCI_BDF, domain, bus, dev, func); + rc =3D write(fd, buf, strlen(buf)); + if (rc < 0) + LOGD(ERROR, domain, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno !=3D ENOENT) + LOGED(ERROR, domain, "Failed to access pciback path %s", reset); + reset =3D GCSPRINTF("%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, = dev, func); + fd =3D open(reset, O_WRONLY); + if (fd >=3D 0) { + rc =3D write(fd, "1", 1); + if (rc < 0) + LOGED(ERROR, domain, "write to %s returned %d", reset, rc); + close(fd); + return rc < 0 ? rc : 0; + } + if (errno =3D=3D ENOENT) { + LOGD(ERROR, domain, + "The kernel doesn't support reset from sysfs for PCI device "= PCI_BDF, + domain, bus, dev, func); + } else { + LOGED(ERROR, domain, "Failed to access reset path %s", reset); + } + return -1; +} + +static int process_device_pci_reset(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc; + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + rc =3D device_pci_reset(gc, dom, bus, dev, func); + if (rc < 0) + return ERROR_FAIL; + return rc; +} + static int process_make_assignable(libxl__gc *gc, yajl_gen gen, char *command_name, const struct libxl__json_object *reques= t, @@ -570,6 +633,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen = gen, else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) =3D=3D 0) ret =3D process_pciback_dev_is_assigned(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_RESET_DEVICE) =3D=3D 0) + ret =3D process_device_pci_reset(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782313; cv=none; d=zohomail.com; s=zohoarc; b=MZOrSmC0gduyCSc/BOkN8W6Bgj8zTBJVQLswQM2kCaTbaJRcQBPtzP9tiCvnBgma1qDQDay2MRxy/maRbbIznj1Ktb9Q4zqwvp60BgaaBuTWwX8za5PrWCpX9LFE4/Yz8BmzoKYtBejDHA0fLElMZz8Y0DzPsEknTZa9h0MvmT8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782313; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=+mtALKQlPwVEF5U0ik7VRrk0fFuHPK8gOgYu9sCiUsM=; b=HLdj5rzdtvBUNf1YMQ64ZQ25kxApoqs+SfGIwtQHR+2zqnlq+UDCqXoxFbSZhx/9l7pPBkYkWcpTiizughqrrj55SxVlT8HMVDIVuFWDF6KOywejCGE5CkCY3FvJZiJZC6s6CJG7VL6AxmlSgD7+OvkbENjpFMPhk2eoB2Naf8c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782313969344.0314207302905; Sun, 15 Jan 2023 03:31:53 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477867.740852 (Exim 4.92) (envelope-from ) id 1pH1EY-0007Fx-O6; Sun, 15 Jan 2023 11:31:30 +0000 Received: by outflank-mailman (output) from mailman id 477867.740852; Sun, 15 Jan 2023 11:31:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EY-0007EO-A9; Sun, 15 Jan 2023 11:31:30 +0000 Received: by outflank-mailman (input) for mailman id 477867; Sun, 15 Jan 2023 11:31:28 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EV-0004co-Ne for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:27 +0000 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [2a00:1450:4864:20::635]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 24d8fbed-94c8-11ed-b8d0-410ff93cb8f0; Sun, 15 Jan 2023 12:31:25 +0100 (CET) Received: by mail-ej1-x635.google.com with SMTP id kt14so3138294ejc.3 for ; Sun, 15 Jan 2023 03:31:25 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:24 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 24d8fbed-94c8-11ed-b8d0-410ff93cb8f0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+mtALKQlPwVEF5U0ik7VRrk0fFuHPK8gOgYu9sCiUsM=; b=CE/3ULVB9SpcW6LlUxdmDTxQectR15DDiHVLnD89g9HUpoRoGsdV12uwSxniPJ1jnU BXf2msA30m3zan9lIOwObqXPV3SkvPeIzxr8HDGiUF86QIMY/NOvm72ke6qglA2eOUmb DTypfSN/covIcd7c4Zay4nnzRuFGrgRNWsipmNZJDjcpYSaXAanIHbc/4j8I5BK58nLn zSiQAVfV8lpgh0UZUTReA9h08ayhW7P/QndYf77Ok4P0ffTr7lb3HsIk63ZkhbhzjaCX egOJkXcpezAFuUJ66pmcKCXO/v1+sgS8VxDF8DuUny3KuOThUxHjYVMTjYJMcCVTsYLa 4dtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+mtALKQlPwVEF5U0ik7VRrk0fFuHPK8gOgYu9sCiUsM=; b=IsL1ihP/pMIxdLwHeLrVEc/oyLkAUH16YMB4ypuftsp9ZtnqplbcnPPpJ03LA+q8SW L+k1RaRM6JiZbJxfJHJbJwJIYlxKE5E9YzNAzmZpeL+hKSrXM8wn4GbimFQ1OFWnDFNl Ydyu5Xh02IRS8KIUuElZzoFP63tTzLjIVYJVY8LVPSTGIB4XrNgdseaRt1Ao+/Zm0Ouk TK95u9AdExGdFvAC6hzKcMQvFy7XoDZ0gWpxIJOaJTIVXfHgT44Ua9NV4vnzNvxUgANv lOv4af7WqZUK7y2REkuKnQ33eBBh5DeR0h5FEprkWKklANjeMk4FgDxHQkWRbnb3zOiF l57A== X-Gm-Message-State: AFqh2kp4Y1ev+SOgsELayMrjQoms+shNuE3eAmPkSd2LnjsrGNaNjPGG lRxTtCHaPSp9RunHfiNDM/9oITs+PIBUvTmr X-Google-Smtp-Source: AMrXdXsSAXNShODj7QVtcBkVZdHwv7RQ9FqDmQAFZzvvyzYxA7FcyDE/dmJoJZTz3YV19UI4Vtu+TQ== X-Received: by 2002:a17:906:e81:b0:7c1:962e:cf23 with SMTP id p1-20020a1709060e8100b007c1962ecf23mr70469799ejf.37.1673782284482; Sun, 15 Jan 2023 03:31:24 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 09/10] tools/libs/light: pcid: implement resource_list command Date: Sun, 15 Jan 2023 13:31:10 +0200 Message-Id: <20230115113111.1207605-10-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782314827100017 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Signed-off-by: Dmytro Semenets --- tools/include/pcid.h | 26 ++++++++ tools/libs/light/libxl_pci.c | 63 ++++++++++--------- tools/libs/light/libxl_pcid.c | 110 +++++++++++++++++++++++++++++++++ tools/libs/light/libxl_vchan.c | 8 +++ tools/libs/light/libxl_vchan.h | 4 +- 5 files changed, 180 insertions(+), 31 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 63ac0bcac9..833b6c7f3e 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -155,6 +155,32 @@ #define PCID_CMD_IS_ASSIGNED "is_device_assigned" #define PCID_MSG_FIELD_RESULT "result" =20 +/* + *************************************************************************= ****** + * Get device resources + * + * This command returns resource list of device + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "resource_list". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "resource_list". + * Command specific response data: + * +-------------+--------------+-----------------------------------------= -----+ + * | resources | map | key 'iomem' - list of memory regions = | + * | | | key 'irqs' - list of irqs = | + * +-------------+--------------+-----------------------------------------= -----+ + */ +#define PCID_CMD_RESOURCE_LIST "resource_list" +/* Arguments */ +#define PCID_MSG_FIELD_DOMID "domid" +/* Result */ +#define PCID_MSG_FIELD_RESOURCES "resources" +#define PCID_RESULT_KEY_IOMEM "iomem" +#define PCID_RESULT_KEY_IRQS "irqs" + /* *************************************************************************= ****** * Reset PCI device diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index e9f0bad442..2e7bd2eae5 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -81,16 +81,19 @@ static int pci_handle_response(libxl__gc *gc, LOG(DEBUG, "command: %s", command_name); =20 if (strcmp(command_name, PCID_CMD_LIST_ASSIGNABLE) =3D=3D 0) - ret =3D process_list_assignable(gc, response, result); + ret =3D process_list_assignable(gc, response, result); else if (strcmp(command_name, PCID_CMD_MAKE_ASSIGNABLE) =3D=3D 0) *result =3D libxl__json_object_alloc(gc, JSON_NULL); else if (strcmp(command_name, PCID_CMD_REVERT_ASSIGNABLE) =3D=3D 0) *result =3D libxl__json_object_alloc(gc, JSON_NULL); else if (strcmp(command_name, PCID_CMD_IS_ASSIGNED) =3D=3D 0) *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIE= LD_RESULT, - response, JSON_B= OOL); + response, JSON_BOOL); else if (strcmp(command_name, PCID_CMD_RESET_DEVICE) =3D=3D 0) *result =3D libxl__json_object_alloc(gc, JSON_NULL); + else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) =3D=3D 0) + *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIE= LD_RESOURCES, + response, JSON_MAP); return ret; } =20 @@ -1388,14 +1391,21 @@ static void pci_add_dm_done(libxl__egc *egc, STATE_AO_GC(pas->aodev->ao); libxl_ctx *ctx =3D libxl__gc_owner(gc); libxl_domid domid =3D pas->pci_domid; - char *sysfs_path; - FILE *f; unsigned long long start, end, flags, size; int irq, i; int r; uint32_t flag =3D XEN_DOMCTL_DEV_RDM_RELAXED; uint32_t domainid =3D domid; bool isstubdom =3D libxl_is_stubdom(ctx, domid, &domainid); + struct vchan_info *vchan; + libxl__json_object *result; + libxl__json_object *args; + const libxl__json_object *value; + libxl__json_object *res_obj; + + vchan =3D pci_vchan_get_client(gc); + if (!vchan) + goto out; =20 /* Convenience aliases */ bool starting =3D pas->starting; @@ -1404,25 +1414,27 @@ static void pci_add_dm_done(libxl__egc *egc, =20 libxl__ev_qmp_dispose(gc, &pas->qmp); =20 - if (rc) goto out; + args =3D libxl__vchan_start_args(gc); + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, pci->domain, + pci->bus, pci->dev, pci->func)); + libxl__vchan_arg_add_integer(gc, args, PCID_MSG_FIELD_DOMID, domid); + + result =3D vchan_send_command(gc, vchan, PCID_CMD_RESOURCE_LIST, args); + if (!result) + goto vchan_free; + value =3D libxl__json_map_get(PCID_RESULT_KEY_IOMEM, result, JSON_ARRA= Y); =20 /* stubdomain is always running by now, even at create time */ if (isstubdom) starting =3D false; - - sysfs_path =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->doma= in, - pci->bus, pci->dev, pci->func); - f =3D fopen(sysfs_path, "r"); start =3D end =3D flags =3D size =3D 0; irq =3D 0; - - if (f =3D=3D NULL) { - LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); - rc =3D ERROR_FAIL; - goto out; - } for (i =3D 0; i < PROC_PCI_NUM_RESOURCES; i++) { - if (fscanf(f, "0x%llx 0x%llx 0x%llx\n", &start, &end, &flags) !=3D= 3) + if ((res_obj =3D libxl__json_array_get(value, i)) =3D=3D NULL) + continue; + const char *iomem_str =3D libxl__json_object_get_string(res_obj); + if (sscanf(iomem_str, "0x%llx 0x%llx 0x%llx\n", &start, &end, &fla= gs) !=3D 3) continue; size =3D end - start + 1; if (start) { @@ -1432,7 +1444,6 @@ static void pci_add_dm_done(libxl__egc *egc, LOGED(ERROR, domainid, "xc_domain_ioport_permission 0x%llx/0x%llx (erro= r %d)", start, size, r); - fclose(f); rc =3D ERROR_FAIL; goto out; } @@ -1443,29 +1454,21 @@ static void pci_add_dm_done(libxl__egc *egc, LOGED(ERROR, domainid, "xc_domain_iomem_permission 0x%llx/0x%llx (error= %d)", start, size, r); - fclose(f); rc =3D ERROR_FAIL; goto out; } } } } - fclose(f); if (!pci_supp_legacy_irq()) goto out_no_irq; - sysfs_path =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain, - pci->bus, pci->dev, pci->func); - f =3D fopen(sysfs_path, "r"); - if (f =3D=3D NULL) { - LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); - goto out_no_irq; - } - if ((fscanf(f, "%u", &irq) =3D=3D 1) && irq) { + value =3D libxl__json_map_get(PCID_RESULT_KEY_IRQS, result, JSON_ARRAY= ); + if ((res_obj =3D libxl__json_array_get(value, i)) && + (irq =3D libxl__json_object_get_integer(res_obj))) { r =3D xc_physdev_map_pirq(ctx->xch, domid, irq, &irq); if (r < 0) { LOGED(ERROR, domainid, "xc_physdev_map_pirq irq=3D%d (error=3D= %d)", irq, r); - fclose(f); rc =3D ERROR_FAIL; goto out; } @@ -1473,12 +1476,10 @@ static void pci_add_dm_done(libxl__egc *egc, if (r < 0) { LOGED(ERROR, domainid, "xc_domain_irq_permission irq=3D%d (error=3D%d)", irq, r= ); - fclose(f); rc =3D ERROR_FAIL; goto out; } } - fclose(f); =20 /* Don't restrict writes to the PCI config space from this VM */ if (pci->permissive) { @@ -1511,6 +1512,8 @@ out_no_irq: rc =3D libxl__device_pci_add_xenstore(gc, domid, pci, starting); else rc =3D 0; +vchan_free: + pci_vchan_free(gc, vchan); out: libxl__ev_time_deregister(gc, &pas->timeout); libxl__ev_time_deregister(gc, &pas->timeout_retries); diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index 80bcd3c63e..d968071224 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -40,6 +40,10 @@ =20 #define PCI_BDF "%04x:%02x:%02x.%01x" =20 +static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path, + unsigned int domain, unsigned int bus, + unsigned int dev, unsigned int func); + struct vchan_client { XEN_LIST_ENTRY(struct vchan_client) list; =20 @@ -121,6 +125,109 @@ static int process_list_assignable(libxl__gc *gc, yaj= l_gen gen, return 0; } =20 +static bool pci_supp_legacy_irq(void) +{ +#ifdef CONFIG_PCI_SUPP_LEGACY_IRQ + return true; +#else + return false; +#endif +} + +static int process_list_resources(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + struct libxl__json_object *iomem =3D + libxl__json_object_alloc(gc, JSON_ARRAY); + struct libxl__json_object *irqs =3D + libxl__json_object_alloc(gc, JSON_ARRAY); + const struct libxl__json_object *json_sdbf; + const struct libxl__json_object *json_domid; + unsigned int dom, bus, dev, func; + libxl_domid domainid; + char *sysfs_path; + FILE *f; + unsigned long long start, end, flags; + int irq, i; + int rc =3D 0; + libxl__json_map_node *map_node =3D NULL; + + json_sdbf =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_S= TRING); + if (!json_sdbf) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + if (sscanf(libxl__json_object_get_string(json_sdbf), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + + json_domid =3D libxl__json_map_get(PCID_MSG_FIELD_DOMID, request, JSON= _INTEGER); + if (!json_domid) { + make_error_reply(gc, gen, "No mandatory parameter 'domid'", comman= d_name); + return ERROR_FAIL; + } + domainid =3D libxl__json_object_get_integer(json_domid); + + libxl__yajl_gen_asciiz(gen, PCID_MSG_FIELD_RESOURCES); + *response =3D libxl__json_object_alloc(gc, JSON_MAP); + + sysfs_path =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", dom, bus,= dev, func); + f =3D fopen(sysfs_path, "r"); + start =3D 0; + irq =3D 0; + + if (f =3D=3D NULL) { + LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); + rc =3D ERROR_FAIL; + goto out; + } + for (i =3D 0; i < PROC_PCI_NUM_RESOURCES; i++) { + if (fscanf(f, "0x%llx 0x%llx 0x%llx\n", &start, &end, &flags) !=3D= 3) + continue; + if (start) { + struct libxl__json_object *node =3D + libxl__json_object_alloc(gc, JSON_STRING); + + node->u.string =3D GCSPRINTF("0x%llx 0x%llx 0x%llx", start, en= d, flags); + flexarray_append(iomem->u.array, node); + } + } + fclose(f); + if (!pci_supp_legacy_irq()) + goto out_no_irq; + sysfs_path =3D GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", dom, bus, dev,= func); + f =3D fopen(sysfs_path, "r"); + if (f =3D=3D NULL) { + LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); + goto out_no_irq; + } + if ((fscanf(f, "%u", &irq) =3D=3D 1) && irq) { + struct libxl__json_object *node =3D + libxl__json_object_alloc(gc, JSON_INTEGER); + + node->u.i =3D irq; + flexarray_append(irqs->u.array, node); + } + fclose(f); + + GCNEW(map_node); + map_node->map_key =3D libxl__strdup(gc, PCID_RESULT_KEY_IRQS); + map_node->obj =3D irqs; + flexarray_append((*response)->u.map, map_node); +out_no_irq: + GCNEW(map_node); + map_node->map_key =3D libxl__strdup(gc, PCID_RESULT_KEY_IOMEM); + map_node->obj =3D iomem; + flexarray_append((*response)->u.map, map_node); + rc =3D 0; +out: + return rc; +} + static int pciback_dev_is_assigned(libxl__gc *gc, unsigned int domain, unsigned int bus, unsigned int dev, unsigned int func) @@ -636,6 +743,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen = gen, else if (strcmp(command_name, PCID_CMD_RESET_DEVICE) =3D=3D 0) ret =3D process_device_pci_reset(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) =3D=3D 0) + ret =3D process_list_resources(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over diff --git a/tools/libs/light/libxl_vchan.c b/tools/libs/light/libxl_vchan.c index 7611816f52..a1beda9e1b 100644 --- a/tools/libs/light/libxl_vchan.c +++ b/tools/libs/light/libxl_vchan.c @@ -99,6 +99,14 @@ void libxl__vchan_arg_add_bool(libxl__gc *gc, libxl__jso= n_object *args, obj->u.b =3D val; } =20 +void libxl__vchan_arg_add_integer(libxl__gc *gc, libxl__json_object *args, + char *key, int val) +{ + libxl__json_object *obj =3D libxl__vchan_arg_new(gc, JSON_INTEGER, arg= s, key); + + obj->u.i =3D val; +} + static void reset_yajl_generator(struct vchan_state *state) { yajl_gen_clear(state->gen); diff --git a/tools/libs/light/libxl_vchan.h b/tools/libs/light/libxl_vchan.h index 0968875298..07f0db4e93 100644 --- a/tools/libs/light/libxl_vchan.h +++ b/tools/libs/light/libxl_vchan.h @@ -58,7 +58,9 @@ static inline libxl__json_object *libxl__vchan_start_args= (libxl__gc *gc) void libxl__vchan_arg_add_string(libxl__gc *gc, libxl__json_object *args, char *key, char *val); void libxl__vchan_arg_add_bool(libxl__gc *gc, libxl__json_object *args, - char *key, bool val); + char *key, bool val); +void libxl__vchan_arg_add_integer(libxl__gc *gc, libxl__json_object *args, + char *key, int val); =20 libxl__json_object *vchan_send_command(libxl__gc *gc, struct vchan_info *v= chan, char *cmd, libxl__json_object *args= ); --=20 2.34.1 From nobody Mon Apr 29 13:28:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1673782313; cv=none; d=zohomail.com; s=zohoarc; b=n5YQjpwfe1Qrb6Re4opzR8gwkSqy1LvIRVJIzYOt6Bi7OEx9jOvxoeSuGfe1+b6KPoDa8sJj4voz+3aNPo6YdnPgnXs2mleZ8KKiA1axcqk6sV86+0YDq39R9pRTD6bbiMVG5maNYSmfF+1/AUID626n2XW3Op0iTeBxV+SXr/4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1673782313; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=6Di8T7RFkSXJWtJ7IeU06hxU0Lz5Aq6jlmAWzDwNGXI=; b=fvbGh/3teLhDOPDdgzF8Pso+UiUcNNydit5syMgcduyDr6P/HcMSyD6ylqgtM6cRU3HkrQFps46WMSjFmGdXf73xcbfrlsB6qtsopmfN4UFMstRvND9n2eNRmewsg9B5Rcd7VtLbMWXnTkH8sGaZxyLQq5VLeI7jiWK9wNdmnpQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1673782313852817.2908775882761; Sun, 15 Jan 2023 03:31:53 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.477866.740845 (Exim 4.92) (envelope-from ) id 1pH1EY-0007B4-32; Sun, 15 Jan 2023 11:31:30 +0000 Received: by outflank-mailman (output) from mailman id 477866.740845; Sun, 15 Jan 2023 11:31:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EX-0007Ap-UN; Sun, 15 Jan 2023 11:31:29 +0000 Received: by outflank-mailman (input) for mailman id 477866; Sun, 15 Jan 2023 11:31:27 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pH1EV-0004ci-3Q for xen-devel@lists.xenproject.org; Sun, 15 Jan 2023 11:31:27 +0000 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [2a00:1450:4864:20::62a]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 257c687c-94c8-11ed-91b6-6bf2151ebd3b; Sun, 15 Jan 2023 12:31:26 +0100 (CET) Received: by mail-ej1-x62a.google.com with SMTP id bk15so4531706ejb.9 for ; Sun, 15 Jan 2023 03:31:26 -0800 (PST) Received: from dsemenets-HP-EliteBook-850-G8-Notebook-PC.. ([91.219.254.73]) by smtp.gmail.com with ESMTPSA id uj42-20020a170907c9aa00b0084d4e612a22sm7459961ejc.67.2023.01.15.03.31.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Jan 2023 03:31:25 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 257c687c-94c8-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6Di8T7RFkSXJWtJ7IeU06hxU0Lz5Aq6jlmAWzDwNGXI=; b=iweg5CpL5M1YkOuzr2tqeKOpn4QsKSQbE4lPh15fHRb/E+IKHE0gont35IDfqMQ3Xm XEEi5YbTezWUNspnrfixupk/0YXZKwk9Zs6Lu4EAi8fDm0Ui3K710o2P29IO8tQLzSIt h/TtF4V7sgs+s3t4m8vi66Kl9mJIALrEE24zQ3jXym+rnvc6oXEdBJ4Wl0xBPQwfbGV6 0c27JUPC4gw94jUI3c+FZMe6UBL3ydJPwARhFwLZ8yWYs+VGTWAYpSiqWN7ObU7hPqYn 8lYZdkteljcxSLGijGGgaI5xVAFudZ5o6viwYgOZQWeLoNZ5vwR6WZkasgFR/IpPGnXM /qXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6Di8T7RFkSXJWtJ7IeU06hxU0Lz5Aq6jlmAWzDwNGXI=; b=sRryGQ0ivXOL70uigOJjg/3B0/pHgMfiB12CXKqGpj5cUHhinL4I1O/yKzmHVYmRB0 kmAhEXTiOm76Vxqwzsk+m94M9eetaeDgNSWuM5ifBcgTLIt6HZagSw2Js/sQSuSbynZY SPS+OlklwV4dwVY+TJG9AUSHcDcFVI4KPIzdXfoRAqAm3ZCQ3f6P4zTlbpkbd0ROpt55 Ku6WcewNTqsbdIjiafw/4EmTK4iNJUKNCTq/vKk0gl3Z2aEyiiPWEzRo1cCqOd+tC8N9 THJgt7MeKT7V2EQxu5GyMXqQJlaflEmffXDXcQcR5VvlwJxbbIFLrO62pmKs6hghuyxC s1Eg== X-Gm-Message-State: AFqh2kqWl2q3UT1VsfP+qZJ5YJFGtYYpRKkz31K5zjJYksvv1dGcRmvt g/nsMpOP0MN9D7X181cJ6Sz7xvPwqaLnZG9G X-Google-Smtp-Source: AMrXdXvLAVwK3qonUGLjg/wBl1L74Jpy3sI9dIZFYwDnDYGuPwbOjHUZ+FDmnz+U9lCjjOwhNEgR3A== X-Received: by 2002:a17:907:4d6:b0:7c0:d6ba:c934 with SMTP id vz22-20020a17090704d600b007c0d6bac934mr8040416ejb.13.1673782285537; Sun, 15 Jan 2023 03:31:25 -0800 (PST) From: Dmytro Semenets To: xen-devel@lists.xenproject.org Cc: Dmytro Semenets , Wei Liu , Anthony PERARD , Juergen Gross Subject: [RFC PATCH v3 10/10] tools/libs/light: pcid: implement write_bdf command Date: Sun, 15 Jan 2023 13:31:11 +0200 Message-Id: <20230115113111.1207605-11-dmitry.semenets@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230115113111.1207605-1-dmitry.semenets@gmail.com> References: <20230115113111.1207605-1-dmitry.semenets@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1673782314804100015 Content-Type: text/plain; charset="utf-8" From: Dmytro Semenets Signed-off-by: Dmytro Semenets --- tools/include/pcid.h | 17 +++++++++ tools/libs/light/libxl_pci.c | 67 ++++++++++++++++++----------------- tools/libs/light/libxl_pcid.c | 38 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 833b6c7f3e..2c1bd0727e 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -181,6 +181,23 @@ #define PCID_RESULT_KEY_IOMEM "iomem" #define PCID_RESULT_KEY_IRQS "irqs" =20 +/* + *************************************************************************= ****** + * Write BDF values to the pciback sysfs path + * + * This command resets PCI device + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "write_bdf". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * - "name" name of sysfs file of pciback driver + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "write_bdf". + */ +#define PCID_CMD_WRITE_BDF "write_bdf" +#define PCID_MSG_FIELD_NAME "name" + /* *************************************************************************= ****** * Reset PCI device diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 2e7bd2eae5..a9a641829a 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -94,6 +94,8 @@ static int pci_handle_response(libxl__gc *gc, else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) =3D=3D 0) *result =3D (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIE= LD_RESOURCES, response, JSON_MAP); + else if (strcmp(command_name, PCID_CMD_WRITE_BDF) =3D=3D 0) + *result =3D libxl__json_object_alloc(gc, JSON_NULL); return ret; } =20 @@ -511,33 +513,6 @@ static bool is_pci_in_array(libxl_device_pci *pcis, in= t num, return i < num; } =20 -/* Write the standard BDF into the sysfs path given by sysfs_path. */ -static int sysfs_write_bdf(libxl__gc *gc, const char * sysfs_path, - libxl_device_pci *pci) -{ - int rc, fd; - char *buf; - - fd =3D open(sysfs_path, O_WRONLY); - if (fd < 0) { - LOGE(ERROR, "Couldn't open %s", sysfs_path); - return ERROR_FAIL; - } - - buf =3D GCSPRINTF(PCI_BDF, pci->domain, pci->bus, - pci->dev, pci->func); - rc =3D write(fd, buf, strlen(buf)); - /* Annoying to have two if's, but we need the errno */ - if (rc < 0) - LOGE(ERROR, "write to %s returned %d", sysfs_path, rc); - close(fd); - - if (rc < 0) - return ERROR_FAIL; - - return 0; -} - #define PCI_INFO_PATH "/libxl/pci" =20 static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci, @@ -1384,6 +1359,36 @@ static bool pci_supp_legacy_irq(void) #endif } =20 +static int pciback_write_bdf(libxl__gc *gc, char *name, libxl_device_pci *= pci) +{ + struct vchan_info *vchan; + int rc; + libxl__json_object *args, *result; + + vchan =3D pci_vchan_get_client(gc); + if (!vchan) { + rc =3D ERROR_NOT_READY; + goto out; + } + + args =3D libxl__vchan_start_args(gc); + + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, pci->domain, + pci->bus, pci->dev, pci->func)); + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_NAME, name); + + result =3D vchan_send_command(gc, vchan, PCID_CMD_WRITE_BDF, args); + if (!result) { + rc =3D ERROR_FAIL; + goto vchan_free; + } +vchan_free: + pci_vchan_free(gc, vchan); +out: + return rc; +} + static void pci_add_dm_done(libxl__egc *egc, pci_add_state *pas, int rc) @@ -1421,8 +1426,9 @@ static void pci_add_dm_done(libxl__egc *egc, libxl__vchan_arg_add_integer(gc, args, PCID_MSG_FIELD_DOMID, domid); =20 result =3D vchan_send_command(gc, vchan, PCID_CMD_RESOURCE_LIST, args); + pci_vchan_free(gc, vchan); if (!result) - goto vchan_free; + goto out; value =3D libxl__json_map_get(PCID_RESULT_KEY_IOMEM, result, JSON_ARRA= Y); =20 /* stubdomain is always running by now, even at create time */ @@ -1483,8 +1489,7 @@ static void pci_add_dm_done(libxl__egc *egc, =20 /* Don't restrict writes to the PCI config space from this VM */ if (pci->permissive) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive", - pci) < 0 ) { + if (pciback_write_bdf(gc, "permissive", pci)) { LOGD(ERROR, domainid, "Setting permissive for device"); rc =3D ERROR_FAIL; goto out; @@ -1512,8 +1517,6 @@ out_no_irq: rc =3D libxl__device_pci_add_xenstore(gc, domid, pci, starting); else rc =3D 0; -vchan_free: - pci_vchan_free(gc, vchan); out: libxl__ev_time_deregister(gc, &pas->timeout); libxl__ev_time_deregister(gc, &pas->timeout_retries); diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index d968071224..66b433d2bf 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -257,6 +257,41 @@ static int pciback_dev_is_assigned(libxl__gc *gc, unsi= gned int domain, return 0; } =20 +static int process_pciback_write_bdf(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *reques= t, + struct libxl__json_object **response) +{ + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc =3D 0; + const char *name; + char *spath; + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command= _name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) !=3D 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + + json_o =3D libxl__json_map_get(PCID_MSG_FIELD_NAME, request, JSON_STRI= NG); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'rebind'", comma= nd_name); + return ERROR_FAIL; + } + + name =3D libxl__json_object_get_string(json_o); + spath =3D GCSPRINTF("%s/%s", SYSFS_PCIBACK_DRIVER, name); + LOG(WARN, "sysf_write_bdf(%s, %d, %d, %d, %d)", spath, dom, bus, dev,f= unc); + return rc; +} + #define PCID_INFO_PATH "pcid" #define PCID_BDF_XSPATH "%04x-%02x-%02x-%01x" =20 @@ -746,6 +781,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen = gen, else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) =3D=3D 0) ret =3D process_list_resources(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_WRITE_BDF) =3D=3D 0) + ret =3D process_pciback_write_bdf(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over --=20 2.34.1