va_high_addr_switch.sh 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Copyright (C) 2022 Adam Sindelar (Meta) <adam@wowsignal.io>
  5. #
  6. # This is a test for mmap behavior with 5-level paging. This script wraps the
  7. # real test to check that the kernel is configured to support at least 5
  8. # pagetable levels.
  9. # Kselftest framework requirement - SKIP code is 4.
  10. ksft_skip=4
  11. orig_nr_hugepages=0
  12. skip()
  13. {
  14. echo "$1"
  15. exit $ksft_skip
  16. }
  17. check_supported_x86_64()
  18. {
  19. local config="/proc/config.gz"
  20. [[ -f "${config}" ]] || config="/boot/config-$(uname -r)"
  21. [[ -f "${config}" ]] || skip "Cannot find kernel config in /proc or /boot"
  22. # gzip -dcfq automatically handles both compressed and plaintext input.
  23. # See man 1 gzip under '-f'.
  24. local pg_table_levels=$(gzip -dcfq "${config}" | grep PGTABLE_LEVELS | cut -d'=' -f 2)
  25. local cpu_supports_pl5=$(awk '/^flags/ {if (/la57/) {print 0;}
  26. else {print 1}; exit}' /proc/cpuinfo 2>/dev/null)
  27. if [[ "${pg_table_levels}" -lt 5 ]]; then
  28. skip "$0: PGTABLE_LEVELS=${pg_table_levels}, must be >= 5 to run this test"
  29. elif [[ "${cpu_supports_pl5}" -ne 0 ]]; then
  30. skip "$0: CPU does not have the necessary la57 flag to support page table level 5"
  31. fi
  32. }
  33. check_supported_ppc64()
  34. {
  35. local config="/proc/config.gz"
  36. [[ -f "${config}" ]] || config="/boot/config-$(uname -r)"
  37. [[ -f "${config}" ]] || skip "Cannot find kernel config in /proc or /boot"
  38. local pg_table_levels=$(gzip -dcfq "${config}" | grep PGTABLE_LEVELS | cut -d'=' -f 2)
  39. if [[ "${pg_table_levels}" -lt 5 ]]; then
  40. skip "$0: PGTABLE_LEVELS=${pg_table_levels}, must be >= 5 to run this test"
  41. fi
  42. local mmu_support=$(grep -m1 "mmu" /proc/cpuinfo | awk '{print $3}')
  43. if [[ "$mmu_support" != "radix" ]]; then
  44. skip "$0: System does not use Radix MMU, required for 5-level paging"
  45. fi
  46. local hugepages_total=$(awk '/HugePages_Total/ {print $2}' /proc/meminfo)
  47. if [[ "${hugepages_total}" -eq 0 ]]; then
  48. skip "$0: HugePages are not enabled, required for some tests"
  49. fi
  50. }
  51. check_test_requirements()
  52. {
  53. # The test supports x86_64, powerpc64 and arm64. There's check for arm64
  54. # in va_high_addr_switch.c. The test itself will reject other architectures.
  55. case `uname -m` in
  56. "x86_64")
  57. check_supported_x86_64
  58. ;;
  59. "ppc64le"|"ppc64")
  60. check_supported_ppc64
  61. ;;
  62. *)
  63. return 0
  64. ;;
  65. esac
  66. }
  67. save_nr_hugepages()
  68. {
  69. orig_nr_hugepages=$(cat /proc/sys/vm/nr_hugepages)
  70. }
  71. restore_nr_hugepages()
  72. {
  73. echo "$orig_nr_hugepages" > /proc/sys/vm/nr_hugepages
  74. }
  75. setup_nr_hugepages()
  76. {
  77. local needpgs=$1
  78. while read -r name size unit; do
  79. if [ "$name" = "HugePages_Free:" ]; then
  80. freepgs="$size"
  81. break
  82. fi
  83. done < /proc/meminfo
  84. if [ "$freepgs" -ge "$needpgs" ]; then
  85. return
  86. fi
  87. local hpgs=$((orig_nr_hugepages + needpgs))
  88. echo $hpgs > /proc/sys/vm/nr_hugepages
  89. local nr_hugepgs=$(cat /proc/sys/vm/nr_hugepages)
  90. if [ "$nr_hugepgs" != "$hpgs" ]; then
  91. restore_nr_hugepages
  92. skip "$0: no enough hugepages for testing"
  93. fi
  94. }
  95. check_test_requirements
  96. save_nr_hugepages
  97. # The HugeTLB tests require 6 pages
  98. setup_nr_hugepages 6
  99. ./va_high_addr_switch --run-hugetlb
  100. retcode=$?
  101. restore_nr_hugepages
  102. exit $retcode