summaryrefslogtreecommitdiff
path: root/scripts/basic/split-include.c
diff options
context:
space:
mode:
authorZhenzhong Duan <zhenzhong.duan@intel.com>2026-09-28 11:27:14 +0800
committerJoerg Roedel <joerg.roedel@amd.com>2026-09-28 10:17:41 +0200
commitd00ac5f7b52bb1f3a2b605f0e773b0397c8e325a (patch)
tree596d976307932d4f2cec7a057c6f46682f9dd343 /scripts/basic/split-include.c
parent93f51579e7df248780214094418f205253383cc5 (diff)
downloadlinux-d00ac5f7b52bb1f3a2b605f0e773b0397c8e325a.tar.gz
linux-d00ac5f7b52bb1f3a2b605f0e773b0397c8e325a.zip
iommu/vt-d: Fix page table level calculation in compute_vasz_lg2_ss()
compute_vasz_lg2_ss() finds the optimal Second-Stage page table level by intersecting the maximum guest address width (mgaw) with the hardware's SAGAW capability register. The VT-d spec maps the SAGAW bit field positions as: - Bit 1: 39-bit AGAW (3-level page table, top_level = 2) - Bit 2: 48-bit AGAW (4-level page table, top_level = 3) - Bit 3: 57-bit AGAW (5-level page table, top_level = 4) The fallback paths use bit shifts that are one position too large, causing ffs() to select a deeper page table level than the mgaw window requires: - mgaw > 39: "3 + ffs(sagaw >> 3)" evaluates to top_level = 4 (5-level) instead of top_level = 3 (4-level) when hardware supports both 48-bit (Bit 2) and 57-bit (Bit 3) AGAW. - mgaw > 30: "2 + ffs(sagaw >> 2)" evaluates to top_level = 3 (4-level) instead of top_level = 2 (3-level) when hardware supports both 39-bit (Bit 1) and 48-bit (Bit 2) AGAW. In both cases the selected level is still one that the hardware advertises in its SAGAW capability, so IOVA translation remains functionally correct. However, an unnecessarily deep page table may be selected, adding an extra level of page walk overhead and reducing TLB and cache efficiency without providing any increase in addressable IOVA space beyond what the mgaw window already caps. Fix by decreasing the shift offset by one in each fallback case, ensuring ffs() targets the correct SAGAW bit position and selects the smallest page table level that fully covers the mgaw range: - mgaw > 39: "2 + ffs(sagaw >> 2)" correctly yields top_level = 3 - mgaw > 30: "1 + ffs(sagaw >> 1)" correctly yields top_level = 2 Fixes: d856f9d27885 ("iommupt/vtd: Allow VT-d to have a larger table top than the vasz requires") Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'scripts/basic/split-include.c')
0 files changed, 0 insertions, 0 deletions