From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2FC4AA0C4B; Sat, 6 Nov 2021 21:44:55 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A6AA340151; Sat, 6 Nov 2021 21:44:54 +0100 (CET) Received: from na01-obe.outbound.protection.outlook.com (mail-cusazon11021017.outbound.protection.outlook.com [52.101.62.17]) by mails.dpdk.org (Postfix) with ESMTP id B813B40040 for ; Sat, 6 Nov 2021 21:44:52 +0100 (CET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KIvKmsQAZQPhJV/UU/fLRc47xFFtPDllbJMnqAiFj1WIRofHNCClnBIDqrJN9ygDl3uUjlPTN2sXxlfhrpJcDsnf+bKKv+W2TUv7iAK7qURM40KJHshHgmXmPHiOzDQaBMvTMV+344rNAwL8w/JKtC3HPTAkvO8UTaFj6vKFdHjXNoG+pWMnQi8XGeXNOlNeijcK7KoH8Km9ux+YPawhWyxwdKCWiJYJOhPYlpuhiIYoHSdzTEfouP864xQUKNSoWfqkEHt1M/yy++LGqUtqOTJEjiq3jKT/L701EOK06WvyLVZ2zh4Z3EZqAVyu+7rf5Po7FQJ/+sOMqK1WK4PuRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Gh76SO3W7NFP3nzbbwTwPFmt9nMqGt+Ur2EXQLZ7QaU=; b=UQOe9ysdKvvPE/YhrGkTofNahWvblen7SkMgEtI6S8Q3Ri03PGEnGyZYDNvHv2w1p+OwRvPiBxam0lrBbhYIqExjbPuokBFA1JgjkEsUbVyjQ/KGLCBovpFLaO7VnnFiO5gXVe1n2liCSEQut0WSCszM2Id1m6uw/bwP/so8QL47xLBIFSQ85oz4kPE4AHYXOC5k9IYh4yvSamv9zY56XuGrGkPARIBdXDDieFBz2LxurmcgFeltvFuGh0om7opkpOHlmhGIJRf/blJikFTzR3Rs30qUVemj76oxePtqC7Pnadk98yj7I1XIcN0k/LpHXFDmRugApZAQ05qwr2CZyg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=microsoft.com; dmarc=pass action=none header.from=microsoft.com; dkim=pass header.d=microsoft.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Gh76SO3W7NFP3nzbbwTwPFmt9nMqGt+Ur2EXQLZ7QaU=; b=IsP2yL+4UEDAExJC7b7ftfu7FYGwfxGTVF75sSsFvMwscV5ryhxbj0kHJTFTgG6qHsLtUmjK8h0V7Wyq8kJToEzNHlLBu8sN/kb5MwGN/SVP9MKL+6IQMVNhtTn9gbvbgYLhf2bMmpm3vrPtdbNBKAiZcv6vCj47jba12IE6MWs= Received: from BY5PR21MB1506.namprd21.prod.outlook.com (2603:10b6:a03:23d::12) by SJ0PR21MB1293.namprd21.prod.outlook.com (2603:10b6:a03:3e5::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4713.3; Sat, 6 Nov 2021 20:44:36 +0000 Received: from BY5PR21MB1506.namprd21.prod.outlook.com ([fe80::1db2:a482:d774:93ea]) by BY5PR21MB1506.namprd21.prod.outlook.com ([fe80::1db2:a482:d774:93ea%3]) with mapi id 15.20.4713.000; Sat, 6 Nov 2021 20:44:36 +0000 From: Long Li To: Srikanth Kaka , Stephen Hemminger CC: "dev@dpdk.org" , Vag Singh , Anand Thulasiram Thread-Topic: [PATCH 01/11] bus/vmbus: stub for FreeBSD support Thread-Index: AQHXs6WabGaJs7EH7U2no41sP2upAKv3NtLw Date: Sat, 6 Nov 2021 20:44:35 +0000 Message-ID: References: <20210927134231.11177-1-srikanth.k@oneconvergence.com> <20210927134231.11177-2-srikanth.k@oneconvergence.com> In-Reply-To: <20210927134231.11177-2-srikanth.k@oneconvergence.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ActionId=6c64702b-af89-474b-bbe0-0b19299629b7; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_ContentBits=0; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=true; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Method=Standard; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=Internal; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2021-11-06T20:44:13Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=microsoft.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 3f11968a-8c08-4d69-3391-08d9a1663ebb x-ms-traffictypediagnostic: SJ0PR21MB1293: x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:1824; x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 9BB8O4qlQXllShgqDe8BudyZtLl8zGKHtw8wneSHZaN380H57hAzbBrw2CGM/aX9Hl6K795ViyiMAY75M4h6ZvMOfahrXDgmMNwv5/Po4k9sZ3fl3hz3U7Swsrmu7QmeG5L4xYQuc90BatMhl8WEBXqADCW8TuTA8Fuw+b5LtpCCMtilqLnthdU+F+q31M/MUlM3iSnt1n9a5I7sXPUz4fkZA6AoOYRIu7YMCZ7KtPhZcWO0IpWuY404n1dlGVbxQ48r/CzYEytobAymRo1zJHg7R/jRFaxq8AH2h64PwrRZ+E/nRjjfcitjnzLkkkJ8R62iEzoLnRFFcH+2CE+eHgYyPmJThZ7e+zuaD/Kb+FZ0zu/f+gr5ZEIgYx1pu4QbyugBfo+j2pUn0yThxaiRGDnJayCzayZskMcfhXJW0UZGKUbpMhZgLXIa7b37bdlcj6vVtlYZbJIBSIpVex7M5+ojZVM4T37Fdvk9BdTPVJK5cD/jWN3os4SA7Xs8qDCPJnuhcIwTKQ0emkQNgYpvS4oyGZngm4fgnWWrwMVu1t2/ExXAa0CLRx7oM3qfKJB1/VYVUG1uD28v69/Ekh5u4SkOq2jyAwpmEW/5nz0ZuHN/eWBuOQWu0x7x0PNECqg3UeuSaEKUjaQ+kT/IBM+acOGYl2jCcPJiqrBW2Q0PgezEV9eB3thwPpf/IhFlnfy1GZ6TeY8vGb67pvAltHng4nqHVNgeduVw2vUzz4bY0jhWrOWZQdqxzHgv4jkcdtOw x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BY5PR21MB1506.namprd21.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(26005)(52536014)(110136005)(6636002)(10290500003)(54906003)(316002)(186003)(30864003)(2906002)(38070700005)(4326008)(82960400001)(82950400001)(83380400001)(33656002)(8990500004)(5660300002)(38100700002)(122000001)(86362001)(66446008)(8676002)(66476007)(66556008)(64756008)(8936002)(6506007)(508600001)(9686003)(7696005)(55016002)(53546011)(71200400001)(966005)(66946007)(76116006)(579004)(559001)(10090945008); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?JTRkDT4wxMBtJYnXCOYKPsTrfSWaldKrK0lKXVb/xeGzPwYSeI/856SwZ/Om?= =?us-ascii?Q?BhNNuH4PBvV4Irm2LM9BB3ZTtIAkapXOWDdBESWJoLtZIjDv8LPi6ovRIdeM?= =?us-ascii?Q?sQSh0tNHr3cPWKI77U3Ufl+1ZJyvXWVc9jFTyGxH0Ek5ucRrf036LSzCokAS?= =?us-ascii?Q?KvgxwOEDxn2KqqsrRps5GYtg07ipucqNbRMbY+0FNkwsmr2HBq71+qEe1cGD?= =?us-ascii?Q?GuZ3aPcHyK8zFT+m3aPd0z3KWf6PPj9W/Sy8boCDiIdkDUjLsP12QIClY/06?= =?us-ascii?Q?Z6zphSLTlTQz3Se16XeD2TvxX4Ejk1/MVhEv6AuMw4bKoHWJr4eGR4FgeuRR?= =?us-ascii?Q?h8EAV6V21keQgb4z95siz5VYH+PXGSek1VwzWNzV5uxMf6VVhE2/0b6dMM17?= =?us-ascii?Q?u+RPS48kPbJZKWLVhd8y4+vnMahsLvIRM5OsGU3aSjFldIKL0GkQmXkHYeOB?= =?us-ascii?Q?6xSN5PQzhZwg6mDyLFkmdwYSDIqqRjhZlqrU0g4mwrW06WrH/zPj6jcrvJMX?= =?us-ascii?Q?9RoXjDh7vwSn3e+kYcFsVYZO3oKfKLpZj/4u0ZFOkWRzG/+c5l8LN69COexV?= =?us-ascii?Q?aI+9WE+wEv3WQjKjjkoEmWQgizvbN+z861ZRrL0xQTD+XITaDszHFX/7qQm6?= =?us-ascii?Q?iKWh8N7+9WlKYP0wAwPo/YjReHvX5AUAhtYG/vTv8Jo6uOOs82nGNTTE2pHG?= =?us-ascii?Q?Q7NGapzeq0PpTj3tmxyHYAC+9m9+ttKDvDmm/6gxWx8g9bVe1xTRv+tUQZOn?= =?us-ascii?Q?nfBQZpjem3Jk1z/TlDisN7jZVPMPMImbddjUfFjMFUrLB9o7X4QlwdMADGa5?= =?us-ascii?Q?+3u4K/G0jWqhU6lcEm19l4aEh2hr1Pk8PWYkhmeNSXrgJe7b8oY7jfjO0A6G?= =?us-ascii?Q?M0TDwkO+3eXvK7c6ljo2o6Et2qjAJ5SyRKr0/NxcPxvfM2UA+yZEOE7HQOti?= =?us-ascii?Q?iT61vo222uYouOe7ePxhSuc921bVdr/0HuY1uekYgjeaBieoHI9ynIv1lEL2?= =?us-ascii?Q?6vKyAsuPlrwVx8pO1sSbjJtGky46E/U1GHJyqww+7HaarSFvx75iKi7BNQ1j?= =?us-ascii?Q?n9sTjRwWxT5ac2vJLE4sC0EMMUg5LDfBIC3kAaHX4lNrlgfj+uz/MDe9M9jw?= =?us-ascii?Q?YysslKakzyvQM3Ta+8NGmZokRAAzrYmHF8oriKDp9CZAMkXzPNeAmb59AGKi?= =?us-ascii?Q?Sek6Boa+5s92e3Zk7N26pFXaKngceKCAtxtvrV0JPZIHFq5I0Chajsxqrel9?= =?us-ascii?Q?Gd9xezbEq0xnfa87wLQDG7/0eYOAFpF8GBbzwhs/B8v1Qq/uLTBCPg2pS2GP?= =?us-ascii?Q?/cIBVXa9PiAQJrVkalGIstnFXvleFRo3TjNFar7JXSiZ9Wdmvtk+e7NKtXIS?= =?us-ascii?Q?sbmrjXyp6G3ORmqB/j0XawdNpsqbAahzndGyVK4+wD63rI0LKAhAiYURQXlb?= =?us-ascii?Q?RuWiRlEDA6t2iVa6G6L30q0ij2WXchjFHfdxsPOzVLJeXETq3P4MlKxbVK/T?= =?us-ascii?Q?9rAnmRWuBOiVv109BQdnLCYI/LZ5N7/qGJldUM1yDY4B4Nyjz0yPUD9engmq?= =?us-ascii?Q?8yoly300Th60VGquIwBeDZX6+A2KGgalY9iQddjDSQ+WzVQ+mFONylVHtmIj?= =?us-ascii?Q?Yg=3D=3D?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BY5PR21MB1506.namprd21.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3f11968a-8c08-4d69-3391-08d9a1663ebb X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Nov 2021 20:44:35.9423 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: mc5cn7tcmENOkmrT76sTaLxDkGaOiLM1BfU+bSgMjsej3V+e30CwZ39X1P0qs0cYXiiw6jEFyj7MM3Ewl+SwJg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR21MB1293 Subject: Re: [dpdk-dev] [PATCH 01/11] bus/vmbus: stub for FreeBSD support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > From: Srikanth Kaka > Sent: Monday, September 27, 2021 6:42 AM > To: Stephen Hemminger ; Long Li > > Cc: dev@dpdk.org; Vag Singh ; Anand > Thulasiram ; Srikanth Kaka > > Subject: [PATCH 01/11] bus/vmbus: stub for FreeBSD support >=20 > [You don't often get email from srikanth.k@oneconvergence.com. Learn why > this is important at http://aka.ms/LearnAboutSenderIdentification.] >=20 > These files are a copy of their Linux equivalents. > They will be ported to FreeBSD. >=20 > Signed-off-by: Srikanth Kaka > Signed-off-by: Vag Singh > Signed-off-by: Anand Thulasiram Reviewed-by: Long Li > --- > drivers/bus/vmbus/freebsd/vmbus_bus.c | 376 +++++++++++++++++++++ > drivers/bus/vmbus/freebsd/vmbus_uio.c | 453 ++++++++++++++++++++++++++ > 2 files changed, 829 insertions(+) > create mode 100644 drivers/bus/vmbus/freebsd/vmbus_bus.c > create mode 100644 drivers/bus/vmbus/freebsd/vmbus_uio.c >=20 > diff --git a/drivers/bus/vmbus/freebsd/vmbus_bus.c > b/drivers/bus/vmbus/freebsd/vmbus_bus.c > new file mode 100644 > index 0000000000..3c924eee14 > --- /dev/null > +++ b/drivers/bus/vmbus/freebsd/vmbus_bus.c > @@ -0,0 +1,376 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (c) 2018, Microsoft Corporation. > + * All Rights Reserved. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "eal_filesystem.h" > +#include "private.h" > + > +/** Pathname of VMBUS devices directory. */ #define SYSFS_VMBUS_DEVICES > +"/sys/bus/vmbus/devices" > + > +/* > + * GUID associated with network devices > + * {f8615163-df3e-46c5-913f-f2d2f965ed0e} > + */ > +static const rte_uuid_t vmbus_nic_uuid =3D { > + 0xf8, 0x61, 0x51, 0x63, > + 0xdf, 0x3e, > + 0x46, 0xc5, > + 0x91, 0x3f, > + 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0xe }; > + > +extern struct rte_vmbus_bus rte_vmbus_bus; > + > +/* Read sysfs file to get UUID */ > +static int > +parse_sysfs_uuid(const char *filename, rte_uuid_t uu) { > + char buf[BUFSIZ]; > + char *cp, *in =3D buf; > + FILE *f; > + > + f =3D fopen(filename, "r"); > + if (f =3D=3D NULL) { > + VMBUS_LOG(ERR, "cannot open sysfs value %s: %s", > + filename, strerror(errno)); > + return -1; > + } > + > + if (fgets(buf, sizeof(buf), f) =3D=3D NULL) { > + VMBUS_LOG(ERR, "cannot read sysfs value %s", > + filename); > + fclose(f); > + return -1; > + } > + fclose(f); > + > + cp =3D strchr(buf, '\n'); > + if (cp) > + *cp =3D '\0'; > + > + /* strip { } notation */ > + if (buf[0] =3D=3D '{') { > + in =3D buf + 1; > + cp =3D strchr(in, '}'); > + if (cp) > + *cp =3D '\0'; > + } > + > + if (rte_uuid_parse(in, uu) < 0) { > + VMBUS_LOG(ERR, "%s %s not a valid UUID", > + filename, buf); > + return -1; > + } > + > + return 0; > +} > + > +static int > +get_sysfs_string(const char *filename, char *buf, size_t buflen) { > + char *cp; > + FILE *f; > + > + f =3D fopen(filename, "r"); > + if (f =3D=3D NULL) { > + VMBUS_LOG(ERR, "cannot open sysfs value %s:%s", > + filename, strerror(errno)); > + return -1; > + } > + > + if (fgets(buf, buflen, f) =3D=3D NULL) { > + VMBUS_LOG(ERR, "cannot read sysfs value %s", > + filename); > + fclose(f); > + return -1; > + } > + fclose(f); > + > + /* remove trailing newline */ > + cp =3D memchr(buf, '\n', buflen); > + if (cp) > + *cp =3D '\0'; > + > + return 0; > +} > + > +static int > +vmbus_get_uio_dev(const struct rte_vmbus_device *dev, > + char *dstbuf, size_t buflen) { > + char dirname[PATH_MAX]; > + unsigned int uio_num; > + struct dirent *e; > + DIR *dir; > + > + /* Assume recent kernel where uio is in uio/uioX */ > + snprintf(dirname, sizeof(dirname), > + SYSFS_VMBUS_DEVICES "/%s/uio", dev->device.name); > + > + dir =3D opendir(dirname); > + if (dir =3D=3D NULL) > + return -1; /* Not a UIO device */ > + > + /* take the first file starting with "uio" */ > + while ((e =3D readdir(dir)) !=3D NULL) { > + const int prefix_len =3D 3; > + char *endptr; > + > + if (strncmp(e->d_name, "uio", prefix_len) !=3D 0) > + continue; > + > + /* try uio%d */ > + errno =3D 0; > + uio_num =3D strtoull(e->d_name + prefix_len, &endptr, 10)= ; > + if (errno =3D=3D 0 && endptr !=3D (e->d_name + prefix_len= )) { > + snprintf(dstbuf, buflen, "%s/uio%u", dirname, uio= _num); > + break; > + } > + } > + closedir(dir); > + > + if (e =3D=3D NULL) > + return -1; > + > + return uio_num; > +} > + > +/* Check map names with kernel names */ static const char > +*map_names[VMBUS_MAX_RESOURCE] =3D { > + [HV_TXRX_RING_MAP] =3D "txrx_rings", > + [HV_INT_PAGE_MAP] =3D "int_page", > + [HV_MON_PAGE_MAP] =3D "monitor_page", > + [HV_RECV_BUF_MAP] =3D "recv:", > + [HV_SEND_BUF_MAP] =3D "send:", > +}; > + > + > +/* map the resources of a vmbus device in virtual memory */ int > +rte_vmbus_map_device(struct rte_vmbus_device *dev) { > + char uioname[PATH_MAX], filename[PATH_MAX]; > + char dirname[PATH_MAX], mapname[64]; > + int i; > + > + dev->uio_num =3D vmbus_get_uio_dev(dev, uioname, sizeof(uioname))= ; > + if (dev->uio_num < 0) { > + VMBUS_LOG(DEBUG, "Not managed by UIO driver, skipped"); > + return 1; > + } > + > + /* Extract resource value */ > + for (i =3D 0; i < VMBUS_MAX_RESOURCE; i++) { > + struct rte_mem_resource *res =3D &dev->resource[i]; > + unsigned long len, gpad =3D 0; > + char *cp; > + > + snprintf(dirname, sizeof(dirname), > + "%s/maps/map%d", uioname, i); > + > + snprintf(filename, sizeof(filename), > + "%s/name", dirname); > + > + if (get_sysfs_string(filename, mapname, sizeof(mapname)) = < 0) { > + VMBUS_LOG(ERR, "could not read %s", filename); > + return -1; > + } > + > + if (strncmp(map_names[i], mapname, strlen(map_names[i])) = !=3D 0) { > + VMBUS_LOG(ERR, > + "unexpected resource %s (expected %s)", > + mapname, map_names[i]); > + return -1; > + } > + > + snprintf(filename, sizeof(filename), > + "%s/size", dirname); > + if (eal_parse_sysfs_value(filename, &len) < 0) { > + VMBUS_LOG(ERR, > + "could not read %s", filename); > + return -1; > + } > + res->len =3D len; > + > + /* both send and receive buffers have gpad in name */ > + cp =3D memchr(mapname, ':', sizeof(mapname)); > + if (cp) > + gpad =3D strtoul(cp+1, NULL, 0); > + > + /* put the GPAD value in physical address */ > + res->phys_addr =3D gpad; > + } > + > + return vmbus_uio_map_resource(dev); } > + > +void > +rte_vmbus_unmap_device(struct rte_vmbus_device *dev) { > + vmbus_uio_unmap_resource(dev); > +} > + > +/* Scan one vmbus sysfs entry, and fill the devices list from it. */ > +static int vmbus_scan_one(const char *name) { > + struct rte_vmbus_device *dev, *dev2; > + char filename[PATH_MAX]; > + char dirname[PATH_MAX]; > + unsigned long tmp; > + > + dev =3D calloc(1, sizeof(*dev)); > + if (dev =3D=3D NULL) > + return -1; > + > + dev->device.bus =3D &rte_vmbus_bus.bus; > + dev->device.name =3D strdup(name); > + if (!dev->device.name) > + goto error; > + > + /* sysfs base directory > + * /sys/bus/vmbus/devices/7a08391f-f5a0-4ac0-9802-d13fd964f8df > + * or on older kernel > + * /sys/bus/vmbus/devices/vmbus_1 > + */ > + snprintf(dirname, sizeof(dirname), "%s/%s", > + SYSFS_VMBUS_DEVICES, name); > + > + /* get device class */ > + snprintf(filename, sizeof(filename), "%s/class_id", dirname); > + if (parse_sysfs_uuid(filename, dev->class_id) < 0) > + goto error; > + > + /* skip non-network devices */ > + if (rte_uuid_compare(dev->class_id, vmbus_nic_uuid) !=3D 0) { > + free(dev); > + return 0; > + } > + > + /* get device id */ > + snprintf(filename, sizeof(filename), "%s/device_id", dirname); > + if (parse_sysfs_uuid(filename, dev->device_id) < 0) > + goto error; > + > + /* get relid */ > + snprintf(filename, sizeof(filename), "%s/id", dirname); > + if (eal_parse_sysfs_value(filename, &tmp) < 0) > + goto error; > + dev->relid =3D tmp; > + > + /* get monitor id */ > + snprintf(filename, sizeof(filename), "%s/monitor_id", dirname); > + if (eal_parse_sysfs_value(filename, &tmp) < 0) > + goto error; > + dev->monitor_id =3D tmp; > + > + /* get numa node (if present) */ > + snprintf(filename, sizeof(filename), "%s/numa_node", > + dirname); > + > + if (access(filename, R_OK) =3D=3D 0) { > + if (eal_parse_sysfs_value(filename, &tmp) < 0) > + goto error; > + dev->device.numa_node =3D tmp; > + } else { > + /* if no NUMA support, set default to 0 */ > + dev->device.numa_node =3D SOCKET_ID_ANY; > + } > + > + dev->device.devargs =3D vmbus_devargs_lookup(dev); > + > + /* device is valid, add in list (sorted) */ > + VMBUS_LOG(DEBUG, "Adding vmbus device %s", name); > + > + TAILQ_FOREACH(dev2, &rte_vmbus_bus.device_list, next) { > + int ret; > + > + ret =3D rte_uuid_compare(dev->device_id, dev2->device_id)= ; > + if (ret > 0) > + continue; > + > + if (ret < 0) { > + vmbus_insert_device(dev2, dev); > + } else { /* already registered */ > + VMBUS_LOG(NOTICE, > + "%s already registered", name); > + free(dev); > + } > + return 0; > + } > + > + vmbus_add_device(dev); > + return 0; > +error: > + VMBUS_LOG(DEBUG, "failed"); > + > + free(dev); > + return -1; > +} > + > +/* > + * Scan the content of the vmbus, and the devices in the devices list > +*/ int > +rte_vmbus_scan(void) > +{ > + struct dirent *e; > + DIR *dir; > + > + dir =3D opendir(SYSFS_VMBUS_DEVICES); > + if (dir =3D=3D NULL) { > + if (errno =3D=3D ENOENT) > + return 0; > + > + VMBUS_LOG(ERR, "opendir %s failed: %s", > + SYSFS_VMBUS_DEVICES, strerror(errno)); > + return -1; > + } > + > + while ((e =3D readdir(dir)) !=3D NULL) { > + if (e->d_name[0] =3D=3D '.') > + continue; > + > + if (vmbus_scan_one(e->d_name) < 0) > + goto error; > + } > + closedir(dir); > + return 0; > + > +error: > + closedir(dir); > + return -1; > +} > + > +void rte_vmbus_irq_mask(struct rte_vmbus_device *device) { > + vmbus_uio_irq_control(device, 1); } > + > +void rte_vmbus_irq_unmask(struct rte_vmbus_device *device) { > + vmbus_uio_irq_control(device, 0); } > + > +int rte_vmbus_irq_read(struct rte_vmbus_device *device) { > + return vmbus_uio_irq_read(device); } > diff --git a/drivers/bus/vmbus/freebsd/vmbus_uio.c > b/drivers/bus/vmbus/freebsd/vmbus_uio.c > new file mode 100644 > index 0000000000..b52ca5bf1d > --- /dev/null > +++ b/drivers/bus/vmbus/freebsd/vmbus_uio.c > @@ -0,0 +1,453 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright (c) 2018, Microsoft Corporation. > + * All Rights Reserved. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "private.h" > + > +/** Pathname of VMBUS devices directory. */ #define SYSFS_VMBUS_DEVICES > +"/sys/bus/vmbus/devices" > + > +static void *vmbus_map_addr; > + > +/* Control interrupts */ > +void vmbus_uio_irq_control(struct rte_vmbus_device *dev, int32_t onoff) > +{ > + if (write(dev->intr_handle.fd, &onoff, sizeof(onoff)) < 0) { > + VMBUS_LOG(ERR, "cannot write to %d:%s", > + dev->intr_handle.fd, strerror(errno)); > + } > +} > + > +int vmbus_uio_irq_read(struct rte_vmbus_device *dev) { > + int32_t count; > + int cc; > + > + cc =3D read(dev->intr_handle.fd, &count, sizeof(count)); > + if (cc < (int)sizeof(count)) { > + if (cc < 0) { > + VMBUS_LOG(ERR, "IRQ read failed %s", > + strerror(errno)); > + return -errno; > + } > + VMBUS_LOG(ERR, "can't read IRQ count"); > + return -EINVAL; > + } > + > + return count; > +} > + > +void > +vmbus_uio_free_resource(struct rte_vmbus_device *dev, > + struct mapped_vmbus_resource *uio_res) { > + rte_free(uio_res); > + > + if (dev->intr_handle.uio_cfg_fd >=3D 0) { > + close(dev->intr_handle.uio_cfg_fd); > + dev->intr_handle.uio_cfg_fd =3D -1; > + } > + > + if (dev->intr_handle.fd >=3D 0) { > + close(dev->intr_handle.fd); > + dev->intr_handle.fd =3D -1; > + dev->intr_handle.type =3D RTE_INTR_HANDLE_UNKNOWN; > + } > +} > + > +int > +vmbus_uio_alloc_resource(struct rte_vmbus_device *dev, > + struct mapped_vmbus_resource **uio_res) { > + char devname[PATH_MAX]; /* contains the /dev/uioX */ > + > + /* save fd if in primary process */ > + snprintf(devname, sizeof(devname), "/dev/uio%u", dev->uio_num); > + dev->intr_handle.fd =3D open(devname, O_RDWR); > + if (dev->intr_handle.fd < 0) { > + VMBUS_LOG(ERR, "Cannot open %s: %s", > + devname, strerror(errno)); > + goto error; > + } > + dev->intr_handle.type =3D RTE_INTR_HANDLE_UIO_INTX; > + > + /* allocate the mapping details for secondary processes*/ > + *uio_res =3D rte_zmalloc("UIO_RES", sizeof(**uio_res), 0); > + if (*uio_res =3D=3D NULL) { > + VMBUS_LOG(ERR, "cannot store uio mmap details"); > + goto error; > + } > + > + strlcpy((*uio_res)->path, devname, PATH_MAX); > + rte_uuid_copy((*uio_res)->id, dev->device_id); > + > + return 0; > + > +error: > + vmbus_uio_free_resource(dev, *uio_res); > + return -1; > +} > + > +static int > +find_max_end_va(const struct rte_memseg_list *msl, void *arg) { > + size_t sz =3D msl->memseg_arr.len * msl->page_sz; > + void *end_va =3D RTE_PTR_ADD(msl->base_va, sz); > + void **max_va =3D arg; > + > + if (*max_va < end_va) > + *max_va =3D end_va; > + return 0; > +} > + > +/* > + * TODO: this should be part of memseg api. > + * code is duplicated from PCI. > + */ > +static void * > +vmbus_find_max_end_va(void) > +{ > + void *va =3D NULL; > + > + rte_memseg_list_walk(find_max_end_va, &va); > + return va; > +} > + > +int > +vmbus_uio_map_resource_by_index(struct rte_vmbus_device *dev, int idx, > + struct mapped_vmbus_resource *uio_res, > + int flags) { > + size_t size =3D dev->resource[idx].len; > + struct vmbus_map *maps =3D uio_res->maps; > + void *mapaddr; > + off_t offset; > + int fd; > + > + /* devname for mmap */ > + fd =3D open(uio_res->path, O_RDWR); > + if (fd < 0) { > + VMBUS_LOG(ERR, "Cannot open %s: %s", > + uio_res->path, strerror(errno)); > + return -1; > + } > + > + /* try mapping somewhere close to the end of hugepages */ > + if (vmbus_map_addr =3D=3D NULL) > + vmbus_map_addr =3D vmbus_find_max_end_va(); > + > + /* offset is special in uio it indicates which resource */ > + offset =3D idx * rte_mem_page_size(); > + > + mapaddr =3D vmbus_map_resource(vmbus_map_addr, fd, offset, size, = flags); > + close(fd); > + > + if (mapaddr =3D=3D MAP_FAILED) > + return -1; > + > + dev->resource[idx].addr =3D mapaddr; > + vmbus_map_addr =3D RTE_PTR_ADD(mapaddr, size); > + > + /* Record result of successful mapping for use by secondary */ > + maps[idx].addr =3D mapaddr; > + maps[idx].size =3D size; > + > + return 0; > +} > + > +static int vmbus_uio_map_primary(struct vmbus_channel *chan, > + void **ring_buf, uint32_t *ring_size) { > + struct mapped_vmbus_resource *uio_res; > + > + uio_res =3D vmbus_uio_find_resource(chan->device); > + if (!uio_res) { > + VMBUS_LOG(ERR, "can not find resources!"); > + return -ENOMEM; > + } > + > + if (uio_res->nb_maps < VMBUS_MAX_RESOURCE) { > + VMBUS_LOG(ERR, "VMBUS: only %u resources found!", > + uio_res->nb_maps); > + return -EINVAL; > + } > + > + *ring_size =3D uio_res->maps[HV_TXRX_RING_MAP].size / 2; > + *ring_buf =3D uio_res->maps[HV_TXRX_RING_MAP].addr; > + return 0; > +} > + > +static int vmbus_uio_map_subchan(const struct rte_vmbus_device *dev, > + const struct vmbus_channel *chan, > + void **ring_buf, uint32_t *ring_size) { > + char ring_path[PATH_MAX]; > + size_t file_size; > + struct stat sb; > + void *mapaddr; > + int fd; > + > + snprintf(ring_path, sizeof(ring_path), > + "%s/%s/channels/%u/ring", > + SYSFS_VMBUS_DEVICES, dev->device.name, > + chan->relid); > + > + fd =3D open(ring_path, O_RDWR); > + if (fd < 0) { > + VMBUS_LOG(ERR, "Cannot open %s: %s", > + ring_path, strerror(errno)); > + return -errno; > + } > + > + if (fstat(fd, &sb) < 0) { > + VMBUS_LOG(ERR, "Cannot state %s: %s", > + ring_path, strerror(errno)); > + close(fd); > + return -errno; > + } > + file_size =3D sb.st_size; > + > + if (file_size =3D=3D 0 || (file_size & (rte_mem_page_size() - 1))= ) { > + VMBUS_LOG(ERR, "incorrect size %s: %zu", > + ring_path, file_size); > + > + close(fd); > + return -EINVAL; > + } > + > + mapaddr =3D vmbus_map_resource(vmbus_map_addr, fd, > + 0, file_size, 0); > + close(fd); > + > + if (mapaddr =3D=3D MAP_FAILED) > + return -EIO; > + > + *ring_size =3D file_size / 2; > + *ring_buf =3D mapaddr; > + > + vmbus_map_addr =3D RTE_PTR_ADD(mapaddr, file_size); > + return 0; > +} > + > +int > +vmbus_uio_map_secondary_subchan(const struct rte_vmbus_device *dev, > + const struct vmbus_channel *chan) { > + const struct vmbus_br *br =3D &chan->txbr; > + char ring_path[PATH_MAX]; > + void *mapaddr, *ring_buf; > + uint32_t ring_size; > + int fd; > + > + snprintf(ring_path, sizeof(ring_path), > + "%s/%s/channels/%u/ring", > + SYSFS_VMBUS_DEVICES, dev->device.name, > + chan->relid); > + > + ring_buf =3D br->vbr; > + ring_size =3D br->dsize + sizeof(struct vmbus_bufring); > + VMBUS_LOG(INFO, "secondary ring_buf %p size %u", > + ring_buf, ring_size); > + > + fd =3D open(ring_path, O_RDWR); > + if (fd < 0) { > + VMBUS_LOG(ERR, "Cannot open %s: %s", > + ring_path, strerror(errno)); > + return -errno; > + } > + > + mapaddr =3D vmbus_map_resource(ring_buf, fd, 0, 2 * ring_size, 0)= ; > + close(fd); > + > + if (mapaddr =3D=3D ring_buf) > + return 0; > + > + if (mapaddr =3D=3D MAP_FAILED) > + VMBUS_LOG(ERR, > + "mmap subchan %u in secondary failed", chan->re= lid); > + else { > + VMBUS_LOG(ERR, > + "mmap subchan %u in secondary address mismatch"= , > + chan->relid); > + vmbus_unmap_resource(mapaddr, 2 * ring_size); > + } > + return -1; > +} > + > +int vmbus_uio_map_rings(struct vmbus_channel *chan) { > + const struct rte_vmbus_device *dev =3D chan->device; > + uint32_t ring_size; > + void *ring_buf; > + int ret; > + > + /* Primary channel */ > + if (chan->subchannel_id =3D=3D 0) > + ret =3D vmbus_uio_map_primary(chan, &ring_buf, &ring_size= ); > + else > + ret =3D vmbus_uio_map_subchan(dev, chan, &ring_buf, > + &ring_size); > + > + if (ret) > + return ret; > + > + vmbus_br_setup(&chan->txbr, ring_buf, ring_size); > + vmbus_br_setup(&chan->rxbr, (char *)ring_buf + ring_size, ring_si= ze); > + return 0; > +} > + > +static int vmbus_uio_sysfs_read(const char *dir, const char *name, > + unsigned long *val, unsigned long > +max_range) { > + char path[PATH_MAX]; > + FILE *f; > + int ret; > + > + snprintf(path, sizeof(path), "%s/%s", dir, name); > + f =3D fopen(path, "r"); > + if (!f) { > + VMBUS_LOG(ERR, "can't open %s:%s", > + path, strerror(errno)); > + return -errno; > + } > + > + if (fscanf(f, "%lu", val) !=3D 1) > + ret =3D -EIO; > + else if (*val > max_range) > + ret =3D -ERANGE; > + else > + ret =3D 0; > + fclose(f); > + > + return ret; > +} > + > +static bool vmbus_uio_ring_present(const struct rte_vmbus_device *dev, > + uint32_t relid) { > + char ring_path[PATH_MAX]; > + > + /* Check if kernel has subchannel sysfs files */ > + snprintf(ring_path, sizeof(ring_path), > + "%s/%s/channels/%u/ring", > + SYSFS_VMBUS_DEVICES, dev->device.name, relid); > + > + return access(ring_path, R_OK|W_OK) =3D=3D 0; } > + > +bool vmbus_uio_subchannels_supported(const struct rte_vmbus_device *dev, > + const struct vmbus_channel *chan) { > + return vmbus_uio_ring_present(dev, chan->relid); } > + > +static bool vmbus_isnew_subchannel(struct vmbus_channel *primary, > + unsigned long id) { > + const struct vmbus_channel *c; > + > + STAILQ_FOREACH(c, &primary->subchannel_list, next) { > + if (c->relid =3D=3D id) > + return false; > + } > + return true; > +} > + > +int vmbus_uio_get_subchan(struct vmbus_channel *primary, > + struct vmbus_channel **subchan) { > + const struct rte_vmbus_device *dev =3D primary->device; > + char chan_path[PATH_MAX], subchan_path[PATH_MAX]; > + struct dirent *ent; > + DIR *chan_dir; > + int err; > + > + snprintf(chan_path, sizeof(chan_path), > + "%s/%s/channels", > + SYSFS_VMBUS_DEVICES, dev->device.name); > + > + chan_dir =3D opendir(chan_path); > + if (!chan_dir) { > + VMBUS_LOG(ERR, "cannot open %s: %s", > + chan_path, strerror(errno)); > + return -errno; > + } > + > + while ((ent =3D readdir(chan_dir))) { > + unsigned long relid, subid, monid; > + char *endp; > + > + if (ent->d_name[0] =3D=3D '.') > + continue; > + > + errno =3D 0; > + relid =3D strtoul(ent->d_name, &endp, 0); > + if (*endp || errno !=3D 0 || relid > UINT16_MAX) { > + VMBUS_LOG(NOTICE, "not a valid channel relid: %s"= , > + ent->d_name); > + continue; > + } > + > + if (!vmbus_isnew_subchannel(primary, relid)) { > + VMBUS_LOG(DEBUG, "skip already found channel: %lu= ", > + relid); > + continue; > + } > + > + if (!vmbus_uio_ring_present(dev, relid)) { > + VMBUS_LOG(DEBUG, "ring mmap not found (yet) for: = %lu", > + relid); > + continue; > + } > + > + snprintf(subchan_path, sizeof(subchan_path), "%s/%lu", > + chan_path, relid); > + err =3D vmbus_uio_sysfs_read(subchan_path, "subchannel_id= ", > + &subid, UINT16_MAX); > + if (err) { > + VMBUS_LOG(NOTICE, "no subchannel_id in %s:%s", > + subchan_path, strerror(-err)); > + goto fail; > + } > + > + if (subid =3D=3D 0) > + continue; /* skip primary channel */ > + > + err =3D vmbus_uio_sysfs_read(subchan_path, "monitor_id", > + &monid, UINT8_MAX); > + if (err) { > + VMBUS_LOG(NOTICE, "no monitor_id in %s:%s", > + subchan_path, strerror(-err)); > + goto fail; > + } > + > + err =3D vmbus_chan_create(dev, relid, subid, monid, subch= an); > + if (err) { > + VMBUS_LOG(ERR, "subchannel setup failed"); > + goto fail; > + } > + break; > + } > + closedir(chan_dir); > + > + return (ent =3D=3D NULL) ? -ENOENT : 0; > +fail: > + closedir(chan_dir); > + return err; > +} > -- > 2.30.2