kunit_iommu.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
  4. */
  5. #ifndef __GENERIC_PT_KUNIT_IOMMU_H
  6. #define __GENERIC_PT_KUNIT_IOMMU_H
  7. #define GENERIC_PT_KUNIT 1
  8. #include <kunit/device.h>
  9. #include <kunit/test.h>
  10. #include "../iommu-pages.h"
  11. #include "pt_iter.h"
  12. #define pt_iommu_table_cfg CONCATENATE(pt_iommu_table, _cfg)
  13. #define pt_iommu_init CONCATENATE(CONCATENATE(pt_iommu_, PTPFX), init)
  14. int pt_iommu_init(struct pt_iommu_table *fmt_table,
  15. const struct pt_iommu_table_cfg *cfg, gfp_t gfp);
  16. /* The format can provide a list of configurations it would like to test */
  17. #ifdef kunit_fmt_cfgs
  18. static const void *kunit_pt_gen_params_cfg(struct kunit *test, const void *prev,
  19. char *desc)
  20. {
  21. uintptr_t cfg_id = (uintptr_t)prev;
  22. cfg_id++;
  23. if (cfg_id >= ARRAY_SIZE(kunit_fmt_cfgs) + 1)
  24. return NULL;
  25. snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s_cfg_%u",
  26. __stringify(PTPFX_RAW), (unsigned int)(cfg_id - 1));
  27. return (void *)cfg_id;
  28. }
  29. #define KUNIT_CASE_FMT(test_name) \
  30. KUNIT_CASE_PARAM(test_name, kunit_pt_gen_params_cfg)
  31. #else
  32. #define KUNIT_CASE_FMT(test_name) KUNIT_CASE(test_name)
  33. #endif
  34. #define KUNIT_ASSERT_NO_ERRNO(test, ret) \
  35. KUNIT_ASSERT_EQ_MSG(test, ret, 0, KUNIT_SUBSUBTEST_INDENT "errno %pe", \
  36. ERR_PTR(ret))
  37. #define KUNIT_ASSERT_NO_ERRNO_FN(test, fn, ret) \
  38. KUNIT_ASSERT_EQ_MSG(test, ret, 0, \
  39. KUNIT_SUBSUBTEST_INDENT "errno %pe from %s", \
  40. ERR_PTR(ret), fn)
  41. /*
  42. * When the test is run on a 32 bit system unsigned long can be 32 bits. This
  43. * cause the iommu op signatures to be restricted to 32 bits. Meaning the test
  44. * has to be mindful not to create any VA's over the 32 bit limit. Reduce the
  45. * scope of the testing as the main purpose of checking on full 32 bit is to
  46. * look for 32bitism in the core code. Run the test on i386 with X86_PAE=y to
  47. * get the full coverage when dma_addr_t & phys_addr_t are 8 bytes
  48. */
  49. #define IS_32BIT (sizeof(unsigned long) == 4)
  50. struct kunit_iommu_priv {
  51. union {
  52. struct iommu_domain domain;
  53. struct pt_iommu_table fmt_table;
  54. };
  55. spinlock_t top_lock;
  56. struct device *dummy_dev;
  57. struct pt_iommu *iommu;
  58. struct pt_common *common;
  59. struct pt_iommu_table_cfg cfg;
  60. struct pt_iommu_info info;
  61. unsigned int smallest_pgsz_lg2;
  62. pt_vaddr_t smallest_pgsz;
  63. unsigned int largest_pgsz_lg2;
  64. pt_oaddr_t test_oa;
  65. pt_vaddr_t safe_pgsize_bitmap;
  66. unsigned long orig_nr_secondary_pagetable;
  67. };
  68. PT_IOMMU_CHECK_DOMAIN(struct kunit_iommu_priv, fmt_table.iommu, domain);
  69. static void pt_kunit_iotlb_sync(struct iommu_domain *domain,
  70. struct iommu_iotlb_gather *gather)
  71. {
  72. iommu_put_pages_list(&gather->freelist);
  73. }
  74. #define IOMMU_PT_DOMAIN_OPS1(x) IOMMU_PT_DOMAIN_OPS(x)
  75. static const struct iommu_domain_ops kunit_pt_ops = {
  76. IOMMU_PT_DOMAIN_OPS1(PTPFX_RAW),
  77. .iotlb_sync = &pt_kunit_iotlb_sync,
  78. };
  79. static void pt_kunit_change_top(struct pt_iommu *iommu_table,
  80. phys_addr_t top_paddr, unsigned int top_level)
  81. {
  82. }
  83. static spinlock_t *pt_kunit_get_top_lock(struct pt_iommu *iommu_table)
  84. {
  85. struct kunit_iommu_priv *priv = container_of(
  86. iommu_table, struct kunit_iommu_priv, fmt_table.iommu);
  87. return &priv->top_lock;
  88. }
  89. static const struct pt_iommu_driver_ops pt_kunit_driver_ops = {
  90. .change_top = &pt_kunit_change_top,
  91. .get_top_lock = &pt_kunit_get_top_lock,
  92. };
  93. static int pt_kunit_priv_init(struct kunit *test, struct kunit_iommu_priv *priv)
  94. {
  95. unsigned int va_lg2sz;
  96. int ret;
  97. /* Enough so the memory allocator works */
  98. priv->dummy_dev = kunit_device_register(test, "pt_kunit_dev");
  99. if (IS_ERR(priv->dummy_dev))
  100. return PTR_ERR(priv->dummy_dev);
  101. set_dev_node(priv->dummy_dev, NUMA_NO_NODE);
  102. spin_lock_init(&priv->top_lock);
  103. #ifdef kunit_fmt_cfgs
  104. priv->cfg = kunit_fmt_cfgs[((uintptr_t)test->param_value) - 1];
  105. /*
  106. * The format can set a list of features that the kunit_fmt_cfgs
  107. * controls, other features are default to on.
  108. */
  109. priv->cfg.common.features |= PT_SUPPORTED_FEATURES &
  110. (~KUNIT_FMT_FEATURES);
  111. #else
  112. priv->cfg.common.features = PT_SUPPORTED_FEATURES;
  113. #endif
  114. /* Defaults, for the kunit */
  115. if (!priv->cfg.common.hw_max_vasz_lg2)
  116. priv->cfg.common.hw_max_vasz_lg2 = PT_MAX_VA_ADDRESS_LG2;
  117. if (!priv->cfg.common.hw_max_oasz_lg2)
  118. priv->cfg.common.hw_max_oasz_lg2 = pt_max_oa_lg2(NULL);
  119. priv->fmt_table.iommu.nid = NUMA_NO_NODE;
  120. priv->fmt_table.iommu.driver_ops = &pt_kunit_driver_ops;
  121. priv->fmt_table.iommu.iommu_device = priv->dummy_dev;
  122. priv->domain.ops = &kunit_pt_ops;
  123. ret = pt_iommu_init(&priv->fmt_table, &priv->cfg, GFP_KERNEL);
  124. if (ret) {
  125. if (ret == -EOVERFLOW)
  126. kunit_skip(
  127. test,
  128. "This configuration cannot be tested on 32 bit");
  129. return ret;
  130. }
  131. priv->iommu = &priv->fmt_table.iommu;
  132. priv->common = common_from_iommu(&priv->fmt_table.iommu);
  133. priv->iommu->ops->get_info(priv->iommu, &priv->info);
  134. /*
  135. * size_t is used to pass the mapping length, it can be 32 bit, truncate
  136. * the pagesizes so we don't use large sizes.
  137. */
  138. priv->info.pgsize_bitmap = (size_t)priv->info.pgsize_bitmap;
  139. priv->smallest_pgsz_lg2 = vaffs(priv->info.pgsize_bitmap);
  140. priv->smallest_pgsz = log2_to_int(priv->smallest_pgsz_lg2);
  141. priv->largest_pgsz_lg2 =
  142. vafls((dma_addr_t)priv->info.pgsize_bitmap) - 1;
  143. priv->test_oa =
  144. oalog2_mod(0x74a71445deadbeef, priv->common->max_oasz_lg2);
  145. /*
  146. * We run out of VA space if the mappings get too big, make something
  147. * smaller that can safely pass through dma_addr_t API.
  148. */
  149. va_lg2sz = priv->common->max_vasz_lg2;
  150. if (IS_32BIT && va_lg2sz > 32)
  151. va_lg2sz = 32;
  152. priv->safe_pgsize_bitmap =
  153. log2_mod(priv->info.pgsize_bitmap, va_lg2sz - 1);
  154. return 0;
  155. }
  156. #endif