From patchwork Mon Feb 13 15:13:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yi Liu X-Patchwork-Id: 13138578 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B9351C636CC for ; Mon, 13 Feb 2023 15:14:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC96B10E615; Mon, 13 Feb 2023 15:14:20 +0000 (UTC) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id DE8D810E607; Mon, 13 Feb 2023 15:14:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676301256; x=1707837256; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3zOXD1RbfeucNZAh8WbNS2DPkEQBdEJs4OFK1RTOx1s=; b=kW1xBhwmlklGeuGXwE+dkQs28+P9SmCdleRcwe32rhWoJGfIFsNyK3LD XEz88nratSO1WEQogKqnFUNs2cnZPRY+f4igBbwOXmeTazl2eBOfoMbZk JP+rKcD9KuSxfJrhRHmHSTO0pw231cWB8L1box1vp/dH/sBgcUExmn2Zf IQ72GcCymm82775nbJ/M5mWrwN2ZScyAdEtWpZv7cAz1QF4k0TFzfoffB QBLQlcutUkD8UW/kiAnrRu1ACcDf/jYR0LCrj8H7QgUj1xw23fhYegdjp lInWk25iUYzdj12ONUwAqdAoHHZ3mr3TS4a+NiZjWZlQt1hRm2MtBxyKX Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10620"; a="318931649" X-IronPort-AV: E=Sophos;i="5.97,294,1669104000"; d="scan'208";a="318931649" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Feb 2023 07:14:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10620"; a="701289687" X-IronPort-AV: E=Sophos;i="5.97,294,1669104000"; d="scan'208";a="701289687" Received: from 984fee00a4c6.jf.intel.com ([10.165.58.231]) by orsmga001.jf.intel.com with ESMTP; 13 Feb 2023 07:14:00 -0800 From: Yi Liu To: joro@8bytes.org, alex.williamson@redhat.com, jgg@nvidia.com, kevin.tian@intel.com, robin.murphy@arm.com Date: Mon, 13 Feb 2023 07:13:45 -0800 Message-Id: <20230213151348.56451-13-yi.l.liu@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230213151348.56451-1-yi.l.liu@intel.com> References: <20230213151348.56451-1-yi.l.liu@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v3 12/15] vfio: Make vfio_device_open() single open for device cdev path X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-s390@vger.kernel.org, yi.l.liu@intel.com, yi.y.sun@linux.intel.com, kvm@vger.kernel.org, mjrosato@linux.ibm.com, jasowang@redhat.com, cohuck@redhat.com, peterx@redhat.com, eric.auger@redhat.com, nicolinc@nvidia.com, shameerali.kolothum.thodi@huawei.com, suravee.suthikulpanit@amd.com, chao.p.peng@linux.intel.com, lulu@redhat.com, intel-gvt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" With the introduction of vfio device cdev, userspace can get device access by either the legacy group path or the cdev path. For VFIO devices, it can only be opened by one of the group path and the cdev path at one time. e.g. when the device is opened via cdev path, the group path should be failed. Both paths will call into vfio_device_open(), so the exclusion is done in it. VFIO group has historically allowed multi-open of the device FD. This was made secure because the "open" was executed via an ioctl to the group FD which is itself only single open. However, no known use of multiple device FDs today. It is kind of a strange thing to do because new device FDs can naturally be created via dup(). When we implement the new device uAPI (only used in cdev path) there is no natural way to allow the device itself from being multi-opened in a secure manner. Without the group FD we cannot prove the security context of the opener. Thus, when moving to the new uAPI we block the ability to multi-open the device. Old group path still allows it. vfio_device_open() needs to sustain both the legacy behavior i.e. multi-open in the group path and the new behavior i.e. single-open in the cdev path. This mixture leads to the introduction of a new is_cdev_device flag in struct vfio_device_file. Signed-off-by: Yi Liu --- drivers/vfio/vfio.h | 2 ++ drivers/vfio/vfio_main.c | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index 7a77fb12bd2c..620ebcf966fc 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -18,6 +18,8 @@ struct vfio_container; struct vfio_device_file { struct vfio_device *device; + bool is_cdev_device; + bool access_granted; spinlock_t kvm_ref_lock; /* protect kvm field */ struct kvm *kvm; diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 05dd4b89e9d1..c0be4b27f96c 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -472,6 +472,15 @@ int vfio_device_open(struct vfio_device_file *df, lockdep_assert_held(&device->dev_set->lock); + /* + * Device cdev path cannot support multiple device open since + * it doesn't have a secure way for it. So a second device + * open attempt should be failed if the caller is from a cdev + * path. + */ + if (device->open_count != 0 && df->is_cdev_device) + return -EINVAL; + device->open_count++; if (device->open_count == 1) { ret = vfio_device_first_open(df, dev_id, pt_id); @@ -543,7 +552,12 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) struct vfio_device_file *df = filep->private_data; struct vfio_device *device = df->device; - vfio_device_group_close(df); + /* + * group path supports multiple device open, while cdev doesn't. + * So use vfio_device_group_close() for !is_cdev_device case. + */ + if (!df->is_cdev_device) + vfio_device_group_close(df); vfio_device_put_registration(device);