From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 697C030507E for ; Tue, 2 Dec 2025 23:03:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764716613; cv=none; b=O/Q1WCCcW6+JZMOxCNk5jHe/3flD0rXXsZ7mi8B6x6hh9s0aAKT8wOUOvjjfmMLWWStETr42gRSOD3XC6iP91RMayEs3WexoYggh/i9odDGmGylNKMnDBRx8QInClbdk70SwmYjGzXhOvNqjEoCmMyefagSIJg4QovrIZO8FVJ0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764716613; c=relaxed/simple; bh=KY1jCAENzds73jSibtdEvckeq1aC3PSmjlk3rwiYZhE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hSqKSaJEGyKQx87cR8xU8g+BJDWOmyMbUAYRmM/hb/uWJ82AXBj4b0x+5GlsjIr0WImtgOAem7pHK5JgbGueo5N3kn5laxrRzpiqT2ecELYwoYYG3wotghVSZ1/2nxrqj0D89Snv9CaJN8DjcDQhbDhk4fho/7tYzlmRLzCgf+c= 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=TihJpvvJ; arc=none smtp.client-ip=209.85.214.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="TihJpvvJ" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2955f0b8895so2795345ad.0 for ; Tue, 02 Dec 2025 15:03:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1764716611; x=1765321411; 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=ASFM5WU8uj7qIqqTRFyOlN4Z5qMVIRe9aLNxE/AiT3g=; b=TihJpvvJ0drhOqTZMQ2HB4Uklo/2AsLb7LRWo3BichMnCuk3LlWZaknQxI8e3tav7w lFjT8FBn8I9X6Wh9ieXh0fluy2ICEYpeFMcJE6eWOpTCNsCDnG1dr5UnF4MHG3YWk3Rp zGpftPcPgxe/FQ0Lo+9YRAgeT+2JcwA8HRTvhCe7WwgDKSrSAz6CYJdrd03F+wDo7nwi LVpRMarD3bpTZRXBs7ExXo2LYO5PgrtykBIzc444uqI4n7nHrkG67+BMKBjg+7VyhVOU WClZ4rIx/Tg3FkATp7luCOQtQ8Ncy66Wls4ATUt38TfbgqpiQpQ1+lbF/aRrcTkb1DAi KLDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764716611; x=1765321411; 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=ASFM5WU8uj7qIqqTRFyOlN4Z5qMVIRe9aLNxE/AiT3g=; b=j1SsPSk8X2jpcATGSdFkBDvQebSFzVRdXmDbP++uAPnuQT+9+VGoj6uAbbKBZfbeCQ clXYqQJ4hGjVzt05utMxHbLQ5/+xts7xSMH7MC9CBWMEeIzN/RvDdrpl2ctOif/S+eGB C951mwc8mtguFNfESYsAWo4vTOm5XXthZa789GZqs4AAg/y0LCSXnNTKoe9NXlz+ImCK kX58ASzE/hYpTALwVTpraLc7j3GTqCoceIrmdZZDhKpCCwU+rNC+yVOzlHZ1VmU36RAl KFS1+v7pQuJyAm4Mv9rzNIKcrLPb0gAXkS1jEWRXTj3V26wJYn2C3XMv3Svzak5sfPo1 bj/A== X-Forwarded-Encrypted: i=1; AJvYcCUDJLh8o2S1nSF03/HxZewBG8biYlc0hdRX+m80TAi1cT3lJuHb/qCA/fq8lhHuL2WEinQaR4MFq5rgV3c=@vger.kernel.org X-Gm-Message-State: AOJu0Yzax+wNV9sgBal+Xg1lj2eoQsRmd6TpQn2zZKILb/wel8hrPGvl 1jDKoje5kGOHPbWD6gQqB8cJumCP4M4SlabFp5C4d84iCi8XApjKiWiLFOCHuE1LuFHbUUWvn/r rmWZ5GPPRUV4tuA== X-Google-Smtp-Source: AGHT+IEg5NNIUB6X64tEFw5/b+/+7BN0IW2m/iavzJE/zMLhoaJ9lg94QcuL/07M6FzbTXsE+QlaIn2zzDj21g== X-Received: from plko11.prod.google.com ([2002:a17:902:6b0b:b0:29d:5afa:2c9]) (user=skhawaja job=prod-delivery.src-stubby-dispatcher) by 2002:a17:903:2341:b0:295:96bc:8698 with SMTP id d9443c01a7336-29d67f33102mr3185125ad.19.1764716610737; Tue, 02 Dec 2025 15:03:30 -0800 (PST) Date: Tue, 2 Dec 2025 23:02:47 +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-18-skhawaja@google.com> Subject: [RFC PATCH v2 17/32] iommu/vt-d: Implement device and iommu preserve/unpreserve ops From: Samiullah Khawaja To: David Woodhouse , Lu Baolu , Joerg Roedel , Will Deacon , Pasha Tatashin , Jason Gunthorpe , iommu@lists.linux.dev Cc: Samiullah Khawaja , Robin Murphy , Pratyush Yadav , Kevin Tian , Alex Williamson , linux-kernel@vger.kernel.org, Saeed Mahameed , Adithya Jayachandran , Parav Pandit , Leon Romanovsky , William Tu , Vipin Sharma , dmatlack@google.com, YiFei Zhu , Chris Li , praan@google.com Content-Type: text/plain; charset="UTF-8" Add implementation of the device and iommu presevation in a separate file. Also set the device and iommu preserve/unpreserve ops in the struct iommu_ops Signed-off-by: Samiullah Khawaja --- drivers/iommu/intel/Makefile | 1 + drivers/iommu/intel/iommu.c | 6 +- drivers/iommu/intel/iommu.h | 9 +++ drivers/iommu/intel/liveupdate.c | 127 +++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 drivers/iommu/intel/liveupdate.c diff --git a/drivers/iommu/intel/Makefile b/drivers/iommu/intel/Makefile index ada651c4a01b..58922d580c79 100644 --- a/drivers/iommu/intel/Makefile +++ b/drivers/iommu/intel/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o +obj-$(CONFIG_LIVEUPDATE) += liveupdate.o diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index d745f833d8b5..3f69a073b2d8 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -60,8 +60,6 @@ static int force_on = 0; static int intel_iommu_tboot_noforce; static int no_platform_optin; -#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) - /* * Take a root_entry and return the Lower Context Table Pointer (LCTP) * if marked present. @@ -3909,6 +3907,10 @@ const struct iommu_ops intel_iommu_ops = { .is_attach_deferred = intel_iommu_is_attach_deferred, .def_domain_type = device_def_domain_type, .page_response = intel_iommu_page_response, + .preserve_device = intel_iommu_preserve_device, + .unpreserve_device = intel_iommu_unpreserve_device, + .preserve = intel_iommu_preserve, + .unpreserve = intel_iommu_unpreserve, }; static void quirk_iommu_igfx(struct pci_dev *dev) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 25c5e22096d4..ea88c86030bb 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -557,6 +557,8 @@ struct root_entry { u64 hi; }; +#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) + /* * low 64 bits: * 0: present @@ -1276,6 +1278,13 @@ static inline int iopf_for_domain_replace(struct iommu_domain *new, return 0; } +#ifdef CONFIG_LIVEUPDATE +int intel_iommu_preserve_device(struct device *dev, struct device_ser *device_ser); +void intel_iommu_unpreserve_device(struct device *dev, struct device_ser *device_ser); +int intel_iommu_preserve(struct iommu_device *iommu, struct iommu_ser *iommu_ser); +void intel_iommu_unpreserve(struct iommu_device *iommu, struct iommu_ser *iommu_ser); +#endif + #ifdef CONFIG_INTEL_IOMMU_SVM void intel_svm_check(struct intel_iommu *iommu); struct iommu_domain *intel_svm_domain_alloc(struct device *dev, diff --git a/drivers/iommu/intel/liveupdate.c b/drivers/iommu/intel/liveupdate.c new file mode 100644 index 000000000000..491075802e4b --- /dev/null +++ b/drivers/iommu/intel/liveupdate.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * Copyright (C) 2025, Google LLC + * Author: Samiullah Khawaja + */ + +#define pr_fmt(fmt) "iommu: liveupdate: " fmt + +#include +#include +#include +#include + +#include "iommu.h" +#include "../iommu-pages.h" + +static void unpreserve_iommu_context(struct intel_iommu *iommu, int end) +{ + struct context_entry *context; + int i; + + if (end < 0) + end = ROOT_ENTRY_NR; + + for (i = 0; i < end; i++) { + context = iommu_context_addr(iommu, i, 0, 0); + if (context) + iommu_unpreserve_page(context); + + if (!sm_supported(iommu)) + continue; + + context = iommu_context_addr(iommu, i, 0x80, 0); + if (context) + iommu_unpreserve_page(context); + } +} + +static int preserve_iommu_context(struct intel_iommu *iommu) +{ + struct context_entry *context; + int ret; + int i; + + for (i = 0; i < ROOT_ENTRY_NR; i++) { + context = iommu_context_addr(iommu, i, 0, 0); + if (context) { + ret = iommu_preserve_page(context); + if (ret) + goto error; + } + + if (!sm_supported(iommu)) + continue; + + context = iommu_context_addr(iommu, i, 0x80, 0); + if (context) { + ret = iommu_preserve_page(context); + if (ret) + goto error_sm; + } + } + + return 0; + +error_sm: + context = iommu_context_addr(iommu, i, 0, 0); + iommu_unpreserve_page(context); +error: + unpreserve_iommu_context(iommu, i); + return ret; +} + +int intel_iommu_preserve_device(struct device *dev, struct device_ser *device_ser) +{ + struct device_domain_info *info = dev_iommu_priv_get(dev); + + if (!dev_is_pci(dev)) + return -EOPNOTSUPP; + + if (!info) + return -EINVAL; + + device_ser->domain_iommu_ser.did = domain_id_iommu(info->domain, info->iommu); + + /* TODO: Add support preservation of PASIDs. */ + return 0; +} + +void intel_iommu_unpreserve_device(struct device *dev, struct device_ser *device_ser) +{ +} + +int intel_iommu_preserve(struct iommu_device *iommu_dev, struct iommu_ser *ser) +{ + struct intel_iommu *iommu; + int ret; + + iommu = container_of(iommu_dev, struct intel_iommu, iommu); + + spin_lock(&iommu->lock); + ret = preserve_iommu_context(iommu); + if (ret) + goto err; + + ret = iommu_preserve_page(iommu->root_entry); + if (ret) { + unpreserve_iommu_context(iommu, -1); + goto err; + } + + ser->intel.phys_addr = iommu->reg_phys; + ser->intel.root_table = __pa(iommu->root_entry); + ser->type = IOMMU_INTEL; + ser->token = ser->intel.phys_addr; + spin_unlock(&iommu->lock); + + return 0; +err: + spin_unlock(&iommu->lock); + return ret; +} + +void intel_iommu_unpreserve(struct iommu_device *iommu, struct iommu_ser *iommu_ser) +{ +} -- 2.52.0.158.g65b55ccf14-goog