aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJérôme Glisse <jglisse@redhat.com>2017-09-08 19:11:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-08 21:26:46 -0400
commitda4c3c735ea4dcc2a0b0ff0bd4803c336361b6f5 (patch)
tree147e824606045d05f0cc2965d8fc3f4fafeba7b7 /include/linux
parentc0b124054f9e42eb6da545a10fe9122a7d7c3f72 (diff)
mm/hmm/mirror: helper to snapshot CPU page table
This does not use existing page table walker because we want to share same code for our page fault handler. Link: http://lkml.kernel.org/r/20170817000548.32038-5-jglisse@redhat.com Signed-off-by: Jérôme Glisse <jglisse@redhat.com> Signed-off-by: Evgeny Baskakov <ebaskakov@nvidia.com> Signed-off-by: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Mark Hairgrove <mhairgrove@nvidia.com> Signed-off-by: Sherry Cheung <SCheung@nvidia.com> Signed-off-by: Subhash Gutti <sgutti@nvidia.com> Cc: Aneesh Kumar <aneesh.kumar@linux.vnet.ibm.com> Cc: Balbir Singh <bsingharora@gmail.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Dan Williams <dan.j.williams@intel.com> Cc: David Nellans <dnellans@nvidia.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Vladimir Davydov <vdavydov.dev@gmail.com> Cc: Bob Liu <liubo95@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/hmm.h55
1 files changed, 53 insertions, 2 deletions
diff --git a/include/linux/hmm.h b/include/linux/hmm.h
index 76310726ee9c..62899c9829c9 100644
--- a/include/linux/hmm.h
+++ b/include/linux/hmm.h
@@ -79,13 +79,26 @@ struct hmm;
79 * 79 *
80 * Flags: 80 * Flags:
81 * HMM_PFN_VALID: pfn is valid 81 * HMM_PFN_VALID: pfn is valid
82 * HMM_PFN_READ: CPU page table has read permission set
82 * HMM_PFN_WRITE: CPU page table has write permission set 83 * HMM_PFN_WRITE: CPU page table has write permission set
84 * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned memory
85 * HMM_PFN_EMPTY: corresponding CPU page table entry is pte_none()
86 * HMM_PFN_SPECIAL: corresponding CPU page table entry is special; i.e., the
87 * result of vm_insert_pfn() or vm_insert_page(). Therefore, it should not
88 * be mirrored by a device, because the entry will never have HMM_PFN_VALID
89 * set and the pfn value is undefined.
90 * HMM_PFN_DEVICE_UNADDRESSABLE: unaddressable device memory (ZONE_DEVICE)
83 */ 91 */
84typedef unsigned long hmm_pfn_t; 92typedef unsigned long hmm_pfn_t;
85 93
86#define HMM_PFN_VALID (1 << 0) 94#define HMM_PFN_VALID (1 << 0)
87#define HMM_PFN_WRITE (1 << 1) 95#define HMM_PFN_READ (1 << 1)
88#define HMM_PFN_SHIFT 2 96#define HMM_PFN_WRITE (1 << 2)
97#define HMM_PFN_ERROR (1 << 3)
98#define HMM_PFN_EMPTY (1 << 4)
99#define HMM_PFN_SPECIAL (1 << 5)
100#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 6)
101#define HMM_PFN_SHIFT 7
89 102
90/* 103/*
91 * hmm_pfn_t_to_page() - return struct page pointed to by a valid hmm_pfn_t 104 * hmm_pfn_t_to_page() - return struct page pointed to by a valid hmm_pfn_t
@@ -241,6 +254,44 @@ struct hmm_mirror {
241 254
242int hmm_mirror_register(struct hmm_mirror *mirror, struct mm_struct *mm); 255int hmm_mirror_register(struct hmm_mirror *mirror, struct mm_struct *mm);
243void hmm_mirror_unregister(struct hmm_mirror *mirror); 256void hmm_mirror_unregister(struct hmm_mirror *mirror);
257
258
259/*
260 * struct hmm_range - track invalidation lock on virtual address range
261 *
262 * @list: all range lock are on a list
263 * @start: range virtual start address (inclusive)
264 * @end: range virtual end address (exclusive)
265 * @pfns: array of pfns (big enough for the range)
266 * @valid: pfns array did not change since it has been fill by an HMM function
267 */
268struct hmm_range {
269 struct list_head list;
270 unsigned long start;
271 unsigned long end;
272 hmm_pfn_t *pfns;
273 bool valid;
274};
275
276/*
277 * To snapshot the CPU page table, call hmm_vma_get_pfns(), then take a device
278 * driver lock that serializes device page table updates, then call
279 * hmm_vma_range_done(), to check if the snapshot is still valid. The same
280 * device driver page table update lock must also be used in the
281 * hmm_mirror_ops.sync_cpu_device_pagetables() callback, so that CPU page
282 * table invalidation serializes on it.
283 *
284 * YOU MUST CALL hmm_vma_range_done() ONCE AND ONLY ONCE EACH TIME YOU CALL
285 * hmm_vma_get_pfns() WITHOUT ERROR !
286 *
287 * IF YOU DO NOT FOLLOW THE ABOVE RULE THE SNAPSHOT CONTENT MIGHT BE INVALID !
288 */
289int hmm_vma_get_pfns(struct vm_area_struct *vma,
290 struct hmm_range *range,
291 unsigned long start,
292 unsigned long end,
293 hmm_pfn_t *pfns);
294bool hmm_vma_range_done(struct vm_area_struct *vma, struct hmm_range *range);
244#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ 295#endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */
245 296
246 297