mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 23:03:57 -04:00
Add calls for the new iommu debug config IOMMU_DEBUG_PAGEALLOC: - iommu_debug_init: Enable the debug mode if configured by the user. - iommu_debug_map: Track iommu pages mapped, using physical address. - iommu_debug_unmap_begin: Track start of iommu unmap operation, with IOVA and size. - iommu_debug_unmap_end: Track the end of unmap operation, passing the actual unmapped size versus the tracked one at unmap_begin. We have to do the unmap_begin/end as once pages are unmapped we lose the information of the physical address. This is racy, but the API is racy by construction as it uses refcounts and doesn't attempt to lock/synchronize with the IOMMU API as that will be costly, meaning that possibility of false negative exists. Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Mostafa Saleh <smostafa@google.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
61 lines
1.3 KiB
C
61 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2025 - Google Inc
|
|
* Author: Mostafa Saleh <smostafa@google.com>
|
|
* IOMMU API debug page alloc sanitizer
|
|
*/
|
|
#include <linux/atomic.h>
|
|
#include <linux/iommu.h>
|
|
#include <linux/iommu-debug-pagealloc.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/page_ext.h>
|
|
|
|
#include "iommu-priv.h"
|
|
|
|
static bool needed;
|
|
DEFINE_STATIC_KEY_FALSE(iommu_debug_initialized);
|
|
|
|
struct iommu_debug_metadata {
|
|
atomic_t ref;
|
|
};
|
|
|
|
static __init bool need_iommu_debug(void)
|
|
{
|
|
return needed;
|
|
}
|
|
|
|
struct page_ext_operations page_iommu_debug_ops = {
|
|
.size = sizeof(struct iommu_debug_metadata),
|
|
.need = need_iommu_debug,
|
|
};
|
|
|
|
void __iommu_debug_map(struct iommu_domain *domain, phys_addr_t phys, size_t size)
|
|
{
|
|
}
|
|
|
|
void __iommu_debug_unmap_begin(struct iommu_domain *domain,
|
|
unsigned long iova, size_t size)
|
|
{
|
|
}
|
|
|
|
void __iommu_debug_unmap_end(struct iommu_domain *domain,
|
|
unsigned long iova, size_t size,
|
|
size_t unmapped)
|
|
{
|
|
}
|
|
|
|
void iommu_debug_init(void)
|
|
{
|
|
if (!needed)
|
|
return;
|
|
|
|
pr_info("iommu: Debugging page allocations, expect overhead or disable iommu.debug_pagealloc");
|
|
static_branch_enable(&iommu_debug_initialized);
|
|
}
|
|
|
|
static int __init iommu_debug_pagealloc(char *str)
|
|
{
|
|
return kstrtobool(str, &needed);
|
|
}
|
|
early_param("iommu.debug_pagealloc", iommu_debug_pagealloc);
|