Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp4618368rwl; Mon, 3 Apr 2023 07:27:30 -0700 (PDT) X-Google-Smtp-Source: AKy350aEey7IyQQ/QVi83Cm6yHFT/CPt8W1LN+VgmOIR5frTOGEobXQPCOl1X+d1ku3m+h2ZyoUs X-Received: by 2002:a17:906:9f15:b0:931:c7fd:10b1 with SMTP id fy21-20020a1709069f1500b00931c7fd10b1mr36720327ejc.19.1680532050239; Mon, 03 Apr 2023 07:27:30 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1680532050; cv=pass; d=google.com; s=arc-20160816; b=KysnJ4WP1KnJHl4DpEU1Qwi9CPIyCUKHMRrwZTmVTx7vSt2HD7aNnIzzIkC0nec72u qo9X1dMr5T/OsYN7tTpe+qaTjFnGp2qYJn1dB++vTIiJq0BI86Wl2PI0nWC3mtDLfRKI jMTolVPcWIOafym5MQ/xZgFyIOj0VVSZ5qownP6PgOryAXaQGByZZ84QfrmhuyC0+uqa xNwhE7omEppH75SnYFwEnRq0gUTgku3OKUESeHsB01EVS0rZmEttJsp/8RNvUfj/lxUI ILh1BfBNcknfp4Qzavj5mW1nAXMcANoa4SFv7LgtwEys4urQMSnNrs4+28d9O4F3zUJk DSGg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :dkim-signature; bh=WWgAPJJmwmJFnDVQ7OLWIXK+tdZUAP8PUJIC/us56VU=; b=pwwwMshM+Q7BJ/WcIcDuXE1SBniVqWhgeCgU9B3dBl3t2tKv/yVnUXw8sW9Hm0QYdr 8SqOKbQz973/HSmvPFqArBhNAamsYc3Be47xF1AvcI/r3oOLFZweZKDb/n+e5eYmD8BY xBtMqNvIsTYuVj0B5L8qxSQ+/QY1mIox4az82Ntf68wUF4rCkX7GbL1DC1GdPEFlD3gM J+amJoXd0s6afuHHxW+MEAlg3EAv25r6Ap9pQo6CW70HQmfYW67XJemv5OXD+HHM9LXN 0/E+U/AKgRhUrB7iDYurbYwkLwghrJMkkCQ5Vu2Z3Fu3DUrZZ9aMPcoMnyGnRST8qD7G NAfA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@amd.com header.s=selector1 header.b=AMnKF5IV; arc=pass (i=1 spf=pass spfdomain=amd.com dmarc=pass fromdomain=amd.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amd.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e24-20020a170906845800b009334a8e8c07si4717570ejy.103.2023.04.03.07.26.38; Mon, 03 Apr 2023 07:27:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@amd.com header.s=selector1 header.b=AMnKF5IV; arc=pass (i=1 spf=pass spfdomain=amd.com dmarc=pass fromdomain=amd.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amd.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233274AbjDCOZm (ORCPT + 99 others); Mon, 3 Apr 2023 10:25:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233276AbjDCOZk (ORCPT ); Mon, 3 Apr 2023 10:25:40 -0400 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2087.outbound.protection.outlook.com [40.107.94.87]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7CA1F2C9F1; Mon, 3 Apr 2023 07:25:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Gv8H2cATP6RCZvU2jw1Gfszb+ReAL0MDm3xSAaKfJAljzT/9T9CpXOnUSD0QuPVPkQfRETg3XbN0BCblNmTArE+V2touzEMZDP2i0xky6S+bjV4i+QU2QdYa9Ec1N+c5MnKoCpjytGuuQz2+ZZuM44s7LsgxvM1rUktqPtodM7tpNue/P0udbKICuit8clus75+lv0Gho8vI8nxud2k5RTIumUMH2wzSyKuXwP2Y4uCewOmmnY8UjV/LAjoZGrd1O0akSEJl0pYbntiYQGWIh0JNGi8hXVthE5NhzaopL2XuxyDR8e2LRqsktc/yaRD+NU6+JFFymXipUqiOlNo8jQ== 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=WWgAPJJmwmJFnDVQ7OLWIXK+tdZUAP8PUJIC/us56VU=; b=URpcsBZrqcaqytYQcHMcfFUNrhs3KanJ4+QMkMb8ct1D8bIllM0E9WI4N7CiwMdCOMRNVmmv2bH61m8xAGo39D7NvAFtPtGz9JkwWVcrGfkX7NP4WjJ//wB1qQ5eVFaOdtTAXctoKHqSvAYx3xfQ0ZMZsrCnPaEnhMEXNcAXHAG3rSwFfs4/bW63L2hA9OhVvQ6xM0TrsuiurH3AFcTivAR1jVqJNKyhZ+BlZFF+3JE1ZVTqkXmMQva+1CeTpH951GgzJbsZdhr7bcGLC3Ju64o6pvk3wjuVCsXI3g2szcBISWy5RK1mSNlqGC0WdM1Bk8Dz9YuUneyZw+w8R2V2CQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=redhat.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WWgAPJJmwmJFnDVQ7OLWIXK+tdZUAP8PUJIC/us56VU=; b=AMnKF5IV303hMeHtAikVWqB863HuxCz7XHF4PiZ/6esKtgn6mLT/jDFQhnhoCDkBUjkTVph+wLzqmFKFY/WGll8KlJmKlRZvs3ajgD2op+nzOwhBKDy/y/CKcT8uxjF2AoH0yA3umRiLUwY9RO6BgdJtdm3apePtBLxzVCIltIw= Received: from MW4PR03CA0211.namprd03.prod.outlook.com (2603:10b6:303:b9::6) by PH7PR12MB7260.namprd12.prod.outlook.com (2603:10b6:510:208::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6254.33; Mon, 3 Apr 2023 14:25:35 +0000 Received: from CO1PEPF00001A5D.namprd05.prod.outlook.com (2603:10b6:303:b9:cafe::2) by MW4PR03CA0211.outlook.office365.com (2603:10b6:303:b9::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6254.22 via Frontend Transport; Mon, 3 Apr 2023 14:25:35 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by CO1PEPF00001A5D.mail.protection.outlook.com (10.167.241.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6178.30 via Frontend Transport; Mon, 3 Apr 2023 14:25:35 +0000 Received: from SATLEXMB05.amd.com (10.181.40.146) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Mon, 3 Apr 2023 09:25:32 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB05.amd.com (10.181.40.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Mon, 3 Apr 2023 09:25:32 -0500 Received: from xhdipdslab41.xilinx.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server id 15.1.2375.34 via Frontend Transport; Mon, 3 Apr 2023 09:25:30 -0500 From: Nipun Gupta To: , , CC: , , , "Nipun Gupta" Subject: [PATCH] vfio/cdx: add support for CDX bus Date: Mon, 3 Apr 2023 19:55:25 +0530 Message-ID: <20230403142525.29494-1-nipun.gupta@amd.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Content-Type: text/plain X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1PEPF00001A5D:EE_|PH7PR12MB7260:EE_ X-MS-Office365-Filtering-Correlation-Id: 74645897-e3a1-4d92-f2a0-08db344f4a18 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TLrPKhwF1KP2uNBHyzlSaHJUNbsqeKSxZ/ILmp48ywqdvl8U+BtqofGYNEp8Vd1a4bwxz3DmQhRh6WhqGZvSzHwpcLPy0if0qFQ8xU5vm0Xd467GubYrA3NYWFI5EXGbpxpshLTLLzvs2m35paSWOlm/TEdxSzb0pGfmugzkFyFDvdbxjeMhaBQjgn1aZpW6vmL6E88yeMYBXZjITjnSnsYf3u0C2FM+1A6kjxWLP1U/XQWyD0XcGENVEf3gJwkWGPQjJzNeT+QI9IQ1bvdTCQQmD5S8M56n8egb98syxo0F1+xhFkHR3u8BKbktjcBF5TOffim7mGB3XCub4SmxAAOIAr+hNJFi6QFahgaHqZwM4YF8oj+q4s9yyYJnvPtSDlWlm2VHVx2IQgiUudivMEBN0Oeqpv+NumL4LADC+h1qt41IjzGS4P5vIMGQdueT46MM51AORiXBTypDyYiAimXeUIK2QZQ0U8SFNYisqZn6/ZlTurYCy4f7osXor1ehI3gUJXZyunmLJa7IbBZpXXGAqvV+PG/8TjFoxAv0SxekTVJdlN3VxNYOMfDzO8v5gWa5cB0Qin5WnIPeopd//2+dGap8HNK8w+HpIx/apLkQodWmkZnJnfsQibxZFEy8nog11nbortkPgHex/VnnfsmOAZ3d7wFfl08uUrfRIHzPqqvoq4pW1PvkASFKMFwl968ZPFUibUQqREe1HmwEj99XW3CKnMELiaHxcr6quRs= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230028)(4636009)(376002)(396003)(346002)(136003)(39860400002)(451199021)(46966006)(36840700001)(40470700004)(30864003)(356005)(5660300002)(81166007)(44832011)(47076005)(2616005)(83380400001)(82310400005)(426003)(336012)(110136005)(54906003)(316002)(186003)(478600001)(6666004)(86362001)(40480700001)(1076003)(26005)(82740400003)(36756003)(41300700001)(40460700003)(36860700001)(8676002)(4326008)(8936002)(70586007)(70206006)(2906002)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Apr 2023 14:25:35.1860 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 74645897-e3a1-4d92-f2a0-08db344f4a18 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1PEPF00001A5D.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7260 X-Spam-Status: No, score=0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FORGED_SPF_HELO,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org vfio-cdx driver enables IOCTLs for user space to query MMIO regions for CDX devices and mmap them. This change also adds support for reset of CDX devices. This change adds the VFIO CDX driver and enables the following ioctls for CDX devices: - VFIO_DEVICE_GET_INFO: - VFIO_DEVICE_GET_REGION_INFO - VFIO_DEVICE_RESET Signed-off-by: Nipun Gupta Reviewed-by: Pieter Jansen van Vuuren Tested-by: Nikhil Agarwal --- CDX bus is now merged on linux-next tree. So sending VFIO driver patch for CDX bus. MAINTAINERS | 1 + drivers/vfio/Kconfig | 1 + drivers/vfio/Makefile | 1 + drivers/vfio/cdx/Kconfig | 17 ++ drivers/vfio/cdx/Makefile | 8 + drivers/vfio/cdx/vfio_cdx.c | 314 ++++++++++++++++++++++++++++ drivers/vfio/cdx/vfio_cdx_private.h | 32 +++ 7 files changed, 374 insertions(+) create mode 100644 drivers/vfio/cdx/Kconfig create mode 100644 drivers/vfio/cdx/Makefile create mode 100644 drivers/vfio/cdx/vfio_cdx.c create mode 100644 drivers/vfio/cdx/vfio_cdx_private.h diff --git a/MAINTAINERS b/MAINTAINERS index 99b665e85f0a..2acb3dbff174 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -970,6 +970,7 @@ M: Nikhil Agarwal S: Maintained F: Documentation/devicetree/bindings/bus/xlnx,versal-net-cdx.yaml F: drivers/cdx/* +F: drivers/vfio/cdx/* F: include/linux/cdx/* AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index 89e06c981e43..aba36f5be4ec 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -57,6 +57,7 @@ source "drivers/vfio/pci/Kconfig" source "drivers/vfio/platform/Kconfig" source "drivers/vfio/mdev/Kconfig" source "drivers/vfio/fsl-mc/Kconfig" +source "drivers/vfio/cdx/Kconfig" endif source "virt/lib/Kconfig" diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 70e7dcb302ef..1a27b2516612 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_VFIO_PCI) += pci/ obj-$(CONFIG_VFIO_PLATFORM) += platform/ obj-$(CONFIG_VFIO_MDEV) += mdev/ obj-$(CONFIG_VFIO_FSL_MC) += fsl-mc/ +obj-$(CONFIG_VFIO_CDX) += cdx/ diff --git a/drivers/vfio/cdx/Kconfig b/drivers/vfio/cdx/Kconfig new file mode 100644 index 000000000000..e6de0a0caa32 --- /dev/null +++ b/drivers/vfio/cdx/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# VFIO CDX configuration +# +# Copyright (C) 2022-2023, Advanced Micro Devices, Inc. +# + +config VFIO_CDX + tristate "VFIO support for CDX bus devices" + depends on CDX_BUS + select EVENTFD + help + Driver to enable VFIO support for the devices on CDX bus. + This is required to make use of CDX devices present in + the system using the VFIO framework. + + If you don't know what to do here, say N. diff --git a/drivers/vfio/cdx/Makefile b/drivers/vfio/cdx/Makefile new file mode 100644 index 000000000000..82e4ef412c0f --- /dev/null +++ b/drivers/vfio/cdx/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2022-2023, Advanced Micro Devices, Inc. +# + +obj-$(CONFIG_VFIO_CDX) += vfio-cdx.o + +vfio-cdx-objs := vfio_cdx.o diff --git a/drivers/vfio/cdx/vfio_cdx.c b/drivers/vfio/cdx/vfio_cdx.c new file mode 100644 index 000000000000..c23be3e06495 --- /dev/null +++ b/drivers/vfio/cdx/vfio_cdx.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vfio_cdx_private.h" + +static struct cdx_driver vfio_cdx_driver; + +enum { + CDX_ID_F_VFIO_DRIVER_OVERRIDE = 1, +}; + +static int vfio_cdx_init_device(struct vfio_device *core_vdev) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + struct cdx_device *cdx_dev = to_cdx_device(core_vdev->dev); + + vdev->cdx_dev = cdx_dev; + vdev->dev = &cdx_dev->dev; + + return 0; +} + +static void vfio_cdx_release_device(struct vfio_device *core_vdev) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + + vdev->cdx_dev = NULL; + vdev->dev = NULL; +} + +/** + * CDX_DRIVER_OVERRIDE_DEVICE_VFIO - macro used to describe a VFIO + * "driver_override" CDX device. + * @vend: the 16 bit CDX Vendor ID + * @dev: the 16 bit CDX Device ID + * + * This macro is used to create a struct cdx_device_id that matches a + * specific device. driver_override will be set to + * CDX_ID_F_VFIO_DRIVER_OVERRIDE. + */ +#define CDX_DRIVER_OVERRIDE_DEVICE_VFIO(vend, dev) \ + CDX_DEVICE_DRIVER_OVERRIDE(vend, dev, CDX_ID_F_VFIO_DRIVER_OVERRIDE) + +static int vfio_cdx_open_device(struct vfio_device *core_vdev) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + struct cdx_device *cdx_dev = vdev->cdx_dev; + int count = cdx_dev->res_count; + int i; + + vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region), + GFP_KERNEL); + if (!vdev->regions) + return -ENOMEM; + + for (i = 0; i < count; i++) { + struct resource *res = &cdx_dev->res[i]; + + vdev->regions[i].addr = res->start; + vdev->regions[i].size = resource_size(res); + vdev->regions[i].type = res->flags; + /* + * Only regions addressed with PAGE granularity may be + * MMAP'ed securely. + */ + if (!(vdev->regions[i].addr & ~PAGE_MASK) && + !(vdev->regions[i].size & ~PAGE_MASK)) + vdev->regions[i].flags |= + VFIO_REGION_INFO_FLAG_MMAP; + vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_READ; + if (!(cdx_dev->res[i].flags & IORESOURCE_READONLY)) + vdev->regions[i].flags |= VFIO_REGION_INFO_FLAG_WRITE; + } + + return 0; +} + +static void vfio_cdx_regions_cleanup(struct vfio_cdx_device *vdev) +{ + kfree(vdev->regions); +} + +static int vfio_cdx_reset_device(struct vfio_cdx_device *vdev) +{ + return cdx_dev_reset(&vdev->cdx_dev->dev); +} + +static void vfio_cdx_close_device(struct vfio_device *core_vdev) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + int ret; + + vfio_cdx_regions_cleanup(vdev); + + /* reset the device before cleaning up the interrupts */ + ret = vfio_cdx_reset_device(vdev); + if (WARN_ON(ret)) + dev_warn(core_vdev->dev, + "VFIO_CDX: reset device has failed (%d)\n", ret); +} + +static long vfio_cdx_ioctl(struct vfio_device *core_vdev, + unsigned int cmd, unsigned long arg) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + struct cdx_device *cdx_dev = vdev->cdx_dev; + unsigned long minsz; + + switch (cmd) { + case VFIO_DEVICE_GET_INFO: + { + struct vfio_device_info info; + + minsz = offsetofend(struct vfio_device_info, num_irqs); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + + if (info.argsz < minsz) + return -EINVAL; + + info.flags = VFIO_DEVICE_FLAGS_RESET; + + info.num_regions = cdx_dev->res_count; + info.num_irqs = 0; + + return copy_to_user((void __user *)arg, &info, minsz) ? + -EFAULT : 0; + } + case VFIO_DEVICE_GET_REGION_INFO: + { + struct vfio_region_info info; + + minsz = offsetofend(struct vfio_region_info, offset); + + if (copy_from_user(&info, (void __user *)arg, minsz)) + return -EFAULT; + + if (info.argsz < minsz) + return -EINVAL; + + if (info.index >= cdx_dev->res_count) + return -EINVAL; + + /* map offset to the physical address */ + info.offset = VFIO_CDX_INDEX_TO_OFFSET(info.index); + info.size = vdev->regions[info.index].size; + info.flags = vdev->regions[info.index].flags; + + if (copy_to_user((void __user *)arg, &info, minsz)) + return -EFAULT; + return 0; + } + case VFIO_DEVICE_RESET: + { + return vfio_cdx_reset_device(vdev); + } + default: + return -ENOTTY; + } +} + +static int vfio_cdx_mmap_mmio(struct vfio_cdx_region region, + struct vm_area_struct *vma) +{ + u64 size = vma->vm_end - vma->vm_start; + u64 pgoff, base; + + pgoff = vma->vm_pgoff & + ((1U << (VFIO_CDX_OFFSET_SHIFT - PAGE_SHIFT)) - 1); + base = pgoff << PAGE_SHIFT; + + if (region.size < PAGE_SIZE || base + size > region.size) + return -EINVAL; + + vma->vm_pgoff = (region.addr >> PAGE_SHIFT) + pgoff; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + size, vma->vm_page_prot); +} + +static int vfio_cdx_mmap(struct vfio_device *core_vdev, + struct vm_area_struct *vma) +{ + struct vfio_cdx_device *vdev = + container_of(core_vdev, struct vfio_cdx_device, vdev); + struct cdx_device *cdx_dev = vdev->cdx_dev; + unsigned int index; + + index = vma->vm_pgoff >> (VFIO_CDX_OFFSET_SHIFT - PAGE_SHIFT); + + if (vma->vm_end < vma->vm_start) + return -EINVAL; + if (vma->vm_start & ~PAGE_MASK) + return -EINVAL; + if (vma->vm_end & ~PAGE_MASK) + return -EINVAL; + if (!(vma->vm_flags & VM_SHARED)) + return -EINVAL; + if (index >= cdx_dev->res_count) + return -EINVAL; + + if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_MMAP)) + return -EINVAL; + + if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_READ) && + (vma->vm_flags & VM_READ)) + return -EINVAL; + + if (!(vdev->regions[index].flags & VFIO_REGION_INFO_FLAG_WRITE) && + (vma->vm_flags & VM_WRITE)) + return -EINVAL; + + vma->vm_private_data = cdx_dev; + + return vfio_cdx_mmap_mmio(vdev->regions[index], vma); +} + +static const struct vfio_device_ops vfio_cdx_ops = { + .name = "vfio-cdx", + .init = vfio_cdx_init_device, + .release = vfio_cdx_release_device, + .open_device = vfio_cdx_open_device, + .close_device = vfio_cdx_close_device, + .ioctl = vfio_cdx_ioctl, + .mmap = vfio_cdx_mmap, +}; + +static int vfio_cdx_probe(struct cdx_device *cdx_dev) +{ + struct vfio_cdx_device *vdev = NULL; + struct device *dev = &cdx_dev->dev; + int ret; + + vdev = vfio_alloc_device(vfio_cdx_device, vdev, dev, + &vfio_cdx_ops); + if (IS_ERR(vdev)) + return PTR_ERR(vdev); + + ret = vfio_register_group_dev(&vdev->vdev); + if (ret) { + dev_err(dev, "VFIO_CDX: Failed to add to vfio group\n"); + goto out_uninit; + } + + dev_set_drvdata(dev, vdev); + return 0; + +out_uninit: + vfio_put_device(&vdev->vdev); + return ret; +} + +static int vfio_cdx_remove(struct cdx_device *cdx_dev) +{ + struct device *dev = &cdx_dev->dev; + struct vfio_cdx_device *vdev; + + vdev = dev_get_drvdata(dev); + vfio_unregister_group_dev(&vdev->vdev); + vfio_put_device(&vdev->vdev); + + return 0; +} + +static const struct cdx_device_id vfio_cdx_table[] = { + { CDX_DRIVER_OVERRIDE_DEVICE_VFIO(CDX_ANY_ID, CDX_ANY_ID) }, /* match all by default */ + {} +}; + +static struct cdx_driver vfio_cdx_driver = { + .probe = vfio_cdx_probe, + .remove = vfio_cdx_remove, + .match_id_table = vfio_cdx_table, + .driver = { + .name = "vfio-cdx", + .owner = THIS_MODULE, + }, + .driver_managed_dma = true, +}; + +static int __init vfio_cdx_driver_init(void) +{ + return cdx_driver_register(&vfio_cdx_driver); +} + +static void __exit vfio_cdx_driver_exit(void) +{ + cdx_driver_unregister(&vfio_cdx_driver); +} + +module_init(vfio_cdx_driver_init); +module_exit(vfio_cdx_driver_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("VFIO for CDX devices - User Level meta-driver"); diff --git a/drivers/vfio/cdx/vfio_cdx_private.h b/drivers/vfio/cdx/vfio_cdx_private.h new file mode 100644 index 000000000000..8b6f1ee3f5cd --- /dev/null +++ b/drivers/vfio/cdx/vfio_cdx_private.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. + */ + +#ifndef VFIO_CDX_PRIVATE_H +#define VFIO_CDX_PRIVATE_H + +#define VFIO_CDX_OFFSET_SHIFT 40 +#define VFIO_CDX_OFFSET_MASK (((u64)(1) << VFIO_CDX_OFFSET_SHIFT) - 1) + +#define VFIO_CDX_OFFSET_TO_INDEX(off) ((off) >> VFIO_CDX_OFFSET_SHIFT) + +#define VFIO_CDX_INDEX_TO_OFFSET(index) \ + ((u64)(index) << VFIO_CDX_OFFSET_SHIFT) + +struct vfio_cdx_region { + u32 flags; + u32 type; + u64 addr; + resource_size_t size; + void __iomem *ioaddr; +}; + +struct vfio_cdx_device { + struct vfio_device vdev; + struct cdx_device *cdx_dev; + struct device *dev; + struct vfio_cdx_region *regions; +}; + +#endif /* VFIO_CDX_PRIVATE_H */ -- 2.17.1