Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iommupt: Add a kunit test for the SW bits

Add some basic checks that the sw_bit APIs work as expected.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

authored by

Jason Gunthorpe and committed by
Joerg Roedel
6303c018 101a2854

+110
+110
drivers/iommu/generic_pt/kunit_generic_pt.h
··· 660 660 check_all_levels(test, test_lvl_dirty, NULL); 661 661 } 662 662 663 + static void test_lvl_sw_bit_leaf(struct kunit *test, struct pt_state *pts, 664 + void *arg) 665 + { 666 + struct kunit_iommu_priv *priv = test->priv; 667 + pt_vaddr_t pgsize_bitmap = pt_possible_sizes(pts); 668 + unsigned int isz_lg2 = pt_table_item_lg2sz(pts); 669 + struct pt_write_attrs attrs = {}; 670 + unsigned int len_lg2; 671 + 672 + if (!pt_can_have_leaf(pts)) 673 + return; 674 + if (pts->index != 0) 675 + return; 676 + 677 + KUNIT_ASSERT_NO_ERRNO_FN(test, "pt_iommu_set_prot", 678 + pt_iommu_set_prot(pts->range->common, &attrs, 679 + IOMMU_READ)); 680 + 681 + for (len_lg2 = 0; len_lg2 < PT_VADDR_MAX_LG2 - 1; len_lg2++) { 682 + pt_oaddr_t paddr = log2_set_mod(priv->test_oa, 0, len_lg2); 683 + struct pt_write_attrs new_attrs = {}; 684 + unsigned int bitnr; 685 + 686 + if (!(pgsize_bitmap & log2_to_int(len_lg2))) 687 + continue; 688 + 689 + pt_install_leaf_entry(pts, paddr, len_lg2, &attrs); 690 + 691 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); 692 + bitnr++) 693 + KUNIT_ASSERT_FALSE(test, 694 + pt_test_sw_bit_acquire(pts, bitnr)); 695 + 696 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); 697 + bitnr++) { 698 + KUNIT_ASSERT_FALSE(test, 699 + pt_test_sw_bit_acquire(pts, bitnr)); 700 + pt_set_sw_bit_release(pts, bitnr); 701 + KUNIT_ASSERT_TRUE(test, 702 + pt_test_sw_bit_acquire(pts, bitnr)); 703 + } 704 + 705 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); 706 + bitnr++) 707 + KUNIT_ASSERT_TRUE(test, 708 + pt_test_sw_bit_acquire(pts, bitnr)); 709 + 710 + KUNIT_ASSERT_EQ(test, pt_item_oa(pts), paddr); 711 + 712 + /* SW bits didn't leak into the attrs */ 713 + pt_attr_from_entry(pts, &new_attrs); 714 + KUNIT_ASSERT_MEMEQ(test, &new_attrs, &attrs, sizeof(attrs)); 715 + 716 + pt_clear_entries(pts, len_lg2 - isz_lg2); 717 + KUNIT_ASSERT_PT_LOAD(test, pts, PT_ENTRY_EMPTY); 718 + } 719 + } 720 + 721 + static __maybe_unused void test_sw_bit_leaf(struct kunit *test) 722 + { 723 + check_all_levels(test, test_lvl_sw_bit_leaf, NULL); 724 + } 725 + 726 + static void test_lvl_sw_bit_table(struct kunit *test, struct pt_state *pts, 727 + void *arg) 728 + { 729 + struct kunit_iommu_priv *priv = test->priv; 730 + struct pt_write_attrs attrs = {}; 731 + pt_oaddr_t paddr = 732 + log2_set_mod(priv->test_oa, 0, priv->smallest_pgsz_lg2); 733 + unsigned int bitnr; 734 + 735 + if (!pt_can_have_leaf(pts)) 736 + return; 737 + if (pts->index != 0) 738 + return; 739 + 740 + KUNIT_ASSERT_NO_ERRNO_FN(test, "pt_iommu_set_prot", 741 + pt_iommu_set_prot(pts->range->common, &attrs, 742 + IOMMU_READ)); 743 + 744 + KUNIT_ASSERT_TRUE(test, pt_install_table(pts, paddr, &attrs)); 745 + 746 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); bitnr++) 747 + KUNIT_ASSERT_FALSE(test, pt_test_sw_bit_acquire(pts, bitnr)); 748 + 749 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); bitnr++) { 750 + KUNIT_ASSERT_FALSE(test, pt_test_sw_bit_acquire(pts, bitnr)); 751 + pt_set_sw_bit_release(pts, bitnr); 752 + KUNIT_ASSERT_TRUE(test, pt_test_sw_bit_acquire(pts, bitnr)); 753 + } 754 + 755 + for (bitnr = 0; bitnr <= pt_max_sw_bit(pts->range->common); bitnr++) 756 + KUNIT_ASSERT_TRUE(test, pt_test_sw_bit_acquire(pts, bitnr)); 757 + 758 + KUNIT_ASSERT_EQ(test, pt_table_pa(pts), paddr); 759 + 760 + pt_clear_entries(pts, ilog2(1)); 761 + KUNIT_ASSERT_PT_LOAD(test, pts, PT_ENTRY_EMPTY); 762 + } 763 + 764 + static __maybe_unused void test_sw_bit_table(struct kunit *test) 765 + { 766 + check_all_levels(test, test_lvl_sw_bit_table, NULL); 767 + } 768 + 663 769 static struct kunit_case generic_pt_test_cases[] = { 664 770 KUNIT_CASE_FMT(test_init), 665 771 KUNIT_CASE_FMT(test_bitops), ··· 778 672 KUNIT_CASE_FMT(test_attr_from_entry), 779 673 #ifdef pt_entry_is_write_dirty 780 674 KUNIT_CASE_FMT(test_dirty), 675 + #endif 676 + #ifdef pt_sw_bit 677 + KUNIT_CASE_FMT(test_sw_bit_leaf), 678 + KUNIT_CASE_FMT(test_sw_bit_table), 781 679 #endif 782 680 {}, 783 681 };