From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62AB32FD1B1 for ; Tue, 2 Dec 2025 23:03:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764716595; cv=none; b=uZa4a9zVteQGZ874LvKgdHrTvS0TujU5jGJwq9jlBEbVTi0f9z33X90YkPQmFKQIN/VdMSR/ugr3xyBPMNB9anSTslOC74QZY/pOr517Sdv/d/I5Bxup7D5WZhDKgEK8yQfkR1mHn7lw4HT7bZtwTqjSO14hlf9RSUwr6MhKgaU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764716595; c=relaxed/simple; bh=/K8uDik6QCSK0i4Ua+hwdlpt8lNrAg5n9NpxcAWSP/k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qxxS4dP1kMGB5pThCdaO4UlLRMDut1WdU2dbSQM1zJ6mhxGBKzsBz3Z9pQ60u8pyEiZ+1ZsoUfOPe6qkr6oRFhTbw8UXwI2Hdo1eN6dp6gAuqzCT8XPtuGRhb7FhlGhhxpBn0JMmqu35xbDqupc//ZFQuWDKGkQPMYkJV8gzkY0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--skhawaja.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HEhmKojU; arc=none smtp.client-ip=209.85.214.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--skhawaja.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HEhmKojU" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-297df52c960so112431705ad.1 for ; Tue, 02 Dec 2025 15:03:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764716592; x=1765321392; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=VumBE9iyIyTLHQhOOSNkQDglvxXqmYKVB+enH/zsx64=; b=HEhmKojUNmGy6wO1Y+JV0A7zW62vARAs3tutjxII5DsJXV6cCv4F6YUj29If2F8h1+ eiWatW9L5OH8JJAt3kMfszDiyrRtdnPl1DnlMsZPitSw/0G8NQDY8MpuA8nQz3qr2Rto qaUcJQ7pY4Ixh6R2pVV/clxSeP5lm3/CzeV0fh0ps4aZ5YN1JdVDK9IvoBoXY1IbPXXC f58ljKI17g9foU+Vnq4arqShnxQ+7KNJjvxeAUHtWEpFtIsqilOSFZXfgnVBOS7UoRf+ CUIrnbvxjT9OQpi6bA7XCPdanbHx2cDKuJV64tgdtlNtMwf103sZwyzR0hRx372Ph9k5 zgug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764716592; x=1765321392; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VumBE9iyIyTLHQhOOSNkQDglvxXqmYKVB+enH/zsx64=; b=aILrXWCxgd/+tY9gtp7SqMTPPoI6Ga06lSjUK7tiYbH75jtJTYkO6X2FxhDtF+ml+T Jy9k1fPDstnLOXMOOy3NzwD/J/w9V/66YOGJbzuIk0dTEuDZKyT3jREsS9x2iLG6Mb/Q BoXMNlw8oBVmaVyFgWyDiRcxCpCgfpUQHtVMss1Fiy1TWBeYfuS7px3hsI8ZfJgZnf0Z Tn8FPGmV+TT37j5bReJ5q2/q0YWlUPYdksFUaYjfAhWxTQoExT767WpZgaj5E5V+zDGY O/9YHKcFPcMyvDO5gtXqygFWEFySDU9d8CCskwB0+tF9xwHavGpc0Mr5Vi2KqVrWsj0x yjaA== X-Forwarded-Encrypted: i=1; AJvYcCVvsZUaOoLMfq5qvNG9zLJjdEAtVNUGz4si/n4OL4zuvxBxOSchZTpH+sGUxWkVGJS5zyYWIWkbl+akbuI=@vger.kernel.org X-Gm-Message-State: AOJu0Yx7AIvJpN5gHlH9V5z5l7yErArI94OKDNuGDnGw8K6Ed2uFtnod GCUJsarphhieos/KYKyEneyxqAQWRwGp3tzn32HvkFt0X0e5lmORVN4W2Jb97PwpjiwPWUQwDdT 8ThQoCQfWDp2ogA== X-Google-Smtp-Source: AGHT+IG7VCw8eaNOJNxgVk4TOR4lIrv+Bnt6tRhRT5Yugq8N193VMxylwCUSAkx/8zZtEOQIev4r4qStGl2Cxw== X-Received: from plpj3.prod.google.com ([2002:a17:903:3d83:b0:25f:48ba:97e1]) (user=skhawaja job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:4407:b0:295:5625:7e41 with SMTP id d9443c01a7336-29d6836bebdmr2461475ad.22.1764716592610; Tue, 02 Dec 2025 15:03:12 -0800 (PST) Date: Tue, 2 Dec 2025 23:02:35 +0000 In-Reply-To: <20251202230303.1017519-1-skhawaja@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251202230303.1017519-1-skhawaja@google.com> X-Mailer: git-send-email 2.52.0.158.g65b55ccf14-goog Message-ID: <20251202230303.1017519-6-skhawaja@google.com> Subject: [RFC PATCH v2 05/32] iommufd-lu: Implement ioctl to let userspace mark an HWPT to be preserved From: Samiullah Khawaja To: David Woodhouse , Lu Baolu , Joerg Roedel , Will Deacon , Pasha Tatashin , Jason Gunthorpe , iommu@lists.linux.dev Cc: YiFei Zhu , Robin Murphy , Pratyush Yadav , Samiullah Khawaja , Kevin Tian , Alex Williamson , linux-kernel@vger.kernel.org, Saeed Mahameed , Adithya Jayachandran , Parav Pandit , Leon Romanovsky , William Tu , Vipin Sharma , dmatlack@google.com, Chris Li , praan@google.com Content-Type: text/plain; charset="UTF-8" From: YiFei Zhu Userspace provides a token, which will then be used at restore to identify this HWPT. A skeleton for te restore-side ioctl is also added. Signed-off-by: YiFei Zhu --- drivers/iommu/iommufd/iommufd_private.h | 18 ++++++++++ drivers/iommu/iommufd/liveupdate.c | 46 +++++++++++++++++++++++++ drivers/iommu/iommufd/main.c | 4 +++ include/uapi/linux/iommufd.h | 41 ++++++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index dfe9120aced0..54c7c9888de3 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -381,6 +381,10 @@ struct iommufd_hwpt_paging { bool auto_domain : 1; bool enforce_cache_coherency : 1; bool nest_parent : 1; +#ifdef CONFIG_LIVEUPDATE + bool lu_preserved : 1; + u32 lu_token; +#endif /* Head at iommufd_ioas::hwpt_list */ struct list_head hwpt_item; struct iommufd_sw_msi_maps present_sw_msi; @@ -721,6 +725,10 @@ iommufd_get_vdevice(struct iommufd_ctx *ictx, u32 id) #ifdef CONFIG_LIVEUPDATE int iommufd_liveupdate_register_lufs(void); int iommufd_liveupdate_unregister_lufs(void); + + +int iommufd_hwpt_lu_set_preserved(struct iommufd_ucmd *ucmd); +int iommufd_hwpt_lu_restore(struct iommufd_ucmd *ucmd); #else static inline int iommufd_liveupdate_register_lufs(void) { @@ -731,6 +739,16 @@ static inline int iommufd_liveupdate_unregister_lufs(void) { return 0; } + +static inline int iommufd_hwpt_lu_set_preserved(struct iommufd_ucmd *ucmd) +{ + return -ENOTTY; +} + +static inline int iommufd_hwpt_lu_restore(struct iommufd_ucmd *ucmd) +{ + return -ENOTTY; +} #endif #ifdef CONFIG_IOMMUFD_TEST diff --git a/drivers/iommu/iommufd/liveupdate.c b/drivers/iommu/iommufd/liveupdate.c index a9b5956c0dee..83d1b888d914 100644 --- a/drivers/iommu/iommufd/liveupdate.c +++ b/drivers/iommu/iommufd/liveupdate.c @@ -12,6 +12,47 @@ #include "iommufd_private.h" +int iommufd_hwpt_lu_set_preserved(struct iommufd_ucmd *ucmd) +{ + struct iommu_hwpt_lu_set_preserved *cmd = ucmd->cmd; + struct iommufd_hwpt_paging *hwpt_target, *hwpt; + struct iommufd_ctx *ictx = ucmd->ictx; + struct iommufd_object *obj; + unsigned long index; + int rc = 0; + + /* TODO: return error if iommufd is already preserved. */ + + hwpt_target = iommufd_get_hwpt_paging(ucmd, cmd->hwpt_id); + if (IS_ERR(hwpt_target)) + return PTR_ERR(hwpt_target); + + xa_lock(&ictx->objects); + xa_for_each(&ictx->objects, index, obj) { + if (obj->type != IOMMUFD_OBJ_HWPT_PAGING) + continue; + + hwpt = container_of(obj, struct iommufd_hwpt_paging, common.obj); + + if (hwpt == hwpt_target) + continue; + if (!hwpt->lu_preserved) + continue; + if (hwpt->lu_token == cmd->hwpt_token) { + rc = -EADDRINUSE; + goto out; + } + } + + hwpt_target->lu_preserved = cmd->preserved; + hwpt_target->lu_token = cmd->hwpt_token; + +out: + xa_unlock(&ictx->objects); + iommufd_put_object(ictx, &hwpt_target->common.obj); + return rc; +} + static int iommufd_liveupdate_preserve(struct liveupdate_file_op_args *args) { struct iommufd_ctx *ictx = iommufd_ctx_from_file(args->file); @@ -121,6 +162,11 @@ static bool iommufd_liveupdate_can_finish(struct liveupdate_file_op_args *args) return true; } +int iommufd_hwpt_lu_restore(struct iommufd_ucmd *ucmd) +{ + return -ENOTTY; +} + static void iommufd_liveupdate_finish(struct liveupdate_file_op_args *args) { struct iommufd_lu *iommufd_lu; diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 12601f9ad217..b63f61331cae 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -493,6 +493,10 @@ static const struct iommufd_ioctl_op iommufd_ioctl_ops[] = { __reserved), IOCTL_OP(IOMMU_VIOMMU_ALLOC, iommufd_viommu_alloc_ioctl, struct iommu_viommu_alloc, out_viommu_id), + IOCTL_OP(IOMMU_HWPT_LU_SET_PRESERVED, iommufd_hwpt_lu_set_preserved, + struct iommu_hwpt_lu_set_preserved, preserved), + IOCTL_OP(IOMMU_HWPT_LU_RESTORE, iommufd_hwpt_lu_restore, + struct iommu_hwpt_lu_restore, hwpt_token), #ifdef CONFIG_IOMMUFD_TEST IOCTL_OP(IOMMU_TEST_CMD, iommufd_test, struct iommu_test_cmd, last), #endif diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 2c41920b641d..4b953129f8d8 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -57,6 +57,8 @@ enum { IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, IOMMUFD_CMD_VEVENTQ_ALLOC = 0x93, IOMMUFD_CMD_HW_QUEUE_ALLOC = 0x94, + IOMMUFD_CMD_HWPT_LU_SET_PRESERVED = 0x95, + IOMMUFD_CMD_HWPT_LU_RESTORE = 0x96, }; /** @@ -1299,4 +1301,43 @@ struct iommu_hw_queue_alloc { __aligned_u64 length; }; #define IOMMU_HW_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HW_QUEUE_ALLOC) + +/** + * struct iommu_hwpt_lu_set_preserved - ioctl(IOMMU_HWPT_LU_SET_PRESERVED) + * @size: sizeof(struct iommu_hwpt_lu_set_preserved) + * @hwpt_id: Iommufd object ID of the target HWPT + * @hwpt_token: Token to identify this hwpt upon restore + * @preserved: If non-zero, HWPT is preserved by liveupdate + * + * If preserved set to non-zero, the target HWPT will be preserved. + * + * The hwpt_token is provided by userspace. If userspace enters a token + * already in use within this iommufd, -EADDRINUSE is returned from this ioctl. + */ +struct iommu_hwpt_lu_set_preserved { + __u32 size; + __u32 hwpt_id; + __u32 hwpt_token; + __u8 preserved; +}; +#define IOMMU_HWPT_LU_SET_PRESERVED _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_LU_SET_PRESERVED) + +/** + * struct iommu_hwpt_lu_restore - ioctl(IOMMU_HWPT_LU_RESTORE) + * @size: sizeof(struct iommu_hwpt_lu_restore) + * @pt_id: Output the ID of the recreated HWPT. + * @hwpt_token: Token to identify this hwpt + * @hwpt_alloc_flags: Combination of enum iommufd_hwpt_alloc_flags + + * An immutable HWPT is restored without a parent IOAS, and the ID + * of this new HWPT is returned. + */ + +struct iommu_hwpt_lu_restore { + __u32 size; + __u32 pt_id; + __u32 hwpt_token; + __u32 hwpt_alloc_flags; +}; +#define IOMMU_HWPT_LU_RESTORE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_LU_RESTORE) #endif -- 2.52.0.158.g65b55ccf14-goog