From patchwork Tue Jul 11 01:06:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307895 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D8DAEB64D9 for ; Tue, 11 Jul 2023 01:08:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230478AbjGKBIp (ORCPT ); Mon, 10 Jul 2023 21:08:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229560AbjGKBIl (ORCPT ); Mon, 10 Jul 2023 21:08:41 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3FEE12A; Mon, 10 Jul 2023 18:08:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037719; x=1720573719; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VKbn7FTMrmA2gag5V43hXHFMFPrVOoIKW+6Z0tPtfV0=; b=RPR6zNFFyQDCrs3e4Sz12Ne90wWvLJT6QjiOGRM2uYalLjCB90pr+uyG A6izxNcsrjFXlvI0HxQsrZpd9Yzi+ga+trTufMZhw+QxqK7Gl+dGCtPX3 rI/3XdTls2RhHPuPQfCP5EjeJDQS0HWqorUVJ3T3VBZVHzFNapDOUmKTe BvNRDEUXYJdueJ226CoX+/SoTA7SZymEknB3HqWALh6A+m1MFY+ODYnYI 9R6uoUc3c1n/dfzf0CkPc94eJ8I4kMpoNzWq1hHx+1gmBrjEcdivL2ts0 W167wjue4qWhT1onHVjCRGOxtGyb7AJyFF5qjZxWhrdPfGes8/+kvQMkL Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816049" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816049" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999797" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999797" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:35 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 1/9] iommu: Move iommu fault data to linux/iommu.h Date: Tue, 11 Jul 2023 09:06:34 +0800 Message-Id: <20230711010642.19707-2-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The iommu fault data is currently defined in uapi/linux/iommu.h, but is only used inside the iommu subsystem. Move it to linux/iommu.h, where it will be more accessible to kernel drivers. With this done, uapi/linux/iommu.h becomes empty and can be removed from the tree. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 152 +++++++++++++++++++++++++++++++++- include/uapi/linux/iommu.h | 161 ------------------------------------- MAINTAINERS | 1 - 3 files changed, 151 insertions(+), 163 deletions(-) delete mode 100644 include/uapi/linux/iommu.h diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d31642596675..0eb0fb852020 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -13,7 +13,6 @@ #include #include #include -#include #define IOMMU_READ (1 << 0) #define IOMMU_WRITE (1 << 1) @@ -42,6 +41,157 @@ struct iommu_sva; struct iommu_fault_event; struct iommu_dma_cookie; +#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */ +#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */ +#define IOMMU_FAULT_PERM_EXEC (1 << 2) /* exec */ +#define IOMMU_FAULT_PERM_PRIV (1 << 3) /* privileged */ + +/* Generic fault types, can be expanded IRQ remapping fault */ +enum iommu_fault_type { + IOMMU_FAULT_DMA_UNRECOV = 1, /* unrecoverable fault */ + IOMMU_FAULT_PAGE_REQ, /* page request fault */ +}; + +enum iommu_fault_reason { + IOMMU_FAULT_REASON_UNKNOWN = 0, + + /* Could not access the PASID table (fetch caused external abort) */ + IOMMU_FAULT_REASON_PASID_FETCH, + + /* PASID entry is invalid or has configuration errors */ + IOMMU_FAULT_REASON_BAD_PASID_ENTRY, + + /* + * PASID is out of range (e.g. exceeds the maximum PASID + * supported by the IOMMU) or disabled. + */ + IOMMU_FAULT_REASON_PASID_INVALID, + + /* + * An external abort occurred fetching (or updating) a translation + * table descriptor + */ + IOMMU_FAULT_REASON_WALK_EABT, + + /* + * Could not access the page table entry (Bad address), + * actual translation fault + */ + IOMMU_FAULT_REASON_PTE_FETCH, + + /* Protection flag check failed */ + IOMMU_FAULT_REASON_PERMISSION, + + /* access flag check failed */ + IOMMU_FAULT_REASON_ACCESS, + + /* Output address of a translation stage caused Address Size fault */ + IOMMU_FAULT_REASON_OOR_ADDRESS, +}; + +/** + * struct iommu_fault_unrecoverable - Unrecoverable fault data + * @reason: reason of the fault, from &enum iommu_fault_reason + * @flags: parameters of this fault (IOMMU_FAULT_UNRECOV_* values) + * @pasid: Process Address Space ID + * @perm: requested permission access using by the incoming transaction + * (IOMMU_FAULT_PERM_* values) + * @addr: offending page address + * @fetch_addr: address that caused a fetch abort, if any + */ +struct iommu_fault_unrecoverable { + __u32 reason; +#define IOMMU_FAULT_UNRECOV_PASID_VALID (1 << 0) +#define IOMMU_FAULT_UNRECOV_ADDR_VALID (1 << 1) +#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID (1 << 2) + __u32 flags; + __u32 pasid; + __u32 perm; + __u64 addr; + __u64 fetch_addr; +}; + +/** + * struct iommu_fault_page_request - Page Request data + * @flags: encodes whether the corresponding fields are valid and whether this + * is the last page in group (IOMMU_FAULT_PAGE_REQUEST_* values). + * When IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID is set, the page response + * must have the same PASID value as the page request. When it is clear, + * the page response should not have a PASID. + * @pasid: Process Address Space ID + * @grpid: Page Request Group Index + * @perm: requested page permissions (IOMMU_FAULT_PERM_* values) + * @addr: page address + * @private_data: device-specific private information + */ +struct iommu_fault_page_request { +#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0) +#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1) +#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA (1 << 2) +#define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 3) + __u32 flags; + __u32 pasid; + __u32 grpid; + __u32 perm; + __u64 addr; + __u64 private_data[2]; +}; + +/** + * struct iommu_fault - Generic fault data + * @type: fault type from &enum iommu_fault_type + * @padding: reserved for future use (should be zero) + * @event: fault event, when @type is %IOMMU_FAULT_DMA_UNRECOV + * @prm: Page Request message, when @type is %IOMMU_FAULT_PAGE_REQ + * @padding2: sets the fault size to allow for future extensions + */ +struct iommu_fault { + __u32 type; + __u32 padding; + union { + struct iommu_fault_unrecoverable event; + struct iommu_fault_page_request prm; + __u8 padding2[56]; + }; +}; + +/** + * enum iommu_page_response_code - Return status of fault handlers + * @IOMMU_PAGE_RESP_SUCCESS: Fault has been handled and the page tables + * populated, retry the access. This is "Success" in PCI PRI. + * @IOMMU_PAGE_RESP_FAILURE: General error. Drop all subsequent faults from + * this device if possible. This is "Response Failure" in PCI PRI. + * @IOMMU_PAGE_RESP_INVALID: Could not handle this fault, don't retry the + * access. This is "Invalid Request" in PCI PRI. + */ +enum iommu_page_response_code { + IOMMU_PAGE_RESP_SUCCESS = 0, + IOMMU_PAGE_RESP_INVALID, + IOMMU_PAGE_RESP_FAILURE, +}; + +/** + * struct iommu_page_response - Generic page response information + * @argsz: User filled size of this data + * @version: API version of this structure + * @flags: encodes whether the corresponding fields are valid + * (IOMMU_FAULT_PAGE_RESPONSE_* values) + * @pasid: Process Address Space ID + * @grpid: Page Request Group Index + * @code: response code from &enum iommu_page_response_code + */ +struct iommu_page_response { + __u32 argsz; +#define IOMMU_PAGE_RESP_VERSION_1 1 + __u32 version; +#define IOMMU_PAGE_RESP_PASID_VALID (1 << 0) + __u32 flags; + __u32 pasid; + __u32 grpid; + __u32 code; +}; + + /* iommu fault flags */ #define IOMMU_FAULT_READ 0x0 #define IOMMU_FAULT_WRITE 0x1 diff --git a/include/uapi/linux/iommu.h b/include/uapi/linux/iommu.h deleted file mode 100644 index 65d8b0234f69..000000000000 --- a/include/uapi/linux/iommu.h +++ /dev/null @@ -1,161 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * IOMMU user API definitions - */ - -#ifndef _UAPI_IOMMU_H -#define _UAPI_IOMMU_H - -#include - -#define IOMMU_FAULT_PERM_READ (1 << 0) /* read */ -#define IOMMU_FAULT_PERM_WRITE (1 << 1) /* write */ -#define IOMMU_FAULT_PERM_EXEC (1 << 2) /* exec */ -#define IOMMU_FAULT_PERM_PRIV (1 << 3) /* privileged */ - -/* Generic fault types, can be expanded IRQ remapping fault */ -enum iommu_fault_type { - IOMMU_FAULT_DMA_UNRECOV = 1, /* unrecoverable fault */ - IOMMU_FAULT_PAGE_REQ, /* page request fault */ -}; - -enum iommu_fault_reason { - IOMMU_FAULT_REASON_UNKNOWN = 0, - - /* Could not access the PASID table (fetch caused external abort) */ - IOMMU_FAULT_REASON_PASID_FETCH, - - /* PASID entry is invalid or has configuration errors */ - IOMMU_FAULT_REASON_BAD_PASID_ENTRY, - - /* - * PASID is out of range (e.g. exceeds the maximum PASID - * supported by the IOMMU) or disabled. - */ - IOMMU_FAULT_REASON_PASID_INVALID, - - /* - * An external abort occurred fetching (or updating) a translation - * table descriptor - */ - IOMMU_FAULT_REASON_WALK_EABT, - - /* - * Could not access the page table entry (Bad address), - * actual translation fault - */ - IOMMU_FAULT_REASON_PTE_FETCH, - - /* Protection flag check failed */ - IOMMU_FAULT_REASON_PERMISSION, - - /* access flag check failed */ - IOMMU_FAULT_REASON_ACCESS, - - /* Output address of a translation stage caused Address Size fault */ - IOMMU_FAULT_REASON_OOR_ADDRESS, -}; - -/** - * struct iommu_fault_unrecoverable - Unrecoverable fault data - * @reason: reason of the fault, from &enum iommu_fault_reason - * @flags: parameters of this fault (IOMMU_FAULT_UNRECOV_* values) - * @pasid: Process Address Space ID - * @perm: requested permission access using by the incoming transaction - * (IOMMU_FAULT_PERM_* values) - * @addr: offending page address - * @fetch_addr: address that caused a fetch abort, if any - */ -struct iommu_fault_unrecoverable { - __u32 reason; -#define IOMMU_FAULT_UNRECOV_PASID_VALID (1 << 0) -#define IOMMU_FAULT_UNRECOV_ADDR_VALID (1 << 1) -#define IOMMU_FAULT_UNRECOV_FETCH_ADDR_VALID (1 << 2) - __u32 flags; - __u32 pasid; - __u32 perm; - __u64 addr; - __u64 fetch_addr; -}; - -/** - * struct iommu_fault_page_request - Page Request data - * @flags: encodes whether the corresponding fields are valid and whether this - * is the last page in group (IOMMU_FAULT_PAGE_REQUEST_* values). - * When IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID is set, the page response - * must have the same PASID value as the page request. When it is clear, - * the page response should not have a PASID. - * @pasid: Process Address Space ID - * @grpid: Page Request Group Index - * @perm: requested page permissions (IOMMU_FAULT_PERM_* values) - * @addr: page address - * @private_data: device-specific private information - */ -struct iommu_fault_page_request { -#define IOMMU_FAULT_PAGE_REQUEST_PASID_VALID (1 << 0) -#define IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE (1 << 1) -#define IOMMU_FAULT_PAGE_REQUEST_PRIV_DATA (1 << 2) -#define IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID (1 << 3) - __u32 flags; - __u32 pasid; - __u32 grpid; - __u32 perm; - __u64 addr; - __u64 private_data[2]; -}; - -/** - * struct iommu_fault - Generic fault data - * @type: fault type from &enum iommu_fault_type - * @padding: reserved for future use (should be zero) - * @event: fault event, when @type is %IOMMU_FAULT_DMA_UNRECOV - * @prm: Page Request message, when @type is %IOMMU_FAULT_PAGE_REQ - * @padding2: sets the fault size to allow for future extensions - */ -struct iommu_fault { - __u32 type; - __u32 padding; - union { - struct iommu_fault_unrecoverable event; - struct iommu_fault_page_request prm; - __u8 padding2[56]; - }; -}; - -/** - * enum iommu_page_response_code - Return status of fault handlers - * @IOMMU_PAGE_RESP_SUCCESS: Fault has been handled and the page tables - * populated, retry the access. This is "Success" in PCI PRI. - * @IOMMU_PAGE_RESP_FAILURE: General error. Drop all subsequent faults from - * this device if possible. This is "Response Failure" in PCI PRI. - * @IOMMU_PAGE_RESP_INVALID: Could not handle this fault, don't retry the - * access. This is "Invalid Request" in PCI PRI. - */ -enum iommu_page_response_code { - IOMMU_PAGE_RESP_SUCCESS = 0, - IOMMU_PAGE_RESP_INVALID, - IOMMU_PAGE_RESP_FAILURE, -}; - -/** - * struct iommu_page_response - Generic page response information - * @argsz: User filled size of this data - * @version: API version of this structure - * @flags: encodes whether the corresponding fields are valid - * (IOMMU_FAULT_PAGE_RESPONSE_* values) - * @pasid: Process Address Space ID - * @grpid: Page Request Group Index - * @code: response code from &enum iommu_page_response_code - */ -struct iommu_page_response { - __u32 argsz; -#define IOMMU_PAGE_RESP_VERSION_1 1 - __u32 version; -#define IOMMU_PAGE_RESP_PASID_VALID (1 << 0) - __u32 flags; - __u32 pasid; - __u32 grpid; - __u32 code; -}; - -#endif /* _UAPI_IOMMU_H */ diff --git a/MAINTAINERS b/MAINTAINERS index 3be1bdfe8ecc..8fded0298961 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10877,7 +10877,6 @@ F: drivers/iommu/ F: include/linux/iommu.h F: include/linux/iova.h F: include/linux/of_iommu.h -F: include/uapi/linux/iommu.h IOMMUFD M: Jason Gunthorpe From patchwork Tue Jul 11 01:06:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307894 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 216E4EB64DC for ; Tue, 11 Jul 2023 01:08:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229583AbjGKBIq (ORCPT ); Mon, 10 Jul 2023 21:08:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50294 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230505AbjGKBIp (ORCPT ); Mon, 10 Jul 2023 21:08:45 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DFA312A; Mon, 10 Jul 2023 18:08:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037724; x=1720573724; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Yw3ldqeV4muXTG+DI6j0gzlwD7xkWN/7ajkI9p76rt8=; b=NYSPCErfOGoQQIJ9+CI5B4Im+GrCpPLcDcCRq5xpj3LfWEdH5GXS5GVG 6hh52Q28Q0D+AjJq92awABs2Wwx2kZSYxK77C/2HXbGPiDHck7VzsLlua WrVrsqXnZUkXCH6vy2S0qxtLGQGSYapKlIwOTpbdJ7knLFoa7b42KeD9H KilLb98UclQh/APnh7zxqbXG+rJJYigwKrIvW+ClPyJjgSTeOyn0rodli aiSXZ/GcRAnAqryuqh0hUkboVlkxqc3eZptO+4UFA+YpTuPXm39z2AdUt aH8GANXwXmEoJMTF1oQlMaq2gkEQ3JjfREPSuXfcchGP+tsWQjjsQdkT6 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816069" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816069" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999814" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999814" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:39 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 2/9] iommu: Add device parameter to iopf handler Date: Tue, 11 Jul 2023 09:06:35 +0800 Message-Id: <20230711010642.19707-3-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add the device parameter to the iopf handler so that it can know which device this fault was generated. This is necessary for use cases such as delivering IO page faults to user space. The IOMMUFD layer needs to be able to lookup the device id of a fault and route it together with the fault message to the user space. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 1 + drivers/iommu/iommu-sva.h | 4 ++-- drivers/iommu/io-pgfault.c | 2 +- drivers/iommu/iommu-sva.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 0eb0fb852020..a00fb43b5e73 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -249,6 +249,7 @@ struct iommu_domain { struct iommu_domain_geometry geometry; struct iommu_dma_cookie *iova_cookie; enum iommu_page_response_code (*iopf_handler)(struct iommu_fault *fault, + struct device *dev, void *data); void *fault_data; union { diff --git a/drivers/iommu/iommu-sva.h b/drivers/iommu/iommu-sva.h index 54946b5a7caf..c848661c4e20 100644 --- a/drivers/iommu/iommu-sva.h +++ b/drivers/iommu/iommu-sva.h @@ -23,7 +23,7 @@ struct iopf_queue *iopf_queue_alloc(const char *name); void iopf_queue_free(struct iopf_queue *queue); int iopf_queue_discard_partial(struct iopf_queue *queue); enum iommu_page_response_code -iommu_sva_handle_iopf(struct iommu_fault *fault, void *data); +iommu_sva_handle_iopf(struct iommu_fault *fault, struct device *dev, void *data); #else /* CONFIG_IOMMU_SVA */ static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie) @@ -63,7 +63,7 @@ static inline int iopf_queue_discard_partial(struct iopf_queue *queue) } static inline enum iommu_page_response_code -iommu_sva_handle_iopf(struct iommu_fault *fault, void *data) +iommu_sva_handle_iopf(struct iommu_fault *fault, struct device *dev, void *data) { return IOMMU_PAGE_RESP_INVALID; } diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index e5b8b9110c13..fa604e1b5c5c 100644 --- a/drivers/iommu/io-pgfault.c +++ b/drivers/iommu/io-pgfault.c @@ -88,7 +88,7 @@ static void iopf_handler(struct work_struct *work) * faults in the group if there is an error. */ if (status == IOMMU_PAGE_RESP_SUCCESS) - status = domain->iopf_handler(&iopf->fault, + status = domain->iopf_handler(&iopf->fault, group->dev, domain->fault_data); if (!(iopf->fault.prm.flags & diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c index 3ebd4b6586b3..14766a2b61af 100644 --- a/drivers/iommu/iommu-sva.c +++ b/drivers/iommu/iommu-sva.c @@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_get_pasid); * I/O page fault handler for SVA */ enum iommu_page_response_code -iommu_sva_handle_iopf(struct iommu_fault *fault, void *data) +iommu_sva_handle_iopf(struct iommu_fault *fault, struct device *dev, void *data) { vm_fault_t ret; struct vm_area_struct *vma; From patchwork Tue Jul 11 01:06:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307896 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 262E1EB64D9 for ; Tue, 11 Jul 2023 01:08:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231201AbjGKBI5 (ORCPT ); Mon, 10 Jul 2023 21:08:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231127AbjGKBIy (ORCPT ); Mon, 10 Jul 2023 21:08:54 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8AD8AE4C; Mon, 10 Jul 2023 18:08:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037728; x=1720573728; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oKqphfPLpxwX/axdCJ/TL8Nqz/Tmz3XMJfkFpiYRxCo=; b=T8v2tepWHIHNYjA9mHSUUdyqAnymV/eV6uLuAKGf4hhftRy01LpX1uzG zFwaUd58zk20TU5ff2eKFDvPsQlNdEKbkTl02D2j7g8iN0AtqB+0UOVFn vLq42pMBjMyKmzmjwLfP3JrZ/5RjBnCzfnOG+YcVw/Tm+d4y3/fLXhg/C ACCvJTXMm7kpyWhYQt85HAfTAF/Aj/37J6w1LYMwLIF10BxCmrv456Ft2 3KFd59xkOGrydmhbLBz1O9ikLpl3Wpaxdye8ozaxa89fig74VMCjFbI2v /lW4kvdhqC8MYvXqQfXaCYZ7F9Wd95KoGdvzanIXRd0qtWmSxwHlUC9zO Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816083" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816083" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999840" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999840" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:44 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 3/9] iommu: Add common code to handle IO page faults Date: Tue, 11 Jul 2023 09:06:36 +0800 Message-Id: <20230711010642.19707-4-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The individual iommu drivers report iommu faults by calling iommu_report_device_fault(), where a pre-registered device fault handler is called to route the fault to another fault handler installed on the corresponding iommu domain. The pre-registered device fault handler is static and won't be dynamic as the fault handler is eventually per iommu domain. Replace the device fault handler with a static common code to avoid unnecessary code. Signed-off-by: Lu Baolu --- drivers/iommu/iommu.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index da340f11c5f5..41328f03e8b4 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1278,6 +1278,28 @@ int iommu_unregister_device_fault_handler(struct device *dev) } EXPORT_SYMBOL_GPL(iommu_unregister_device_fault_handler); +static int iommu_handle_io_pgfault(struct device *dev, + struct iommu_fault *fault) +{ + struct iommu_domain *domain; + + if (fault->type != IOMMU_FAULT_PAGE_REQ) + return -EINVAL; + + if (fault->prm.flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID) + domain = iommu_get_domain_for_dev_pasid(dev, fault->prm.pasid, 0); + else + domain = iommu_get_domain_for_dev(dev); + + if (!domain || !domain->iopf_handler) + return -ENODEV; + + if (domain->iopf_handler == iommu_sva_handle_iopf) + return iommu_queue_iopf(fault, dev); + + return domain->iopf_handler(fault, dev, domain->fault_data); +} + /** * iommu_report_device_fault() - Report fault event to device driver * @dev: the device @@ -1320,7 +1342,7 @@ int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt) mutex_unlock(&fparam->lock); } - ret = fparam->handler(&evt->fault, fparam->data); + ret = iommu_handle_io_pgfault(dev, &evt->fault); if (ret && evt_pending) { mutex_lock(&fparam->lock); list_del(&evt_pending->list); From patchwork Tue Jul 11 01:06:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307897 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24D8FEB64D9 for ; Tue, 11 Jul 2023 01:09:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231186AbjGKBJC (ORCPT ); Mon, 10 Jul 2023 21:09:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231177AbjGKBI5 (ORCPT ); Mon, 10 Jul 2023 21:08:57 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 28E53E7A; Mon, 10 Jul 2023 18:08:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037732; x=1720573732; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KFCYwINW+Ez0BStnuTZ0pJyGBX2+iWULH1gI+15dKZA=; b=LE66WEKzBF8h3unZK8MDTnJNOaX/dldl+D9mnLaD8yCKfAguGYSsSON3 qO1dcMqbF7xpZM7JJD3S/3FRetiGiwWg/r8pk3zp2OfoeBYjD6tTvp6I7 2blXtFEc55iWRW42iHLrNCIFdZi/9AQ4kFHNsKCjJ5d1fZRSFux5li6L8 p6+s6w5l+rLNgSbLTT+J2AhUpDVs/r2uK1H63vq4WRnNNrewMt1flvKXc RcRktOigxJ+GMPxIbTDlTcB1kxBDTbCfHAlBJeA6Q2L+Uzh3O+w2COXvr 5dGSDrYHcQXHYra9YS1rWSfMbpI04pNvBHqlnUzIi8G5+GUPGeOiVm6l6 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816099" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816099" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999867" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999867" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:48 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 4/9] iommu: Change the return value of dev_iommu_get() Date: Tue, 11 Jul 2023 09:06:37 +0800 Message-Id: <20230711010642.19707-5-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Make dev_iommu_get() return 0 for success and error numbers for failure. This will make the code neat and readable. No functionality changes. Signed-off-by: Lu Baolu Reviewed-by: Jacob Pan --- drivers/iommu/iommu.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 41328f03e8b4..65895b987e22 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -287,20 +287,20 @@ void iommu_device_unregister(struct iommu_device *iommu) } EXPORT_SYMBOL_GPL(iommu_device_unregister); -static struct dev_iommu *dev_iommu_get(struct device *dev) +static int dev_iommu_get(struct device *dev) { struct dev_iommu *param = dev->iommu; if (param) - return param; + return 0; param = kzalloc(sizeof(*param), GFP_KERNEL); if (!param) - return NULL; + return -ENOMEM; mutex_init(¶m->lock); dev->iommu = param; - return param; + return 0; } static void dev_iommu_free(struct device *dev) @@ -351,10 +351,9 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list * but for now enforcing a simple global ordering is fine. */ mutex_lock(&iommu_probe_device_lock); - if (!dev_iommu_get(dev)) { - ret = -ENOMEM; + ret = dev_iommu_get(dev); + if (ret) goto err_unlock; - } if (!try_module_get(ops->owner)) { ret = -EINVAL; @@ -2751,12 +2750,14 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, const struct iommu_ops *ops) { struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + int ret; if (fwspec) return ops == fwspec->ops ? 0 : -EINVAL; - if (!dev_iommu_get(dev)) - return -ENOMEM; + ret = dev_iommu_get(dev); + if (ret) + return ret; /* Preallocate for the overwhelmingly common case of 1 ID */ fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL); From patchwork Tue Jul 11 01:06:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307898 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1487DEB64DA for ; Tue, 11 Jul 2023 01:09:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231148AbjGKBJK (ORCPT ); Mon, 10 Jul 2023 21:09:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231142AbjGKBJG (ORCPT ); Mon, 10 Jul 2023 21:09:06 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0D9D1BC; Mon, 10 Jul 2023 18:08:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037735; x=1720573735; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HDO/3SJrjs+J31UeSjn79Qj5Ue9JvEOiFH2FjTHY2ts=; b=i4Pl+QTkVVwXGp4WyejyWSMcw82NkZBlcgEKRyidW5J+B+Q9ki8JIbpU BhOoQlgSj7W3BtT6Aso7QCEkZFaokUi25glkOn7U7tZRESTdRsM1aMbj5 ItG4KFk/QbzsmKivPVVUWd9ODNHtcu60fBDxVxICBgYy0i38wnULl6gFM lz71j3YNpN6uHM7bVsHhuhZU2pgri5PBqHmYnMTlS5rdu0uS0faIO3csO VzTzozOMDnHQf7EtOQykwc2eKx4rc2HhRUXMEH3RvAabv8HTEKiL8/yBW dt/jClzZPasPoA85VP9xpFIoFICKVzoD5Zwf9HVKUDgTzATSm8TmqUxyA w==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816109" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816109" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999890" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999890" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:51 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 5/9] iommu: Make fault_param generic Date: Tue, 11 Jul 2023 09:06:38 +0800 Message-Id: <20230711010642.19707-6-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The iommu faults, including recoverable faults (IO page faults) and unrecoverable faults (DMA faults), are generic to all devices. The iommu faults could possibly be triggered for every device. The fault_param pointer under struct dev_iommu is the per-device fault data. Therefore, the fault_param pointer should be allocated during iommu device probe and freed when the device is released. With this done, the individual iommu drivers that support iopf have no need to call iommu_[un]register_device_fault_handler() any more. This will make it easier for the iommu drivers to support iopf, and it will also make the fault_param allocation and free simpler. Signed-off-by: Lu Baolu --- .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 13 +------------ drivers/iommu/intel/iommu.c | 18 ++++-------------- drivers/iommu/iommu.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c index a5a63b1c947e..fa8ab9d413f8 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c @@ -437,7 +437,6 @@ bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master) static int arm_smmu_master_sva_enable_iopf(struct arm_smmu_master *master) { - int ret; struct device *dev = master->dev; /* @@ -450,16 +449,7 @@ static int arm_smmu_master_sva_enable_iopf(struct arm_smmu_master *master) if (!master->iopf_enabled) return -EINVAL; - ret = iopf_queue_add_device(master->smmu->evtq.iopf, dev); - if (ret) - return ret; - - ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf, dev); - if (ret) { - iopf_queue_remove_device(master->smmu->evtq.iopf, dev); - return ret; - } - return 0; + return iopf_queue_add_device(master->smmu->evtq.iopf, dev); } static void arm_smmu_master_sva_disable_iopf(struct arm_smmu_master *master) @@ -469,7 +459,6 @@ static void arm_smmu_master_sva_disable_iopf(struct arm_smmu_master *master) if (!master->iopf_enabled) return; - iommu_unregister_device_fault_handler(dev); iopf_queue_remove_device(master->smmu->evtq.iopf, dev); } diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 5c8c5cdc36cf..22e43db20252 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4594,23 +4594,14 @@ static int intel_iommu_enable_iopf(struct device *dev) if (ret) return ret; - ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf, dev); - if (ret) - goto iopf_remove_device; - ret = pci_enable_pri(pdev, PRQ_DEPTH); - if (ret) - goto iopf_unregister_handler; + if (ret) { + iopf_queue_remove_device(iommu->iopf_queue, dev); + return ret; + } info->pri_enabled = 1; return 0; - -iopf_unregister_handler: - iommu_unregister_device_fault_handler(dev); -iopf_remove_device: - iopf_queue_remove_device(iommu->iopf_queue, dev); - - return ret; } static int intel_iommu_disable_iopf(struct device *dev) @@ -4637,7 +4628,6 @@ static int intel_iommu_disable_iopf(struct device *dev) * fault handler and removing device from iopf queue should never * fail. */ - WARN_ON(iommu_unregister_device_fault_handler(dev)); WARN_ON(iopf_queue_remove_device(iommu->iopf_queue, dev)); return 0; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 65895b987e22..8d1f0935ea71 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -299,7 +299,15 @@ static int dev_iommu_get(struct device *dev) return -ENOMEM; mutex_init(¶m->lock); + param->fault_param = kzalloc(sizeof(*param->fault_param), GFP_KERNEL); + if (!param->fault_param) { + kfree(param); + return -ENOMEM; + } + mutex_init(¶m->fault_param->lock); + INIT_LIST_HEAD(¶m->fault_param->faults); dev->iommu = param; + return 0; } @@ -312,6 +320,12 @@ static void dev_iommu_free(struct device *dev) fwnode_handle_put(param->fwspec->iommu_fwnode); kfree(param->fwspec); } + /* + * All pending faults should have been drained before + * device release. + */ + WARN_ON_ONCE(!list_empty(¶m->fault_param->faults)); + kfree(param->fault_param); kfree(param); } From patchwork Tue Jul 11 01:06:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307899 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2563EB64D9 for ; Tue, 11 Jul 2023 01:09:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231183AbjGKBJV (ORCPT ); Mon, 10 Jul 2023 21:09:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231205AbjGKBJT (ORCPT ); Mon, 10 Jul 2023 21:09:19 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89A6C10F4; Mon, 10 Jul 2023 18:08:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037739; x=1720573739; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aODFKOoERpdpMb+cr314m7Sc7Io2x3Zhb5iJbRFOqQA=; b=n4dpSz5tPB2KqjCHeFP7DNlNNqH07g6F7utaIZIJvqiOKjKeZudUg0Dx RiF2tzlAwWYzkKDs+qfw3uJ8oQE48HcAy1q1UHWP3B73Pxspg00obO+MN isaPmbU2VH/3s8CUpGUT6qVTm1tHg9rlx/jEeQ9ieogNDws3e/lGwXyLn S61xkImoY57P/WtxLi7UvgENHSKgDyiU1Y6+w3ddQQvwHN/n2Dz3zjHwd 4YJi3+/pBFMT6LdibJbICMXPwpoLRFFEf4IB2JwmRici2YPRM6t8ke8a3 oOcfFMlXEZqB+SoxD5czBcS6O0o6XnsYvuxVyupgIYajVkbI2RntQ6LwT A==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816120" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816120" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:08:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999907" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999907" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:55 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 6/9] iommu: Remove iommu_[un]register_device_fault_handler() Date: Tue, 11 Jul 2023 09:06:39 +0800 Message-Id: <20230711010642.19707-7-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This pair of interfaces are not used anywhere in the tree. Remove it to avoid dead code. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 23 --------- drivers/iommu/iommu-sva.h | 4 +- drivers/iommu/io-pgfault.c | 6 +-- drivers/iommu/iommu.c | 96 -------------------------------------- 4 files changed, 4 insertions(+), 125 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a00fb43b5e73..f10be6680f8a 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -198,7 +198,6 @@ struct iommu_page_response { typedef int (*iommu_fault_handler_t)(struct iommu_domain *, struct device *, unsigned long, int, void *); -typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault *, void *); struct iommu_domain_geometry { dma_addr_t aperture_start; /* First address that can be mapped */ @@ -538,14 +537,10 @@ struct iommu_fault_event { /** * struct iommu_fault_param - per-device IOMMU fault data - * @handler: Callback function to handle IOMMU faults at device level - * @data: handler private data * @faults: holds the pending faults which needs response * @lock: protect pending faults list */ struct iommu_fault_param { - iommu_dev_fault_handler_t handler; - void *data; struct list_head faults; struct mutex lock; }; @@ -669,11 +664,6 @@ extern int iommu_group_for_each_dev(struct iommu_group *group, void *data, extern struct iommu_group *iommu_group_get(struct device *dev); extern struct iommu_group *iommu_group_ref_get(struct iommu_group *group); extern void iommu_group_put(struct iommu_group *group); -extern int iommu_register_device_fault_handler(struct device *dev, - iommu_dev_fault_handler_t handler, - void *data); - -extern int iommu_unregister_device_fault_handler(struct device *dev); extern int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt); @@ -1055,19 +1045,6 @@ static inline void iommu_group_put(struct iommu_group *group) { } -static inline -int iommu_register_device_fault_handler(struct device *dev, - iommu_dev_fault_handler_t handler, - void *data) -{ - return -ENODEV; -} - -static inline int iommu_unregister_device_fault_handler(struct device *dev) -{ - return 0; -} - static inline int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt) { diff --git a/drivers/iommu/iommu-sva.h b/drivers/iommu/iommu-sva.h index c848661c4e20..7b26224c536b 100644 --- a/drivers/iommu/iommu-sva.h +++ b/drivers/iommu/iommu-sva.h @@ -13,7 +13,7 @@ struct iommu_fault; struct iopf_queue; #ifdef CONFIG_IOMMU_SVA -int iommu_queue_iopf(struct iommu_fault *fault, void *cookie); +int iommu_queue_iopf(struct iommu_fault *fault, struct device *dev); int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev); int iopf_queue_remove_device(struct iopf_queue *queue, @@ -26,7 +26,7 @@ enum iommu_page_response_code iommu_sva_handle_iopf(struct iommu_fault *fault, struct device *dev, void *data); #else /* CONFIG_IOMMU_SVA */ -static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie) +static inline int iommu_queue_iopf(struct iommu_fault *fault, struct device *dev) { return -ENODEV; } diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index fa604e1b5c5c..1749e0869f2e 100644 --- a/drivers/iommu/io-pgfault.c +++ b/drivers/iommu/io-pgfault.c @@ -103,7 +103,7 @@ static void iopf_handler(struct work_struct *work) /** * iommu_queue_iopf - IO Page Fault handler * @fault: fault event - * @cookie: struct device, passed to iommu_register_device_fault_handler. + * @dev: struct device. * * Add a fault to the device workqueue, to be handled by mm. * @@ -140,14 +140,12 @@ static void iopf_handler(struct work_struct *work) * * Return: 0 on success and <0 on error. */ -int iommu_queue_iopf(struct iommu_fault *fault, void *cookie) +int iommu_queue_iopf(struct iommu_fault *fault, struct device *dev) { int ret; struct iopf_group *group; struct iopf_fault *iopf, *next; struct iopf_device_param *iopf_param; - - struct device *dev = cookie; struct dev_iommu *param = dev->iommu; lockdep_assert_held(¶m->lock); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 8d1f0935ea71..fc5e9698b35c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1199,98 +1199,6 @@ void iommu_group_put(struct iommu_group *group) } EXPORT_SYMBOL_GPL(iommu_group_put); -/** - * iommu_register_device_fault_handler() - Register a device fault handler - * @dev: the device - * @handler: the fault handler - * @data: private data passed as argument to the handler - * - * When an IOMMU fault event is received, this handler gets called with the - * fault event and data as argument. The handler should return 0 on success. If - * the fault is recoverable (IOMMU_FAULT_PAGE_REQ), the consumer should also - * complete the fault by calling iommu_page_response() with one of the following - * response code: - * - IOMMU_PAGE_RESP_SUCCESS: retry the translation - * - IOMMU_PAGE_RESP_INVALID: terminate the fault - * - IOMMU_PAGE_RESP_FAILURE: terminate the fault and stop reporting - * page faults if possible. - * - * Return 0 if the fault handler was installed successfully, or an error. - */ -int iommu_register_device_fault_handler(struct device *dev, - iommu_dev_fault_handler_t handler, - void *data) -{ - struct dev_iommu *param = dev->iommu; - int ret = 0; - - if (!param) - return -EINVAL; - - mutex_lock(¶m->lock); - /* Only allow one fault handler registered for each device */ - if (param->fault_param) { - ret = -EBUSY; - goto done_unlock; - } - - get_device(dev); - param->fault_param = kzalloc(sizeof(*param->fault_param), GFP_KERNEL); - if (!param->fault_param) { - put_device(dev); - ret = -ENOMEM; - goto done_unlock; - } - param->fault_param->handler = handler; - param->fault_param->data = data; - mutex_init(¶m->fault_param->lock); - INIT_LIST_HEAD(¶m->fault_param->faults); - -done_unlock: - mutex_unlock(¶m->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iommu_register_device_fault_handler); - -/** - * iommu_unregister_device_fault_handler() - Unregister the device fault handler - * @dev: the device - * - * Remove the device fault handler installed with - * iommu_register_device_fault_handler(). - * - * Return 0 on success, or an error. - */ -int iommu_unregister_device_fault_handler(struct device *dev) -{ - struct dev_iommu *param = dev->iommu; - int ret = 0; - - if (!param) - return -EINVAL; - - mutex_lock(¶m->lock); - - if (!param->fault_param) - goto unlock; - - /* we cannot unregister handler if there are pending faults */ - if (!list_empty(¶m->fault_param->faults)) { - ret = -EBUSY; - goto unlock; - } - - kfree(param->fault_param); - param->fault_param = NULL; - put_device(dev); -unlock: - mutex_unlock(¶m->lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iommu_unregister_device_fault_handler); - static int iommu_handle_io_pgfault(struct device *dev, struct iommu_fault *fault) { @@ -1337,10 +1245,6 @@ int iommu_report_device_fault(struct device *dev, struct iommu_fault_event *evt) /* we only report device fault if there is a handler registered */ mutex_lock(¶m->lock); fparam = param->fault_param; - if (!fparam || !fparam->handler) { - ret = -EINVAL; - goto done_unlock; - } if (evt->fault.type == IOMMU_FAULT_PAGE_REQ && (evt->fault.prm.flags & IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE)) { From patchwork Tue Jul 11 01:06:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307900 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDC1DEB64D9 for ; Tue, 11 Jul 2023 01:09:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231206AbjGKBJd (ORCPT ); Mon, 10 Jul 2023 21:09:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51346 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229811AbjGKBJc (ORCPT ); Mon, 10 Jul 2023 21:09:32 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51A0C12A; Mon, 10 Jul 2023 18:09:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037745; x=1720573745; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Tu0/OPEWkWpyHRU5FU3MEKAkLZnjJWJALBRzwq16sRE=; b=aF4JbhtORQVmOYw9xEylvEa2+MiUIV8KoB8YNZI5OOYySPuuNn1TAYpw 1lYMjkBg1GXbyfsakqnErBnD37SGUSy0TAW6envjEjjzPNcksXOoA8fXx pe/6Ev7qTiae3bsxCW+W30UEYzswyUz3huHwFFKCkv1eB2aGDSkI2+N3W gkHhLmfDJSME92Heefwf7sLl/tEJexX5Xu/i5+O81rQx5c0HOuqESVI/X oGVFRfGii1E3kIMit6PmBgEaPdBePgI0KPHt896qBftv+ya3Fu4OI5FD9 Xd2550pThZDCiZ04GDiFu851AG1Iiewq29Mk9STddK1IDlQVDpjPKrCdo Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816135" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816135" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:09:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999932" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999932" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:08:59 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 7/9] iommu: Add helper to set iopf handler for domain Date: Tue, 11 Jul 2023 09:06:40 +0800 Message-Id: <20230711010642.19707-8-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org To avoid open code everywhere. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 14 +++++++++++--- drivers/iommu/iommu.c | 20 ++++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f10be6680f8a..c86ff10b40f3 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -198,6 +198,8 @@ struct iommu_page_response { typedef int (*iommu_fault_handler_t)(struct iommu_domain *, struct device *, unsigned long, int, void *); +typedef enum iommu_page_response_code (*iommu_iopf_handler_t)(struct iommu_fault *, + struct device *dev, void *data); struct iommu_domain_geometry { dma_addr_t aperture_start; /* First address that can be mapped */ @@ -247,9 +249,7 @@ struct iommu_domain { unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */ struct iommu_domain_geometry geometry; struct iommu_dma_cookie *iova_cookie; - enum iommu_page_response_code (*iopf_handler)(struct iommu_fault *fault, - struct device *dev, - void *data); + iommu_iopf_handler_t iopf_handler; void *fault_data; union { struct { @@ -634,6 +634,8 @@ extern ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); +void iommu_domain_set_iopf_handler(struct iommu_domain *domain, + iommu_iopf_handler_t handler, void *data); extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); @@ -957,6 +959,12 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain, { } +static inline void iommu_domain_set_iopf_handler(struct iommu_domain *domain, + iommu_iopf_handler_t handler, + void *data) +{ +} + static inline void iommu_get_resv_regions(struct device *dev, struct list_head *list) { diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index fc5e9698b35c..3dc59af24208 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1847,6 +1847,23 @@ void iommu_set_fault_handler(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_set_fault_handler); +/** + * iommu_domain_set_iopf_handler() - set io page fault handler for a domain + * @domain: iommu domain + * @handler: fault handler + * @data: user data, will be passed back to the fault handler + * + * This function should be used by iommu domain users which want to be notified + * whenever an IOMMU I/O page fault happens. + */ +void iommu_domain_set_iopf_handler(struct iommu_domain *domain, + iommu_iopf_handler_t handler, void *data) +{ + domain->iopf_handler = handler; + domain->fault_data = data; +} +EXPORT_SYMBOL_GPL(iommu_domain_set_iopf_handler); + static struct iommu_domain *__iommu_domain_alloc(const struct bus_type *bus, unsigned type) { @@ -3335,8 +3352,7 @@ struct iommu_domain *iommu_sva_domain_alloc(struct device *dev, domain->type = IOMMU_DOMAIN_SVA; mmgrab(mm); domain->mm = mm; - domain->iopf_handler = iommu_sva_handle_iopf; - domain->fault_data = mm; + iommu_domain_set_iopf_handler(domain, iommu_sva_handle_iopf, mm); return domain; } From patchwork Tue Jul 11 01:06:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307901 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF69CEB64D9 for ; Tue, 11 Jul 2023 01:09:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231219AbjGKBJg (ORCPT ); Mon, 10 Jul 2023 21:09:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231137AbjGKBJe (ORCPT ); Mon, 10 Jul 2023 21:09:34 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7BC01708; Mon, 10 Jul 2023 18:09:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037746; x=1720573746; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kDNvl2xq4daGW1gpeGo7tFuYd3E44JZ84AN2RiOMGAA=; b=H7jZgCo83x820b1WDmJwyrdQArT6k6hB5aKvVm/ln1+ZFfQbWrXKVIg6 pD3Z06j7zPgxKtTDFLLR4Tr+9TA5xS/rQkHBWwBCNxI11ZMgXYiR3PKN2 6YuGonTOdR3hJQbjyfLPmbx4zNio8TqlM6gkyH93PBMH8BE2wzYFrKMK6 x1OxF9ltQNifACxKe90x1xnLvTlAKwKlozdBLvI/LxbucQ8sFxCGlbDH4 h/yf3QXxRhyHrXq2MShijIkCrQFmZ2N0mfj4KhhS29zhGhIQD7wSoDTI2 iL+1ShhHLS0XXf7ISM5OGvFkbtDvqOYecDIJlAk5WLU/rSXv1Ac8qdbHA w==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816151" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816151" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:09:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999949" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999949" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:09:02 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 8/9] iommu: Add iommu page fault cookie helpers Date: Tue, 11 Jul 2023 09:06:41 +0800 Message-Id: <20230711010642.19707-9-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add an xarray in iommu_fault_param as place holder for per-{device, pasid} fault cookie. They could be used in varous cases. For example, SVA needs to handle IO page faults through work queues to batch process all faults in a fault group. It needs a fault cookie as a temporary storage of partial faults, together with other meta data. The iommufd will also use the fault cookie to store the mapping of device object ID and a pasid of a device. This allows the iommufd to quickly retrieve the device object ID for a given {device, pasid} pair in the hot path of IO page fault delivery. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 16 ++++++++++++++++ drivers/iommu/iommu.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index c86ff10b40f3..ffd6fe1317f4 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -539,10 +539,12 @@ struct iommu_fault_event { * struct iommu_fault_param - per-device IOMMU fault data * @faults: holds the pending faults which needs response * @lock: protect pending faults list + * @pasid_cookie: per-pasid fault cookie */ struct iommu_fault_param { struct list_head faults; struct mutex lock; + struct xarray pasid_cookie; }; /** @@ -636,6 +638,8 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); void iommu_domain_set_iopf_handler(struct iommu_domain *domain, iommu_iopf_handler_t handler, void *data); +void *iommu_set_device_fault_cookie(struct device *dev, ioasid_t pasid, void *cookie); +void *iommu_get_device_fault_cookie(struct device *dev, ioasid_t pasid); extern void iommu_get_resv_regions(struct device *dev, struct list_head *list); extern void iommu_put_resv_regions(struct device *dev, struct list_head *list); @@ -965,6 +969,18 @@ static inline void iommu_domain_set_iopf_handler(struct iommu_domain *domain, { } +static inline void *iommu_set_device_fault_cookie(struct device *dev, + ioasid_t pasid, void *cookie) +{ + return ERR_PTR(-ENODEV); +} + +static inline void *iommu_get_device_fault_cookie(struct device *dev, + ioasid_t pasid) +{ + return ERR_PTR(-ENODEV); +} + static inline void iommu_get_resv_regions(struct device *dev, struct list_head *list) { diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 3dc59af24208..d52b827982a4 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1336,6 +1336,50 @@ int iommu_page_response(struct device *dev, } EXPORT_SYMBOL_GPL(iommu_page_response); +/** + * iommu_set_device_fault_cookie - Set a fault cookie for per-{device, pasid} + * @dev: the device to set the cookie + * @pasid: the pasid on this device + * @cookie: the opaque data + * + * Return the old cookie on success, or ERR_PTR(err#) on failure. + */ +void *iommu_set_device_fault_cookie(struct device *dev, ioasid_t pasid, + void *cookie) +{ + struct iommu_fault_param *fault_param; + void *curr; + + if (!dev->iommu || !dev->iommu->fault_param) + return ERR_PTR(-ENODEV); + + fault_param = dev->iommu->fault_param; + curr = xa_store(&fault_param->pasid_cookie, pasid, cookie, GFP_KERNEL); + + return xa_is_err(curr) ? ERR_PTR(xa_err(curr)) : curr; +} +EXPORT_SYMBOL_GPL(iommu_set_device_fault_cookie); + +/** + * iommu_get_device_fault_cookie - Get the fault cookie for {device, pasid} + * @dev: the device to set the cookie + * @pasid: the pasid on this device + * + * Return the cookie on success, or ERR_PTR(err#) on failure. + */ +void *iommu_get_device_fault_cookie(struct device *dev, ioasid_t pasid) +{ + struct iommu_fault_param *fault_param; + + if (!dev->iommu || !dev->iommu->fault_param) + return ERR_PTR(-ENODEV); + + fault_param = dev->iommu->fault_param; + + return xa_load(&fault_param->pasid_cookie, pasid); +} +EXPORT_SYMBOL_GPL(iommu_get_device_fault_cookie); + /** * iommu_group_id - Return ID for a group * @group: the group to ID From patchwork Tue Jul 11 01:06:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baolu Lu X-Patchwork-Id: 13307902 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62EFAEB64D9 for ; Tue, 11 Jul 2023 01:09:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231230AbjGKBJr (ORCPT ); Mon, 10 Jul 2023 21:09:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231213AbjGKBJp (ORCPT ); Mon, 10 Jul 2023 21:09:45 -0400 Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B2D21715; Mon, 10 Jul 2023 18:09:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1689037757; x=1720573757; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+AYwr3bKWy7rpxtl+3/vsQbCiRF0Z5vJWyLMxV8Tnsg=; b=j+bLA1HVho0kUV6c5hloOBr5qerIUVXDKyMUuNqKhwvv29AoI1Wos/y6 CumZQZauMYoNPLWe5QSmzHJBgNbv0aoFo724mZXbkgwURec+OSsmwyXhz I6E1H+e51DIA9iubp1ztP8WnxkqoKf+YBOP4syd8LiGrN5AbCBL6gBkYj DeocInu0a42cKYaDBkR8o+wo7GovbveqnLi0MYtb0BWZiFjTj729X+vsS d1sAFTvYxrRUUXryQZOxiokwdUGVMDDsyNKP6RNUDsY+NhbvDZ+6z4PBb m3WaAXk89/Mq3cxGw1UVZpmp0fll+7FWk1SrQU5wiK6sdXDekY6blGK+u Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="344816168" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="344816168" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2023 18:09:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10767"; a="810999967" X-IronPort-AV: E=Sophos;i="6.01,195,1684825200"; d="scan'208";a="810999967" Received: from allen-box.sh.intel.com ([10.239.159.127]) by FMSMGA003.fm.intel.com with ESMTP; 10 Jul 2023 18:09:06 -0700 From: Lu Baolu To: Joerg Roedel , Will Deacon , Robin Murphy , Jason Gunthorpe , Kevin Tian , Jean-Philippe Brucker , Nicolin Chen Cc: Yi Liu , Jacob Pan , iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu Subject: [PATCH 9/9] iommu: Use fault cookie to store iopf_param Date: Tue, 11 Jul 2023 09:06:42 +0800 Message-Id: <20230711010642.19707-10-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230711010642.19707-1-baolu.lu@linux.intel.com> References: <20230711010642.19707-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Remove the static iopf_param pointer from struct iommu_fault_param to save memory. Signed-off-by: Lu Baolu --- include/linux/iommu.h | 2 -- drivers/iommu/io-pgfault.c | 47 +++++++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index ffd6fe1317f4..5fe37a7c5a55 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -551,7 +551,6 @@ struct iommu_fault_param { * struct dev_iommu - Collection of per-device IOMMU data * * @fault_param: IOMMU detected device fault reporting data - * @iopf_param: I/O Page Fault queue and data * @fwspec: IOMMU fwspec data * @iommu_dev: IOMMU device this device is linked to * @priv: IOMMU Driver private data @@ -564,7 +563,6 @@ struct iommu_fault_param { struct dev_iommu { struct mutex lock; struct iommu_fault_param *fault_param; - struct iopf_device_param *iopf_param; struct iommu_fwspec *fwspec; struct iommu_device *iommu_dev; void *priv; diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index 1749e0869f2e..6a3a4e08e67e 100644 --- a/drivers/iommu/io-pgfault.c +++ b/drivers/iommu/io-pgfault.c @@ -158,7 +158,7 @@ int iommu_queue_iopf(struct iommu_fault *fault, struct device *dev) * As long as we're holding param->lock, the queue can't be unlinked * from the device and therefore cannot disappear. */ - iopf_param = param->iopf_param; + iopf_param = iommu_get_device_fault_cookie(dev, 0); if (!iopf_param) return -ENODEV; @@ -235,7 +235,7 @@ int iopf_queue_flush_dev(struct device *dev) return -ENODEV; mutex_lock(¶m->lock); - iopf_param = param->iopf_param; + iopf_param = iommu_get_device_fault_cookie(dev, 0); if (iopf_param) flush_workqueue(iopf_param->queue->wq); else @@ -286,9 +286,9 @@ EXPORT_SYMBOL_GPL(iopf_queue_discard_partial); */ int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev) { - int ret = -EBUSY; - struct iopf_device_param *iopf_param; + struct iopf_device_param *iopf_param, *curr; struct dev_iommu *param = dev->iommu; + int ret; if (!param) return -ENODEV; @@ -303,16 +303,27 @@ int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev) mutex_lock(&queue->lock); mutex_lock(¶m->lock); - if (!param->iopf_param) { - list_add(&iopf_param->queue_list, &queue->devices); - param->iopf_param = iopf_param; - ret = 0; + curr = iommu_set_device_fault_cookie(dev, 0, iopf_param); + if (IS_ERR(curr)) { + ret = PTR_ERR(curr); + goto err_free; } + + if (curr) { + ret = -EBUSY; + goto err_restore; + } + list_add(&iopf_param->queue_list, &queue->devices); mutex_unlock(¶m->lock); mutex_unlock(&queue->lock); - if (ret) - kfree(iopf_param); + return 0; +err_restore: + iommu_set_device_fault_cookie(dev, 0, curr); +err_free: + mutex_unlock(¶m->lock); + mutex_unlock(&queue->lock); + kfree(iopf_param); return ret; } @@ -329,7 +340,6 @@ EXPORT_SYMBOL_GPL(iopf_queue_add_device); */ int iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev) { - int ret = -EINVAL; struct iopf_fault *iopf, *next; struct iopf_device_param *iopf_param; struct dev_iommu *param = dev->iommu; @@ -339,16 +349,17 @@ int iopf_queue_remove_device(struct iopf_queue *queue, struct device *dev) mutex_lock(&queue->lock); mutex_lock(¶m->lock); - iopf_param = param->iopf_param; - if (iopf_param && iopf_param->queue == queue) { - list_del(&iopf_param->queue_list); - param->iopf_param = NULL; - ret = 0; + iopf_param = iommu_get_device_fault_cookie(dev, 0); + if (!iopf_param || iopf_param->queue != queue) { + mutex_unlock(¶m->lock); + mutex_unlock(&queue->lock); + return -EINVAL; } + + list_del(&iopf_param->queue_list); + iommu_set_device_fault_cookie(dev, 0, NULL); mutex_unlock(¶m->lock); mutex_unlock(&queue->lock); - if (ret) - return ret; /* Just in case some faults are still stuck */ list_for_each_entry_safe(iopf, next, &iopf_param->partial, list)