mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
To: <linux-kernel@vger.kernel.org>, <iommu@lists.linux.dev>,
	<joro@8bytes.org>, <jgg@nvidia.com>
Cc: <yi.l.liu@intel.com>, <kevin.tian@intel.com>,
	<nicolinc@nvidia.com>, <vasant.hegde@amd.com>,
	<jon.grimm@amd.com>, <santosh.shukla@amd.com>,
	<sairaj.arunkodilkar@amd.com>, <jay.chen@amd.com>,
	<wvw@google.com>, <wnliu@google.com>, <dantuluris@google.com>,
	<chriscli@google.com>, <kpsingh@google.com>,
	Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: [PATCH 21/22] iommu/amd: Handle set/get option for AMD vIOMMU hw_queue
Date: Mon, 30 Mar 2026 08:42:05 +0000	[thread overview]
Message-ID: <20260330084206.9251-22-suravee.suthikulpanit@amd.com> (raw)
In-Reply-To: <20260330084206.9251-1-suravee.suthikulpanit@amd.com>

Guest kernel programs guest Command Buffer, Event Log, and PPR Log
(a.k.a hardware queue) settings via guest control MMIO register
(guest MMIO offset 0x18). Accesses to the register is trapped by VMM (QEMU)
and information is passed as IOMMU_VIOMMU_OPTION to host IOMMU driver via
struct iommufd_viommu_ops set_option() and get_option().

Provides AMD IOMMU driver hooks to handle set/get operations for the
guest control MMIO register, which uses key parameter as AMD IOMMU MMIO
offset. The value parameter contains the value of the corresponding guest
MMIO register, which is converted to the format of AMD vIOMMU VF Control
MMIO registers then programed onto the hardware.

Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
 drivers/iommu/amd/Makefile          |   2 +-
 drivers/iommu/amd/amd_iommu_types.h |   5 +
 drivers/iommu/amd/amd_viommu.h      |  15 +++
 drivers/iommu/amd/iommufd.c         |   2 +
 drivers/iommu/amd/vfctrl_mmio.c     | 145 ++++++++++++++++++++++++++++
 5 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iommu/amd/vfctrl_mmio.c

diff --git a/drivers/iommu/amd/Makefile b/drivers/iommu/amd/Makefile
index e1e824b9c7b0..a5049fd7f789 100644
--- a/drivers/iommu/amd/Makefile
+++ b/drivers/iommu/amd/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += iommu.o init.o quirks.o ppr.o pasid.o
-obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o nested.o viommu.o
+obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o nested.o viommu.o vfctrl_mmio.o
 obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index 1cd50a4008fb..ff72023fa512 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -194,10 +194,15 @@
 #define CONTROL_GAM_EN		25
 #define CONTROL_GALOG_EN	28
 #define CONTROL_GAINT_EN	29
+#define CONTROL_DUALPPRLOG_EN   30
+#define CONTROL_DUALEVTLOG_EN   32
+#define CONTROL_PPR_AUTO_RSP_EN 39
+#define CONTROL_BLKSTOPMRK_EN   41
 #define CONTROL_NUM_INT_REMAP_MODE	43
 #define CONTROL_NUM_INT_REMAP_MODE_MASK	0x03
 #define CONTROL_NUM_INT_REMAP_MODE_2K	0x01
 #define CONTROL_EPH_EN		45
+#define CONTROL_PPR_AUTO_RSP_AON 48
 #define CONTROL_XT_EN		50
 #define CONTROL_INTCAPXT_EN	51
 #define CONTROL_GCR3TRPMODE	58
diff --git a/drivers/iommu/amd/amd_viommu.h b/drivers/iommu/amd/amd_viommu.h
index 93e44f8b6012..bd4e7481ee0c 100644
--- a/drivers/iommu/amd/amd_viommu.h
+++ b/drivers/iommu/amd/amd_viommu.h
@@ -21,6 +21,11 @@ int amd_viommu_domain_id_update(struct amd_iommu *iommu, u16 gid,
 
 void amd_viommu_set_device_mapping(struct amd_iommu *iommu, u16 hDevId,
 				   u16 guestId, u16 gDevId);
+
+int amd_viommu_guest_mmio_write(struct iommufd_viommu *viommu, u16 offset, u64 value);
+
+int amd_viommu_guest_mmio_read(struct iommufd_viommu *viommu, u16 offset, u64 *value);
+
 #else
 
 static inline int amd_viommu_init(struct amd_iommu *iommu)
@@ -47,6 +52,16 @@ static inline void amd_viommu_set_device_mapping(struct amd_iommu *iommu, u16 hD
 {
 }
 
+static inline int amd_viommu_guest_mmio_write(struct iommufd_viommu *viommu, u16 offset, u64 value)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int amd_viommu_guest_mmio_read(struct iommufd_viommu *viommu, u16 offset, u64 *value)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif /* CONFIG_AMD_IOMMU_IOMMUFD */
 
 #endif /* AMD_VIOMMU_H */
diff --git a/drivers/iommu/amd/iommufd.c b/drivers/iommu/amd/iommufd.c
index 6f766254a390..b10cbff02288 100644
--- a/drivers/iommu/amd/iommufd.c
+++ b/drivers/iommu/amd/iommufd.c
@@ -242,4 +242,6 @@ static const struct iommufd_viommu_ops amd_viommu_ops = {
 	.vdevice_init = _amd_viommu_vdevice_init,
 	.get_hw_queue_size = _amd_viommu_get_hw_queue_size,
 	.hw_queue_init = _amd_viommu_hw_queue_init,
+	.set_option = amd_viommu_guest_mmio_write,
+	.get_option = amd_viommu_guest_mmio_read,
 };
diff --git a/drivers/iommu/amd/vfctrl_mmio.c b/drivers/iommu/amd/vfctrl_mmio.c
new file mode 100644
index 000000000000..1dcccc24e847
--- /dev/null
+++ b/drivers/iommu/amd/vfctrl_mmio.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Advanced Micro Devices, Inc.
+ * Author: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+ */
+
+#define pr_fmt(fmt)     "AMD-Vi: " fmt
+#define dev_fmt(fmt)    pr_fmt(fmt)
+
+#include <linux/iommu.h>
+#include <linux/amd-iommu.h>
+
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/ioctl.h>
+#include <linux/iommufd.h>
+#include <uapi/linux/iommufd.h>
+#include <linux/mem_encrypt.h>
+
+#include <asm/iommu.h>
+#include <asm/set_memory.h>
+
+#include "amd_iommu.h"
+#include "amd_iommu_types.h"
+#include "amd_viommu.h"
+#include "../iommu-pages.h"
+
+#define GET_CTRL_BITS(reg, bit, msk)	(((reg) >> (bit)) & (ULL(msk)))
+#define SET_CTRL_BITS(reg, bit1, bit2, msk) \
+	((((reg) >> (bit1)) & (ULL(msk))) << (bit2))
+
+int amd_viommu_guest_mmio_read(struct iommufd_viommu *viommu, u16 offset, u64 *value)
+{
+	u8 __iomem *vfctrl, *vf;
+	u64 val, tmp = 0;
+	struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core);
+	struct amd_iommu *iommu = container_of(viommu->iommu_dev, struct amd_iommu, iommu);
+	int gid = aviommu->gid;
+
+	vf = VIOMMU_VF_MMIO_BASE(iommu, gid);
+	vfctrl = VIOMMU_VFCTRL_MMIO_BASE(iommu, gid);
+
+	switch (offset) {
+	case MMIO_CONTROL_OFFSET:
+	{
+		/* VFCTRL offset 20h */
+		val = readq(vfctrl + 0x20);
+		tmp |= SET_CTRL_BITS(val, 8, CONTROL_CMDBUF_EN, 1); // [12]
+		tmp |= SET_CTRL_BITS(val, 9, CONTROL_COMWAIT_EN, 1); // [4]
+
+		/* VFCTRL offset 28h */
+		val = readq(vfctrl + 0x28);
+		tmp |= SET_CTRL_BITS(val, 8, CONTROL_EVT_LOG_EN, 1); // [2]
+		tmp |= SET_CTRL_BITS(val, 9, CONTROL_EVT_INT_EN, 1); // [3]
+		tmp |= SET_CTRL_BITS(val, 10, CONTROL_DUALEVTLOG_EN, 3); // [33:32]
+
+		/* VFCTRL offset 30h */
+		val = readq(vfctrl + 0x30);
+		tmp |= SET_CTRL_BITS(val, 8, CONTROL_PPRLOG_EN, 1); // [13]
+		tmp |= SET_CTRL_BITS(val, 9, CONTROL_PPRINT_EN, 1); // [14]
+		tmp |= SET_CTRL_BITS(val, 10, CONTROL_PPR_EN, 1); // [15]
+		tmp |= SET_CTRL_BITS(val, 11, CONTROL_DUALPPRLOG_EN, 3); // [31:30]
+		tmp |= SET_CTRL_BITS(val, 13, CONTROL_PPR_AUTO_RSP_EN, 1); // [39]
+		tmp |= SET_CTRL_BITS(val, 14, CONTROL_BLKSTOPMRK_EN, 1); // [41]
+		tmp |= SET_CTRL_BITS(val, 15, CONTROL_PPR_AUTO_RSP_AON, 1); // [42]
+
+		*value = tmp;
+		break;
+	}
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	pr_debug("%s: iommu_devid=%#x, gid=%u, offset=%#x, value=%#llx\n",
+		 __func__, iommu->devid, gid, offset, *value);
+	return 0;
+}
+EXPORT_SYMBOL(amd_viommu_guest_mmio_read);
+
+int amd_viommu_guest_mmio_write(struct iommufd_viommu *viommu, u16 offset, u64 value)
+{
+	u8 __iomem *vfctrl, *vf;
+	u64 val, tmp, ctrl = value;
+	struct amd_iommu_viommu *aviommu = container_of(viommu, struct amd_iommu_viommu, core);
+	struct amd_iommu *iommu = container_of(viommu->iommu_dev, struct amd_iommu, iommu);
+	int gid = aviommu->gid;
+
+	pr_debug("%s: iommu_devid=%#x, gid=%u, offset=%#x, value=%#llx\n",
+		 __func__, iommu->devid, gid, offset, value);
+
+	vf = VIOMMU_VF_MMIO_BASE(iommu, gid);
+	vfctrl = VIOMMU_VFCTRL_MMIO_BASE(iommu, gid);
+
+	switch (offset) {
+	case MMIO_CONTROL_OFFSET:
+	{
+		/* VFCTRL offset 20h */
+		val = readq(vfctrl + 0x20);
+		val &= ~(0x3ULL << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_CMDBUF_EN, 1); // [12]
+		val |= (tmp << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_COMWAIT_EN, 1); // [4]
+		val |= (tmp << 9);
+		writeq(val, vfctrl + 0x20);
+
+		/* VFCTRL offset 28h */
+		val = readq(vfctrl + 0x28);
+		val &= ~(0xFULL << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_EVT_LOG_EN, 1); // [2]
+		val |= (tmp << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_EVT_INT_EN, 1); // [3]
+		val |= (tmp << 9);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_DUALEVTLOG_EN, 3); // [33:32]
+		val |= (tmp << 10);
+		writeq(val, vfctrl + 0x28);
+
+		/* VFCTRL offset 30h */
+		val = readq(vfctrl + 0x30);
+		val &= ~(0xFFULL << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_PPRLOG_EN, 1); // [13]
+		val |= (tmp << 8);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_PPRINT_EN, 1); // [14]
+		val |= (tmp << 9);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_PPR_EN, 1); // [15]
+		val |= (tmp << 10);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_DUALPPRLOG_EN, 3); // [31:30]
+		val |= (tmp << 11);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_PPR_AUTO_RSP_EN, 1); // [39]
+		val |= (tmp << 13);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_BLKSTOPMRK_EN, 1); // [41]
+		val |= (tmp << 14);
+		tmp = GET_CTRL_BITS(ctrl, CONTROL_PPR_AUTO_RSP_AON, 1); // [42]
+		val |= (tmp << 15);
+		writeq(val, vfctrl + 0x30);
+		break;
+	}
+	default:
+		WARN_ON(1);
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(amd_viommu_guest_mmio_write);
-- 
2.34.1


  parent reply	other threads:[~2026-03-30  8:44 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-30  8:41 [PATCH 00/22] iommu/amd: Introduce AMD Hardware-accelerated Virtualized IOMMU (vIOMMU) Support Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 01/22] iommu/amd: Make amd_iommu_completion_wait() non-static Suravee Suthikulpanit
2026-03-30  9:39   ` Nicolin Chen
2026-03-30  8:41 ` [PATCH 02/22] iommu/amd: Introduce vIOMMU-specific events and event info Suravee Suthikulpanit
2026-03-30  9:34   ` Nicolin Chen
2026-04-06  3:25     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 03/22] iommu/amd: Detect and initialize AMD vIOMMU feature Suravee Suthikulpanit
2026-03-31  5:12   ` iommu/amd: Initialize IOMMU Private Address (IPA) space mapping region Weinan Liu
2026-04-06  8:32     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 04/22] iommu/amd: Introduce IOMMUFD vIOMMU support for AMD Suravee Suthikulpanit
2026-04-07  6:46   ` [PATCH 4/22] " Weinan Liu
2026-05-12 15:14     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 05/22] iommu/amd: Introduce vIOMMU Guest-ID (GID) Suravee Suthikulpanit
2026-04-07  7:01   ` Weinan Liu
2026-05-12 15:07     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 06/22] iommu/amd: Map vIOMMU VF MMIO and VF Control MMIO regions Suravee Suthikulpanit
2026-03-31  5:30   ` Weinan Liu
2026-04-06  8:57     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 07/22] iommu/amd: Add support for AMD vIOMMU VF MMIO region Suravee Suthikulpanit
2026-03-31  5:55   ` Weinan Liu
2026-04-06  9:03     ` Suthikulpanit, Suravee
2026-03-30  8:41 ` [PATCH 08/22] iommu/amd: Introduce Reset vMMIO Command Suravee Suthikulpanit
2026-04-07  7:20   ` [PATCH 8/22] " Weinan Liu
2026-03-30  8:41 ` [PATCH 09/22] iommu/amd: Introduce domain for IOMMU Private Address (IPA) region Suravee Suthikulpanit
2026-03-30 12:20   ` Jason Gunthorpe
2026-04-06  3:48     ` Suthikulpanit, Suravee
2026-04-06 11:47       ` Jason Gunthorpe
2026-03-30  8:41 ` [PATCH 10/22] iommu/amd: Assign IOMMU Private Address domain to IOMMU Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 11/22] iommu/amd: Allocate and map vIOMMU private regions Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 12/22] iommu/amd: Add helper functions to manage private address region for each VM Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 13/22] iommu/amd: Add helper functions to manage DevID / DomID mapping tables Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 14/22] iommu/amd: Introduce IOMMUFD vDevice support for AMD Suravee Suthikulpanit
2026-03-30  8:41 ` [PATCH 15/22] iommu/amd: Introduce helper function for updating domain ID mapping table Suravee Suthikulpanit
2026-03-30 12:17   ` Jason Gunthorpe
2026-04-06  3:49     ` Suthikulpanit, Suravee
2026-03-30  8:42 ` [PATCH 16/22] iommu/amd: Introduce helper function for updating device " Suravee Suthikulpanit
2026-03-30  8:42 ` [PATCH 17/22] iommu/amd: Introduce vIOMMU Translation DTE Suravee Suthikulpanit
2026-03-30  8:42 ` [PATCH 18/22] iommufd: Introduce iommufd_viommu_ops.hw_queue_init Suravee Suthikulpanit
2026-03-30  8:42 ` [PATCH 19/22] iommu/amd: Add support for vIOMMU HW queues initialization Suravee Suthikulpanit
2026-03-30  8:42 ` [PATCH 20/22] iommufd: Introduce vIOMMU option via IOMMU_OPTION ioctl Suravee Suthikulpanit
2026-03-30 12:15   ` Jason Gunthorpe
2026-04-06 17:02     ` Suthikulpanit, Suravee
2026-03-30  8:42 ` Suravee Suthikulpanit [this message]
2026-03-30  8:42 ` [PATCH 22/22] iommu/amd: Introduce logic to check and enable vIOMMU feature Suravee Suthikulpanit
2026-03-30 12:15   ` Jason Gunthorpe
2026-04-06  3:51     ` Suthikulpanit, Suravee

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=20260330084206.9251-22-suravee.suthikulpanit@amd.com \
    --to=suravee.suthikulpanit@amd.com \
    --cc=chriscli@google.com \
    --cc=dantuluris@google.com \
    --cc=iommu@lists.linux.dev \
    --cc=jay.chen@amd.com \
    --cc=jgg@nvidia.com \
    --cc=jon.grimm@amd.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=kpsingh@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nicolinc@nvidia.com \
    --cc=sairaj.arunkodilkar@amd.com \
    --cc=santosh.shukla@amd.com \
    --cc=vasant.hegde@amd.com \
    --cc=wnliu@google.com \
    --cc=wvw@google.com \
    --cc=yi.l.liu@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®