hmm.c (9f454612f602d02204b1f6e86b6bec2bfb368c4b) | hmm.c (25f23a0c7127b65c4d8200ccda8a352ad5ce1e1d) |
---|---|
1/* 2 * Copyright 2013 Red Hat Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 688 unchanged lines hidden (view full) --- 697{ 698 unsigned long addr = range->start, i = 0; 699 700 for (; addr < range->end; addr += PAGE_SIZE, i++) 701 range->pfns[i] = range->values[HMM_PFN_SPECIAL]; 702} 703 704/* | 1/* 2 * Copyright 2013 Red Hat Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 688 unchanged lines hidden (view full) --- 697{ 698 unsigned long addr = range->start, i = 0; 699 700 for (; addr < range->end; addr += PAGE_SIZE, i++) 701 range->pfns[i] = range->values[HMM_PFN_SPECIAL]; 702} 703 704/* |
705 * hmm_vma_get_pfns() - snapshot CPU page table for a range of virtual addresses 706 * @range: range being snapshotted 707 * Returns: -EINVAL if invalid argument, -ENOMEM out of memory, -EPERM invalid 708 * vma permission, 0 success | 705 * hmm_range_snapshot() - snapshot CPU page table for a range 706 * @range: range 707 * Returns: number of valid pages in range->pfns[] (from range start 708 * address). This may be zero. If the return value is negative, 709 * then one of the following values may be returned: |
709 * | 710 * |
711 * -EINVAL invalid arguments or mm or virtual address are in an 712 * invalid vma (ie either hugetlbfs or device file vma). 713 * -EPERM For example, asking for write, when the range is 714 * read-only 715 * -EAGAIN Caller needs to retry 716 * -EFAULT Either no valid vma exists for this range, or it is 717 * illegal to access the range 718 * |
|
710 * This snapshots the CPU page table for a range of virtual addresses. Snapshot 711 * validity is tracked by range struct. See hmm_vma_range_done() for further 712 * information. | 719 * This snapshots the CPU page table for a range of virtual addresses. Snapshot 720 * validity is tracked by range struct. See hmm_vma_range_done() for further 721 * information. |
713 * 714 * The range struct is initialized here. It tracks the CPU page table, but only 715 * if the function returns success (0), in which case the caller must then call 716 * hmm_vma_range_done() to stop CPU page table update tracking on this range. 717 * 718 * NOT CALLING hmm_vma_range_done() IF FUNCTION RETURNS 0 WILL LEAD TO SERIOUS 719 * MEMORY CORRUPTION ! YOU HAVE BEEN WARNED ! | |
720 */ | 722 */ |
721int hmm_vma_get_pfns(struct hmm_range *range) | 723long hmm_range_snapshot(struct hmm_range *range) |
722{ 723 struct vm_area_struct *vma = range->vma; 724 struct hmm_vma_walk hmm_vma_walk; 725 struct mm_walk mm_walk; 726 struct hmm *hmm; 727 728 range->hmm = NULL; 729 --- 37 unchanged lines hidden (view full) --- 767 spin_lock(&hmm->lock); 768 range->valid = true; 769 list_add_rcu(&range->list, &hmm->ranges); 770 spin_unlock(&hmm->lock); 771 772 hmm_vma_walk.fault = false; 773 hmm_vma_walk.range = range; 774 mm_walk.private = &hmm_vma_walk; | 724{ 725 struct vm_area_struct *vma = range->vma; 726 struct hmm_vma_walk hmm_vma_walk; 727 struct mm_walk mm_walk; 728 struct hmm *hmm; 729 730 range->hmm = NULL; 731 --- 37 unchanged lines hidden (view full) --- 769 spin_lock(&hmm->lock); 770 range->valid = true; 771 list_add_rcu(&range->list, &hmm->ranges); 772 spin_unlock(&hmm->lock); 773 774 hmm_vma_walk.fault = false; 775 hmm_vma_walk.range = range; 776 mm_walk.private = &hmm_vma_walk; |
777 hmm_vma_walk.last = range->start; |
|
775 776 mm_walk.vma = vma; 777 mm_walk.mm = vma->vm_mm; 778 mm_walk.pte_entry = NULL; 779 mm_walk.test_walk = NULL; 780 mm_walk.hugetlb_entry = NULL; 781 mm_walk.pmd_entry = hmm_vma_walk_pmd; 782 mm_walk.pte_hole = hmm_vma_walk_hole; 783 784 walk_page_range(range->start, range->end, &mm_walk); 785 /* 786 * Transfer hmm reference to the range struct it will be drop inside 787 * the hmm_vma_range_done() function (which _must_ be call if this 788 * function return 0). 789 */ 790 range->hmm = hmm; | 778 779 mm_walk.vma = vma; 780 mm_walk.mm = vma->vm_mm; 781 mm_walk.pte_entry = NULL; 782 mm_walk.test_walk = NULL; 783 mm_walk.hugetlb_entry = NULL; 784 mm_walk.pmd_entry = hmm_vma_walk_pmd; 785 mm_walk.pte_hole = hmm_vma_walk_hole; 786 787 walk_page_range(range->start, range->end, &mm_walk); 788 /* 789 * Transfer hmm reference to the range struct it will be drop inside 790 * the hmm_vma_range_done() function (which _must_ be call if this 791 * function return 0). 792 */ 793 range->hmm = hmm; |
791 return 0; | 794 return (hmm_vma_walk.last - range->start) >> PAGE_SHIFT; |
792} | 795} |
793EXPORT_SYMBOL(hmm_vma_get_pfns); | 796EXPORT_SYMBOL(hmm_range_snapshot); |
794 795/* 796 * hmm_vma_range_done() - stop tracking change to CPU page table over a range 797 * @range: range being tracked 798 * Returns: false if range data has been invalidated, true otherwise 799 * 800 * Range struct is used to track updates to the CPU page table after a call to 801 * either hmm_vma_get_pfns() or hmm_vma_fault(). Once the device driver is done --- 487 unchanged lines hidden --- | 797 798/* 799 * hmm_vma_range_done() - stop tracking change to CPU page table over a range 800 * @range: range being tracked 801 * Returns: false if range data has been invalidated, true otherwise 802 * 803 * Range struct is used to track updates to the CPU page table after a call to 804 * either hmm_vma_get_pfns() or hmm_vma_fault(). Once the device driver is done --- 487 unchanged lines hidden --- |