Loading arch/x86/include/asm/amd_iommu_types.h +9 −0 Original line number Diff line number Diff line Loading @@ -146,12 +146,21 @@ #define PAGE_MODE_1_LEVEL 0x01 #define PAGE_MODE_2_LEVEL 0x02 #define PAGE_MODE_3_LEVEL 0x03 #define PAGE_MODE_4_LEVEL 0x04 #define PAGE_MODE_5_LEVEL 0x05 #define PAGE_MODE_6_LEVEL 0x06 #define IOMMU_PDE_NL_0 0x000ULL #define IOMMU_PDE_NL_1 0x200ULL #define IOMMU_PDE_NL_2 0x400ULL #define IOMMU_PDE_NL_3 0x600ULL #define PM_LEVEL_SHIFT(x) (12 + ((x) * 9)) #define PM_LEVEL_SIZE(x) (((x) < 6) ? \ ((1ULL << PM_LEVEL_SHIFT((x))) - 1): \ (0xffffffffffffffffULL)) #define PM_LEVEL_INDEX(x, a) (((a) >> PM_LEVEL_SHIFT((x))) & 0x1ffULL) #define IOMMU_PTE_L2_INDEX(address) (((address) >> 30) & 0x1ffULL) #define IOMMU_PTE_L1_INDEX(address) (((address) >> 21) & 0x1ffULL) #define IOMMU_PTE_L0_INDEX(address) (((address) >> 12) & 0x1ffULL) Loading arch/x86/kernel/amd_iommu.c +13 −11 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static u64* alloc_pte(struct protection_domain *dom, static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, unsigned long start_page, unsigned int pages); static u64 *fetch_pte(struct protection_domain *domain, unsigned long address); #ifndef BUS_NOTIFY_UNBOUND_DRIVER #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 Loading Loading @@ -673,21 +675,21 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, static u64 *fetch_pte(struct protection_domain *domain, unsigned long address) { int level; u64 *pte; pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; level = domain->mode - 1; pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; while (level > 0) { if (!IOMMU_PTE_PRESENT(*pte)) return NULL; pte = IOMMU_PTE_PAGE(*pte); pte = &pte[IOMMU_PTE_L1_INDEX(address)]; if (!IOMMU_PTE_PRESENT(*pte)) return NULL; level -= 1; pte = IOMMU_PTE_PAGE(*pte); pte = &pte[IOMMU_PTE_L0_INDEX(address)]; pte = &pte[PM_LEVEL_INDEX(level, address)]; } return pte; } Loading Loading
arch/x86/include/asm/amd_iommu_types.h +9 −0 Original line number Diff line number Diff line Loading @@ -146,12 +146,21 @@ #define PAGE_MODE_1_LEVEL 0x01 #define PAGE_MODE_2_LEVEL 0x02 #define PAGE_MODE_3_LEVEL 0x03 #define PAGE_MODE_4_LEVEL 0x04 #define PAGE_MODE_5_LEVEL 0x05 #define PAGE_MODE_6_LEVEL 0x06 #define IOMMU_PDE_NL_0 0x000ULL #define IOMMU_PDE_NL_1 0x200ULL #define IOMMU_PDE_NL_2 0x400ULL #define IOMMU_PDE_NL_3 0x600ULL #define PM_LEVEL_SHIFT(x) (12 + ((x) * 9)) #define PM_LEVEL_SIZE(x) (((x) < 6) ? \ ((1ULL << PM_LEVEL_SHIFT((x))) - 1): \ (0xffffffffffffffffULL)) #define PM_LEVEL_INDEX(x, a) (((a) >> PM_LEVEL_SHIFT((x))) & 0x1ffULL) #define IOMMU_PTE_L2_INDEX(address) (((address) >> 30) & 0x1ffULL) #define IOMMU_PTE_L1_INDEX(address) (((address) >> 21) & 0x1ffULL) #define IOMMU_PTE_L0_INDEX(address) (((address) >> 12) & 0x1ffULL) Loading
arch/x86/kernel/amd_iommu.c +13 −11 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ static u64* alloc_pte(struct protection_domain *dom, static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, unsigned long start_page, unsigned int pages); static u64 *fetch_pte(struct protection_domain *domain, unsigned long address); #ifndef BUS_NOTIFY_UNBOUND_DRIVER #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 Loading Loading @@ -673,21 +675,21 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, static u64 *fetch_pte(struct protection_domain *domain, unsigned long address) { int level; u64 *pte; pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; level = domain->mode - 1; pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; while (level > 0) { if (!IOMMU_PTE_PRESENT(*pte)) return NULL; pte = IOMMU_PTE_PAGE(*pte); pte = &pte[IOMMU_PTE_L1_INDEX(address)]; if (!IOMMU_PTE_PRESENT(*pte)) return NULL; level -= 1; pte = IOMMU_PTE_PAGE(*pte); pte = &pte[IOMMU_PTE_L0_INDEX(address)]; pte = &pte[PM_LEVEL_INDEX(level, address)]; } return pte; } Loading