diff options
Diffstat (limited to 'arch/x86/kernel/amd_iommu.c')
| -rw-r--r-- | arch/x86/kernel/amd_iommu.c | 486 |
1 files changed, 361 insertions, 125 deletions
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 9f89bb645b31..8510e90ebfec 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
| @@ -55,7 +55,12 @@ struct iommu_cmd { | |||
| 55 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | 55 | static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, |
| 56 | struct unity_map_entry *e); | 56 | struct unity_map_entry *e); |
| 57 | static struct dma_ops_domain *find_protection_domain(u16 devid); | 57 | static struct dma_ops_domain *find_protection_domain(u16 devid); |
| 58 | 58 | static u64* alloc_pte(struct protection_domain *dom, | |
| 59 | unsigned long address, u64 | ||
| 60 | **pte_page, gfp_t gfp); | ||
| 61 | static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | ||
| 62 | unsigned long start_page, | ||
| 63 | unsigned int pages); | ||
| 59 | 64 | ||
| 60 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER | 65 | #ifndef BUS_NOTIFY_UNBOUND_DRIVER |
| 61 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 | 66 | #define BUS_NOTIFY_UNBOUND_DRIVER 0x0005 |
| @@ -217,7 +222,7 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data) | |||
| 217 | { | 222 | { |
| 218 | struct amd_iommu *iommu; | 223 | struct amd_iommu *iommu; |
| 219 | 224 | ||
| 220 | list_for_each_entry(iommu, &amd_iommu_list, list) | 225 | for_each_iommu(iommu) |
| 221 | iommu_poll_events(iommu); | 226 | iommu_poll_events(iommu); |
| 222 | 227 | ||
| 223 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
| @@ -444,7 +449,7 @@ static void iommu_flush_domain(u16 domid) | |||
| 444 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, | 449 | __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, |
| 445 | domid, 1, 1); | 450 | domid, 1, 1); |
| 446 | 451 | ||
| 447 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 452 | for_each_iommu(iommu) { |
| 448 | spin_lock_irqsave(&iommu->lock, flags); | 453 | spin_lock_irqsave(&iommu->lock, flags); |
| 449 | __iommu_queue_command(iommu, &cmd); | 454 | __iommu_queue_command(iommu, &cmd); |
| 450 | __iommu_completion_wait(iommu); | 455 | __iommu_completion_wait(iommu); |
| @@ -453,6 +458,35 @@ static void iommu_flush_domain(u16 domid) | |||
| 453 | } | 458 | } |
| 454 | } | 459 | } |
| 455 | 460 | ||
| 461 | void amd_iommu_flush_all_domains(void) | ||
| 462 | { | ||
| 463 | int i; | ||
| 464 | |||
| 465 | for (i = 1; i < MAX_DOMAIN_ID; ++i) { | ||
| 466 | if (!test_bit(i, amd_iommu_pd_alloc_bitmap)) | ||
| 467 | continue; | ||
| 468 | iommu_flush_domain(i); | ||
| 469 | } | ||
| 470 | } | ||
| 471 | |||
| 472 | void amd_iommu_flush_all_devices(void) | ||
| 473 | { | ||
| 474 | struct amd_iommu *iommu; | ||
| 475 | int i; | ||
| 476 | |||
| 477 | for (i = 0; i <= amd_iommu_last_bdf; ++i) { | ||
| 478 | if (amd_iommu_pd_table[i] == NULL) | ||
| 479 | continue; | ||
| 480 | |||
| 481 | iommu = amd_iommu_rlookup_table[i]; | ||
| 482 | if (!iommu) | ||
| 483 | continue; | ||
| 484 | |||
| 485 | iommu_queue_inv_dev_entry(iommu, i); | ||
| 486 | iommu_completion_wait(iommu); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 456 | /**************************************************************************** | 490 | /**************************************************************************** |
| 457 | * | 491 | * |
| 458 | * The functions below are used the create the page table mappings for | 492 | * The functions below are used the create the page table mappings for |
| @@ -472,7 +506,7 @@ static int iommu_map_page(struct protection_domain *dom, | |||
| 472 | unsigned long phys_addr, | 506 | unsigned long phys_addr, |
| 473 | int prot) | 507 | int prot) |
| 474 | { | 508 | { |
| 475 | u64 __pte, *pte, *page; | 509 | u64 __pte, *pte; |
| 476 | 510 | ||
| 477 | bus_addr = PAGE_ALIGN(bus_addr); | 511 | bus_addr = PAGE_ALIGN(bus_addr); |
| 478 | phys_addr = PAGE_ALIGN(phys_addr); | 512 | phys_addr = PAGE_ALIGN(phys_addr); |
| @@ -481,27 +515,7 @@ static int iommu_map_page(struct protection_domain *dom, | |||
| 481 | if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) | 515 | if (bus_addr > IOMMU_MAP_SIZE_L3 || !(prot & IOMMU_PROT_MASK)) |
| 482 | return -EINVAL; | 516 | return -EINVAL; |
| 483 | 517 | ||
| 484 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(bus_addr)]; | 518 | pte = alloc_pte(dom, bus_addr, NULL, GFP_KERNEL); |
| 485 | |||
| 486 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
| 487 | page = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
| 488 | if (!page) | ||
| 489 | return -ENOMEM; | ||
| 490 | *pte = IOMMU_L2_PDE(virt_to_phys(page)); | ||
| 491 | } | ||
| 492 | |||
| 493 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 494 | pte = &pte[IOMMU_PTE_L1_INDEX(bus_addr)]; | ||
| 495 | |||
| 496 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
| 497 | page = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
| 498 | if (!page) | ||
| 499 | return -ENOMEM; | ||
| 500 | *pte = IOMMU_L1_PDE(virt_to_phys(page)); | ||
| 501 | } | ||
| 502 | |||
| 503 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 504 | pte = &pte[IOMMU_PTE_L0_INDEX(bus_addr)]; | ||
| 505 | 519 | ||
| 506 | if (IOMMU_PTE_PRESENT(*pte)) | 520 | if (IOMMU_PTE_PRESENT(*pte)) |
| 507 | return -EBUSY; | 521 | return -EBUSY; |
| @@ -599,7 +613,8 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom, | |||
| 599 | * as allocated in the aperture | 613 | * as allocated in the aperture |
| 600 | */ | 614 | */ |
| 601 | if (addr < dma_dom->aperture_size) | 615 | if (addr < dma_dom->aperture_size) |
| 602 | __set_bit(addr >> PAGE_SHIFT, dma_dom->bitmap); | 616 | __set_bit(addr >> PAGE_SHIFT, |
| 617 | dma_dom->aperture[0]->bitmap); | ||
| 603 | } | 618 | } |
| 604 | 619 | ||
| 605 | return 0; | 620 | return 0; |
| @@ -636,42 +651,191 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom, | |||
| 636 | ****************************************************************************/ | 651 | ****************************************************************************/ |
| 637 | 652 | ||
| 638 | /* | 653 | /* |
| 639 | * The address allocator core function. | 654 | * The address allocator core functions. |
| 640 | * | 655 | * |
| 641 | * called with domain->lock held | 656 | * called with domain->lock held |
| 642 | */ | 657 | */ |
| 658 | |||
| 659 | /* | ||
| 660 | * This function checks if there is a PTE for a given dma address. If | ||
| 661 | * there is one, it returns the pointer to it. | ||
| 662 | */ | ||
| 663 | static u64* fetch_pte(struct protection_domain *domain, | ||
| 664 | unsigned long address) | ||
| 665 | { | ||
| 666 | u64 *pte; | ||
| 667 | |||
| 668 | pte = &domain->pt_root[IOMMU_PTE_L2_INDEX(address)]; | ||
| 669 | |||
| 670 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 671 | return NULL; | ||
| 672 | |||
| 673 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 674 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | ||
| 675 | |||
| 676 | if (!IOMMU_PTE_PRESENT(*pte)) | ||
| 677 | return NULL; | ||
| 678 | |||
| 679 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 680 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | ||
| 681 | |||
| 682 | return pte; | ||
| 683 | } | ||
| 684 | |||
| 685 | /* | ||
| 686 | * This function is used to add a new aperture range to an existing | ||
| 687 | * aperture in case of dma_ops domain allocation or address allocation | ||
| 688 | * failure. | ||
| 689 | */ | ||
| 690 | static int alloc_new_range(struct amd_iommu *iommu, | ||
| 691 | struct dma_ops_domain *dma_dom, | ||
| 692 | bool populate, gfp_t gfp) | ||
| 693 | { | ||
| 694 | int index = dma_dom->aperture_size >> APERTURE_RANGE_SHIFT; | ||
| 695 | int i; | ||
| 696 | |||
| 697 | #ifdef CONFIG_IOMMU_STRESS | ||
| 698 | populate = false; | ||
| 699 | #endif | ||
| 700 | |||
| 701 | if (index >= APERTURE_MAX_RANGES) | ||
| 702 | return -ENOMEM; | ||
| 703 | |||
| 704 | dma_dom->aperture[index] = kzalloc(sizeof(struct aperture_range), gfp); | ||
| 705 | if (!dma_dom->aperture[index]) | ||
| 706 | return -ENOMEM; | ||
| 707 | |||
| 708 | dma_dom->aperture[index]->bitmap = (void *)get_zeroed_page(gfp); | ||
| 709 | if (!dma_dom->aperture[index]->bitmap) | ||
| 710 | goto out_free; | ||
| 711 | |||
| 712 | dma_dom->aperture[index]->offset = dma_dom->aperture_size; | ||
| 713 | |||
| 714 | if (populate) { | ||
| 715 | unsigned long address = dma_dom->aperture_size; | ||
| 716 | int i, num_ptes = APERTURE_RANGE_PAGES / 512; | ||
| 717 | u64 *pte, *pte_page; | ||
| 718 | |||
| 719 | for (i = 0; i < num_ptes; ++i) { | ||
| 720 | pte = alloc_pte(&dma_dom->domain, address, | ||
| 721 | &pte_page, gfp); | ||
| 722 | if (!pte) | ||
| 723 | goto out_free; | ||
| 724 | |||
| 725 | dma_dom->aperture[index]->pte_pages[i] = pte_page; | ||
| 726 | |||
| 727 | address += APERTURE_RANGE_SIZE / 64; | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 731 | dma_dom->aperture_size += APERTURE_RANGE_SIZE; | ||
| 732 | |||
| 733 | /* Intialize the exclusion range if necessary */ | ||
| 734 | if (iommu->exclusion_start && | ||
| 735 | iommu->exclusion_start >= dma_dom->aperture[index]->offset && | ||
| 736 | iommu->exclusion_start < dma_dom->aperture_size) { | ||
| 737 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | ||
| 738 | int pages = iommu_num_pages(iommu->exclusion_start, | ||
| 739 | iommu->exclusion_length, | ||
| 740 | PAGE_SIZE); | ||
| 741 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | ||
| 742 | } | ||
| 743 | |||
| 744 | /* | ||
| 745 | * Check for areas already mapped as present in the new aperture | ||
| 746 | * range and mark those pages as reserved in the allocator. Such | ||
| 747 | * mappings may already exist as a result of requested unity | ||
| 748 | * mappings for devices. | ||
| 749 | */ | ||
| 750 | for (i = dma_dom->aperture[index]->offset; | ||
| 751 | i < dma_dom->aperture_size; | ||
| 752 | i += PAGE_SIZE) { | ||
| 753 | u64 *pte = fetch_pte(&dma_dom->domain, i); | ||
| 754 | if (!pte || !IOMMU_PTE_PRESENT(*pte)) | ||
| 755 | continue; | ||
| 756 | |||
| 757 | dma_ops_reserve_addresses(dma_dom, i << PAGE_SHIFT, 1); | ||
| 758 | } | ||
| 759 | |||
| 760 | return 0; | ||
| 761 | |||
| 762 | out_free: | ||
| 763 | free_page((unsigned long)dma_dom->aperture[index]->bitmap); | ||
| 764 | |||
| 765 | kfree(dma_dom->aperture[index]); | ||
| 766 | dma_dom->aperture[index] = NULL; | ||
| 767 | |||
| 768 | return -ENOMEM; | ||
| 769 | } | ||
| 770 | |||
| 771 | static unsigned long dma_ops_area_alloc(struct device *dev, | ||
| 772 | struct dma_ops_domain *dom, | ||
| 773 | unsigned int pages, | ||
| 774 | unsigned long align_mask, | ||
| 775 | u64 dma_mask, | ||
| 776 | unsigned long start) | ||
| 777 | { | ||
| 778 | unsigned long next_bit = dom->next_address % APERTURE_RANGE_SIZE; | ||
| 779 | int max_index = dom->aperture_size >> APERTURE_RANGE_SHIFT; | ||
| 780 | int i = start >> APERTURE_RANGE_SHIFT; | ||
| 781 | unsigned long boundary_size; | ||
| 782 | unsigned long address = -1; | ||
| 783 | unsigned long limit; | ||
| 784 | |||
| 785 | next_bit >>= PAGE_SHIFT; | ||
| 786 | |||
| 787 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | ||
| 788 | PAGE_SIZE) >> PAGE_SHIFT; | ||
| 789 | |||
| 790 | for (;i < max_index; ++i) { | ||
| 791 | unsigned long offset = dom->aperture[i]->offset >> PAGE_SHIFT; | ||
| 792 | |||
| 793 | if (dom->aperture[i]->offset >= dma_mask) | ||
| 794 | break; | ||
| 795 | |||
| 796 | limit = iommu_device_max_index(APERTURE_RANGE_PAGES, offset, | ||
| 797 | dma_mask >> PAGE_SHIFT); | ||
| 798 | |||
| 799 | address = iommu_area_alloc(dom->aperture[i]->bitmap, | ||
| 800 | limit, next_bit, pages, 0, | ||
| 801 | boundary_size, align_mask); | ||
| 802 | if (address != -1) { | ||
| 803 | address = dom->aperture[i]->offset + | ||
| 804 | (address << PAGE_SHIFT); | ||
| 805 | dom->next_address = address + (pages << PAGE_SHIFT); | ||
| 806 | break; | ||
| 807 | } | ||
| 808 | |||
| 809 | next_bit = 0; | ||
| 810 | } | ||
| 811 | |||
| 812 | return address; | ||
| 813 | } | ||
| 814 | |||
| 643 | static unsigned long dma_ops_alloc_addresses(struct device *dev, | 815 | static unsigned long dma_ops_alloc_addresses(struct device *dev, |
| 644 | struct dma_ops_domain *dom, | 816 | struct dma_ops_domain *dom, |
| 645 | unsigned int pages, | 817 | unsigned int pages, |
| 646 | unsigned long align_mask, | 818 | unsigned long align_mask, |
| 647 | u64 dma_mask) | 819 | u64 dma_mask) |
| 648 | { | 820 | { |
| 649 | unsigned long limit; | ||
| 650 | unsigned long address; | 821 | unsigned long address; |
| 651 | unsigned long boundary_size; | ||
| 652 | 822 | ||
| 653 | boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, | 823 | #ifdef CONFIG_IOMMU_STRESS |
| 654 | PAGE_SIZE) >> PAGE_SHIFT; | 824 | dom->next_address = 0; |
| 655 | limit = iommu_device_max_index(dom->aperture_size >> PAGE_SHIFT, 0, | 825 | dom->need_flush = true; |
| 656 | dma_mask >> PAGE_SHIFT); | 826 | #endif |
| 657 | 827 | ||
| 658 | if (dom->next_bit >= limit) { | 828 | address = dma_ops_area_alloc(dev, dom, pages, align_mask, |
| 659 | dom->next_bit = 0; | 829 | dma_mask, dom->next_address); |
| 660 | dom->need_flush = true; | ||
| 661 | } | ||
| 662 | 830 | ||
| 663 | address = iommu_area_alloc(dom->bitmap, limit, dom->next_bit, pages, | ||
| 664 | 0 , boundary_size, align_mask); | ||
| 665 | if (address == -1) { | 831 | if (address == -1) { |
| 666 | address = iommu_area_alloc(dom->bitmap, limit, 0, pages, | 832 | dom->next_address = 0; |
| 667 | 0, boundary_size, align_mask); | 833 | address = dma_ops_area_alloc(dev, dom, pages, align_mask, |
| 834 | dma_mask, 0); | ||
| 668 | dom->need_flush = true; | 835 | dom->need_flush = true; |
| 669 | } | 836 | } |
| 670 | 837 | ||
| 671 | if (likely(address != -1)) { | 838 | if (unlikely(address == -1)) |
| 672 | dom->next_bit = address + pages; | ||
| 673 | address <<= PAGE_SHIFT; | ||
| 674 | } else | ||
| 675 | address = bad_dma_address; | 839 | address = bad_dma_address; |
| 676 | 840 | ||
| 677 | WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size); | 841 | WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size); |
| @@ -688,11 +852,23 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, | |||
| 688 | unsigned long address, | 852 | unsigned long address, |
| 689 | unsigned int pages) | 853 | unsigned int pages) |
| 690 | { | 854 | { |
| 691 | address >>= PAGE_SHIFT; | 855 | unsigned i = address >> APERTURE_RANGE_SHIFT; |
| 692 | iommu_area_free(dom->bitmap, address, pages); | 856 | struct aperture_range *range = dom->aperture[i]; |
| 857 | |||
| 858 | BUG_ON(i >= APERTURE_MAX_RANGES || range == NULL); | ||
| 859 | |||
| 860 | #ifdef CONFIG_IOMMU_STRESS | ||
| 861 | if (i < 4) | ||
| 862 | return; | ||
| 863 | #endif | ||
| 693 | 864 | ||
| 694 | if (address >= dom->next_bit) | 865 | if (address >= dom->next_address) |
| 695 | dom->need_flush = true; | 866 | dom->need_flush = true; |
| 867 | |||
| 868 | address = (address % APERTURE_RANGE_SIZE) >> PAGE_SHIFT; | ||
| 869 | |||
| 870 | iommu_area_free(range->bitmap, address, pages); | ||
| 871 | |||
| 696 | } | 872 | } |
| 697 | 873 | ||
| 698 | /**************************************************************************** | 874 | /**************************************************************************** |
| @@ -740,12 +916,16 @@ static void dma_ops_reserve_addresses(struct dma_ops_domain *dom, | |||
| 740 | unsigned long start_page, | 916 | unsigned long start_page, |
| 741 | unsigned int pages) | 917 | unsigned int pages) |
| 742 | { | 918 | { |
| 743 | unsigned int last_page = dom->aperture_size >> PAGE_SHIFT; | 919 | unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT; |
| 744 | 920 | ||
| 745 | if (start_page + pages > last_page) | 921 | if (start_page + pages > last_page) |
| 746 | pages = last_page - start_page; | 922 | pages = last_page - start_page; |
| 747 | 923 | ||
| 748 | iommu_area_reserve(dom->bitmap, start_page, pages); | 924 | for (i = start_page; i < start_page + pages; ++i) { |
| 925 | int index = i / APERTURE_RANGE_PAGES; | ||
| 926 | int page = i % APERTURE_RANGE_PAGES; | ||
| 927 | __set_bit(page, dom->aperture[index]->bitmap); | ||
| 928 | } | ||
| 749 | } | 929 | } |
| 750 | 930 | ||
| 751 | static void free_pagetable(struct protection_domain *domain) | 931 | static void free_pagetable(struct protection_domain *domain) |
| @@ -784,14 +964,19 @@ static void free_pagetable(struct protection_domain *domain) | |||
| 784 | */ | 964 | */ |
| 785 | static void dma_ops_domain_free(struct dma_ops_domain *dom) | 965 | static void dma_ops_domain_free(struct dma_ops_domain *dom) |
| 786 | { | 966 | { |
| 967 | int i; | ||
| 968 | |||
| 787 | if (!dom) | 969 | if (!dom) |
| 788 | return; | 970 | return; |
| 789 | 971 | ||
| 790 | free_pagetable(&dom->domain); | 972 | free_pagetable(&dom->domain); |
| 791 | 973 | ||
| 792 | kfree(dom->pte_pages); | 974 | for (i = 0; i < APERTURE_MAX_RANGES; ++i) { |
| 793 | 975 | if (!dom->aperture[i]) | |
| 794 | kfree(dom->bitmap); | 976 | continue; |
| 977 | free_page((unsigned long)dom->aperture[i]->bitmap); | ||
| 978 | kfree(dom->aperture[i]); | ||
| 979 | } | ||
| 795 | 980 | ||
| 796 | kfree(dom); | 981 | kfree(dom); |
| 797 | } | 982 | } |
| @@ -801,19 +986,9 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) | |||
| 801 | * It also intializes the page table and the address allocator data | 986 | * It also intializes the page table and the address allocator data |
| 802 | * structures required for the dma_ops interface | 987 | * structures required for the dma_ops interface |
| 803 | */ | 988 | */ |
| 804 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | 989 | static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu) |
| 805 | unsigned order) | ||
| 806 | { | 990 | { |
| 807 | struct dma_ops_domain *dma_dom; | 991 | struct dma_ops_domain *dma_dom; |
| 808 | unsigned i, num_pte_pages; | ||
| 809 | u64 *l2_pde; | ||
| 810 | u64 address; | ||
| 811 | |||
| 812 | /* | ||
| 813 | * Currently the DMA aperture must be between 32 MB and 1GB in size | ||
| 814 | */ | ||
| 815 | if ((order < 25) || (order > 30)) | ||
| 816 | return NULL; | ||
| 817 | 992 | ||
| 818 | dma_dom = kzalloc(sizeof(struct dma_ops_domain), GFP_KERNEL); | 993 | dma_dom = kzalloc(sizeof(struct dma_ops_domain), GFP_KERNEL); |
| 819 | if (!dma_dom) | 994 | if (!dma_dom) |
| @@ -830,55 +1005,20 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu, | |||
| 830 | dma_dom->domain.priv = dma_dom; | 1005 | dma_dom->domain.priv = dma_dom; |
| 831 | if (!dma_dom->domain.pt_root) | 1006 | if (!dma_dom->domain.pt_root) |
| 832 | goto free_dma_dom; | 1007 | goto free_dma_dom; |
| 833 | dma_dom->aperture_size = (1ULL << order); | ||
| 834 | dma_dom->bitmap = kzalloc(dma_dom->aperture_size / (PAGE_SIZE * 8), | ||
| 835 | GFP_KERNEL); | ||
| 836 | if (!dma_dom->bitmap) | ||
| 837 | goto free_dma_dom; | ||
| 838 | /* | ||
| 839 | * mark the first page as allocated so we never return 0 as | ||
| 840 | * a valid dma-address. So we can use 0 as error value | ||
| 841 | */ | ||
| 842 | dma_dom->bitmap[0] = 1; | ||
| 843 | dma_dom->next_bit = 0; | ||
| 844 | 1008 | ||
| 845 | dma_dom->need_flush = false; | 1009 | dma_dom->need_flush = false; |
| 846 | dma_dom->target_dev = 0xffff; | 1010 | dma_dom->target_dev = 0xffff; |
| 847 | 1011 | ||
| 848 | /* Intialize the exclusion range if necessary */ | 1012 | if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL)) |
| 849 | if (iommu->exclusion_start && | 1013 | goto free_dma_dom; |
| 850 | iommu->exclusion_start < dma_dom->aperture_size) { | ||
| 851 | unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT; | ||
| 852 | int pages = iommu_num_pages(iommu->exclusion_start, | ||
| 853 | iommu->exclusion_length, | ||
| 854 | PAGE_SIZE); | ||
| 855 | dma_ops_reserve_addresses(dma_dom, startpage, pages); | ||
| 856 | } | ||
| 857 | 1014 | ||
| 858 | /* | 1015 | /* |
| 859 | * At the last step, build the page tables so we don't need to | 1016 | * mark the first page as allocated so we never return 0 as |
| 860 | * allocate page table pages in the dma_ops mapping/unmapping | 1017 | * a valid dma-address. So we can use 0 as error value |
| 861 | * path. | ||
| 862 | */ | 1018 | */ |
| 863 | num_pte_pages = dma_dom->aperture_size / (PAGE_SIZE * 512); | 1019 | dma_dom->aperture[0]->bitmap[0] = 1; |
| 864 | dma_dom->pte_pages = kzalloc(num_pte_pages * sizeof(void *), | 1020 | dma_dom->next_address = 0; |
| 865 | GFP_KERNEL); | ||
| 866 | if (!dma_dom->pte_pages) | ||
| 867 | goto free_dma_dom; | ||
| 868 | |||
| 869 | l2_pde = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
| 870 | if (l2_pde == NULL) | ||
| 871 | goto free_dma_dom; | ||
| 872 | 1021 | ||
| 873 | dma_dom->domain.pt_root[0] = IOMMU_L2_PDE(virt_to_phys(l2_pde)); | ||
| 874 | |||
| 875 | for (i = 0; i < num_pte_pages; ++i) { | ||
| 876 | dma_dom->pte_pages[i] = (u64 *)get_zeroed_page(GFP_KERNEL); | ||
| 877 | if (!dma_dom->pte_pages[i]) | ||
| 878 | goto free_dma_dom; | ||
| 879 | address = virt_to_phys(dma_dom->pte_pages[i]); | ||
| 880 | l2_pde[i] = IOMMU_L1_PDE(address); | ||
| 881 | } | ||
| 882 | 1022 | ||
| 883 | return dma_dom; | 1023 | return dma_dom; |
| 884 | 1024 | ||
| @@ -987,7 +1127,6 @@ static int device_change_notifier(struct notifier_block *nb, | |||
| 987 | struct protection_domain *domain; | 1127 | struct protection_domain *domain; |
| 988 | struct dma_ops_domain *dma_domain; | 1128 | struct dma_ops_domain *dma_domain; |
| 989 | struct amd_iommu *iommu; | 1129 | struct amd_iommu *iommu; |
| 990 | int order = amd_iommu_aperture_order; | ||
| 991 | unsigned long flags; | 1130 | unsigned long flags; |
| 992 | 1131 | ||
| 993 | if (devid > amd_iommu_last_bdf) | 1132 | if (devid > amd_iommu_last_bdf) |
| @@ -1013,8 +1152,9 @@ static int device_change_notifier(struct notifier_block *nb, | |||
| 1013 | if (!dma_domain) | 1152 | if (!dma_domain) |
| 1014 | dma_domain = iommu->default_dom; | 1153 | dma_domain = iommu->default_dom; |
| 1015 | attach_device(iommu, &dma_domain->domain, devid); | 1154 | attach_device(iommu, &dma_domain->domain, devid); |
| 1016 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | 1155 | DUMP_printk(KERN_INFO "AMD IOMMU: Using protection domain " |
| 1017 | "device %s\n", dma_domain->domain.id, dev_name(dev)); | 1156 | "%d for device %s\n", |
| 1157 | dma_domain->domain.id, dev_name(dev)); | ||
| 1018 | break; | 1158 | break; |
| 1019 | case BUS_NOTIFY_UNBOUND_DRIVER: | 1159 | case BUS_NOTIFY_UNBOUND_DRIVER: |
| 1020 | if (!domain) | 1160 | if (!domain) |
| @@ -1026,7 +1166,7 @@ static int device_change_notifier(struct notifier_block *nb, | |||
| 1026 | dma_domain = find_protection_domain(devid); | 1166 | dma_domain = find_protection_domain(devid); |
| 1027 | if (dma_domain) | 1167 | if (dma_domain) |
| 1028 | goto out; | 1168 | goto out; |
| 1029 | dma_domain = dma_ops_domain_alloc(iommu, order); | 1169 | dma_domain = dma_ops_domain_alloc(iommu); |
| 1030 | if (!dma_domain) | 1170 | if (!dma_domain) |
| 1031 | goto out; | 1171 | goto out; |
| 1032 | dma_domain->target_dev = devid; | 1172 | dma_domain->target_dev = devid; |
| @@ -1137,8 +1277,9 @@ static int get_device_resources(struct device *dev, | |||
| 1137 | dma_dom = (*iommu)->default_dom; | 1277 | dma_dom = (*iommu)->default_dom; |
| 1138 | *domain = &dma_dom->domain; | 1278 | *domain = &dma_dom->domain; |
| 1139 | attach_device(*iommu, *domain, *bdf); | 1279 | attach_device(*iommu, *domain, *bdf); |
| 1140 | printk(KERN_INFO "AMD IOMMU: Using protection domain %d for " | 1280 | DUMP_printk(KERN_INFO "AMD IOMMU: Using protection domain " |
| 1141 | "device %s\n", (*domain)->id, dev_name(dev)); | 1281 | "%d for device %s\n", |
| 1282 | (*domain)->id, dev_name(dev)); | ||
| 1142 | } | 1283 | } |
| 1143 | 1284 | ||
| 1144 | if (domain_for_device(_bdf) == NULL) | 1285 | if (domain_for_device(_bdf) == NULL) |
| @@ -1148,6 +1289,66 @@ static int get_device_resources(struct device *dev, | |||
| 1148 | } | 1289 | } |
| 1149 | 1290 | ||
| 1150 | /* | 1291 | /* |
| 1292 | * If the pte_page is not yet allocated this function is called | ||
| 1293 | */ | ||
| 1294 | static u64* alloc_pte(struct protection_domain *dom, | ||
| 1295 | unsigned long address, u64 **pte_page, gfp_t gfp) | ||
| 1296 | { | ||
| 1297 | u64 *pte, *page; | ||
| 1298 | |||
| 1299 | pte = &dom->pt_root[IOMMU_PTE_L2_INDEX(address)]; | ||
| 1300 | |||
| 1301 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
| 1302 | page = (u64 *)get_zeroed_page(gfp); | ||
| 1303 | if (!page) | ||
| 1304 | return NULL; | ||
| 1305 | *pte = IOMMU_L2_PDE(virt_to_phys(page)); | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 1309 | pte = &pte[IOMMU_PTE_L1_INDEX(address)]; | ||
| 1310 | |||
| 1311 | if (!IOMMU_PTE_PRESENT(*pte)) { | ||
| 1312 | page = (u64 *)get_zeroed_page(gfp); | ||
| 1313 | if (!page) | ||
| 1314 | return NULL; | ||
| 1315 | *pte = IOMMU_L1_PDE(virt_to_phys(page)); | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | pte = IOMMU_PTE_PAGE(*pte); | ||
| 1319 | |||
| 1320 | if (pte_page) | ||
| 1321 | *pte_page = pte; | ||
| 1322 | |||
| 1323 | pte = &pte[IOMMU_PTE_L0_INDEX(address)]; | ||
| 1324 | |||
| 1325 | return pte; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | /* | ||
| 1329 | * This function fetches the PTE for a given address in the aperture | ||
| 1330 | */ | ||
| 1331 | static u64* dma_ops_get_pte(struct dma_ops_domain *dom, | ||
| 1332 | unsigned long address) | ||
| 1333 | { | ||
| 1334 | struct aperture_range *aperture; | ||
| 1335 | u64 *pte, *pte_page; | ||
| 1336 | |||
| 1337 | aperture = dom->aperture[APERTURE_RANGE_INDEX(address)]; | ||
| 1338 | if (!aperture) | ||
| 1339 | return NULL; | ||
| 1340 | |||
| 1341 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; | ||
| 1342 | if (!pte) { | ||
| 1343 | pte = alloc_pte(&dom->domain, address, &pte_page, GFP_ATOMIC); | ||
| 1344 | aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page; | ||
| 1345 | } else | ||
| 1346 | pte += IOMMU_PTE_L0_INDEX(address); | ||
| 1347 | |||
| 1348 | return pte; | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | /* | ||
| 1151 | * This is the generic map function. It maps one 4kb page at paddr to | 1352 | * This is the generic map function. It maps one 4kb page at paddr to |
| 1152 | * the given address in the DMA address space for the domain. | 1353 | * the given address in the DMA address space for the domain. |
| 1153 | */ | 1354 | */ |
| @@ -1163,8 +1364,9 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu, | |||
| 1163 | 1364 | ||
| 1164 | paddr &= PAGE_MASK; | 1365 | paddr &= PAGE_MASK; |
| 1165 | 1366 | ||
| 1166 | pte = dom->pte_pages[IOMMU_PTE_L1_INDEX(address)]; | 1367 | pte = dma_ops_get_pte(dom, address); |
| 1167 | pte += IOMMU_PTE_L0_INDEX(address); | 1368 | if (!pte) |
| 1369 | return bad_dma_address; | ||
| 1168 | 1370 | ||
| 1169 | __pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC; | 1371 | __pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC; |
| 1170 | 1372 | ||
| @@ -1189,14 +1391,20 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu, | |||
| 1189 | struct dma_ops_domain *dom, | 1391 | struct dma_ops_domain *dom, |
| 1190 | unsigned long address) | 1392 | unsigned long address) |
| 1191 | { | 1393 | { |
| 1394 | struct aperture_range *aperture; | ||
| 1192 | u64 *pte; | 1395 | u64 *pte; |
| 1193 | 1396 | ||
| 1194 | if (address >= dom->aperture_size) | 1397 | if (address >= dom->aperture_size) |
| 1195 | return; | 1398 | return; |
| 1196 | 1399 | ||
| 1197 | WARN_ON(address & ~PAGE_MASK || address >= dom->aperture_size); | 1400 | aperture = dom->aperture[APERTURE_RANGE_INDEX(address)]; |
| 1401 | if (!aperture) | ||
| 1402 | return; | ||
| 1403 | |||
| 1404 | pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)]; | ||
| 1405 | if (!pte) | ||
| 1406 | return; | ||
| 1198 | 1407 | ||
| 1199 | pte = dom->pte_pages[IOMMU_PTE_L1_INDEX(address)]; | ||
| 1200 | pte += IOMMU_PTE_L0_INDEX(address); | 1408 | pte += IOMMU_PTE_L0_INDEX(address); |
| 1201 | 1409 | ||
| 1202 | WARN_ON(!*pte); | 1410 | WARN_ON(!*pte); |
| @@ -1220,7 +1428,7 @@ static dma_addr_t __map_single(struct device *dev, | |||
| 1220 | u64 dma_mask) | 1428 | u64 dma_mask) |
| 1221 | { | 1429 | { |
| 1222 | dma_addr_t offset = paddr & ~PAGE_MASK; | 1430 | dma_addr_t offset = paddr & ~PAGE_MASK; |
| 1223 | dma_addr_t address, start; | 1431 | dma_addr_t address, start, ret; |
| 1224 | unsigned int pages; | 1432 | unsigned int pages; |
| 1225 | unsigned long align_mask = 0; | 1433 | unsigned long align_mask = 0; |
| 1226 | int i; | 1434 | int i; |
| @@ -1236,14 +1444,33 @@ static dma_addr_t __map_single(struct device *dev, | |||
| 1236 | if (align) | 1444 | if (align) |
| 1237 | align_mask = (1UL << get_order(size)) - 1; | 1445 | align_mask = (1UL << get_order(size)) - 1; |
| 1238 | 1446 | ||
| 1447 | retry: | ||
| 1239 | address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask, | 1448 | address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask, |
| 1240 | dma_mask); | 1449 | dma_mask); |
| 1241 | if (unlikely(address == bad_dma_address)) | 1450 | if (unlikely(address == bad_dma_address)) { |
| 1242 | goto out; | 1451 | /* |
| 1452 | * setting next_address here will let the address | ||
| 1453 | * allocator only scan the new allocated range in the | ||
| 1454 | * first run. This is a small optimization. | ||
| 1455 | */ | ||
| 1456 | dma_dom->next_address = dma_dom->aperture_size; | ||
| 1457 | |||
| 1458 | if (alloc_new_range(iommu, dma_dom, false, GFP_ATOMIC)) | ||
| 1459 | goto out; | ||
| 1460 | |||
| 1461 | /* | ||
| 1462 | * aperture was sucessfully enlarged by 128 MB, try | ||
| 1463 | * allocation again | ||
| 1464 | */ | ||
| 1465 | goto retry; | ||
| 1466 | } | ||
| 1243 | 1467 | ||
| 1244 | start = address; | 1468 | start = address; |
| 1245 | for (i = 0; i < pages; ++i) { | 1469 | for (i = 0; i < pages; ++i) { |
| 1246 | dma_ops_domain_map(iommu, dma_dom, start, paddr, dir); | 1470 | ret = dma_ops_domain_map(iommu, dma_dom, start, paddr, dir); |
| 1471 | if (ret == bad_dma_address) | ||
| 1472 | goto out_unmap; | ||
| 1473 | |||
| 1247 | paddr += PAGE_SIZE; | 1474 | paddr += PAGE_SIZE; |
| 1248 | start += PAGE_SIZE; | 1475 | start += PAGE_SIZE; |
| 1249 | } | 1476 | } |
| @@ -1259,6 +1486,17 @@ static dma_addr_t __map_single(struct device *dev, | |||
| 1259 | 1486 | ||
| 1260 | out: | 1487 | out: |
| 1261 | return address; | 1488 | return address; |
| 1489 | |||
| 1490 | out_unmap: | ||
| 1491 | |||
| 1492 | for (--i; i >= 0; --i) { | ||
| 1493 | start -= PAGE_SIZE; | ||
| 1494 | dma_ops_domain_unmap(iommu, dma_dom, start); | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | dma_ops_free_addresses(dma_dom, address, pages); | ||
| 1498 | |||
| 1499 | return bad_dma_address; | ||
| 1262 | } | 1500 | } |
| 1263 | 1501 | ||
| 1264 | /* | 1502 | /* |
| @@ -1631,7 +1869,6 @@ static void prealloc_protection_domains(void) | |||
| 1631 | struct pci_dev *dev = NULL; | 1869 | struct pci_dev *dev = NULL; |
| 1632 | struct dma_ops_domain *dma_dom; | 1870 | struct dma_ops_domain *dma_dom; |
| 1633 | struct amd_iommu *iommu; | 1871 | struct amd_iommu *iommu; |
| 1634 | int order = amd_iommu_aperture_order; | ||
| 1635 | u16 devid; | 1872 | u16 devid; |
| 1636 | 1873 | ||
| 1637 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 1874 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
| @@ -1644,7 +1881,7 @@ static void prealloc_protection_domains(void) | |||
| 1644 | iommu = amd_iommu_rlookup_table[devid]; | 1881 | iommu = amd_iommu_rlookup_table[devid]; |
| 1645 | if (!iommu) | 1882 | if (!iommu) |
| 1646 | continue; | 1883 | continue; |
| 1647 | dma_dom = dma_ops_domain_alloc(iommu, order); | 1884 | dma_dom = dma_ops_domain_alloc(iommu); |
| 1648 | if (!dma_dom) | 1885 | if (!dma_dom) |
| 1649 | continue; | 1886 | continue; |
| 1650 | init_unity_mappings_for_device(dma_dom, devid); | 1887 | init_unity_mappings_for_device(dma_dom, devid); |
| @@ -1670,7 +1907,6 @@ static struct dma_map_ops amd_iommu_dma_ops = { | |||
| 1670 | int __init amd_iommu_init_dma_ops(void) | 1907 | int __init amd_iommu_init_dma_ops(void) |
| 1671 | { | 1908 | { |
| 1672 | struct amd_iommu *iommu; | 1909 | struct amd_iommu *iommu; |
| 1673 | int order = amd_iommu_aperture_order; | ||
| 1674 | int ret; | 1910 | int ret; |
| 1675 | 1911 | ||
| 1676 | /* | 1912 | /* |
| @@ -1678,8 +1914,8 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 1678 | * found in the system. Devices not assigned to any other | 1914 | * found in the system. Devices not assigned to any other |
| 1679 | * protection domain will be assigned to the default one. | 1915 | * protection domain will be assigned to the default one. |
| 1680 | */ | 1916 | */ |
| 1681 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1917 | for_each_iommu(iommu) { |
| 1682 | iommu->default_dom = dma_ops_domain_alloc(iommu, order); | 1918 | iommu->default_dom = dma_ops_domain_alloc(iommu); |
| 1683 | if (iommu->default_dom == NULL) | 1919 | if (iommu->default_dom == NULL) |
| 1684 | return -ENOMEM; | 1920 | return -ENOMEM; |
| 1685 | iommu->default_dom->domain.flags |= PD_DEFAULT_MASK; | 1921 | iommu->default_dom->domain.flags |= PD_DEFAULT_MASK; |
| @@ -1716,7 +1952,7 @@ int __init amd_iommu_init_dma_ops(void) | |||
| 1716 | 1952 | ||
| 1717 | free_domains: | 1953 | free_domains: |
| 1718 | 1954 | ||
| 1719 | list_for_each_entry(iommu, &amd_iommu_list, list) { | 1955 | for_each_iommu(iommu) { |
| 1720 | if (iommu->default_dom) | 1956 | if (iommu->default_dom) |
| 1721 | dma_ops_domain_free(iommu->default_dom); | 1957 | dma_ops_domain_free(iommu->default_dom); |
| 1722 | } | 1958 | } |
