* [PATCH v3 07/11] iommu: Add iommu_report_device_broken() to quarantine a broken device
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
When an IOMMU hardware detects an error due to a faulty device (e.g. an ATS
invalidation timeout), IOMMU drivers may quarantine the device by disabling
specific hardware features or dropping translation capabilities.
However, the core-level states of the faulty device are out of sync, as the
device can be still attached to a translation domain or even potentially be
moved to a new domain that might overwrite the driver-level quarantine.
Given that such an error can likely be triggered from an ISR, introduce an
asynchronous broken_work per group_device, and provide a helper function to
allow driver initiate a quarantine in the core.
Note that the worker function must not use dev->iommu_group that is NULLed
by iommu_deinit_device() holding group->mutex. The cancel_work_sync() only
gets called afterwards outside the mutex. So, this would be a NULL pointer
dereference. Add a stable group backpointer to struct group_device instead.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
include/linux/iommu.h | 6 +++
drivers/iommu/iommu.c | 100 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 3c5c5fa5cdc6a..97d0e5b90c58f 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -893,6 +893,8 @@ static inline struct iommu_device *__iommu_get_iommu_dev(struct device *dev)
#define iommu_get_iommu_dev(dev, type, member) \
container_of(__iommu_get_iommu_dev(dev), type, member)
+void iommu_report_device_broken(struct device *dev);
+
static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
{
*gather = (struct iommu_iotlb_gather) {
@@ -1207,6 +1209,10 @@ struct iommu_iotlb_gather {};
struct iommu_dirty_bitmap {};
struct iommu_dirty_ops {};
+static inline void iommu_report_device_broken(struct device *dev)
+{
+}
+
static inline bool device_iommu_capable(struct device *dev, enum iommu_cap cap)
{
return false;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 810e7b94a1ae2..bb00918e1b70d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -73,6 +73,7 @@ struct iommu_group {
};
struct group_device {
+ struct iommu_group *group;
struct list_head list;
struct device *dev;
char *name;
@@ -81,10 +82,12 @@ struct group_device {
* retained. This can happen when:
* - Device is undergoing a reset
* - Device failed the last reset
+ * - Device is broken and quarantined
*/
bool blocked;
unsigned int reset_depth;
struct rcu_head rcu;
+ struct work_struct broken_work;
};
/* Iterate over each struct group_device in a struct iommu_group */
@@ -170,6 +173,7 @@ static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
struct device *dev);
static void __iommu_group_free_device(struct iommu_group *group,
struct group_device *grp_dev);
+static void iommu_group_broken_worker(struct work_struct *work);
static void iommu_domain_init(struct iommu_domain *domain, unsigned int type,
const struct iommu_ops *ops);
@@ -752,6 +756,8 @@ static void __iommu_group_free_device(struct iommu_group *group,
sysfs_remove_link(group->devices_kobj, grp_dev->name);
sysfs_remove_link(&dev->kobj, "iommu_group");
+ /* Must wait for broken_work to prevent UAF */
+ cancel_work_sync(&grp_dev->broken_work);
trace_remove_device_from_group(group->id, dev);
kfree(grp_dev->name);
@@ -1284,6 +1290,8 @@ static struct group_device *iommu_group_alloc_device(struct iommu_group *group,
return ERR_PTR(-ENOMEM);
device->dev = dev;
+ device->group = group;
+ INIT_WORK(&device->broken_work, iommu_group_broken_worker);
ret = sysfs_create_link(&dev->kobj, &group->kobj, "iommu_group");
if (ret)
@@ -4178,6 +4186,98 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
}
EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_done);
+static void iommu_group_broken_worker(struct work_struct *work)
+{
+ struct group_device *gdev =
+ container_of(work, struct group_device, broken_work);
+ struct iommu_group *group = gdev->group;
+ struct device *dev = gdev->dev;
+
+ mutex_lock(&group->mutex);
+
+ /*
+ * iommu_deinit_device() frees dev->iommu under group->mutex. Bail
+ * out if the device has already been removed from IOMMU handling.
+ */
+ if (!dev_has_iommu(dev))
+ goto out_unlock;
+
+ if (gdev->blocked) {
+ dev_dbg(dev, "IOMMU has already quarantined the device\n");
+ goto out_unlock;
+ }
+
+ /*
+ * Quarantine the device completely. For a PCI device, it will be lifted
+ * upon a pci_dev_reset_iommu_done(pdev, succeeds=true) call indicating
+ * a device recovery.
+ *
+ * For a non-PCI device, currently it has no recovery framework tied to
+ * the IOMMU subsystem. Quarantine it indefinitely until a recovery path
+ * is introduced.
+ */
+ if (!WARN_ON(__iommu_group_block_device(group, gdev)))
+ dev_warn(dev, "IOMMU has quarantined the device\n");
+
+out_unlock:
+ mutex_unlock(&group->mutex);
+ iommu_group_put(group);
+}
+
+/**
+ * iommu_report_device_broken() - Report a broken device to quarantine it
+ * @dev: Device that has encountered an unrecoverable IOMMU-related error
+ *
+ * When an IOMMU driver detects a critical error caused by a device (e.g. an ATC
+ * invalidation timeout), this function should be used to quarantine the device
+ * at the IOMMU core level.
+ *
+ * The quarantine moves the device's RID and PASIDs to group->blocking_domain to
+ * prevent any further DMA/ATS activity that can potentially corrupt the system
+ * memory due to stale device cache entries.
+ *
+ * This function is safe to call from any context, including interrupt handlers,
+ * as it schedules the actual quarantine work asynchronously. The caller should
+ * have already taken driver-level measures (e.g., disabling ATS in hardware) to
+ * contain the fault immediately, before calling this function.
+ *
+ * For PCI devices, the quarantine will be lifted by a successful device reset
+ * via pci_dev_reset_iommu_done(). For non-PCI devices, the quarantine remains
+ * in effect indefinitely until a recovery mechanism is introduced.
+ *
+ * If the device is concurrently being removed or has already been removed from
+ * the IOMMU subsystem, this function will silently return without any action.
+ */
+void iommu_report_device_broken(struct device *dev)
+{
+ struct iommu_group *group = iommu_group_get(dev);
+ struct group_device *gdev;
+ bool scheduled = false;
+
+ if (!group)
+ return;
+ if (!dev_has_iommu(dev))
+ goto out;
+
+ rcu_read_lock();
+ /*
+ * Note the device might have been concurrently removed from the group
+ * (list_del_rcu) before iommu_deinit_device() cleared the dev->iommu.
+ */
+ list_for_each_entry_rcu(gdev, &group->devices, list) {
+ if (gdev->dev != dev)
+ continue;
+ /* iommu_group_broken_worker() must put the group ref */
+ scheduled = schedule_work(&gdev->broken_work);
+ break;
+ }
+ rcu_read_unlock();
+out:
+ if (!scheduled)
+ iommu_group_put(group);
+}
+EXPORT_SYMBOL_GPL(iommu_report_device_broken);
+
#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)
/**
* iommu_dma_prepare_msi() - Map the MSI page in the IOMMU domain
--
2.43.0
^ permalink raw reply related
* [PATCH v3 06/11] iommu: Defer __iommu_group_free_device() to be outside group->mutex
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
__iommu_group_remove_device() holds group->mutex across the entire call to
__iommu_group_free_device() that performs sysfs removals, tracing, and the
final kfree_rcu(). But in fact, most of these operations don't really need
the group->mutex.
The group_device structure will support a work_struct to quarantine broken
devices asynchronously. The work function must hold group->mutex to safely
update group state. cancel_work_sync() must be called, to cancel that work
before freeing the device. But doing so under group->mutex would deadlock
if the worker is already running and waiting to acquire the same lock.
Separate the assertion from __iommu_group_free_device() to another helper
__iommu_group_empty_assert_owner_cnt().
Defer the __iommu_group_free_device() until the mutex is released.
This is a preparatory refactor with no functional change.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommu.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d1be62a07904a..810e7b94a1ae2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -627,6 +627,19 @@ static struct iommu_domain *pasid_array_entry_to_domain(void *entry)
DEFINE_MUTEX(iommu_probe_device_lock);
+static void __iommu_group_empty_assert_owner_cnt(struct iommu_group *group)
+{
+ lockdep_assert_held(&group->mutex);
+ /*
+ * If the group has become empty then ownership must have been
+ * released, and the current domain must be set back to NULL or
+ * the default domain.
+ */
+ if (list_empty(&group->devices))
+ WARN_ON(group->owner_cnt ||
+ group->domain != group->default_domain);
+}
+
static int __iommu_probe_device(struct device *dev, struct list_head *group_list)
{
struct iommu_group *group;
@@ -700,10 +713,12 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
err_remove_gdev:
list_del_rcu(&gdev->list);
- __iommu_group_free_device(group, gdev);
+ __iommu_group_empty_assert_owner_cnt(group);
err_put_group:
iommu_deinit_device(dev);
mutex_unlock(&group->mutex);
+ if (!IS_ERR(gdev))
+ __iommu_group_free_device(group, gdev);
iommu_group_put(group);
return ret;
@@ -732,20 +747,13 @@ static void __iommu_group_free_device(struct iommu_group *group,
{
struct device *dev = grp_dev->dev;
+ lockdep_assert_not_held(&group->mutex);
+
sysfs_remove_link(group->devices_kobj, grp_dev->name);
sysfs_remove_link(&dev->kobj, "iommu_group");
trace_remove_device_from_group(group->id, dev);
- /*
- * If the group has become empty then ownership must have been
- * released, and the current domain must be set back to NULL or
- * the default domain.
- */
- if (list_empty(&group->devices))
- WARN_ON(group->owner_cnt ||
- group->domain != group->default_domain);
-
kfree(grp_dev->name);
kfree_rcu(grp_dev, rcu);
}
@@ -754,7 +762,7 @@ static void __iommu_group_free_device(struct iommu_group *group,
static void __iommu_group_remove_device(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
- struct group_device *device;
+ struct group_device *device, *to_free = NULL;
mutex_lock(&group->mutex);
for_each_group_device(group, device) {
@@ -762,15 +770,18 @@ static void __iommu_group_remove_device(struct device *dev)
continue;
list_del_rcu(&device->list);
- __iommu_group_free_device(group, device);
+ __iommu_group_empty_assert_owner_cnt(group);
if (dev_has_iommu(dev))
iommu_deinit_device(dev);
else
dev->iommu_group = NULL;
+ to_free = device;
break;
}
mutex_unlock(&group->mutex);
+ if (to_free)
+ __iommu_group_free_device(group, to_free);
/*
* Pairs with the get in iommu_init_device() or
* iommu_group_add_device()
--
2.43.0
^ permalink raw reply related
* [PATCH v3 05/11] iommu: Change group->devices to RCU-protected list
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
To allow lockless iterations of the group->devices list in an ISR context
that cannot hold the group->mutex, change the list to be RCU protected.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommu.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 768ac728b4cc3..d1be62a07904a 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -84,18 +84,20 @@ struct group_device {
*/
bool blocked;
unsigned int reset_depth;
+ struct rcu_head rcu;
};
/* Iterate over each struct group_device in a struct iommu_group */
#define for_each_group_device(group, pos) \
- list_for_each_entry(pos, &(group)->devices, list)
+ list_for_each_entry_rcu(pos, &(group)->devices, list, \
+ lockdep_is_held(&(group)->mutex))
static struct group_device *__dev_to_gdev(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
struct group_device *gdev;
- lockdep_assert_held(&group->mutex);
+ lockdep_assert(lockdep_is_held(&group->mutex) || rcu_read_lock_held());
for_each_group_device(group, gdev) {
if (gdev->dev == dev)
@@ -666,7 +668,7 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
* The gdev must be in the list before calling
* iommu_setup_default_domain()
*/
- list_add_tail(&gdev->list, &group->devices);
+ list_add_tail_rcu(&gdev->list, &group->devices);
WARN_ON(group->default_domain && !group->domain);
if (group->default_domain)
iommu_create_device_direct_mappings(group->default_domain, dev);
@@ -697,7 +699,7 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
return 0;
err_remove_gdev:
- list_del(&gdev->list);
+ list_del_rcu(&gdev->list);
__iommu_group_free_device(group, gdev);
err_put_group:
iommu_deinit_device(dev);
@@ -745,7 +747,7 @@ static void __iommu_group_free_device(struct iommu_group *group,
group->domain != group->default_domain);
kfree(grp_dev->name);
- kfree(grp_dev);
+ kfree_rcu(grp_dev, rcu);
}
/* Remove the iommu_group from the struct device. */
@@ -759,7 +761,7 @@ static void __iommu_group_remove_device(struct device *dev)
if (device->dev != dev)
continue;
- list_del(&device->list);
+ list_del_rcu(&device->list);
__iommu_group_free_device(group, device);
if (dev_has_iommu(dev))
iommu_deinit_device(dev);
@@ -1335,7 +1337,7 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
dev->iommu_group = group;
mutex_lock(&group->mutex);
- list_add_tail(&gdev->list, &group->devices);
+ list_add_tail_rcu(&gdev->list, &group->devices);
mutex_unlock(&group->mutex);
return 0;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v3 04/11] iommu: Add __iommu_group_block_device helper
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
Move the RID/PASID blocking routine into a separate helper, which will be
reused by a new function to quarantine the device but does not bother the
gdev->reset_depth counter.
No functional changes.
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommu.c | 99 ++++++++++++++++++++++++-------------------
1 file changed, 56 insertions(+), 43 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index df23ef0a26e6c..768ac728b4cc3 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3958,6 +3958,57 @@ int iommu_replace_group_handle(struct iommu_group *group,
}
EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL");
+static int __iommu_group_block_device(struct iommu_group *group,
+ struct group_device *gdev)
+{
+ unsigned long pasid;
+ void *entry;
+ int ret;
+
+ lockdep_assert_held(&group->mutex);
+
+ /* Device might be already blocked for a quarantine */
+ if (gdev->blocked)
+ return 0;
+
+ ret = __iommu_group_alloc_blocking_domain(group);
+ if (ret)
+ return ret;
+
+ /* Stage RID domain at blocking_domain while retaining group->domain */
+ if (group->domain != group->blocking_domain) {
+ ret = __iommu_attach_device(group->blocking_domain, gdev->dev,
+ group->domain);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Update gdev->blocked upon the domain change, as it is used to return
+ * the correct domain in iommu_driver_get_domain_for_dev() that might be
+ * called in a set_dev_pasid callback function.
+ */
+ gdev->blocked = true;
+
+ /*
+ * Stage PASID domains at blocking_domain while retaining pasid_array.
+ *
+ * The pasid_array is mostly fenced by group->mutex, except one reader
+ * in iommu_attach_handle_get(), so it's safe to read without xa_lock.
+ */
+ if (gdev->dev->iommu->max_pasids > 0) {
+ xa_for_each_start(&group->pasid_array, pasid, entry, 1) {
+ struct iommu_domain *pasid_dom =
+ pasid_array_entry_to_domain(entry);
+
+ iommu_remove_dev_pasid(gdev->dev, pasid, pasid_dom);
+ }
+ }
+
+ group->recovery_cnt++;
+ return 0;
+}
+
/**
* pci_dev_reset_iommu_prepare() - Block IOMMU to prepare for a PCI device reset
* @pdev: PCI device that is going to enter a reset routine
@@ -3988,8 +4039,6 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
{
struct iommu_group *group = pdev->dev.iommu_group;
struct group_device *gdev;
- unsigned long pasid;
- void *entry;
int ret;
if (!pci_ats_supported(pdev) || !dev_has_iommu(&pdev->dev))
@@ -4003,50 +4052,14 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
if (gdev->reset_depth++)
return 0;
- /* Device might be already blocked for a quarantine */
- if (gdev->blocked)
- return 0;
-
- ret = __iommu_group_alloc_blocking_domain(group);
- if (ret)
- goto err_depth;
- /* Stage RID domain at blocking_domain while retaining group->domain */
- if (group->domain != group->blocking_domain) {
- ret = __iommu_attach_device(group->blocking_domain, &pdev->dev,
- group->domain);
- if (ret)
- goto err_depth;
- }
-
- /*
- * Update gdev->blocked upon the domain change, as it is used to return
- * the correct domain in iommu_driver_get_domain_for_dev() that might be
- * called in a set_dev_pasid callback function.
- */
- gdev->blocked = true;
-
- /*
- * Stage PASID domains at blocking_domain while retaining pasid_array.
- *
- * The pasid_array is mostly fenced by group->mutex, except one reader
- * in iommu_attach_handle_get(), so it's safe to read without xa_lock.
- */
- if (pdev->dev.iommu->max_pasids > 0) {
- xa_for_each_start(&group->pasid_array, pasid, entry, 1) {
- struct iommu_domain *pasid_dom =
- pasid_array_entry_to_domain(entry);
-
- iommu_remove_dev_pasid(&pdev->dev, pasid, pasid_dom);
- }
+ ret = __iommu_group_block_device(group, gdev);
+ if (ret) {
+ gdev->reset_depth--;
+ return ret;
}
- group->recovery_cnt++;
- return ret;
-
-err_depth:
- gdev->reset_depth--;
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_prepare);
--
2.43.0
^ permalink raw reply related
* [PATCH v3 02/11] iommu: Pass in reset result to pci_dev_reset_iommu_done()
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
IOMMU drivers handle ATC cache maintenance. They may encounter ATC-related
errors (e.g., ATC invalidation request timeout), indicating that ATC cache
might have stale entries that can corrupt the memory. In this case, IOMMU
driver has no choice but to block the device's ATS function and wait for a
device recovery.
The pci_dev_reset_iommu_done() called at the end of a reset function could
serve as a reliable signal to the IOMMU subsystem that the physical device
cache is completely clean. However, the function is called unconditionally
even if the reset operation had actually failed, which would re-attach the
faulty device back to a normal translation domain. And this will leave the
system highly exposed, creating vulnerabilities for data corruption:
IOMMU blocks RID/ATS
pci_reset_function():
pci_dev_reset_iommu_prepare(); // Block RID/ATS
__reset(); // Failed (ATC is still stale)
pci_dev_reset_iommu_done(); // Unblock RID/ATS (ah-ha)
Instead, add a @reset_succeeds parameter to pci_dev_reset_iommu_done() and
pass the reset result from each caller:
IOMMU blocks RID/ATS
pci_reset_function():
pci_dev_reset_iommu_prepare(); // Block RID/ATS
rc = __reset();
pci_dev_reset_iommu_done(!rc); // Unblock or quarantine
On a successful reset, done() restores the device to its RID/PASID domains
and decrements group->recovery_cnt. On failure, the device remains blocked,
and concurrent domain attachment will be rejected until a successful reset.
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
include/linux/iommu.h | 5 +++--
drivers/iommu/iommu.c | 28 +++++++++++++++++++++++++---
drivers/pci/pci-acpi.c | 2 +-
drivers/pci/pci.c | 10 +++++-----
drivers/pci/quirks.c | 2 +-
5 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 54b8b48c762e8..d3685967e960a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -1191,7 +1191,7 @@ void iommu_free_global_pasid(ioasid_t pasid);
/* PCI device reset functions */
int pci_dev_reset_iommu_prepare(struct pci_dev *pdev);
-void pci_dev_reset_iommu_done(struct pci_dev *pdev);
+void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds);
#else /* CONFIG_IOMMU_API */
struct iommu_ops {};
@@ -1521,7 +1521,8 @@ static inline int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
return 0;
}
-static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev)
+static inline void pci_dev_reset_iommu_done(struct pci_dev *pdev,
+ bool reset_succeeds)
{
}
#endif /* CONFIG_IOMMU_API */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ff181db687bbf..28d4c1f143a08 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -80,6 +80,7 @@ struct group_device {
* Device is blocked for a pending recovery while its group->domain is
* retained. This can happen when:
* - Device is undergoing a reset
+ * - Device failed the last reset
*/
bool blocked;
unsigned int reset_depth;
@@ -3971,7 +3972,9 @@ EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL");
* reset is finished, pci_dev_reset_iommu_done() can restore everything.
*
* Caller must use pci_dev_reset_iommu_prepare() with pci_dev_reset_iommu_done()
- * before/after the core-level reset routine, to decrement the recovery_cnt.
+ * before/after the core-level reset routine. On a successful reset, done() will
+ * decrement group->recovery_cnt and restore domains. On a failure, recovery_cnt
+ * is left intact and the device stays blocked.
*
* Return: 0 on success or negative error code if the preparation failed.
*
@@ -4000,6 +4003,9 @@ int pci_dev_reset_iommu_prepare(struct pci_dev *pdev)
if (gdev->reset_depth++)
return 0;
+ /* Device might be already blocked for a quarantine */
+ if (gdev->blocked)
+ return 0;
ret = __iommu_group_alloc_blocking_domain(group);
if (ret)
@@ -4047,18 +4053,22 @@ EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_prepare);
/**
* pci_dev_reset_iommu_done() - Restore IOMMU after a PCI device reset is done
* @pdev: PCI device that has finished a reset routine
+ * @reset_succeeds: Whether the PCI device reset is successful or not
*
* After a PCIe device finishes a reset routine, it wants to restore its IOMMU
* activity, including new translation and cache invalidation, by re-attaching
* all RID/PASID of the device back to the domains retained in the core-level
* structure.
*
- * Caller must pair it with a successful pci_dev_reset_iommu_prepare().
+ * This is a pairing function for pci_dev_reset_iommu_prepare(). Caller should
+ * pass in the reset state via @reset_succeeds. On a failed reset, the device
+ * remains blocked for a quarantine with the group->recovery_cnt intact, so as
+ * to protect system memory until a subsequent successful reset.
*
* Note that, although unlikely, there is a risk that re-attaching domains might
* fail due to some unexpected happening like OOM.
*/
-void pci_dev_reset_iommu_done(struct pci_dev *pdev)
+void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
{
struct iommu_group *group = pdev->dev.iommu_group;
struct group_device *gdev;
@@ -4083,6 +4093,18 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev)
if (WARN_ON(!group->blocking_domain))
return;
+ /*
+ * A reset failure implies that the device might be unreliable. E.g. its
+ * device cache might retain stale entries, which potentially results in
+ * memory corruption. Thus, do not unblock the device until a successful
+ * reset.
+ */
+ if (!reset_succeeds) {
+ pci_err(pdev,
+ "Reset failed. Keep it blocked to protect memory\n");
+ return;
+ }
+
/* Re-attach RID domain back to group->domain */
if (group->domain != group->blocking_domain) {
WARN_ON(__iommu_attach_device(group->domain, &pdev->dev,
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 4d0f2cb6c695b..9ffd7f013a7d4 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -977,7 +977,7 @@ int pci_dev_acpi_reset(struct pci_dev *dev, bool probe)
ret = -ENOTTY;
}
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !ret);
return ret;
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8479c2e1f74f1..d78e724027c78 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4358,7 +4358,7 @@ int pcie_flr(struct pci_dev *dev)
ret = pci_dev_wait(dev, "FLR", PCIE_RESET_READY_POLL_MS);
done:
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !ret);
return ret;
}
EXPORT_SYMBOL_GPL(pcie_flr);
@@ -4436,7 +4436,7 @@ static int pci_af_flr(struct pci_dev *dev, bool probe)
ret = pci_dev_wait(dev, "AF_FLR", PCIE_RESET_READY_POLL_MS);
done:
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !ret);
return ret;
}
@@ -4490,7 +4490,7 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
pci_dev_d3_sleep(dev);
ret = pci_dev_wait(dev, "PM D3hot->D0", PCIE_RESET_READY_POLL_MS);
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !ret);
return ret;
}
@@ -4933,7 +4933,7 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
rc = pci_parent_bus_reset(dev, probe);
done:
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !rc);
return rc;
}
@@ -4978,7 +4978,7 @@ static int cxl_reset_bus_function(struct pci_dev *dev, bool probe)
pci_write_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
reg);
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !rc);
return rc;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 05ce12b6b2f76..6ce79a25e5c76 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4271,7 +4271,7 @@ static int __pci_dev_specific_reset(struct pci_dev *dev, bool probe,
}
ret = i->reset(dev, probe);
- pci_dev_reset_iommu_done(dev);
+ pci_dev_reset_iommu_done(dev, !ret);
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v3 03/11] iommu: Add reset_device_done callback for hardware fault recovery
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
When an IOMMU hardware detects an error due to a faulty device (e.g. an ATS
invalidation timeout), IOMMU drivers may quarantine the device by disabling
specific hardware features or dropping translation capabilities.
To recover from these states, the IOMMU driver needs a reliable signal that
the underlying physical hardware has been cleanly reset (e.g., via PCIe AER
or a sysfs Function Level Reset) so as to lift the quarantine.
Introduce a reset_device_done callback in struct iommu_ops. Trigger it from
the existing pci_dev_reset_iommu_done() path to notify the underlying IOMMU
driver that the device's internal state has been sanitized.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
include/linux/iommu.h | 4 ++++
drivers/iommu/iommu.c | 12 ++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d3685967e960a..3c5c5fa5cdc6a 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -626,6 +626,9 @@ __iommu_copy_struct_to_user(const struct iommu_user_data *dst_data,
* @release_device: Remove device from iommu driver handling
* @probe_finalize: Do final setup work after the device is added to an IOMMU
* group and attached to the groups domain
+ * @reset_device_done: Notify the driver that a device has reset successfully.
+ * Note that the core invokes the callback function while
+ * holding the group->mutex
* @device_group: find iommu group for a particular device
* @get_resv_regions: Request list of reserved regions for a device
* @of_xlate: add OF master IDs to iommu grouping
@@ -683,6 +686,7 @@ struct iommu_ops {
struct iommu_device *(*probe_device)(struct device *dev);
void (*release_device)(struct device *dev);
void (*probe_finalize)(struct device *dev);
+ void (*reset_device_done)(struct device *dev);
struct iommu_group *(*device_group)(struct device *dev);
/* Request/Free a list of reserved regions for a device */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 28d4c1f143a08..df23ef0a26e6c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -4071,12 +4071,14 @@ EXPORT_SYMBOL_GPL(pci_dev_reset_iommu_prepare);
void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
{
struct iommu_group *group = pdev->dev.iommu_group;
+ const struct iommu_ops *ops;
struct group_device *gdev;
unsigned long pasid;
void *entry;
if (!pci_ats_supported(pdev) || !dev_has_iommu(&pdev->dev))
return;
+ ops = dev_iommu_ops(&pdev->dev);
guard(mutex)(&group->mutex);
@@ -4105,6 +4107,16 @@ void pci_dev_reset_iommu_done(struct pci_dev *pdev, bool reset_succeeds)
return;
}
+ /*
+ * A PCI device might have been in an error state, so the IOMMU driver
+ * had to quarantine the device by disabling specific hardware features
+ * or dropping translation capability. Here notify the IOMMU driver as
+ * a reliable signal that the faulty PCI device has been cleanly reset
+ * so now it can lift its quarantine and restore full functionality.
+ */
+ if (ops->reset_device_done)
+ ops->reset_device_done(&pdev->dev);
+
/* Re-attach RID domain back to group->domain */
if (group->domain != group->blocking_domain) {
WARN_ON(__iommu_attach_device(group->domain, &pdev->dev,
--
2.43.0
^ permalink raw reply related
* [PATCH v3 01/11] PCI: Propagate FLR return values to callers
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <cover.1776381841.git.nicolinc@nvidia.com>
A reset failure implies that the device might be unreliable. E.g. its ATC
might still retain stale entries. Thus, the IOMMU layer cannot trust this
device to resume its ATS function that can lead to memory corruption. So,
the pci_dev_reset_iommu_done() won't recover the device's IOMMU pathway if
the device reset fails.
Those functions in the pci_dev_reset_methods array invoke pcie_flr(), but
do not check the return value. Propagate them correctly.
Given that these functions have been running okay, and the return values
will be only needed for an incoming work. This is not treated as bug fix.
Suggested-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/pci/quirks.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 48946cca4be72..05ce12b6b2f76 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3957,7 +3957,7 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, bool probe)
* supported.
*/
if (!probe)
- pcie_flr(dev);
+ return pcie_flr(dev);
return 0;
}
@@ -4015,6 +4015,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
{
u16 old_command;
u16 msix_flags;
+ int ret;
/*
* If this isn't a Chelsio T4-based device, return -ENOTTY indicating
@@ -4060,7 +4061,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
PCI_MSIX_FLAGS_ENABLE |
PCI_MSIX_FLAGS_MASKALL);
- pcie_flr(dev);
+ ret = pcie_flr(dev);
/*
* Restore the configuration information (BAR values, etc.) including
@@ -4069,7 +4070,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, bool probe)
*/
pci_restore_state(dev);
pci_write_config_word(dev, PCI_COMMAND, old_command);
- return 0;
+ return ret;
}
#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
@@ -4152,9 +4153,7 @@ static int nvme_disable_and_flr(struct pci_dev *dev, bool probe)
pci_iounmap(dev, bar);
- pcie_flr(dev);
-
- return 0;
+ return pcie_flr(dev);
}
/*
@@ -4166,14 +4165,16 @@ static int nvme_disable_and_flr(struct pci_dev *dev, bool probe)
*/
static int delay_250ms_after_flr(struct pci_dev *dev, bool probe)
{
+ int ret;
+
if (probe)
return pcie_reset_flr(dev, PCI_RESET_PROBE);
- pcie_reset_flr(dev, PCI_RESET_DO_RESET);
+ ret = pcie_reset_flr(dev, PCI_RESET_DO_RESET);
msleep(250);
- return 0;
+ return ret;
}
#define PCI_DEVICE_ID_HINIC_VF 0x375E
@@ -4189,6 +4190,7 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
unsigned long timeout;
void __iomem *bar;
u32 val;
+ int ret;
if (probe)
return 0;
@@ -4209,7 +4211,7 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
val = val | HINIC_VF_FLR_PROC_BIT;
iowrite32be(val, bar + HINIC_VF_OP);
- pcie_flr(pdev);
+ ret = pcie_flr(pdev);
/*
* The device must recapture its Bus and Device Numbers after FLR
@@ -4236,7 +4238,7 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
reset_complete:
pci_iounmap(pdev, bar);
- return 0;
+ return ret;
}
static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
--
2.43.0
^ permalink raw reply related
* [PATCH v3 00/11] iommu/arm-smmu-v3: Quarantine device upon ATC invalidation timeout
From: Nicolin Chen @ 2026-04-16 23:28 UTC (permalink / raw)
To: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
Jason Gunthorpe
Cc: Rafael J . Wysocki, Len Brown, Pranjal Shrivastava, Mostafa Saleh,
Lu Baolu, Kevin Tian, linux-arm-kernel, iommu, linux-kernel,
linux-acpi, linux-pci, vsethi, Shuai Xue
Hi all,
This series addresses a critical vulnerability and stability issue where an
unresponsive PCIe device failing to process ATC (Address Translation Cache)
invalidation requests leads to silent data corruption and continuous SMMU
CMDQ error spam.
[ As Jason pointed out, because this series fundamentally introduces a new
RAS feature to quarantine and recover from hardware faults and relies on
a recently accepted SMMU driver rework, it is not treated as a standard
bug fix. Thus, none of the patches here carries a "Fixes" tag. ]
Currently, when an ATC invalidation times out, the SMMUv3 driver skips the
CMDQ_ERR_CERROR_ATC_INV_IDX error. This leaves the device's ATS cache state
desynchronized from the SMMU: the device cache may retain stale ATC entries
for memory pages that the OS has already reclaimed and reassigned, creating
a direct vector for data corruption. Furthermore, the driver might continue
issuing ATC_INV commands, resulting in constant CMDQ errors:
unexpected global error reported (0x00000001), this could be serious
CMDQ error (cons 0x0302bb84): ATC invalidate timeout
unexpected global error reported (0x00000001), this could be serious
CMDQ error (cons 0x0302bb88): ATC invalidate timeout
unexpected global error reported (0x00000001), this could be serious
CMDQ error (cons 0x0302bb8c): ATC invalidate timeout
...
To resolve this, introduce a mechanism to quarantine a broken device in the
SMMUv3 driver and the IOMMU core. To achieve this, add preparatory changes:
- Tighten the semantics of pci_dev_reset_iommu_done() that is now strictly
called only upon a successful hardware reset
- Introduce a reset_device_done op, allowing the core to signal the driver
when the physical hardware has been cleanly recovered (e.g., via AER or
a manual reset) so the quarantine can be lifted
- Utilize a per-group_device WQ via an iommu_report_device_broken() helper
On the SMMUv3 driver side, retry the timedout ATC_INV batch to identify the
faulty device(s) via an atc_sync_timeouts tracker. Perform a surgical STE
update and flag the ATS as broken to reject further ATS/ATC requests at the
hardware level and suppress further timeout spam.
This is on Github:
https://github.com/nicolinc/iommufd/commits/smmuv3_atc_timeout-v3
Note that patches are rebased on bug-fix under review:
https://lore.kernel.org/all/20260407194644.171304-1-nicolinc@nvidia.com/
Changelog
v3:
* Rebase on arm/smmu/updates branch + bug fix
* Update commit messages and inline comments
* [iommu] Drop unnecessary ops validation
* [iommu] Add missed function stub when !CONFIG_IOMMU_API
* [iommu] Change iommu_report_device_broken() to per gdev
* [iommu] Separate quarantine from pci_dev_reset_prepare()
* [iommu] Check reset failure in pci_dev_reset_iommu_done()
* [smmuv3] Fix STE update with try_cmpxchg64()
* [smmuv3] Fix "continue" bug when skipping ATC commands
* [smmuv3] Replace atomic_t prod_err with a lockless bitmap
* [smmuv3] Drop master->invs_domain; disable ATS per-master directly
* [smmuv3] Return -EIO for ATC timeout v.s. -ETIMEDOUT for poll timeout
* [smmuv3] Replace INV_TYPE_ATS_DISABLED with per-master ats_broken flag
v2:
https://lore.kernel.org/all/cover.1773774441.git.nicolinc@nvidia.com/
* Rebase on arm_smmu_invs-v13 series [0]
* Bisect batched atc invalidation commands
* Drop the direct pci_reset_function() call
* Move the work queue from SMMUv3 to the core
* Proceed a surgical STE update to disable EATS
* Wait for pci_dev_reset_iommu_done() to signal a recovery
v1:
https://lore.kernel.org/all/cover.1772686998.git.nicolinc@nvidia.com/
[0] https://lore.kernel.org/all/cover.1773733797.git.nicolinc@nvidia.com/
Thanks
Nicolin
Nicolin Chen (11):
PCI: Propagate FLR return values to callers
iommu: Pass in reset result to pci_dev_reset_iommu_done()
iommu: Add reset_device_done callback for hardware fault recovery
iommu: Add __iommu_group_block_device helper
iommu: Change group->devices to RCU-protected list
iommu: Defer __iommu_group_free_device() to be outside group->mutex
iommu: Add iommu_report_device_broken() to quarantine a broken device
iommu/arm-smmu-v3: Mark ATC invalidate timeouts via lockless bitmap
iommu/arm-smmu-v3: Replace smmu with master in arm_smmu_inv
iommu/arm-smmu-v3: Introduce master->ats_broken flag
iommu/arm-smmu-v3: Block ATS upon an ATC invalidation timeout
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 4 +-
include/linux/iommu.h | 15 +-
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-test.c | 34 ++-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 193 +++++++++++-
drivers/iommu/iommu.c | 284 ++++++++++++++----
drivers/pci/pci-acpi.c | 2 +-
drivers/pci/pci.c | 10 +-
drivers/pci/quirks.c | 24 +-
8 files changed, 454 insertions(+), 112 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH v2] gpu: ipu-v3: clean up kernel-doc warnings
From: Randy Dunlap @ 2026-04-16 22:44 UTC (permalink / raw)
To: dri-devel
Cc: Philipp Zabel, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, imx,
linux-arm-kernel, Helge Deller, linux-fbdev
In-Reply-To: <20260219215211.459108-1-rdunlap@infradead.org>
ping.
On 2/19/26 1:52 PM, Randy Dunlap wrote:
> Correct all kernel-doc warnings:
> - fix a typedef kernel-doc comment
> - mark a list_head as private
> - use Returns: for function return values
>
> Warning: include/video/imx-ipu-image-convert.h:31 struct member 'list' not
> described in 'ipu_image_convert_run'
> Warning: include/video/imx-ipu-image-convert.h:40 function parameter
> 'ipu_image_convert_cb_t' not described in 'void'
> Warning: include/video/imx-ipu-image-convert.h:40 expecting prototype for
> ipu_image_convert_cb_t(). Prototype was for void() instead
> Warning: include/video/imx-ipu-image-convert.h:66 No description found for
> return value of 'ipu_image_convert_verify'
> Warning: include/video/imx-ipu-image-convert.h:90 No description found for
> return value of 'ipu_image_convert_prepare'
> Warning: include/video/imx-ipu-image-convert.h:125 No description found for
> return value of 'ipu_image_convert_queue'
> Warning: include/video/imx-ipu-image-convert.h:163 No description found for
> return value of 'ipu_image_convert'
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> v2: add Reviewed-by, update Cc: list, rebase, resend
>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-fbdev@vger.kernel.org
>
> include/video/imx-ipu-image-convert.h | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> --- linux-next-20260218.orig/include/video/imx-ipu-image-convert.h
> +++ linux-next-20260218/include/video/imx-ipu-image-convert.h
> @@ -27,12 +27,13 @@ struct ipu_image_convert_run {
>
> int status;
>
> + /* private: */
> /* internal to image converter, callers don't touch */
> struct list_head list;
> };
>
> /**
> - * ipu_image_convert_cb_t - conversion callback function prototype
> + * typedef ipu_image_convert_cb_t - conversion callback function prototype
> *
> * @run: the completed conversion run pointer
> * @ctx: a private context pointer for the callback
> @@ -60,7 +61,7 @@ void ipu_image_convert_adjust(struct ipu
> * @out: output image format
> * @rot_mode: rotation mode
> *
> - * Returns 0 if the formats and rotation mode meet IPU restrictions,
> + * Returns: 0 if the formats and rotation mode meet IPU restrictions,
> * -EINVAL otherwise.
> */
> int ipu_image_convert_verify(struct ipu_image *in, struct ipu_image *out,
> @@ -77,11 +78,11 @@ int ipu_image_convert_verify(struct ipu_
> * @complete: run completion callback
> * @complete_context: a context pointer for the completion callback
> *
> - * Returns an opaque conversion context pointer on success, error pointer
> + * In V4L2, drivers should call ipu_image_convert_prepare() at streamon.
> + *
> + * Returns: an opaque conversion context pointer on success, error pointer
> * on failure. The input/output formats and rotation mode must already meet
> * IPU retrictions.
> - *
> - * In V4L2, drivers should call ipu_image_convert_prepare() at streamon.
> */
> struct ipu_image_convert_ctx *
> ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
> @@ -122,6 +123,8 @@ void ipu_image_convert_unprepare(struct
> * In V4L2, drivers should call ipu_image_convert_queue() while
> * streaming to queue the conversion of a received input buffer.
> * For example mem2mem devices this would be called in .device_run.
> + *
> + * Returns: 0 on success or -errno on error.
> */
> int ipu_image_convert_queue(struct ipu_image_convert_run *run);
>
> @@ -155,6 +158,9 @@ void ipu_image_convert_abort(struct ipu_
> * On successful return the caller can queue more run requests if needed, using
> * the prepared context in run->ctx. The caller is responsible for unpreparing
> * the context when no more conversion requests are needed.
> + *
> + * Returns: pointer to the created &struct ipu_image_convert_run that has
> + * been queued on success; an ERR_PTR(errno) on error.
> */
> struct ipu_image_convert_run *
> ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task,
--
~Randy
^ permalink raw reply
* [PATCH v2] spi: s3c64xx: fix all kernel-doc warnings
From: Randy Dunlap @ 2026-04-16 22:40 UTC (permalink / raw)
To: linux-kernel
Cc: Randy Dunlap, Krzysztof Kozlowski, Andi Shyti, Tudor Ambarus,
linux-spi, linux-samsung-soc, linux-arm-kernel
Add kernel-doc for one struct member and use the correct function name
to eliminate kernel-doc warnings:
Warning: include/linux/platform_data/spi-s3c64xx.h:40 struct member
'polling' not described in 's3c64xx_spi_info'
Warning: include/linux/platform_data/spi-s3c64xx.h:51 expecting prototype
for s3c64xx_spi_set_platdata(). Prototype was for
s3c64xx_spi0_set_platdata() instead
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
v2: add tag; rebase & resend
Cc: Andi Shyti <andi.shyti@kernel.org>
Cc: Tudor Ambarus <tudor.ambarus@linaro.org>
Cc: linux-spi@vger.kernel.org
Cc: linux-samsung-soc@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
include/linux/platform_data/spi-s3c64xx.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- linux-next-20260415.orig/include/linux/platform_data/spi-s3c64xx.h
+++ linux-next-20260415/include/linux/platform_data/spi-s3c64xx.h
@@ -30,6 +30,7 @@ struct s3c64xx_spi_csinfo {
* @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
* @num_cs: Number of CS this controller emulates.
* @no_cs: Used when CS line is not connected.
+ * @polling: Using polling mode when %true (no 'dmas' property in devicetree)
* @cfg_gpio: Configure pins for this SPI controller.
*/
struct s3c64xx_spi_info {
@@ -41,7 +42,7 @@ struct s3c64xx_spi_info {
};
/**
- * s3c64xx_spi_set_platdata - SPI Controller configure callback by the board
+ * s3c64xx_spi0_set_platdata - SPI Controller configure callback by the board
* initialization code.
* @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
* @num_cs: Number of elements in the 'cs' array.
^ permalink raw reply
* [GIT PULL 4/4] soc: ARM code changes for 7.1
From: Arnd Bergmann @ 2026-04-16 22:31 UTC (permalink / raw)
To: Linus Torvalds; +Cc: soc, linux-kernel, linux-arm-kernel
In-Reply-To: <c595dc8e-6367-4922-98ed-90bdd4c3c24f@app.fastmail.com>
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-arm-7.1
for you to fetch changes up to 3ef628c3f37f1dcef0da51e73ad6e458ec74bddb:
Merge tag 'microchip-soc-7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/arm (2026-04-04 17:34:56 +0200)
----------------------------------------------------------------
soc: ARM code changes for 7.1
These are again very minimal updates:
- A workaround for firmware on Google Nexus 10
- A fix for early debugging on OMAP1
- A rework for Microchip SoC configuration
- Cleanups on OMAP2 an R-Car-Gen2
----------------------------------------------------------------
Aaro Koskinen (1):
ARM: OMAP1: Fix DEBUG_LL and earlyprintk on OMAP16XX
Alexandre Marquet (1):
ARM: samsung: exynos5250: Allow CPU1 to boot
Arnd Bergmann (3):
Merge tag 'samsung-soc-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into soc/arm
Merge tag 'renesas-arm-soc-for-v7.1-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/arm
Merge tag 'omap-for-v7.1/soc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap into soc/arm
Bartosz Golaszewski (1):
arm64: Kconfig: provide a top-level switch for Microchip platforms
Geert Uytterhoeven (1):
ARM: shmobile: rcar-gen2: Use of_phandle_args_equal() helper
Julian Braha (1):
ARM: omap2: dead code cleanup in kconfig for ARCH_OMAP4
Krzysztof Kozlowski (1):
Merge tag 'microchip-soc-7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/arm
Randy Dunlap (1):
ARM: omap: fix all kernel-doc warnings
Thorsten Blum (1):
ARM: omap2: Replace scnprintf with strscpy in omap3_cpuinfo
arch/arm/mach-exynos/firmware.c | 4 ++--
arch/arm/mach-omap1/clock_data.c | 4 ++--
arch/arm/mach-omap2/Kconfig | 1 -
arch/arm/mach-omap2/id.c | 3 ++-
arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 16 ++++------------
arch/arm64/Kconfig.platforms | 10 ++++------
arch/arm64/configs/defconfig | 1 +
include/linux/platform_data/voltage-omap.h | 4 ++--
8 files changed, 17 insertions(+), 26 deletions(-)
^ permalink raw reply
* [GIT PULL 3/4] soc: defconfig updates for 7.1
From: Arnd Bergmann @ 2026-04-16 22:30 UTC (permalink / raw)
To: Linus Torvalds; +Cc: soc, linux-kernel, linux-arm-kernel
In-Reply-To: <c595dc8e-6367-4922-98ed-90bdd4c3c24f@app.fastmail.com>
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-defconfig-7.1
for you to fetch changes up to 07e1a498ee9a9e715208c06b39edd8f7d22f3b50:
Merge tag 'at91-defconfig-7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/defconfig (2026-04-04 17:24:37 +0200)
----------------------------------------------------------------
soc: defconfig updates for 7.1
As usual, we enable a number of additional device drivers as loadable
modules, to support the added platforms. The largest change this time
is for OMAP2/3, which were not that well supported in the generic arm32
defconfig.
The Tegra SoC platforms are now enabled by default in Kconfig when
ARCH_TEGRA is enabled, which means the defconfig change is done at
the same time as the Kconfig change here.
----------------------------------------------------------------
Abel Vesa (1):
arm64: defconfig: Enable Qualcomm Eliza basic resource providers
Ajay Kumar Nandam (1):
arm64: defconfig: Enable Qualcomm WCD937x headphone codec as module
Andreas Kemnade (1):
arm: multi_v7_defconfig: Enable more OMAP 3/4 related configs
Arnd Bergmann (5):
Merge tag 'qcom-arm64-defconfig-for-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/defconfig
Merge tag 'ti-k3-config-for-v7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux into soc/defconfig
Merge tag 'omap-for-v7.1/defconfig-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap into soc/defconfig
Merge tag 'tegra-for-7.1-arm-defconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/defconfig
Merge tag 'tegra-for-7.1-arm64-defconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/defconfig
Aubin Constans (1):
ARM: configs: at91: sama7: enable LVDS serializer support
Francesco Dolcini (1):
arm64: defconfig: Enable configurations for Toradex Aquila AM69
Geert Uytterhoeven (1):
ARM: shmobile: defconfig: Refresh for v7.0-rc1
Harshal Dev (1):
arm64: defconfig: Enable QCOMTEE module for QTEE-enabled Qualcomm SoCs
Kathiravan Thirumoorthy (1):
arm64: defconfig: enable IPQ5210 RDP504 base configs
Kory Maincent (TI) (1):
ARM: multi_v7_defconfig: omap2plus_defconfig: Enable ITE IT66121 driver
Krzysztof Kozlowski (6):
Merge tag 'renesas-arm-defconfig-for-v7.1-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/defconfig
arm64: defconfig: Enable Qualcomm Eliza SoC display clock controller
soc/tegra: Make ARCH_TEGRA_SOC_FOO defaults for NVIDIA Tegra
ARM: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC
arm64: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC
Merge tag 'at91-defconfig-7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/defconfig
Luca Weiss (2):
arm64: defconfig: Enable S5KJN1 camera sensor
arm64: defconfig: Enable Milos LPASS LPI pinctrl driver
Meghana Malladi (1):
arm64: defconfig: Enable DP83TG720 PHY driver
Michael Walle (1):
arm64: defconfig: remove SENSORS_SA67MCU
Neil Armstrong (1):
arm64: defconfig: enable pci-pwrctrl-generic as module
Pankaj Patil (1):
arm64: defconfig: Enable configs for Qualcomm Glymur SoC
Romain Sioen (1):
ARM: configs: at91: sama7: enable config for atmel maxtouch
Ryan Wanner (1):
ARM: configs: at91: sama7: enable DRM hlcdc support
Srinivas Kandagatla (1):
arm64: defconfig: Enable configs for Arduino VENTUNO Q
Taniya Das (2):
arm64: defconfig: Enable SM8750 clock controllers
arm64: defconfig: Enable Kaanapali clock controllers
Thierry Reding (2):
Merge branch 'for-7.1/soc' into for-7.1/arm/defconfig
Merge branch 'for-7.1/soc' into for-7.1/arm64/defconfig
Thomas Zimmermann (1):
arch/arm: Drop CONFIG_FIRMWARE_EDID from defconfig files
Vishnu Saini (1):
arm64: defconfig: Enable Lontium LT8713sx driver
arch/arm/configs/davinci_all_defconfig | 1 -
arch/arm/configs/multi_v7_defconfig | 32 ++++++++++++++++++++++++----
arch/arm/configs/omap1_defconfig | 1 -
arch/arm/configs/omap2plus_defconfig | 2 +-
arch/arm/configs/pxa_defconfig | 1 -
arch/arm/configs/sama7_defconfig | 10 +++++++++
arch/arm/configs/shmobile_defconfig | 11 +++++-----
arch/arm/configs/tegra_defconfig | 4 ----
arch/arm64/configs/defconfig | 39 +++++++++++++++++++++++++++-------
drivers/soc/tegra/Kconfig | 11 ++++++++++
10 files changed, 86 insertions(+), 26 deletions(-)
^ permalink raw reply
* Re: [GIT PULL 2/4] soc: drivers for 7.1
From: Arnd Bergmann @ 2026-04-16 22:28 UTC (permalink / raw)
To: Linus Torvalds; +Cc: soc, linux-kernel, linux-arm-kernel
In-Reply-To: <c595dc8e-6367-4922-98ed-90bdd4c3c24f@app.fastmail.com>
The following changes since commit a0e0c2f8c5f32b675f58e25a9338283cedb5ad2b:
reset: spacemit: k3: Decouple composite reset lines (2026-03-23 12:25:47 +0100)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-drivers-7.1
for you to fetch changes up to 33a20cdaf41d08a66581cc01a60c1a3d596ba9cd:
Merge tag 'ffa-fix-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers (2026-04-11 10:48:50 +0200)
----------------------------------------------------------------
soc: drivers for 7.1
The driver updates again are all over the place with many minor fixes
going into platform specific code. The most notable changes are:
- Support for Microchip pic64gx system controllers
- Work on cleaning up devicetree bindings for SoC drivers, and
converting them into the new format
- Lots of smaller changes for Qualcomm SoC drivers, including support
for a number of newly supported chips
- reset controller API cleanups and a new driver for Cix Sky1
- Reworks of the Tegra PMC and CBB drivers, along with a change
to how individual Tegra SoCs get selected in Kconfig and
BPMP firmware driver updates including a refresh of the ABI
header to match the version used by firmware
- STM32 updates to the firewall bus driver and support for
the debug bus through OP-TEE
- SCMI firmware driver improvements for reliability, in particular
for dealing with broken firmware interrupts
- Memory driver updates for Tegra, and a patch to remove the
unused Baikal T1 driver
----------------------------------------------------------------
Abel Vesa (3):
soc: qcom: socinfo: Add PM7550BA PMIC
dt-bindings: firmware: qcom,scm: document Eliza SCM Firmware Interface
soc: qcom: pd-mapper: Add support for Eliza
Aelin Reidel (2):
dt-bindings: arm: qcom,ids: Add SoC IDs for SM7450 and SM7450P
soc: qcom: socinfo: Add SoC IDs for SM7450 and SM7450P
Akhila YS (5):
dt-bindings: arm: microchip,sama7g5-chipid : convert to DT schema
dt-bindings: arm: atmel,at91sam9260-pit: convert to DT schema
dt-bindings: arm: microchip,sam9x60-pit64b : convert to DT schema
dt-bindings: arm: atmel,at91rm9200-st: convert to DT schema
dt-bindings: arm: atmel,at91rm9200-sdramc: convert to DT schema
Alexander Stein (2):
dt-bindings: arm: fsl: add bindings for TQMa8x
MAINTAINERS: Add i.MX team to all arm NXP platforms
Alok Tiwari (2):
soc: qcom: llcc: fix v1 SB syndrome register offset
soc: qcom: aoss: compare against normalized cooling state
Andrew Davis (6):
reset: ath79: Use devm_register_restart_handler()
reset: intel: Use devm_register_restart_handler()
reset: lpc18xx: Use devm_register_sys_off_handler()
reset: ma35d1: Use devm_register_sys_off_handler()
reset: npcm: Use devm_register_sys_off_handler()
reset: sunplus: Use devm_register_sys_off_handler()
André Draszik (1):
dt-bindings: firmware: google,gs101-acpm-ipc: add S2MPG11 secondary PMIC
Andy Shevchenko (2):
memory: bt1-l2-ctl: Remove not-going-to-be-supported code for Baikal SoC
dt-bindings: cache: bt1-l2-ctl: Remove unused bindings
Anjelique Melendez (3):
dt-bindings: soc: qcom: qcom,pmic-glink: Add Glymur and Kaanapali compatibles
soc: qcom: pmic_glink: Add charger PDR service information to client data
soc: qcom: pmic_glink: Add support for Glymur and Kaanapali
Arnd Bergmann (14):
Merge tag 'samsung-drivers-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into soc/drivers
Merge tag 'memory-controller-drv-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into soc/drivers
Merge tag 'scmi-updates-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers
Merge tag 'stm32-bus-firewall-for-7.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32 into soc/drivers
Merge tag 'hisi-drivers-for-7.1' of https://github.com/hisilicon/linux-hisi into soc/drivers
Merge tag 'tee-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee into soc/drivers
Merge tag 'optee-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/jenswi/linux-tee into soc/drivers
Merge tag 'renesas-drivers-for-v7.1-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/drivers
Merge tag 'imx-soc-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/frank.li/linux into soc/drivers
Merge tag 'tegra-for-7.1-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/drivers
Merge tag 'tegra-for-7.1-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/drivers
Merge tag 'imx-bindings-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/frank.li/linux into soc/drivers
Merge tag 'reset-for-v7.1' of https://git.pengutronix.de/git/pza/linux into soc/drivers
Merge tag 'qcom-drivers-for-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers
Bartosz Golaszewski (15):
reset: gpio: remove unneeded OF-node put
reset: gpio: add a devlink between reset-gpio and its consumer
reset: gpio: simplify fallback device matching
reset: gpio: remove unneeded auxiliary_set_drvdata()
reset: warn on reset-gpio release
reset: fold ida_alloc() into reset_create_gpio_aux_device()
reset: use lock guards in reset core
reset: handle removing supplier before consumers
reset: protect struct reset_controller_dev with its own mutex
reset: protect struct reset_control with its own mutex
reset: convert of_reset_control_get_count() to using firmware nodes
reset: convert the core API to using firmware nodes
reset: convert reset core to using firmware nodes
reset: gpio: make the driver fwnode-agnostic
reset: don't overwrite fwnode_reset_n_cells
Biju Das (3):
dt-bindings: soc: renesas: Document RZ/G3L SoC variants, SMARC SoM and Carrier-II EVK
dt-bindings: soc: renesas: renesas,rzg2l-sysc: Document RZ/G3L SoC
soc: renesas: rz-sysc: Add SoC identification for RZ/G3L SoC
Bjorn Andersson (3):
Merge branch '20260309230346.3584252-2-daniel.lezcano@oss.qualcomm.com' into drivers-for-7.1
Merge branch '20260125-iris-ubwc-v4-1-1ff30644ac81@oss.qualcomm.com' into drivers-for-7.1
firmware: qcom: scm: Allow QSEECOM on Lenovo IdeaCentre Mini X
Chris Lew (2):
soc: qcom: smp2p: Add irqchip state support
soc: qcom: smp2p: Add support for smp2p v2
Ciprian Marian Costea (2):
dt-bindings: interrupt-controller: fsl,irqsteer: add S32N79 support
dt-bindings: arm: fsl: Add NXP S32N79 SoC and RDB board
Claudiu Beznea (1):
reset: core: Drop unnecessary double quote
Clément Le Goffic (1):
bus: firewall: move stm32_firewall header file in include folder
Conor Dooley (4):
dt-bindings: soc: microchip: add compatible for the mss-top-sysreg on pic64gx
gpio: mpfs: Add interrupt support
dt-bindings: soc: microchip: document PolarFire SoC's gpio interrupt mux
soc: microchip: add mpfs gpio interrupt mux driver
Daniel Lezcano (3):
soc: qcom: qmi: Enumerate the service IDs of QMI
soc: qcom: pdr: Use the unified QMI service ID instead of defining it locally
samples: qmi: Use the unified QMI service ID instead of defining it locally
Dmitry Baryshkov (6):
soc: qcom: ubwc: disable bank swizzling for Glymur platform
soc: qcom: ocmem: make the core clock optional
soc: qcom: ocmem: register reasons for probe deferrals
soc: qcom: ocmem: return -EPROBE_DEFER is ocmem is not available
soc: qcom: ubwc: add helper to get min_acc length
soc: qcom: ubwc: add helpers to get programmable values
Ernest Van Hoecke (1):
dt-bindings: arm: fsl: add Verdin iMX95
Florian Fainelli (1):
memory: brcmstb_memc: Expand LPDDR4 check to cover for LPDDR5
Frank Li (1):
dt-bindings: arm: lpc: add missed lpc43xx board
Gary Yang (2):
dt-bindings: soc: cix: document the syscon on Sky1 SoC
reset: add Sky1 soc reset support
Gatien Chevallier (8):
bus: rifsc: fix RIF configuration check for peripherals
dt-bindings: document access-controllers property for coresight peripherals
dt-bindings: pinctrl: document access-controllers property for stm32 HDP
dt-bindings: bus: document the stm32 debug bus
bus: stm32_firewall: allow check on different firewall controllers
bus: stm32_firewall: add stm32_firewall_get_grant_all_access() API
drivers: bus: add the stm32 debug bus driver
pinctrl: stm32: add firewall checks before probing the HDP driver
Geert Uytterhoeven (1):
firmware: arm_scmi: Support loop control in quirk code snippets
Gopikrishna Garmidi (2):
soc: qcom: ubwc: Add support for Mahua
firmware: qcom: scm: Allow QSEECOM on Mahua CRD
Haoxiang Li (1):
clk: spear: fix resource leak in clk_register_vco_pll()
Hrishabh Rajput (1):
firmware: qcom: scm: Register gunyah watchdog device
Huisong Li (2):
soc: hisilicon: kunpeng_hccs: Fix discard ‘const’ qualifier compiling warning
soc: hisilicon: kunpeng_hccs: Remove unused input parameter
Jens Glathe (1):
firmware: qcom: scm: allow QSEECOM on ASUS Vivobook X1P42100 variant
Jon Hunter (10):
soc/tegra: pmc: Add kerneldoc for reboot notifier
soc/tegra: pmc: Correct function names in kerneldoc
soc/tegra: pmc: Add kerneldoc for wake-up variables
soc/tegra: pmc: Remove unused AOWAKE definitions
soc/tegra: pmc: Add support for SoC specific AOWAKE offsets
soc/tegra: pmc: Add AOWAKE regs for Tegra264
soc/tegra: pmc: Add Tegra264 wake events
soc/tegra: pmc: Refactor IO pad voltage control
soc/tegra: pmc: Rename has_impl_33v_pwr flag
soc/tegra: pmc: Add IO pads for Tegra264
Josua Mayer (1):
dt-bindings: arm: fsl: Add various solidrun i.MX8M boards
Kathiravan Thirumoorthy (4):
dt-bindings: arm: qcom,ids: add SOC IDs for IPQ5210 family
soc: qcom: socinfo: add SoC ID for IPQ5210 family
dt-bindings: firmware: qcom,scm: Document ipq5210 SCM
dt-bindings: firmware: qcom,scm: Document ipq9650 SCM
Ketan Patil (6):
memory: tegra: Group error handling related registers
memory: tegra: Group register and fields
memory: tegra: Add support for multiple IRQs
memory: tegra: Group SoC specific fields
memory: tegra: Prepare for supporting multiple intmask registers
memory: tegra: Add MC error logging support for Tegra264
Krzysztof Kozlowski (24):
firmware: exynos-acpm: Use unsigned int for acpm_pmic_linux_errmap index
firmware: exynos-acpm: Count number of commands in acpm_xfer
firmware: exynos-acpm: Count acpm_xfer buffers with __counted_by_ptr
firmware: exynos-acpm: Drop fake 'const' on handle pointer
dt-bindings: arm: qcom,ids: Add SoC ID for CQ7790
soc: qcom: socinfo: Add SoC ID for CQ7790
memory: renesas-rpc-if: Simplify printing PTR_ERR with dev_err_probe
memory: tegra-mc: Drop tegra_mc_setup_latency_allowance() return value
memory: tegra-mc: Simplify printing PTR_ERR with dev_err_probe
memory: tegra-mc: Use %pe format
Merge tag 'renesas-drivers-for-v7.1-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/drivers
Merge tag 'renesas-dt-bindings-for-v7.1-tag1' of https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel into soc/drivers
firmware: qcom: uefisecapp: Simplify mutex with guard
firmware: qcom: uefisecapp: Annotate acquiring locks for context tracking
firmware: qcom: scom: Simplify mutex with guard
soc/tegra: Make ARCH_TEGRA_SOC_FOO defaults for NVIDIA Tegra
bus: stm32_firewall: Simplify with scoped for each OF child loop
soc: qcom: ubwc: Remove redundant x1e80100_data
soc: qcom: ubwc: Add configuration Eliza SoC
Merge tag 'tegra-for-7.1-dt-bindings' of https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into soc/drivers
Merge tag 'at91-soc-7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/at91/linux into soc/drivers
Merge tag 'riscv-soc-drivers-for-v7.1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/conor/linux into soc/drivers
Merge tag 'qcom-drivers-for-7.1-2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers
Merge tag 'ffa-fix-7.1' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers
Lad Prabhakar (3):
soc: renesas: r9a09g057-sys: Mark rzv2h_sys_init_data as __initconst
soc: renesas: r9a09g047-sys: Mark rzg3e_sys_init_data as __initconst
soc: renesas: r9a09g056-sys: Mark rzv2n_sys_init_data as __initconst
Le Qi (1):
soc: qcom: pd-mapper: Add QCS615 power domain mappings
Lei wang (2):
dt-bindings: arm: qcom,ids: Add SoC ID for SA8650P
soc: qcom: socinfo: Add SoC ID for SA8650P
Liu Ying (1):
dt-bindings: soc: imx93-media-blk-ctrl: Add PDFC subnode to schema and example
Luca Weiss (1):
soc: qcom: pd-mapper: Add Milos compatible
Marek Vasut (2):
dt-bindings: firmware: arm,scmi: Document arm,no-completion-irq property
firmware: arm_scmi: Implement arm,no-completion-irq property
Markus Niebel (1):
dt-bindings: arm: add bindings for TQMa95xxLA
Martin Schmiedel (1):
dt-bindings: arm: fsl: add MBa93xxLA-MINI
Maud Spierings (1):
dt-bindings: arm: fsl: Add GOcontroll Moduline IV/Mini
Mikko Perttunen (2):
memory: tegra124-emc: Fix dll_change check
memory: tegra30-emc: Fix dll_change check
Mukesh Ojha (1):
firmware: qcom_scm: don't opencode kmemdup
Pankaj Patil (1):
firmware: qcom: scm: Allow QSEECOM on Glymur CRD
Peng Fan (2):
firmware: arm_scmi: Use round_up() for base protocol list size calculation
dt-bindings: fsl: imx7ulp-smc1: Add #clock-cells property
Philipp Zabel (2):
reset: core: Fix indentation
Merge tag 'reset-fixes-for-v7.0-2' into reset/next
Pierre-Henry Moussay (2):
dt-bindings: soc: microchip: mpfs-sys-controller: Add pic64gx compatibility
soc: microchip: mpfs-sys-controller: add support for pic64gx
Randy Dunlap (1):
tee: clean up tee_core.h kernel-doc
Richard Acayan (2):
dt-bindings: cache: qcom,llcc: Add SDM670 compatible
soc: qcom: llcc: Add configuration data for SDM670
Rosen Penev (2):
reset: sti: kzalloc + kcalloc to kzalloc
soc: qcom: wcnss: simplify allocation of req
Rouven Czerwinski (1):
optee: simplify OP-TEE context match
Sebastian Ene (1):
firmware: arm_ffa: Use the correct buffer size during RXTX_MAP
Shengjiu Wang (2):
bus: imx-aipstz: set default value for opacr registers
dt-bindings: arm: fsl: Add compatible for i.MX8MP audio board (version 2)
Sherry Sun (1):
dt-bindings: arm: fsl: Add i.MX93 Wireless EVK board
Srinivas Kandagatla (1):
soc: qcom: pd-mapper: Add support for Glymur and Mahua
Stefano Radaelli (2):
dt-bindings: arm: fsl: add Variscite DART-MX95 Boards
dt-bindings: arm: fsl: add Variscite DART-MX91 Boards
Sumit Gupta (5):
soc/tegra: cbb: Add support for CBB fabrics in Tegra238
soc/tegra: cbb: Set ERD on resume for err interrupt
soc/tegra: cbb: Fix incorrect ARRAY_SIZE in fabric lookup tables
soc/tegra: cbb: Fix cross-fabric target timeout lookup
dt-bindings: arm: tegra: Add Tegra238 CBB compatible strings
Svyatoslav Ryhel (3):
dt-bindings: display: tegra: Document Tegra20 HDMI port
soc/tegra: pmc: Enable core domain support for Tegra114
soc/tegra: common: Add Tegra114 support to devm_tegra_core_dev_init_opp_table
Thierry Reding (16):
memory: tegra: Add support for DBB clock on Tegra264
firmware: tegra: bpmp: Rename Tegra239 to Tegra238
soc/tegra: Add Tegra238 Kconfig symbol
soc/tegra: Update BPMP ABI header
firmware: tegra: bpmp: Add tegra_bpmp_get_with_id() function
dt-bindings: pci: Document the NVIDIA Tegra264 PCIe controller
dt-bindings: phy: tegra-xusb: Document Type C support
dt-bindings: clock: tegra124-dfll: Convert to json-schema
dt-bindings: interrupt-controller: tegra: Fix reg entries
dt-bindings: arm: tegra: Add missing compatible strings
dt-bindings: phy: tegra: Document Tegra210 USB PHY
dt-bindings: memory: Add Tegra210 memory controller bindings
dt-bindings: memory: tegra210: Mark EMC as cooling device
soc/tegra: bpmp: Use ENODEV instead of ENOTSUPP
dt-bindings: arm: tegra: Document Jetson AGX Thor DevKit
MAINTAINERS: Change email address for Thierry Reding
Thorsten Blum (1):
bus: rifsc: Replace snprintf("%s") with strscpy
Tommaso Merciai (5):
reset: rzv2h-usb2phy: Keep PHY clock enabled for entire device lifetime
dt-bindings: reset: renesas,rzv2h-usb2phy: Add '#mux-state-cells' property
dt-bindings: reset: renesas,rzv2h-usb2phy: Document RZ/G3E USB2PHY reset
reset: rzv2h-usb2phy: Convert to regmap API
reset: rzv2h-usb2phy: Add support for VBUS mux controller registration
Unnathi Chalicheemala (2):
soc: qcom: llcc: Add per-slice counter and common llcc slice descriptor
soc: qcom: llcc: Use guards for mutex handling
Val Packett (1):
firmware: qcom: scm: Allow QSEECOM on ECS LIVA QC710
Vladimir Zapolskiy (1):
soc: qcom: pd-mapper: Simplify code using of_root to get root device tree node
Yanan Yang (1):
dt-bindings: arm: fsl: Add FRDM-IMX91S board
Yijie Yang (1):
firmware: qcom: scm: Allow QSEECOM on PURWA-IOT-EVK
.../devicetree/bindings/arm/arm,coresight-cti.yaml | 3 +
.../bindings/arm/arm,coresight-dynamic-funnel.yaml | 3 +
.../devicetree/bindings/arm/arm,coresight-etm.yaml | 3 +
.../devicetree/bindings/arm/arm,coresight-stm.yaml | 3 +
.../devicetree/bindings/arm/arm,coresight-tmc.yaml | 3 +
.../bindings/arm/arm,coresight-tpiu.yaml | 3 +
.../bindings/arm/atmel,at91rm9200-sdramc.yaml | 66 +
.../bindings/arm/atmel,at91rm9200-st.yaml | 69 +
.../bindings/arm/atmel,at91sam9260-pit.yaml | 49 +
.../devicetree/bindings/arm/atmel-sysregs.txt | 48 -
.../bindings/arm/freescale/fsl,imx7ulp-pm.yaml | 5 +
Documentation/devicetree/bindings/arm/fsl.yaml | 86 +
.../bindings/arm/microchip,sam9x60-pit64b.yaml | 68 +
.../bindings/arm/microchip,sama7g5-chipid.yaml | 41 +
.../devicetree/bindings/arm/nxp/lpc32xx.yaml | 22 +
Documentation/devicetree/bindings/arm/tegra.yaml | 56 +-
.../bindings/arm/tegra/nvidia,tegra234-cbb.yaml | 4 +
.../bindings/bus/st,stm32mp131-dbg-bus.yaml | 76 +
.../bindings/cache/baikal,bt1-l2-ctl.yaml | 63 -
.../devicetree/bindings/cache/qcom,llcc.yaml | 2 +
.../bindings/clock/nvidia,tegra124-dfll.txt | 155 -
.../bindings/clock/nvidia,tegra124-dfll.yaml | 290 ++
.../display/tegra/nvidia,tegra20-hdmi.yaml | 13 +-
.../devicetree/bindings/firmware/arm,scmi.yaml | 10 +
.../bindings/firmware/google,gs101-acpm-ipc.yaml | 50 +-
.../devicetree/bindings/firmware/qcom,scm.yaml | 4 +
.../interrupt-controller/fsl,irqsteer.yaml | 4 +-
.../interrupt-controller/nvidia,tegra20-ictlr.yaml | 23 +-
.../memory-controllers/nvidia,tegra210-emc.yaml | 6 +-
.../memory-controllers/nvidia,tegra210-mc.yaml | 77 +
.../bindings/pci/nvidia,tegra264-pcie.yaml | 149 +
.../bindings/phy/nvidia,tegra194-xusb-padctl.yaml | 39 +-
.../bindings/phy/nvidia,tegra20-usb-phy.yaml | 1 +
.../devicetree/bindings/pinctrl/st,stm32-hdp.yaml | 6 +
.../reset/renesas,rzv2h-usb2phy-reset.yaml | 9 +-
.../bindings/soc/cix/cix,sky1-system-control.yaml | 42 +
.../bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml | 78 +
.../soc/microchip/microchip,mpfs-irqmux.yaml | 103 +
.../microchip/microchip,mpfs-mss-top-sysreg.yaml | 18 +-
.../microchip/microchip,mpfs-sys-controller.yaml | 4 +-
.../bindings/soc/qcom/qcom,pmic-glink.yaml | 2 +
.../bindings/soc/renesas/renesas,rzg2l-sysc.yaml | 1 +
.../devicetree/bindings/soc/renesas/renesas.yaml | 13 +
Documentation/driver-api/reset.rst | 1 -
MAINTAINERS | 20 +-
drivers/bus/Kconfig | 10 +
drivers/bus/Makefile | 1 +
drivers/bus/imx-aipstz.c | 15 +
drivers/bus/stm32_dbg_bus.c | 250 ++
drivers/bus/stm32_etzpc.c | 3 +-
drivers/bus/stm32_firewall.c | 59 +-
drivers/bus/stm32_rifsc.c | 61 +-
drivers/clk/samsung/clk-acpm.c | 4 +-
drivers/clk/spear/clk-vco-pll.c | 4 +-
drivers/firmware/arm_ffa/driver.c | 2 +-
drivers/firmware/arm_scmi/base.c | 4 +-
drivers/firmware/arm_scmi/common.h | 4 +
drivers/firmware/arm_scmi/driver.c | 4 +
drivers/firmware/arm_scmi/quirks.h | 8 +-
drivers/firmware/qcom/qcom_qseecom_uefisecapp.c | 9 +-
drivers/firmware/qcom/qcom_scm.c | 71 +-
drivers/firmware/samsung/exynos-acpm-dvfs.c | 13 +-
drivers/firmware/samsung/exynos-acpm-dvfs.h | 4 +-
drivers/firmware/samsung/exynos-acpm-pmic.c | 26 +-
drivers/firmware/samsung/exynos-acpm-pmic.h | 10 +-
drivers/firmware/samsung/exynos-acpm.c | 30 +-
drivers/firmware/samsung/exynos-acpm.h | 10 +-
drivers/firmware/tegra/bpmp.c | 34 +
drivers/gpio/Kconfig | 1 +
drivers/gpio/gpio-mpfs.c | 122 +-
drivers/memory/Kconfig | 11 -
drivers/memory/Makefile | 1 -
drivers/memory/brcmstb_memc.c | 8 +-
drivers/memory/bt1-l2-ctl.c | 323 --
drivers/memory/renesas-rpc-if.c | 8 +-
drivers/memory/tegra/mc.c | 135 +-
drivers/memory/tegra/mc.h | 153 +-
drivers/memory/tegra/tegra114.c | 18 +-
drivers/memory/tegra/tegra124-emc.c | 2 +-
drivers/memory/tegra/tegra124.c | 40 +-
drivers/memory/tegra/tegra186-emc.c | 8 +
drivers/memory/tegra/tegra186.c | 22 +-
drivers/memory/tegra/tegra194.c | 22 +-
drivers/memory/tegra/tegra20.c | 31 +-
drivers/memory/tegra/tegra210.c | 21 +-
drivers/memory/tegra/tegra234.c | 22 +-
drivers/memory/tegra/tegra264.c | 420 +-
drivers/memory/tegra/tegra30-emc.c | 6 +-
drivers/memory/tegra/tegra30.c | 18 +-
drivers/mfd/sec-acpm.c | 10 +-
drivers/pinctrl/stm32/pinctrl-stm32-hdp.c | 14 +
drivers/reset/Kconfig | 9 +
drivers/reset/Makefile | 1 +
drivers/reset/core.c | 505 ++-
drivers/reset/reset-ath79.c | 12 +-
drivers/reset/reset-gpio.c | 27 +-
drivers/reset/reset-intel-gw.c | 11 +-
drivers/reset/reset-lpc18xx.c | 12 +-
drivers/reset/reset-ma35d1.c | 11 +-
drivers/reset/reset-npcm.c | 12 +-
drivers/reset/reset-rzv2h-usb2phy.c | 197 +-
drivers/reset/reset-sky1.c | 367 ++
drivers/reset/reset-sunplus.c | 12 +-
drivers/reset/sti/reset-syscfg.c | 9 +-
drivers/soc/hisilicon/kunpeng_hccs.c | 7 +-
drivers/soc/microchip/Kconfig | 11 +
drivers/soc/microchip/Makefile | 1 +
drivers/soc/microchip/mpfs-irqmux.c | 181 +
drivers/soc/microchip/mpfs-sys-controller.c | 74 +-
drivers/soc/qcom/llcc-qcom.c | 188 +-
drivers/soc/qcom/ocmem.c | 17 +-
drivers/soc/qcom/pdr_interface.c | 4 +-
drivers/soc/qcom/pdr_internal.h | 3 -
drivers/soc/qcom/pmic_glink.c | 66 +-
drivers/soc/qcom/qcom_aoss.c | 2 +-
drivers/soc/qcom/qcom_pd_mapper.c | 33 +-
drivers/soc/qcom/smp2p.c | 103 +-
drivers/soc/qcom/socinfo.c | 11 +
drivers/soc/qcom/ubwc_config.c | 31 +-
drivers/soc/qcom/wcnss_ctrl.c | 17 +-
drivers/soc/renesas/Kconfig | 12 +
drivers/soc/renesas/Makefile | 1 +
drivers/soc/renesas/r9a08g046-sysc.c | 91 +
drivers/soc/renesas/r9a09g047-sys.c | 2 +-
drivers/soc/renesas/r9a09g056-sys.c | 2 +-
drivers/soc/renesas/r9a09g057-sys.c | 2 +-
drivers/soc/renesas/rz-sysc.c | 3 +
drivers/soc/renesas/rz-sysc.h | 1 +
drivers/soc/tegra/Kconfig | 20 +
drivers/soc/tegra/cbb/tegra234-cbb.c | 169 +-
drivers/soc/tegra/common.c | 5 +-
drivers/soc/tegra/pmc.c | 664 +--
drivers/tee/optee/device.c | 5 +-
include/dt-bindings/arm/qcom,ids.h | 10 +
.../dt-bindings/reset/cix,sky1-s5-system-control.h | 163 +
.../dt-bindings/reset/cix,sky1-system-control.h | 41 +
{drivers => include/linux}/bus/stm32_firewall.h | 0
include/linux/bus/stm32_firewall_device.h | 26 +
.../linux/firmware/samsung/exynos-acpm-protocol.h | 40 +-
include/linux/reset-controller.h | 21 +-
include/linux/reset.h | 43 +-
include/linux/soc/qcom/llcc-qcom.h | 8 +-
include/linux/soc/qcom/qmi.h | 12 +
include/linux/soc/qcom/ubwc.h | 25 +
include/linux/tee_core.h | 30 +-
include/soc/tegra/bpmp-abi.h | 4605 ++++++++++++++++----
include/soc/tegra/bpmp.h | 20 +-
include/soc/tegra/mc.h | 40 +-
samples/qmi/qmi_sample_client.c | 2 +-
149 files changed, 9188 insertions(+), 2652 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/atmel,at91rm9200-sdramc.yaml
create mode 100644 Documentation/devicetree/bindings/arm/atmel,at91rm9200-st.yaml
create mode 100644 Documentation/devicetree/bindings/arm/atmel,at91sam9260-pit.yaml
delete mode 100644 Documentation/devicetree/bindings/arm/atmel-sysregs.txt
create mode 100644 Documentation/devicetree/bindings/arm/microchip,sam9x60-pit64b.yaml
create mode 100644 Documentation/devicetree/bindings/arm/microchip,sama7g5-chipid.yaml
create mode 100644 Documentation/devicetree/bindings/bus/st,stm32mp131-dbg-bus.yaml
delete mode 100644 Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml
delete mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml
create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml
create mode 100644 Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
create mode 100644 Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml
create mode 100644 Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
create mode 100644 drivers/bus/stm32_dbg_bus.c
delete mode 100644 drivers/memory/bt1-l2-ctl.c
create mode 100644 drivers/reset/reset-sky1.c
create mode 100644 drivers/soc/microchip/mpfs-irqmux.c
create mode 100644 drivers/soc/renesas/r9a08g046-sysc.c
create mode 100644 include/dt-bindings/reset/cix,sky1-s5-system-control.h
create mode 100644 include/dt-bindings/reset/cix,sky1-system-control.h
rename {drivers => include/linux}/bus/stm32_firewall.h (100%)
^ permalink raw reply
* Re: [PATCH v2 2/4] KVM: arm64: sefltests: Add helpers for guest hypervisors
From: Wei-Lin Chang @ 2026-04-16 22:15 UTC (permalink / raw)
To: Itaru Kitayama
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
Shuah Khan
In-Reply-To: <ad68VjnGQ3trs7AN@sm-arm-grace07>
On Wed, Apr 15, 2026 at 07:14:46AM +0900, Itaru Kitayama wrote:
> On Sun, Apr 12, 2026 at 03:22:14PM +0100, Wei-Lin Chang wrote:
> > Add helpers so that guest hypervisors can run nested guests. SP_EL1
> > save/restore is added to allow nested guests to use a stack.
> >
> > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > ---
> > .../selftests/kvm/include/arm64/nested.h | 17 +++++++
> > tools/testing/selftests/kvm/lib/arm64/entry.S | 5 ++
> > .../testing/selftests/kvm/lib/arm64/nested.c | 46 +++++++++++++++++++
> > 3 files changed, 68 insertions(+)
> >
> > diff --git a/tools/testing/selftests/kvm/include/arm64/nested.h b/tools/testing/selftests/kvm/include/arm64/nested.h
> > index 86d931facacb..7928ef89494a 100644
> > --- a/tools/testing/selftests/kvm/include/arm64/nested.h
> > +++ b/tools/testing/selftests/kvm/include/arm64/nested.h
> > @@ -21,8 +21,17 @@
> >
> > extern char hyp_vectors[];
> >
> > +enum vcpu_sysreg {
> > + __INVALID_SYSREG__, /* 0 is reserved as an invalid value */
> > +
> > + SP_EL1,
> > +
> > + NR_SYS_REGS
> > +};
> > +
> > struct cpu_context {
> > struct user_pt_regs regs; /* sp = sp_el0 */
> > + u64 sys_regs[NR_SYS_REGS];
> > };
> >
> > struct vcpu {
> > @@ -37,9 +46,17 @@ struct hyp_data {
> > struct cpu_context hyp_context;
> > };
>
> I am not sure of these structs you introduced only for nested guest feature
> testing, as the KVM arm64 code they are quite complex and involved,
> extracring part of those and add members as hello_nested or simliar
> tests evolve, then add test cases to me seems fragile.
> But if you have strong reason to add these would you mind explaining a bit?
Sorry, I don't quite get all of your points. I understand your argument
being evolving these structs as time goes is fragile. For this didn't
KVM itself evolve like this?
As for having these structs, how can we make L1 a small hypervisor
without them?
Thanks,
Wei-Lin Chang
>
> Thanks,
> Itaru.
>
> >
> > +void prepare_hyp(void);
> > +void init_vcpu(struct vcpu *vcpu, vm_paddr_t l2_pc, vm_paddr_t l2_stack_top);
> > +int run_l2(struct vcpu *vcpu, struct hyp_data *hyp_data);
> > +
> > +void do_hvc(void);
> > u64 __guest_enter(struct vcpu *vcpu, struct cpu_context *hyp_context);
> > void __hyp_exception(u64 type);
> >
> > +void __sysreg_save_el1_state(struct cpu_context *ctxt);
> > +void __sysreg_restore_el1_state(struct cpu_context *ctxt);
> > +
> > #endif /* !__ASSEMBLER__ */
> >
> > #endif /* SELFTEST_KVM_NESTED_H */
> > diff --git a/tools/testing/selftests/kvm/lib/arm64/entry.S b/tools/testing/selftests/kvm/lib/arm64/entry.S
> > index 33bedf5e7fb2..df3af3463c6c 100644
> > --- a/tools/testing/selftests/kvm/lib/arm64/entry.S
> > +++ b/tools/testing/selftests/kvm/lib/arm64/entry.S
> > @@ -3,6 +3,11 @@
> > * adapted from arch/arm64/kvm/hyp/entry.S
> > */
> >
> > + .globl do_hvc
> > + do_hvc:
> > + hvc #0
> > + ret
> > +
> > /*
> > * Manually define these for now
> > */
> > diff --git a/tools/testing/selftests/kvm/lib/arm64/nested.c b/tools/testing/selftests/kvm/lib/arm64/nested.c
> > index 06ddaab2436f..b30d20b101c4 100644
> > --- a/tools/testing/selftests/kvm/lib/arm64/nested.c
> > +++ b/tools/testing/selftests/kvm/lib/arm64/nested.c
> > @@ -4,7 +4,53 @@
> > */
> >
> > #include "nested.h"
> > +#include "processor.h"
> > #include "test_util.h"
> > +#include <asm/sysreg.h>
> > +
> > +void prepare_hyp(void)
> > +{
> > + write_sysreg(HCR_EL2_E2H | HCR_EL2_RW, hcr_el2);
> > + write_sysreg(hyp_vectors, vbar_el2);
> > + isb();
> > +}
> > +
> > +void init_vcpu(struct vcpu *vcpu, vm_paddr_t l2_pc, vm_paddr_t l2_stack_top)
> > +{
> > + memset(vcpu, 0, sizeof(*vcpu));
> > + vcpu->context.regs.pc = l2_pc;
> > + vcpu->context.regs.pstate = PSR_MODE_EL1h | PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT;
> > + vcpu->context.sys_regs[SP_EL1] = l2_stack_top;
> > +}
> > +
> > +void __sysreg_save_el1_state(struct cpu_context *ctxt)
> > +{
> > + ctxt->sys_regs[SP_EL1] = read_sysreg(sp_el1);
> > +}
> > +
> > +void __sysreg_restore_el1_state(struct cpu_context *ctxt)
> > +{
> > + write_sysreg(ctxt->sys_regs[SP_EL1], sp_el1);
> > +}
> > +
> > +int run_l2(struct vcpu *vcpu, struct hyp_data *hyp_data)
> > +{
> > + u64 ret;
> > +
> > + __sysreg_restore_el1_state(&vcpu->context);
> > +
> > + write_sysreg(vcpu->context.regs.pstate, spsr_el2);
> > + write_sysreg(vcpu->context.regs.pc, elr_el2);
> > +
> > + ret = __guest_enter(vcpu, &hyp_data->hyp_context);
> > +
> > + vcpu->context.regs.pc = read_sysreg(elr_el2);
> > + vcpu->context.regs.pstate = read_sysreg(spsr_el2);
> > +
> > + __sysreg_save_el1_state(&vcpu->context);
> > +
> > + return ret;
> > +}
> >
> > void __hyp_exception(u64 type)
> > {
> > --
> > 2.43.0
> >
^ permalink raw reply
* [GIT PULL 0/4] soc branches for 7.1
From: Arnd Bergmann @ 2026-04-16 22:14 UTC (permalink / raw)
To: Linus Torvalds; +Cc: soc, linux-kernel, linux-arm-kernel
This is another larger set of changes from the soc tree after a rather
quiet 7.0 merge window. In total, we merged 88 branches with over
1000 non-merge changesets, in large parts due to massive devicetree
updates on both Qualcomm and NXP platforms. These include a total of
12 new SoCs, all of them part of an already supported chip family.
The most active contributors by number of patches were
43 Krzysztof Kozlowski
27 Frank Li
26 Dmitry Baryshkov
25 Alexander Stein
23 Marek Vasut
20 Thierry Reding
18 Josua Mayer
17 Stefano Radaelli
17 Sherry Sun
17 Fabio Estevam
17 Bartosz Golaszewski
17 Abel Vesa
16 Luca Weiss
16 Barnabás Czémán
14 Konrad Dybcio
13 Lad Prabhakar
13 Gatien Chevallier
12 Francesco Dolcini
11 Svyatoslav Ryhel
11 Rosen Penev
11 Jon Hunter
11 Christophe Parant
and this is the corresponding dirstat:
0.8% Documentation/devicetree/bindings/arm/
0.9% Documentation/devicetree/bindings/clock/
0.3% Documentation/devicetree/bindings/soc/
0.7% Documentation/devicetree/bindings/
0.2% arch/arm/boot/dts/aspeed/
0.3% arch/arm/boot/dts/broadcom/
0.4% arch/arm/boot/dts/nvidia/
2.7% arch/arm/boot/dts/nxp/imx/
0.9% arch/arm/boot/dts/qcom/
0.2% arch/arm/boot/dts/renesas/
1.0% arch/arm/boot/dts/rockchip/
0.4% arch/arm/boot/dts/samsung/
2.1% arch/arm/boot/dts/st/
1.1% arch/arm/boot/dts/ti/omap/
0.2% arch/arm/
0.3% arch/arm64/boot/dts/allwinner/
0.9% arch/arm64/boot/dts/arm/
0.2% arch/arm64/boot/dts/broadcom/
0.3% arch/arm64/boot/dts/exynos/axis/
0.5% arch/arm64/boot/dts/exynos/google/
1.0% arch/arm64/boot/dts/exynos/
17.4% arch/arm64/boot/dts/freescale/
1.1% arch/arm64/boot/dts/microchip/
0.6% arch/arm64/boot/dts/nvidia/
37.2% arch/arm64/boot/dts/qcom/
1.4% arch/arm64/boot/dts/renesas/
2.1% arch/arm64/boot/dts/rockchip/
0.3% arch/arm64/boot/dts/st/
3.3% arch/arm64/boot/dts/ti/
0.4% arch/arm64/boot/dts/
1.5% arch/riscv/boot/dts/microchip/
0.8% arch/riscv/boot/dts/spacemit/
0.4% drivers/bus/
0.3% drivers/firmware/
1.1% drivers/memory/tegra/
0.3% drivers/memory/
1.8% drivers/reset/
0.2% drivers/soc/microchip/
0.5% drivers/soc/qcom/
0.2% drivers/soc/tegra/cbb/
1.3% drivers/soc/tegra/
0.3% drivers/
1.4% include/dt-bindings/clock/
0.5% include/dt-bindings/reset/
0.3% include/linux/
7.4% include/soc/tegra/
977 files changed, 90981 insertions(+), 15252 deletions(-)
^ permalink raw reply
* Re: [PATCH v2 3/4] KVM: arm64: sefltests: Add basic NV selftest
From: Wei-Lin Chang @ 2026-04-16 21:58 UTC (permalink / raw)
To: Itaru Kitayama
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
Shuah Khan
In-Reply-To: <ad66HasXI2AkEjgK@sm-arm-grace07>
On Wed, Apr 15, 2026 at 07:05:17AM +0900, Itaru Kitayama wrote:
> On Tue, Apr 14, 2026 at 11:16:47AM +0100, Wei-Lin Chang wrote:
> > On Tue, Apr 14, 2026 at 06:31:22AM +0900, Itaru Kitayama wrote:
> > > On Mon, Apr 13, 2026 at 10:18:42AM +0100, Wei-Lin Chang wrote:
> > > > Hi Itaru,
> > > >
> > > > On Mon, Apr 13, 2026 at 08:19:25AM +0900, Itaru Kitayama wrote:
> > > > > On Sun, Apr 12, 2026 at 03:22:15PM +0100, Wei-Lin Chang wrote:
> > > > > > This selftest simply starts an L1, which starts its own guest (L2). L2
> > > > > > runs without stage-1 and 2 translations, it calls an HVC to jump back
> > > > > > to L1.
> > > > >
> > > > > How do you disable both the nested guest (L2)'s MMU and stage 2
> > > > > translations?
> > > >
> > > > Guest stage-2 is disabled by not setting HCR_EL2.VM in prepare_hyp(),
> > > > and stage-1 is disabled by not writing to SCTLR_EL12 in init_vcpu(),
> > > > effectively using the default value set by L0. However since SCTLR_EL1
> > > > has many architecturally UNKNOWN bits (including SCTLR_EL1.M), it should
> > > > be better to write a value before running L2 I suppose...
> > >
> > > Thanks. What do you think of using copy_el2_to_el1() macro in at.c, so we
> > > can prepare in guest_code() to manipulate the SCTLR_EL12 System register
> > > with the sensible programmed values?
> >
> > Yes, using copy_el2_to_el1() can give us an L2 stage-1 that is identical
> > to the L1's stage-1. But what I was considering was if guest stage-2 is
> > enabled (which we plan to implement), then those stage-1 page tables
> > will have to be mapped for L2, and its base address translated to L2IPA.
> > It's doable but seems like extra complexity when stage-1 is not so
> > interesting for KVM (except for AT?), it lets the guest do whatever it
> > likes and let the hardware do the translation.
> >
> > Let me know if you have reasons to want stage-1 for L2, there could be
> > something I should consider but did not.
>
> By keeping nested guest's MMU enabled, we can exercise the shadow stage
> 2 on the host. But I am fine with you starting nested guest's IPA and I
> hope Marc and Oliver approve this seris and merge upstream.
I think you have guest stage-1 and guest stage-2 confused. Whether the
nested guest's stage-1 MMU is enabled or not does not affect what KVM is
doing with the shadow page tables. Stage-1 MMU translates L2VA -> L2IPA.
Shadow page tables store the combined translation of L2IPA -> L1IPA
(stage-2 PTs L1 built for L2) and L1IPA -> host PA (stage-2 PTs host
built for L1).
Additionally, stage-2 not enabled for L2 does not mean shadow stage-2 is
not exercised, there is still a distince shadow stage-2 for it doing the
work, albeit simple (the stored mapping is the same as the canonical
stage-2).
All in all, if we want to make the shadow page tables more interesting,
what we should do is build a stage-2 for L2, and enable it in L1, not
just turn on L2's stage-1 MMU.
Thanks,
Wei-Lin Chang
>
> Thanks,
> Itaru.
>
> >
> > Thanks,
> > Wei-Lin Chang
> >
> > >
> > > Itaru.
> > >
> > > >
> > > > Thanks,
> > > > Wei-Lin Chang
> > > >
> > > > >
> > > > > Itaru.
> > > > >
> > > > > >
> > > > > > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > > > > > ---
> > > > > > tools/testing/selftests/kvm/Makefile.kvm | 1 +
> > > > > > .../selftests/kvm/arm64/hello_nested.c | 103 ++++++++++++++++++
> > > > > > 2 files changed, 104 insertions(+)
> > > > > > create mode 100644 tools/testing/selftests/kvm/arm64/hello_nested.c
> > > > > >
> > > > > > diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> > > > > > index 3dc3e39f7025..e8c108e0c487 100644
> > > > > > --- a/tools/testing/selftests/kvm/Makefile.kvm
> > > > > > +++ b/tools/testing/selftests/kvm/Makefile.kvm
> > > > > > @@ -168,6 +168,7 @@ TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
> > > > > > TEST_GEN_PROGS_arm64 += arm64/at
> > > > > > TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
> > > > > > TEST_GEN_PROGS_arm64 += arm64/hello_el2
> > > > > > +TEST_GEN_PROGS_arm64 += arm64/hello_nested
> > > > > > TEST_GEN_PROGS_arm64 += arm64/host_sve
> > > > > > TEST_GEN_PROGS_arm64 += arm64/hypercalls
> > > > > > TEST_GEN_PROGS_arm64 += arm64/external_aborts
> > > > > > diff --git a/tools/testing/selftests/kvm/arm64/hello_nested.c b/tools/testing/selftests/kvm/arm64/hello_nested.c
> > > > > > new file mode 100644
> > > > > > index 000000000000..97387e4697b3
> > > > > > --- /dev/null
> > > > > > +++ b/tools/testing/selftests/kvm/arm64/hello_nested.c
> > > > > > @@ -0,0 +1,103 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > > +/*
> > > > > > + * hello_nested - Go from vEL2 to EL1 then back
> > > > > > + */
> > > > > > +
> > > > > > +#include "nested.h"
> > > > > > +#include "processor.h"
> > > > > > +#include "test_util.h"
> > > > > > +#include "ucall.h"
> > > > > > +
> > > > > > +#define XLATE2GPA (0xABCD)
> > > > > > +#define L2STACKSZ (0x100)
> > > > > > +
> > > > > > +/*
> > > > > > + * TPIDR_EL2 is used to store vcpu id, so save and restore it.
> > > > > > + */
> > > > > > +static vm_paddr_t ucall_translate_to_gpa(void *gva)
> > > > > > +{
> > > > > > + vm_paddr_t gpa;
> > > > > > + u64 vcpu_id = read_sysreg(tpidr_el2);
> > > > > > +
> > > > > > + GUEST_SYNC2(XLATE2GPA, gva);
> > > > > > +
> > > > > > + /* get the result from userspace */
> > > > > > + gpa = read_sysreg(tpidr_el2);
> > > > > > +
> > > > > > + write_sysreg(vcpu_id, tpidr_el2);
> > > > > > +
> > > > > > + return gpa;
> > > > > > +}
> > > > > > +
> > > > > > +static void l2_guest_code(void)
> > > > > > +{
> > > > > > + do_hvc();
> > > > > > +}
> > > > > > +
> > > > > > +static void guest_code(void)
> > > > > > +{
> > > > > > + struct vcpu vcpu;
> > > > > > + struct hyp_data hyp_data;
> > > > > > + int ret;
> > > > > > + vm_paddr_t l2_pc, l2_stack_top;
> > > > > > + /* force 16-byte alignment for the stack pointer */
> > > > > > + u8 l2_stack[L2STACKSZ] __attribute__((aligned(16)));
> > > > > > +
> > > > > > + GUEST_ASSERT_EQ(get_current_el(), 2);
> > > > > > + GUEST_PRINTF("vEL2 entry\n");
> > > > > > +
> > > > > > + l2_pc = ucall_translate_to_gpa(l2_guest_code);
> > > > > > + l2_stack_top = ucall_translate_to_gpa(&l2_stack[L2STACKSZ]);
> > > > > > +
> > > > > > + init_vcpu(&vcpu, l2_pc, l2_stack_top);
> > > > > > + prepare_hyp();
> > > > > > +
> > > > > > + ret = run_l2(&vcpu, &hyp_data);
> > > > > > + GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
> > > > > > + GUEST_DONE();
> > > > > > +}
> > > > > > +
> > > > > > +int main(void)
> > > > > > +{
> > > > > > + struct kvm_vcpu_init init;
> > > > > > + struct kvm_vcpu *vcpu;
> > > > > > + struct kvm_vm *vm;
> > > > > > + struct ucall uc;
> > > > > > + vm_paddr_t gpa;
> > > > > > +
> > > > > > + TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2));
> > > > > > + vm = vm_create(1);
> > > > > > +
> > > > > > + kvm_get_default_vcpu_target(vm, &init);
> > > > > > + init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
> > > > > > + vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
> > > > > > + kvm_arch_vm_finalize_vcpus(vm);
> > > > > > +
> > > > > > + while (true) {
> > > > > > + vcpu_run(vcpu);
> > > > > > +
> > > > > > + switch (get_ucall(vcpu, &uc)) {
> > > > > > + case UCALL_SYNC:
> > > > > > + if (uc.args[0] == XLATE2GPA) {
> > > > > > + gpa = addr_gva2gpa(vm, (vm_vaddr_t)uc.args[1]);
> > > > > > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL2), gpa);
> > > > > > + }
> > > > > > + break;
> > > > > > + case UCALL_PRINTF:
> > > > > > + pr_info("%s", uc.buffer);
> > > > > > + break;
> > > > > > + case UCALL_DONE:
> > > > > > + pr_info("DONE!\n");
> > > > > > + goto end;
> > > > > > + case UCALL_ABORT:
> > > > > > + REPORT_GUEST_ASSERT(uc);
> > > > > > + fallthrough;
> > > > > > + default:
> > > > > > + TEST_FAIL("Unhandled ucall: %ld\n", uc.cmd);
> > > > > > + }
> > > > > > + }
> > > > > > +
> > > > > > +end:
> > > > > > + kvm_vm_free(vm);
> > > > > > + return 0;
> > > > > > +}
> > > > > > --
> > > > > > 2.43.0
> > > > > >
^ permalink raw reply
* Re: [PATCH v4 1/8] ARM: zte: Add zx297520v3 platform support
From: Randy Dunlap @ 2026-04-16 21:17 UTC (permalink / raw)
To: Stefan Dösinger, Jonathan Corbet, Shuah Khan, Russell King,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial
In-Reply-To: <20260416-send-v4-1-e19d02b944ec@gmail.com>
On 4/16/26 1:19 PM, Stefan Dösinger wrote:
> diff --git a/arch/arm/mach-zte/Kconfig b/arch/arm/mach-zte/Kconfig
> new file mode 100644
> index 000000000000..24699256863b
> --- /dev/null
> +++ b/arch/arm/mach-zte/Kconfig
> @@ -0,0 +1,24 @@
> +# SPDX-License-Identifier: GPL-2.0
> +menuconfig ARCH_ZTE
> + bool "ZTE zx family"
> + depends on ARCH_MULTI_V7
> + help
> + Support for ZTE zx-based family of processors.
> +
> +if ARCH_ZTE
> +
> +config SOC_ZX297520V3
> + default y if ARCH_ZTE
> + bool "ZX297520v3"
> + select ARM_GIC_V3
> + select ARM_AMBA
> + select HAVE_ARM_ARCH_TIMER
> + select PM_GENERIC_DOMAINS if PM
> + help
> + Support for ZTE zx297520v3 SoC. It a single core SoC used in cheap LTE to WiFi routers.
It is
> + These devices can be Identified by the occurrence of the string "zx297520v3" in the boot
identified
> + output and /proc/cpuinfo of their stock firmware.
> +
> + Please read Documentation/arch/arm/zte/zx297520v3.rst on how to boot the kernel.
--
~Randy
^ permalink raw reply
* Re: [PATCH V13 02/12] PCI: host-generic: Add common helpers for parsing Root Port properties
From: Bjorn Helgaas @ 2026-04-16 20:39 UTC (permalink / raw)
To: Sherry Sun
Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach,
imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20260416111422.183860-3-sherry.sun@nxp.com>
On Thu, Apr 16, 2026 at 07:14:12PM +0800, Sherry Sun wrote:
> Introduce generic helper functions to parse Root Port device tree nodes
> and extract common properties like reset GPIOs. This allows multiple
> PCI host controller drivers to share the same parsing logic.
>
> Define struct pci_host_port to hold common Root Port properties
> (currently only reset GPIO descriptor) and add
> pci_host_common_parse_ports() to parse Root Port nodes from device tree.
Are the Root Port and the RC the only possible places for 'reset' GPIO
descriptions in DT? I think PERST# routing is outside the PCIe spec,
so it seems like a system could provide a PERST# GPIO routed to any
Switch Upstream Port or Endpoint (I assume a PERST# connected to a
switch would apply to both the upstream port and the downstream
ports).
^ permalink raw reply
* [PATCH v4 8/8] ARM: defconfig: Add a zx29 defconfig file
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
This enables existing drivers that already are (UART) or will be (USB,
GPIO) necessary to operate this board even if they aren't declared in
the DTS yet.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
arch/arm/configs/zx29_defconfig | 90 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/arch/arm/configs/zx29_defconfig b/arch/arm/configs/zx29_defconfig
new file mode 100644
index 000000000000..dae2d86c7583
--- /dev/null
+++ b/arch/arm/configs/zx29_defconfig
@@ -0,0 +1,90 @@
+CONFIG_SYSVIPC=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_MMU=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_ZTE=y
+CONFIG_SOC_ZX297520V3=y
+# FIXME: There is no PSCI on this board, but ARM_GIC_V3 depends on it
+CONFIG_ARM_PSCI=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="console=ttyAMA1 earlyprintk root=/dev/ram rw"
+# CONFIG_SUSPEND is not set
+CONFIG_BINFMT_FLAT=y
+# CONFIG_UEVENT_HELPER is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_DEVTMPFS=y # FIXME: This is specific to my initrd. Remove before upstream
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_GPIOLIB=y
+CONFIG_OF_GPIO=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_MFD_SYSCON=y
+# CONFIG_HID is not set
+CONFIG_PINCTRL=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_PINMUX=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_PINCONF=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_POWER_RESET=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_LEDS_GPIO=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_GADGET=y
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_SPI_MASTER=y
+CONFIG_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_MDIO_BUS=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_SRAM=y
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_ZTE_ZX=y
+CONFIG_DEBUG_LL_INCLUDE="debug/pl01x.S"
+CONFIG_DEBUG_UART_PL01X=y
+CONFIG_DEBUG_UART_PHYS=0x01408000
+CONFIG_DEBUG_UART_VIRT=0xf4708000
--
2.52.0
^ permalink raw reply related
* [PATCH v4 7/8] ARM: dts: Declare UART1 on zx297520v3 boards
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
This is the UART that sends Uboot messages and is accessible via pins on
the boards I have seen so far. UART0 and UART2 exist as well in the SoC
and can be used with the right pinmux settings on some boards. They will
be added later.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
The reason why I add the serial1=uart1 alias is to keep console=ttyAMA1
stable regardless of the other enabled UARTs. UART0, as the name
implies, has a lower MMIO address, but uart1 is the one that usually has
the boot output and console.
---
arch/arm/boot/dts/zte/zx297520v3.dtsi | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/arm/boot/dts/zte/zx297520v3.dtsi b/arch/arm/boot/dts/zte/zx297520v3.dtsi
index ecd07f3fb8b3..09fbb1d052e3 100644
--- a/arch/arm/boot/dts/zte/zx297520v3.dtsi
+++ b/arch/arm/boot/dts/zte/zx297520v3.dtsi
@@ -6,6 +6,10 @@ / {
#address-cells = <1>;
#size-cells = <1>;
+ aliases {
+ serial1 = &uart1;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -57,5 +61,23 @@ timer {
*/
arm,cpu-registers-not-fw-configured;
};
+
+ /* The UART clock defaults to 26 mhz. It will be replaced when the zx29 clock
+ * framework is added.
+ */
+ uartclk: uartclk: clock-26000000 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ };
+
+ uart1: serial@1408000 {
+ compatible = "arm,pl011", "arm,primecell";
+ arm,primecell-periphid = <0x001feffe>;
+ reg = <0x01408000 0x1000>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uartclk>;
+ clock-names = "apb_pclk";
+ };
};
};
--
2.52.0
^ permalink raw reply related
* [PATCH v4 6/8] ARM: zte: Bring back zx29 UART support
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
This is based on code removed in commit 89d4f98ae90d ("ARM: remove zte
zx platform"). I did not bring back the zx29-uart .compatible as the
arm,primecell-periphid does the job.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
drivers/tty/serial/amba-pl011.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/amba/bus.h | 6 ++++++
2 files changed, 43 insertions(+)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 7f17d288c807..858a0edd3e3b 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -216,6 +216,38 @@ static struct vendor_data vendor_st = {
.get_fifosize = get_fifosize_st,
};
+static const u16 pl011_zte_offsets[REG_ARRAY_SIZE] = {
+ [REG_DR] = ZX_UART011_DR,
+ [REG_FR] = ZX_UART011_FR,
+ [REG_LCRH_RX] = ZX_UART011_LCRH,
+ [REG_LCRH_TX] = ZX_UART011_LCRH,
+ [REG_IBRD] = ZX_UART011_IBRD,
+ [REG_FBRD] = ZX_UART011_FBRD,
+ [REG_CR] = ZX_UART011_CR,
+ [REG_IFLS] = ZX_UART011_IFLS,
+ [REG_IMSC] = ZX_UART011_IMSC,
+ [REG_RIS] = ZX_UART011_RIS,
+ [REG_MIS] = ZX_UART011_MIS,
+ [REG_ICR] = ZX_UART011_ICR,
+ [REG_DMACR] = ZX_UART011_DMACR,
+};
+
+static unsigned int get_fifosize_zte(struct amba_device *dev)
+{
+ return 16;
+}
+
+static struct vendor_data vendor_zte = {
+ .reg_offset = pl011_zte_offsets,
+ .access_32b = true,
+ .ifls = UART011_IFLS_RX4_8 | UART011_IFLS_TX4_8,
+ .fr_busy = ZX_UART01x_FR_BUSY,
+ .fr_dsr = ZX_UART01x_FR_DSR,
+ .fr_cts = ZX_UART01x_FR_CTS,
+ .fr_ri = ZX_UART011_FR_RI,
+ .get_fifosize = get_fifosize_zte,
+};
+
/* Deals with DMA transactions */
struct pl011_dmabuf {
@@ -3081,6 +3113,11 @@ static const struct amba_id pl011_ids[] = {
.mask = 0x00ffffff,
.data = &vendor_st,
},
+ {
+ .id = AMBA_LINUX_ID(0x00, 0x1, 0xffe),
+ .mask = 0x00ffffff,
+ .data = &vendor_zte,
+ },
{ 0, 0 },
};
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 9946276aff73..854c962d70f5 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -103,8 +103,14 @@ enum amba_vendor {
AMBA_VENDOR_ST = 0x80,
AMBA_VENDOR_QCOM = 0x51,
AMBA_VENDOR_LSI = 0xb6,
+ AMBA_VENDOR_LINUX = 0xfe, /* This value is not official */
};
+/* This is used to generate pseudo-ID for AMBA device */
+#define AMBA_LINUX_ID(conf, rev, part) \
+ (((conf) & 0xff) << 24 | ((rev) & 0xf) << 20 | \
+ AMBA_VENDOR_LINUX << 12 | ((part) & 0xfff))
+
extern const struct bus_type amba_bustype;
#define to_amba_device(d) container_of_const(d, struct amba_device, dev)
--
2.52.0
^ permalink raw reply related
* [PATCH v4 5/8] ARM: dts: Add an armv7 timer for zx297520v3
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
The stock kernel does not use this timer, but it seems to work fine. The
board has other board-specific timers that would need a driver and I see
no reason to bother with them since the arm standard timer works.
The caveat is the non-standard GIC setup needed to handle the timer's
level-low PPI. This is the responsibility of the boot loader and
documented in Documentation/arch/arm/zte/zx297520v3.rst.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
arch/arm/boot/dts/zte/zx297520v3.dtsi | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm/boot/dts/zte/zx297520v3.dtsi b/arch/arm/boot/dts/zte/zx297520v3.dtsi
index d6c71d52b26c..ecd07f3fb8b3 100644
--- a/arch/arm/boot/dts/zte/zx297520v3.dtsi
+++ b/arch/arm/boot/dts/zte/zx297520v3.dtsi
@@ -24,6 +24,15 @@ soc {
interrupt-parent = <&gic>;
ranges;
+ /* The GIC has a non-standard way of configuring ints between level-low/level
+ * high or rising edge/falling edge at 0xf2202070 and onwards. See AP_INT_MODE_BASE
+ * and AP_PPI_MODE_REG in the ZTE kernel, although the offsets in the kernel source
+ * seem wrong.
+ *
+ * Everything defaults to active-high/rising edge, but the timer is active-low. We
+ * currently rely on the boot loader to change timer IRQs to active-low for us for
+ * now.
+ */
gic: interrupt-controller@f2000000 {
compatible = "arm,gic-v3";
interrupt-controller;
@@ -33,5 +42,20 @@ gic: interrupt-controller@f2000000 {
reg = <0xf2000000 0x10000>,
<0xf2040000 0x20000>;
};
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ clock-frequency = <26000000>;
+ interrupt-parent = <&gic>;
+ /* I don't think uboot sets CNTVOFF and the stock kernel doesn't use the
+ * arm timer at all. Since this is a single CPU system I don't think it
+ * really matters that the offset is random though.
+ */
+ arm,cpu-registers-not-fw-configured;
+ };
};
};
--
2.52.0
^ permalink raw reply related
* [PATCH v4 4/8] ARM: zte: Add support for zx29 low level debug
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
This is based on the removed zx29 code. A separate (more complicated)
patch will re-add the register map to the pl011 serial driver.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
I am unsure about the virtual address. It doesn't seem to matter, as
long as it is a valid address. This address is based on the old removed
code. Is there a rule-of-thumb physical to virtual mapping I can use to
give a sensible default value?
---
arch/arm/Kconfig.debug | 12 ++++++++++++
arch/arm/include/debug/pl01x.S | 7 +++++++
2 files changed, 19 insertions(+)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 366f162e147d..98d8a5a60048 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1331,6 +1331,16 @@ choice
This option selects UART0 on VIA/Wondermedia System-on-a-chip
devices, including VT8500, WM8505, WM8650 and WM8850.
+ config DEBUG_ZTE_ZX
+ bool "Kernel low-level debugging via zx29 UART"
+ select DEBUG_UART_PL01X
+ depends on ARCH_ZTE
+ help
+ Say Y here if you are enabling ZTE zx297520v3 SOC and need
+ debug UART support. This UART is a PL011 with different
+ register addresses. The UART for boot messages on zx29 boards
+ is usually UART1 and is operating at 921600 8N1.
+
config DEBUG_ZYNQ_UART0
bool "Kernel low-level debugging on Xilinx Zynq using UART0"
depends on ARCH_ZYNQ
@@ -1545,6 +1555,7 @@ config DEBUG_UART_8250
config DEBUG_UART_PHYS
hex "Physical base address of debug UART"
+ default 0x01408000 if DEBUG_ZTE_ZX
default 0x01c28000 if DEBUG_SUNXI_UART0
default 0x01c28400 if DEBUG_SUNXI_UART1
default 0x01d0c000 if DEBUG_DAVINCI_DA8XX_UART1
@@ -1701,6 +1712,7 @@ config DEBUG_UART_VIRT
default 0xf31004c0 if DEBUG_MESON_UARTAO
default 0xf4090000 if DEBUG_LPC32XX
default 0xf4200000 if DEBUG_GEMINI
+ default 0xf4708000 if DEBUG_ZTE_ZX
default 0xf6200000 if DEBUG_PXA_UART1
default 0xf7000000 if DEBUG_SUN9I_UART0
default 0xf7000000 if DEBUG_S3C64XX_UART && DEBUG_S3C_UART0
diff --git a/arch/arm/include/debug/pl01x.S b/arch/arm/include/debug/pl01x.S
index c7e02d0628bf..0c7bfa4c10db 100644
--- a/arch/arm/include/debug/pl01x.S
+++ b/arch/arm/include/debug/pl01x.S
@@ -8,6 +8,13 @@
*/
#include <linux/amba/serial.h>
+#ifdef CONFIG_DEBUG_ZTE_ZX
+#undef UART01x_DR
+#undef UART01x_FR
+#define UART01x_DR 0x04
+#define UART01x_FR 0x14
+#endif
+
#ifdef CONFIG_DEBUG_UART_PHYS
.macro addruart, rp, rv, tmp
ldr \rp, =CONFIG_DEBUG_UART_PHYS
--
2.52.0
^ permalink raw reply related
* [PATCH v4 3/8] ARM: dts: Add D-Link DWR-932M support
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
This adds DT bindings for zx297520v3 and one board that consumes it.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
MAINTAINERS | 1 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/zte/Makefile | 3 +++
arch/arm/boot/dts/zte/dlink-dwr-932m.dts | 21 ++++++++++++++++++
arch/arm/boot/dts/zte/zx297520v3.dtsi | 37 ++++++++++++++++++++++++++++++++
5 files changed, 63 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index bcade90ca14e..f7ca0d478e81 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29203,6 +29203,7 @@ F: tools/testing/selftests/cgroup/test_zswap.c
ZX29
M: Stefan Dösinger <stefandoesinger@gmail.com>
F: Documentation/devicetree/bindings/arm/zte.yaml
+F: arch/arm/boot/dts/zte
F: arch/arm/mach-zte/
SENARYTECH AUDIO CODEC DRIVER
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index efe38eb25301..28fba538d552 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -39,3 +39,4 @@ subdir-y += unisoc
subdir-y += vt8500
subdir-y += xen
subdir-y += xilinx
+subdir-y += zte
diff --git a/arch/arm/boot/dts/zte/Makefile b/arch/arm/boot/dts/zte/Makefile
new file mode 100644
index 000000000000..416c24a489cd
--- /dev/null
+++ b/arch/arm/boot/dts/zte/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_SOC_ZX297520V3) += \
+ dlink-dwr-932m.dtb
diff --git a/arch/arm/boot/dts/zte/dlink-dwr-932m.dts b/arch/arm/boot/dts/zte/dlink-dwr-932m.dts
new file mode 100644
index 000000000000..7b2a26aaaecb
--- /dev/null
+++ b/arch/arm/boot/dts/zte/dlink-dwr-932m.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * D-Link DWR-932M Board
+ *
+ * (C) Copyright 2026 Stefan Dösinger
+ *
+ */
+
+/dts-v1/;
+
+#include "zx297520v3.dtsi"
+
+/ {
+ model = "D-Link DWR-932M";
+ compatible = "dlink,dwr932m", "zte,zx297520v3";
+
+ memory@20000000 {
+ device_type = "memory";
+ reg = <0x20000000 0x04000000>;
+ };
+};
diff --git a/arch/arm/boot/dts/zte/zx297520v3.dtsi b/arch/arm/boot/dts/zte/zx297520v3.dtsi
new file mode 100644
index 000000000000..d6c71d52b26c
--- /dev/null
+++ b/arch/arm/boot/dts/zte/zx297520v3.dtsi
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ reg = <0>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ gic: interrupt-controller@f2000000 {
+ compatible = "arm,gic-v3";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf2000000 0x10000>,
+ <0xf2040000 0x20000>;
+ };
+ };
+};
--
2.52.0
^ permalink raw reply related
* [PATCH v4 2/8] dt-bindings: arm: Add zx297520v3 board binding
From: Stefan Dösinger @ 2026-04-16 20:19 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Russell King, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Arnd Bergmann,
Krzysztof Kozlowski, Alexandre Belloni, Linus Walleij,
Drew Fustini, Greg Kroah-Hartman, Jiri Slaby
Cc: linux-doc, linux-kernel, linux-arm-kernel, devicetree, soc,
linux-serial, Stefan Dösinger
In-Reply-To: <20260416-send-v4-0-e19d02b944ec@gmail.com>
Add a compatible for boards based on the ZTE zx297520v3 SoC.
Signed-off-by: Stefan Dösinger <stefandoesinger@gmail.com>
---
The list of devices is the devices I have access to for testing. There
are many more devices based on this board and it is not always easy to
identify them. Often they are sold without any branding ("4G home
router") or with mobile carrier branding.
---
Documentation/devicetree/bindings/arm/zte.yaml | 25 +++++++++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 26 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/zte.yaml b/Documentation/devicetree/bindings/arm/zte.yaml
new file mode 100644
index 000000000000..6eba09edd2c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/zte.yaml
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/zte.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ZTE zx29
+
+maintainers:
+ - Stefan Dösinger <stefandoesinger@gmail.com>
+
+properties:
+ $nodename:
+ const: "/"
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - dlink,dwr932m
+ - hgsd,r310
+ - tecno,tr118
+ - zte,k10
+ - const: zte,zx297520v3
+
+additionalProperties: true
diff --git a/MAINTAINERS b/MAINTAINERS
index 974d7a98956a..bcade90ca14e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29202,6 +29202,7 @@ F: tools/testing/selftests/cgroup/test_zswap.c
ZX29
M: Stefan Dösinger <stefandoesinger@gmail.com>
+F: Documentation/devicetree/bindings/arm/zte.yaml
F: arch/arm/mach-zte/
SENARYTECH AUDIO CODEC DRIVER
--
2.52.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox