From: Srirangan Madhavan <smadhavan@nvidia.com>
To: Alison Schofield <alison.schofield@intel.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Dave Jiang <dave.jiang@intel.com>,
Davidlohr Bueso <dave@stgolabs.net>,
Ira Weiny <ira.weiny@intel.com>,
Jonathan Cameron <jic23@kernel.org>,
Vishal Verma <vishal.l.verma@intel.com>,
linux-cxl@vger.kernel.org, linux-pci@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: Alex Williamson <alex.williamson@redhat.com>,
vsethi@nvidia.com, alwilliamson@nvidia.com,
Sai Yashwanth Reddy Kancherla <skancherla@nvidia.com>,
Vishal Aslot <vaslot@nvidia.com>,
Manish Honap <mhonap@nvidia.com>, Jiandi An <jan@nvidia.com>,
Richard Cheng <icheng@nvidia.com>,
linux-tegra@vger.kernel.org,
Srirangan Madhavan <smadhavan@nvidia.com>
Subject: [PATCH v15 13/16] PCI/CXL: Restore CXL state after PCI reset
Date: Sun, 11 Oct 2026 02:14:19 +0000 [thread overview]
Message-ID: <20261011021422.3428136-14-smadhavan@nvidia.com> (raw)
In-Reply-To: <20261011021422.3428136-1-smadhavan@nvidia.com>
Restore the PCI configuration needed for HDM access, followed by cached
HDM decoder and CXL Device DVSEC state. Recommit a cleared locked decoder
before restoring its lock, but leave surviving locked state unchanged.
Stop at the first restoration failure and preserve a disabled PCI command
snapshot. Keep IOMMU exclusion active through restoration and post-reset
cache invalidation.
Program the decoders from built-in CXL code that takes only a mapped
register block, and keep PCI state handling in drivers/pci/cxl.c.
The restore helper structure and diagnostics follow Dave Jiang's
reference implementation on his cxl-type2-reset branch.
Link: https://git.kernel.org/pub/scm/linux/kernel/git/djiang/linux.git/commit/?id=81fff5893a3140361cac625b09ada798afb92e03
Suggested-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Srirangan Madhavan <smadhavan@nvidia.com>
Assisted-by: LLM
---
drivers/cxl/core/hdm_regs.c | 180 ++++++++++++++++++++++++++++++++++++
drivers/pci/cxl.c | 176 +++++++++++++++++++++++++++++++++--
include/cxl/hdm.h | 2 +
3 files changed, 351 insertions(+), 7 deletions(-)
diff --git a/drivers/cxl/core/hdm_regs.c b/drivers/cxl/core/hdm_regs.c
index f0b360867655..cef5e9949d2c 100644
--- a/drivers/cxl/core/hdm_regs.c
+++ b/drivers/cxl/core/hdm_regs.c
@@ -73,6 +73,26 @@ int cxld_await_commit(void __iomem *hdm, int id)
}
EXPORT_SYMBOL_FOR_MODULES(cxld_await_commit, "cxl_core");
+static int cxld_await_uncommit(void __iomem *hdm, int id)
+{
+ u32 ctrl;
+ int i;
+
+ for (i = 0; i < COMMIT_TIMEOUT_MS; i++) {
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
+ if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMIT_ERROR, ctrl)) {
+ ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
+ writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
+ return -EIO;
+ }
+ if (!FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
+ return 0;
+ fsleep(1000);
+ }
+
+ return -ETIMEDOUT;
+}
+
static u32 cxl_hdm_write_range(void __iomem *hdm,
const struct cxl_decoder_config *config)
{
@@ -273,3 +293,163 @@ int cxl_hdm_read_state(struct device *dev, void __iomem *hdm,
return 0;
}
+
+static int cxl_hdm_decoder_uncommit(struct device *dev, void __iomem *hdm,
+ int id, bool *retained)
+{
+ u32 ctrl;
+ int rc;
+
+ *retained = false;
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
+ if (ctrl == U32_MAX)
+ return -EIO;
+ if (ctrl & CXL_HDM_DECODER0_CTRL_COMMIT_ERROR) {
+ dev_err(dev, "CXL HDM decoder %d has commit error set\n", id);
+ return -EIO;
+ }
+
+ if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK) {
+ if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED) {
+ *retained = true;
+ return 0;
+ }
+
+ dev_err(dev, "CXL HDM decoder %d is locked and uncommitted\n",
+ id);
+ return -EIO;
+ }
+
+ if (!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED))
+ return 0;
+
+ ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
+ writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
+
+ rc = cxld_await_uncommit(hdm, id);
+ if (rc)
+ dev_err(dev, "CXL HDM decoder %d uncommit failed: %d\n", id, rc);
+
+ return rc;
+}
+
+static bool
+cxl_hdm_decoder_settings_match(const struct cxl_endpoint_decoder_settings *saved,
+ const struct cxl_endpoint_decoder_settings *active)
+{
+ const struct cxl_decoder_config *a = &saved->config;
+ const struct cxl_decoder_config *b = &active->config;
+
+ return a->id == b->id &&
+ a->hpa_range.start == b->hpa_range.start &&
+ a->hpa_range.end == b->hpa_range.end &&
+ a->interleave_ways == b->interleave_ways &&
+ a->interleave_granularity == b->interleave_granularity &&
+ a->target_type == b->target_type &&
+ (a->flags & CXL_DECODER_F_RESET_MASK) ==
+ (b->flags & CXL_DECODER_F_RESET_MASK) &&
+ saved->skip == active->skip;
+}
+
+static int
+cxl_hdm_restore_decoder(struct device *dev, void __iomem *hdm,
+ const struct cxl_endpoint_decoder_settings *settings)
+{
+ const struct cxl_decoder_config *config = &settings->config;
+ bool retained;
+ u32 ctrl;
+ int rc;
+
+ rc = cxl_hdm_decoder_uncommit(dev, hdm, config->id, &retained);
+ if (rc)
+ return rc;
+
+ if (retained) {
+ struct cxl_endpoint_decoder_settings active;
+
+ rc = cxl_hdm_read_decoder_settings(dev, &active, hdm, config->id);
+ if (rc) {
+ dev_err(dev,
+ "CXL HDM decoder %d has invalid configuration: %d\n",
+ config->id, rc);
+ return rc;
+ }
+ if (!cxl_hdm_decoder_settings_match(settings, &active)) {
+ dev_err(dev,
+ "CXL HDM decoder %d retained unexpected locked state\n",
+ config->id);
+ return -EIO;
+ }
+ return 0;
+ }
+
+ if (!(config->flags & CXL_DECODER_F_ENABLE))
+ return 0;
+
+ cxl_commit_start_endpoint(settings, hdm);
+ rc = cxld_await_commit(hdm, config->id);
+ if (rc) {
+ dev_err(dev, "CXL HDM decoder %d restore failed: %d\n",
+ config->id, rc);
+ return rc;
+ }
+
+ if (!(config->flags & CXL_DECODER_F_LOCK))
+ return 0;
+
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(config->id));
+ if (ctrl == U32_MAX)
+ return -EIO;
+ ctrl |= CXL_HDM_DECODER0_CTRL_LOCK;
+ writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(config->id));
+
+ ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(config->id));
+ if (ctrl == U32_MAX ||
+ !(ctrl & CXL_HDM_DECODER0_CTRL_LOCK)) {
+ dev_err(dev, "CXL HDM decoder %d failed to restore lock\n",
+ config->id);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * cxl_hdm_restore_state() - reprogram endpoint HDM decoders from a snapshot
+ * @dev: device for error messages
+ * @hdm: mapped HDM decoder capability
+ * @snapshot: state from cxl_hdm_cache_snapshot()
+ *
+ * Restore global control, then recommit each enabled decoder in order. Leave
+ * a locked decoder that kept its programming across the reset unchanged,
+ * after checking that it still matches @snapshot.
+ *
+ * Return: 0 on success, or the first failure.
+ */
+int cxl_hdm_restore_state(struct device *dev, void __iomem *hdm,
+ const struct cxl_hdm_info *snapshot)
+{
+ int count;
+ int rc;
+
+ count = cxl_hdm_decoder_count(readl(hdm + CXL_HDM_DECODER_CAP_OFFSET));
+ if (count != snapshot->decoder_count) {
+ dev_err(dev, "CXL HDM decoder count changed from %d to %d\n",
+ snapshot->decoder_count, count);
+ return -ENXIO;
+ }
+
+ /* Restore global HDM control before committing individual decoders. */
+ writel(snapshot->global_ctrl, hdm + CXL_HDM_DECODER_CTRL_OFFSET);
+
+ for (int i = 0; i < snapshot->decoder_count; i++) {
+ rc = cxl_hdm_restore_decoder(dev, hdm, &snapshot->settings[i]);
+ if (rc)
+ return rc;
+ }
+
+ /* Flush posted HDM writes before restoring protocol enables. */
+ readl(hdm + CXL_HDM_DECODER_CTRL_OFFSET);
+
+ return 0;
+}
diff --git a/drivers/pci/cxl.c b/drivers/pci/cxl.c
index eccdb57945fe..4c6b712ed4fa 100644
--- a/drivers/pci/cxl.c
+++ b/drivers/pci/cxl.c
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2026 NVIDIA Corporation & Affiliates */
/*
- * CXL reset support in the PCI core. Cache the HDM decoder state of a CXL
- * memory device at enumeration, so it can be restored after a reset without
- * a CXL driver, and implement CXL Device Reset. HDM register formats and
+ * CXL reset support in the PCI core: cache the HDM decoder state of a CXL
+ * memory device at enumeration, implement CXL Device Reset, and restore the
+ * cached state afterwards without a CXL driver. HDM register formats and
* programming live in drivers/cxl.
*/
#include <linux/bitfield.h>
@@ -16,6 +16,7 @@
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/memregion.h>
+#include <linux/overflow.h>
#include <linux/pci.h>
#include <linux/slab.h>
@@ -227,6 +228,150 @@ void pci_cxl_hdm_cache_release(struct pci_dev *pdev)
cxl_hdm_cache_release(&pdev->hdm);
}
+static void __iomem *cxl_pci_hdm_ioremap_current(struct pci_dev *pdev,
+ int bar,
+ resource_size_t offset,
+ resource_size_t size)
+{
+ struct resource *res;
+ resource_size_t hdm_start;
+ void __iomem *hdm;
+
+ if (bar < 0 || bar >= PCI_STD_NUM_BARS || !size)
+ return IOMEM_ERR_PTR(-EINVAL);
+ if (!cxl_pci_bar_assigned(pdev, bar))
+ return IOMEM_ERR_PTR(-ENODEV);
+
+ res = &pdev->resource[bar];
+ if (offset > resource_size(res) || size > resource_size(res) - offset)
+ return IOMEM_ERR_PTR(-ENODEV);
+ if (check_add_overflow(res->start, offset, &hdm_start))
+ return IOMEM_ERR_PTR(-EOVERFLOW);
+
+ hdm = ioremap(hdm_start, size);
+ if (!hdm) {
+ pci_err(pdev, "failed to remap CXL HDM decoder registers\n");
+ return IOMEM_ERR_PTR(-ENOMEM);
+ }
+
+ return hdm;
+}
+
+static void cxl_restore_pci_state_for_hdm_restore(struct pci_dev *pdev,
+ u16 *command)
+{
+ u32 saved_config = pdev->saved_config_space[PCI_COMMAND / 4];
+ u32 restore_config;
+
+ device_lock_assert(&pdev->dev);
+ *command = saved_config & 0xffff;
+
+ /*
+ * Restore BARs and the related PCI state needed to reach HDM MMIO.
+ * Temporarily alter the saved command value so that
+ * pci_restore_state() enables MSE but cannot enable BME or INTx before
+ * CXL state restoration completes. Preserve the original saved value
+ * for the outer PCI reset path.
+ */
+ restore_config = saved_config | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_INTX_DISABLE;
+ restore_config &= ~PCI_COMMAND_MASTER;
+
+ pdev->saved_config_space[PCI_COMMAND / 4] = restore_config;
+ pci_restore_state(pdev);
+ pdev->saved_config_space[PCI_COMMAND / 4] = saved_config;
+}
+
+static int cxl_restore_dvsec_ctrl(struct pci_dev *pdev,
+ const struct cxl_hdm_info *snapshot)
+{
+ int rc;
+
+ if (!snapshot->dvsec_ctrl_valid) {
+ pci_err(pdev, "CXL DVSEC control snapshot is invalid\n");
+ return -ENXIO;
+ }
+
+ rc = pci_write_config_word(pdev, snapshot->dvsec + PCI_DVSEC_CXL_CTRL,
+ snapshot->dvsec_ctrl);
+ if (rc) {
+ rc = pcibios_err_to_errno(rc);
+ pci_err(pdev, "failed to restore CXL DVSEC control: %d\n", rc);
+ }
+
+ return rc;
+}
+
+static int cxl_restore_state(struct pci_dev *pdev,
+ const struct cxl_hdm_info *snapshot)
+{
+ void __iomem *hdm;
+ int rc;
+
+ hdm = cxl_pci_hdm_ioremap_current(pdev, snapshot->hdm_bar,
+ snapshot->hdm_offset,
+ snapshot->hdm_size);
+ if (IS_ERR(hdm)) {
+ pci_err(pdev, "failed to map CXL HDM state for restore: %ld\n",
+ PTR_ERR(hdm));
+ return PTR_ERR(hdm);
+ }
+
+ rc = cxl_hdm_restore_state(&pdev->dev, hdm, snapshot);
+ iounmap(hdm);
+ if (rc)
+ return rc;
+
+ return cxl_restore_dvsec_ctrl(pdev, snapshot);
+}
+
+static void cxl_reset_save_disabled_state(struct pci_dev *pdev)
+{
+ u32 *saved_command = &pdev->saved_config_space[PCI_COMMAND / 4];
+ int rc;
+
+ rc = pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
+ if (rc)
+ pci_err(pdev,
+ "failed to disable device after CXL reset failure: %d\n",
+ pcibios_err_to_errno(rc));
+
+ /* Preserve the pre-reset snapshot if PCI state has not been restored. */
+ if (!pdev->state_saved) {
+ rc = pci_save_state(pdev);
+ if (rc)
+ pci_err(pdev,
+ "failed to save disabled state after CXL reset failure: %d\n",
+ rc);
+ }
+
+ /* Ensure the outer PCI restore cannot re-enable MSE or BME. */
+ *saved_command &= GENMASK(31, 16);
+ *saved_command |= PCI_COMMAND_INTX_DISABLE;
+}
+
+static int cxl_reset_save_restored_state(struct pci_dev *pdev, u16 command)
+{
+ int rc;
+
+ rc = pci_write_config_word(pdev, PCI_COMMAND, command);
+ if (rc) {
+ rc = pcibios_err_to_errno(rc);
+ pci_err(pdev, "failed to restore PCI command state: %d\n", rc);
+ cxl_reset_save_disabled_state(pdev);
+ return rc;
+ }
+
+ rc = pci_save_state(pdev);
+ if (rc) {
+ pci_err(pdev, "failed to save restored state after CXL reset: %d\n",
+ rc);
+ cxl_reset_save_disabled_state(pdev);
+ }
+
+ return rc;
+}
+
/*
* CXL r4.0 sec 9.7.2 defines the reset completion timeout encodings.
* Sec 9.7.3 leaves config-space access behavior undefined for 100 ms after
@@ -394,7 +539,9 @@ static int cxl_clear_memory(struct pci_dev *pdev, int dvsec, bool initiate)
}
static int __cxl_reset_execute(struct pci_dev *pdev, int dvsec, u16 cap,
- struct cxl_hdm_quiesce *q)
+ const struct cxl_hdm_info *snapshot,
+ struct cxl_hdm_quiesce *q,
+ u16 *command)
{
int rc, rc2;
@@ -419,8 +566,15 @@ static int __cxl_reset_execute(struct pci_dev *pdev, int dvsec, u16 cap,
pci_err(pdev, "failed to clear CXL Reset Memory Clear: %d\n", rc2);
rc = rc ?: rc2;
+ if (!rc) {
+ cxl_restore_pci_state_for_hdm_restore(pdev, command);
+ rc = cxl_restore_state(pdev, snapshot);
+ }
+
rc2 = cxl_hdm_quiesce_flush(q);
rc = rc ?: rc2;
+ if (rc)
+ cxl_reset_save_disabled_state(pdev);
pci_dev_reset_iommu_done(pdev);
return rc;
@@ -431,7 +585,7 @@ static int cxl_reset_quiesced(struct pci_dev *pdev, int dvsec, u16 cap)
{
struct cxl_hdm_info *snapshot __free(kfree) = NULL;
struct cxl_hdm_quiesce q;
- u16 saved_ctrl2;
+ u16 command, saved_ctrl2;
int rc, rc2;
rc = pci_read_config_word(pdev, dvsec + PCI_DVSEC_CXL_CTRL2, &saved_ctrl2);
@@ -455,11 +609,19 @@ static int cxl_reset_quiesced(struct pci_dev *pdev, int dvsec, u16 cap)
rc = cxl_reset_disable_cache(pdev, dvsec, cap);
if (!rc)
- rc = __cxl_reset_execute(pdev, dvsec, cap, &q);
+ rc = __cxl_reset_execute(pdev, dvsec, cap, snapshot, &q,
+ &command);
/* Restore cache policy after any attempt to disable caching. */
rc2 = cxl_reset_restore_cache_policy(pdev, dvsec, saved_ctrl2);
cxl_hdm_quiesce_destroy(&q);
- return rc ?: rc2;
+ if (rc)
+ return rc;
+ if (rc2) {
+ cxl_reset_save_disabled_state(pdev);
+ return rc2;
+ }
+
+ return cxl_reset_save_restored_state(pdev, command);
}
static int cxl_reset_execute(struct pci_dev *pdev, int dvsec, u16 cap)
diff --git a/include/cxl/hdm.h b/include/cxl/hdm.h
index f6446a2a7fcd..445093cf0452 100644
--- a/include/cxl/hdm.h
+++ b/include/cxl/hdm.h
@@ -52,6 +52,8 @@ int cxl_hdm_decoder_count_mapped(struct device *dev, void __iomem *hdm,
resource_size_t size);
int cxl_hdm_read_state(struct device *dev, void __iomem *hdm,
struct cxl_hdm_info *info);
+int cxl_hdm_restore_state(struct device *dev, void __iomem *hdm,
+ const struct cxl_hdm_info *snapshot);
bool cxl_hdm_cache_present(struct cxl_hdm_info *const *slot);
void cxl_hdm_cache_publish(struct cxl_hdm_info **slot,
struct cxl_hdm_info *info);
--
2.43.0
next prev parent reply other threads:[~2026-10-11 2:15 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-11 2:14 [PATCH v15 00/16] PCI/CXL: Add CXL reset support for Type 2 devices Srirangan Madhavan
2026-10-11 2:14 ` [PATCH v15 01/16] cxl: Drop stale decoder interleave limit comment Srirangan Madhavan
2026-10-11 2:16 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 02/16] cxl: Share CXL port upstream PCI device lookup Srirangan Madhavan
2026-10-11 2:25 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 03/16] cxl: Move decoder declarations to shared header Srirangan Madhavan
2026-10-11 2:19 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 04/16] cxl: Embed decoder configuration in a standalone structure Srirangan Madhavan
2026-10-11 2:25 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 05/16] cxl: Introduce endpoint HDM decoder settings Srirangan Madhavan
2026-10-11 2:22 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 06/16] cxl: Move HDM decoder helpers to built-in code Srirangan Madhavan
2026-10-11 2:21 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 07/16] cxl: Share HDM decoder register unpacking Srirangan Madhavan
2026-10-11 2:25 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 08/16] cxl: Refresh cached PCI HDM decoder settings Srirangan Madhavan
2026-10-11 2:23 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 09/16] PCI/CXL: Cache endpoint HDM state during PCI enumeration Srirangan Madhavan
2026-10-11 2:25 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 10/16] PCI/CXL: Add CXL Device Reset sequencing Srirangan Madhavan
2026-10-11 2:25 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 11/16] cxl: Validate and synchronize HDM ranges around reset Srirangan Madhavan
2026-10-11 2:21 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 12/16] PCI/CXL: Reject reset with unsafe function scope Srirangan Madhavan
2026-10-11 2:28 ` sashiko-bot
2026-10-11 2:14 ` Srirangan Madhavan [this message]
2026-10-11 2:25 ` [PATCH v15 13/16] PCI/CXL: Restore CXL state after PCI reset sashiko-bot
2026-10-11 2:14 ` [PATCH v15 14/16] PCI/CXL: Expose CXL Reset as a PCI reset method Srirangan Madhavan
2026-10-11 2:34 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 15/16] PCI/CXL: Restore CXL state after CXL bus reset Srirangan Madhavan
2026-10-11 2:24 ` sashiko-bot
2026-10-11 2:14 ` [PATCH v15 16/16] tools/testing/cxl: Add HDM decoder range checks Srirangan Madhavan
2026-10-11 2:22 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261011021422.3428136-14-smadhavan@nvidia.com \
--to=smadhavan@nvidia.com \
--cc=alex.williamson@redhat.com \
--cc=alison.schofield@intel.com \
--cc=alwilliamson@nvidia.com \
--cc=bhelgaas@google.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=icheng@nvidia.com \
--cc=ira.weiny@intel.com \
--cc=jan@nvidia.com \
--cc=jic23@kernel.org \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=mhonap@nvidia.com \
--cc=skancherla@nvidia.com \
--cc=vaslot@nvidia.com \
--cc=vishal.l.verma@intel.com \
--cc=vsethi@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.