From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) (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 21DEA388E51 for ; Sun, 14 Jun 2026 23:37:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781480263; cv=none; b=UFZYPqKiZ5UihbjCv9FWOahacyzVUKxXan+vxMxUbFlc1sPgwRtbGiSliH63sTSSgba/uQIuVjDLUGngstCqpRDri2AsA+WMpXyoTQT6tRIixY8nLRcVT84/zzNsl6qGc7Egc6Z0arW87bXTDfUZoW0AvyGsk47Heij00nK7cdM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781480263; c=relaxed/simple; bh=joV69gjacfTcRWrVT6OQq8u8NrBGJA549Sh4ZYyP7Ns=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=MzQ3uQXURZZjP6GQ2OgtvXEmX3KErmqFMLBu0/8WZW/luXp+z9xqe5o3CkOeVjIdSl36rwqdbjF5cCyB8ueoR/0SnlGTSJKaI0XYdZrJiyXMrw0sMbMSY2oFwLDF5nNgoyyJ9OkzHIyU6GwhLcjT0jZH+XuQj93FTEgpfKTTzNs= 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=rgu6fs3l; arc=none smtp.client-ip=209.85.215.202 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="rgu6fs3l" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-c85a2cde332so1203829a12.3 for ; Sun, 14 Jun 2026 16:37:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1781480260; x=1782085060; 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=nY4FJNVOanhvxXtG88kwftKdSiyXJ7/r90PqLlk19Vc=; b=rgu6fs3lqDT4ykq9XQyEwe5tV9nWLQgFCJKvgTMCzRucNgazetw/K5xte5FqqGtiP3 DOVylngNxVPupm2BoHVPKTQo9holi9cIE5lPoHzLol6eD6xnbd4Ua+ZzQqXWmoLmwiJN ctF8RA5AgFWs1UNuLgCQAORoPCazAL8cg0BAZZkWY+TB9Vb59CBlJ/rrFVqyPwcwFC8V OWHrbpymHJT3miXZRtVY7SSMG0OhIef59ZZyhRz/Q5ryyGmyoJ2wiE+f+IyA27S04Acm USzUvqNykYQdSaTJ3IRUDAC55HhXv/AI2RiVPa/loSPMezapkm6Vjbd6FVjxueNQnml5 eflQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781480260; x=1782085060; 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=nY4FJNVOanhvxXtG88kwftKdSiyXJ7/r90PqLlk19Vc=; b=DRLNuxvwKoxqhh+lIC0N5HGc/KoLcSzRHnxER/xB2fq0og08TgrZYs0JlheJb7kIld 7QOA3KaZGeeu5Qw7nQRt0R9PFeA0qwYnMEGInYNcbOFjCbbBRXPkh2mjt7yIwAEv7Xwx MFxC9uHZpzClJw7tPUlTi9aZQ5KJzgOqSmySzdhWydc8BxuA5MIN3vwpUpmAXwbZC3Ny mvK2xKd3KDKfynN1acx7DVavFY543eTNfvHxu8t2zrQDE65PQ2W9LC9nlJWXFrxjrU/I Q4qmXY5Yy4ggFrySTAqNDrri3hDY/Xr6Ts+IfMNnBZeqdvzTI0X+2GyqavyFJpVDlL1E o5fA== X-Forwarded-Encrypted: i=1; AFNElJ/uhJcyULSqy8cAUgjhQsEce3saKZ8r/+4vVqhy54CHWxiZFPKfw16M1cNhH9aVcAHshEobeIBoOSYadZo=@vger.kernel.org X-Gm-Message-State: AOJu0YxW1nyzN0dJH5kxcMT9ntzzuvp5YO+kCtdBb65HXSEAWFKktdOL dXWqtWfe8F6q55TKQo3+dnx8C+7lsxmiwK79N1cne/w8eyJjn1vJ72MXhdQ5ofitIb8CNBTYD1C ZhQiWZqT5UYdqqQ== X-Received: from pjgg16.prod.google.com ([2002:a17:90b:57d0:b0:36b:8132:e6f4]) (user=skhawaja job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:48cd:b0:368:9da3:c496 with SMTP id 98e67ed59e1d1-37a0497dc45mr12280978a91.24.1781480260146; Sun, 14 Jun 2026 16:37:40 -0700 (PDT) Date: Sun, 14 Jun 2026 23:37:23 +0000 In-Reply-To: <20260614233728.2212104-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: <20260614233728.2212104-1-skhawaja@google.com> X-Mailer: git-send-email 2.54.0.1136.gdb2ca164c4-goog Message-ID: <20260614233728.2212104-14-skhawaja@google.com> Subject: [PATCH v3 13/18] iommu/vt-d: preserve PASID table of preserved device From: Samiullah Khawaja To: David Woodhouse , Lu Baolu , Joerg Roedel , Will Deacon , Jason Gunthorpe Cc: Samiullah Khawaja , Robin Murphy , Kevin Tian , Alex Williamson , Shuah Khan , iommu@lists.linux.dev, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Pratyush Yadav , Pasha Tatashin , David Matlack , Andrew Morton , Pranjal Shrivastava , Vipin Sharma Content-Type: text/plain; charset="UTF-8" In scalable mode the PASID table is used to fetch the io page tables. Preserve and restore the PASID table of the preserved devices. Signed-off-by: Samiullah Khawaja --- drivers/iommu/intel/liveupdate.c | 57 ++++++++++++++++++++++++++++++++ drivers/iommu/intel/pasid.c | 7 ++-- drivers/iommu/intel/pasid.h | 9 +++++ include/linux/kho/abi/iommu.h | 13 ++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel/liveupdate.c b/drivers/iommu/intel/liveupdate.c index 61d864a2e27c..25c940f12955 100644 --- a/drivers/iommu/intel/liveupdate.c +++ b/drivers/iommu/intel/liveupdate.c @@ -14,6 +14,7 @@ #include #include "iommu.h" +#include "pasid.h" #include "../iommu-pages.h" /* 2 tables per bus in scalable mode with upper table at odd bit */ @@ -369,6 +370,7 @@ int intel_iommu_preserve_device(struct device *dev, struct iommu_device_ser *device_ser) { struct device_domain_info *info = dev_iommu_priv_get(dev); + struct pasid_table *pasid_table; int ret; if (!dev_is_pci(dev)) { @@ -385,9 +387,49 @@ int intel_iommu_preserve_device(struct device *dev, device_ser->domain_iommu_ser.attachment_id = domain_id_iommu(info->domain, info->iommu); + + if (!sm_supported(info->iommu)) + return 0; + + pasid_table = intel_pasid_get_table(dev); + if (!pasid_table) + return -EINVAL; + + ret = pasid_lu_handle_pd(pasid_table->table, + pasid_table->max_pasid, + PASID_LU_OP_PRESERVE); + if (ret) + return ret; + + device_ser->intel.pasid_table = virt_to_phys(pasid_table->table); + device_ser->intel.max_pasid = pasid_table->max_pasid; return 0; } +void intel_iommu_unpreserve_device(struct device *dev, + struct iommu_device_ser *device_ser) +{ + struct device_domain_info *info = dev_iommu_priv_get(dev); + struct pasid_table *pasid_table; + + if (!dev_is_pci(dev)) + return; + + if (!info) + return; + + if (!sm_supported(info->iommu)) + return; + + pasid_table = intel_pasid_get_table(dev); + if (!pasid_table) + return; + + pasid_lu_handle_pd(pasid_table->table, + pasid_table->max_pasid, + PASID_LU_OP_UNPRESERVE); +} + int intel_iommu_preserve(struct iommu_device *iommu_dev, struct iommu_hw_ser *ser) { @@ -418,3 +460,18 @@ void intel_iommu_unpreserve(struct iommu_device *iommu_dev, unpreserve_iommu_context_tables(iommu, ser); iommu_unpreserve_pages(iommu->root_entry); } + +void *intel_pasid_try_restore_table(struct device *dev, u64 max_pasid) +{ + struct iommu_device_ser *ser = dev_iommu_restored_state(dev); + + if (!ser || !ser->intel.pasid_table) + return NULL; + + BUG_ON(pasid_lu_handle_pd(phys_to_virt(ser->intel.pasid_table), + ser->intel.max_pasid, + PASID_LU_OP_RESTORE)); + BUG_ON(ser->intel.max_pasid < max_pasid); + + return phys_to_virt(ser->intel.pasid_table); +} diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 89541b74ab8c..5cac8e95f73b 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -60,8 +60,11 @@ int intel_pasid_alloc_table(struct device *dev) size = max_pasid >> (PASID_PDE_SHIFT - 3); order = size ? get_order(size) : 0; - dir = iommu_alloc_pages_node_sz(info->iommu->node, GFP_KERNEL, - 1 << (order + PAGE_SHIFT)); + + dir = intel_pasid_try_restore_table(dev, 1 << (order + PAGE_SHIFT + 3)); + if (!dir) + dir = iommu_alloc_pages_node_sz(info->iommu->node, GFP_KERNEL, + 1 << (order + PAGE_SHIFT)); if (!dir) { kfree(pasid_table); return -ENOMEM; diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index 48d3bb6b68de..44e673a4ad8f 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -301,6 +301,15 @@ static inline void pasid_set_eafe(struct pasid_entry *pe) extern unsigned int intel_pasid_max_id; int intel_pasid_alloc_table(struct device *dev); +#ifdef CONFIG_IOMMU_LIVEUPDATE +void *intel_pasid_try_restore_table(struct device *dev, u64 max_pasid); +#else +static inline void *intel_pasid_try_restore_table(struct device *dev, + u64 max_pasid) +{ + return NULL; +} +#endif void intel_pasid_free_table(struct device *dev); struct pasid_table *intel_pasid_get_table(struct device *dev); int intel_pasid_setup_first_level(struct intel_iommu *iommu, struct device *dev, diff --git a/include/linux/kho/abi/iommu.h b/include/linux/kho/abi/iommu.h index ad760c497e13..27d1fcd7f7e2 100644 --- a/include/linux/kho/abi/iommu.h +++ b/include/linux/kho/abi/iommu.h @@ -127,6 +127,16 @@ struct iommu_dev_map_ser { u64 iommu_phys; } __packed; +/** + * struct iommu_device_intel_ser - Intel specific state of serialized device + * @pasid_table: Physical address of pasid table + * @max_pasid: Maximum supported pasid + */ +struct iommu_device_intel_ser { + u64 pasid_table; + u64 max_pasid; +} __packed; + /** * struct iommu_device_ser - Serialized state of a device * @hdr: Common object header @@ -139,6 +149,9 @@ struct iommu_device_ser { u32 devid; u32 pci_domain_nr; struct iommu_dev_map_ser domain_iommu_ser; + union { + struct iommu_device_intel_ser intel; + }; } __packed; /** -- 2.54.0.1136.gdb2ca164c4-goog