public inbox for linux-riscv@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 0/2] riscv: iommu: Add shutdown callback for kexec
@ 2024-12-13 11:42 Xu Lu
  2024-12-13 11:42 ` [PATCH 1/2] iommu/riscv: Empty iommu queue before enabling it Xu Lu
  2024-12-13 11:42 ` [PATCH 2/2] iommu/riscv: Add shutdown function for iommu driver Xu Lu
  0 siblings, 2 replies; 3+ messages in thread
From: Xu Lu @ 2024-12-13 11:42 UTC (permalink / raw)
  To: tjeznach, joro, will
  Cc: lihangjing, xieyongji, guojinhui.liam, linux-riscv, linux-kernel,
	Xu Lu

After kexec, the newly booted kernel can not initialize iommu driver
successfully as no one resets iommu state before kexec.

This patch series supplies shutdown callback for iommu pmu driver. The
shutdown callback resets necessary registers so that newly booted kernel
can pass riscv_iommu_init_check() after kexec.

Xu Lu (2):
  iommu/riscv: Empty iommu queue before enabling it
  iommu/riscv: Add shutdown function for iommu driver

 drivers/iommu/riscv/iommu-pci.c      |  8 ++++++++
 drivers/iommu/riscv/iommu-platform.c |  6 ++++++
 drivers/iommu/riscv/iommu.c          | 12 ++++++++++--
 drivers/iommu/riscv/iommu.h          |  1 +
 4 files changed, 25 insertions(+), 2 deletions(-)

-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] iommu/riscv: Empty iommu queue before enabling it
  2024-12-13 11:42 [PATCH 0/2] riscv: iommu: Add shutdown callback for kexec Xu Lu
@ 2024-12-13 11:42 ` Xu Lu
  2024-12-13 11:42 ` [PATCH 2/2] iommu/riscv: Add shutdown function for iommu driver Xu Lu
  1 sibling, 0 replies; 3+ messages in thread
From: Xu Lu @ 2024-12-13 11:42 UTC (permalink / raw)
  To: tjeznach, joro, will
  Cc: lihangjing, xieyongji, guojinhui.liam, linux-riscv, linux-kernel,
	Xu Lu

Changing cqen/fqen/pqen from 0 to 1 sets the cqh/fqt/pqt registers to 0.
But the cqt/fqh/pqh registers are left unmodified. This commit resets
cqt/fqh/pqh registers to ensure corresponding queues are empty before
being enabled during initialization.

Signed-off-by: Xu Lu <luxu.kernel@bytedance.com>
---
 drivers/iommu/riscv/iommu.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 8a05def774bd..84806724f568 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -240,6 +240,12 @@ static int riscv_iommu_queue_enable(struct riscv_iommu_device *iommu,
 		return rc;
 	}
 
+	/* Empty queue before enabling it */
+	if (queue->qid == RISCV_IOMMU_INTR_CQ)
+		riscv_iommu_writel(queue->iommu, Q_TAIL(queue), 0);
+	else
+		riscv_iommu_writel(queue->iommu, Q_HEAD(queue), 0);
+
 	/*
 	 * Enable queue with interrupts, clear any memory fault if any.
 	 * Wait for the hardware to acknowledge request and activate queue
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] iommu/riscv: Add shutdown function for iommu driver
  2024-12-13 11:42 [PATCH 0/2] riscv: iommu: Add shutdown callback for kexec Xu Lu
  2024-12-13 11:42 ` [PATCH 1/2] iommu/riscv: Empty iommu queue before enabling it Xu Lu
@ 2024-12-13 11:42 ` Xu Lu
  1 sibling, 0 replies; 3+ messages in thread
From: Xu Lu @ 2024-12-13 11:42 UTC (permalink / raw)
  To: tjeznach, joro, will
  Cc: lihangjing, xieyongji, guojinhui.liam, linux-riscv, linux-kernel,
	Xu Lu

This commit supplies shutdown callback for iommu pmu driver. The shutdown
callback resets necessary registers so that newly booted kernel can pass
riscv_iommu_init_check() after kexec. Also, the shutdown callback resets
iommu mode to bare instead of off so that new kernel can still use PCIE
devices even when CONFIG_RISCV_IOMMU is not enabled.

Signed-off-by: Xu Lu <luxu.kernel@bytedance.com>
---
 drivers/iommu/riscv/iommu-pci.c      | 8 ++++++++
 drivers/iommu/riscv/iommu-platform.c | 6 ++++++
 drivers/iommu/riscv/iommu.c          | 6 ++++--
 drivers/iommu/riscv/iommu.h          | 1 +
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-pci.c b/drivers/iommu/riscv/iommu-pci.c
index c7a89143014c..d82d2b00904c 100644
--- a/drivers/iommu/riscv/iommu-pci.c
+++ b/drivers/iommu/riscv/iommu-pci.c
@@ -101,6 +101,13 @@ static void riscv_iommu_pci_remove(struct pci_dev *pdev)
 	riscv_iommu_remove(iommu);
 }
 
+static void riscv_iommu_pci_shutdown(struct pci_dev *pdev)
+{
+	struct riscv_iommu_device *iommu = dev_get_drvdata(&pdev->dev);
+
+	riscv_iommu_disable(iommu);
+}
+
 static const struct pci_device_id riscv_iommu_pci_tbl[] = {
 	{PCI_VDEVICE(REDHAT, PCI_DEVICE_ID_REDHAT_RISCV_IOMMU), 0},
 	{PCI_VDEVICE(RIVOS, PCI_DEVICE_ID_RIVOS_RISCV_IOMMU_GA), 0},
@@ -112,6 +119,7 @@ static struct pci_driver riscv_iommu_pci_driver = {
 	.id_table = riscv_iommu_pci_tbl,
 	.probe = riscv_iommu_pci_probe,
 	.remove = riscv_iommu_pci_remove,
+	.shutdown = riscv_iommu_pci_shutdown,
 	.driver = {
 		.suppress_bind_attrs = true,
 	},
diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iommu-platform.c
index 382ba2841849..62c40b99cf62 100644
--- a/drivers/iommu/riscv/iommu-platform.c
+++ b/drivers/iommu/riscv/iommu-platform.c
@@ -74,6 +74,11 @@ static void riscv_iommu_platform_remove(struct platform_device *pdev)
 	riscv_iommu_remove(dev_get_drvdata(&pdev->dev));
 };
 
+static void riscv_iommu_platform_shutdown(struct platform_device *pdev)
+{
+	riscv_iommu_disable(dev_get_drvdata(&pdev->dev));
+};
+
 static const struct of_device_id riscv_iommu_of_match[] = {
 	{.compatible = "riscv,iommu",},
 	{},
@@ -82,6 +87,7 @@ static const struct of_device_id riscv_iommu_of_match[] = {
 static struct platform_driver riscv_iommu_platform_driver = {
 	.probe = riscv_iommu_platform_probe,
 	.remove = riscv_iommu_platform_remove,
+	.shutdown = riscv_iommu_platform_shutdown,
 	.driver = {
 		.name = "riscv,iommu",
 		.of_match_table = riscv_iommu_of_match,
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 84806724f568..670b4302aca8 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -651,9 +651,11 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm
  * This is best effort IOMMU translation shutdown flow.
  * Disable IOMMU without waiting for hardware response.
  */
-static void riscv_iommu_disable(struct riscv_iommu_device *iommu)
+void riscv_iommu_disable(struct riscv_iommu_device *iommu)
 {
-	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_DDTP, 0);
+	riscv_iommu_writeq(iommu, RISCV_IOMMU_REG_DDTP,
+			   FIELD_PREP(RISCV_IOMMU_DDTP_IOMMU_MODE,
+				      RISCV_IOMMU_DDTP_IOMMU_MODE_BARE));
 	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_CQCSR, 0);
 	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_FQCSR, 0);
 	riscv_iommu_writel(iommu, RISCV_IOMMU_REG_PQCSR, 0);
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index b1c4664542b4..46df79dd5495 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -64,6 +64,7 @@ struct riscv_iommu_device {
 
 int riscv_iommu_init(struct riscv_iommu_device *iommu);
 void riscv_iommu_remove(struct riscv_iommu_device *iommu);
+void riscv_iommu_disable(struct riscv_iommu_device *iommu);
 
 #define riscv_iommu_readl(iommu, addr) \
 	readl_relaxed((iommu)->reg + (addr))
-- 
2.20.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-12-13 11:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-13 11:42 [PATCH 0/2] riscv: iommu: Add shutdown callback for kexec Xu Lu
2024-12-13 11:42 ` [PATCH 1/2] iommu/riscv: Empty iommu queue before enabling it Xu Lu
2024-12-13 11:42 ` [PATCH 2/2] iommu/riscv: Add shutdown function for iommu driver Xu Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox