![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-or-later */ 0002 /* 0003 * Copyright 2013 Red Hat Inc. 0004 * 0005 * Authors: Jérôme Glisse <jglisse@redhat.com> 0006 * 0007 * See Documentation/mm/hmm.rst for reasons and overview of what HMM is. 0008 */ 0009 #ifndef LINUX_HMM_H 0010 #define LINUX_HMM_H 0011 0012 #include <linux/mm.h> 0013 0014 struct mmu_interval_notifier; 0015 0016 /* 0017 * On output: 0018 * 0 - The page is faultable and a future call with 0019 * HMM_PFN_REQ_FAULT could succeed. 0020 * HMM_PFN_VALID - the pfn field points to a valid PFN. This PFN is at 0021 * least readable. If dev_private_owner is !NULL then this could 0022 * point at a DEVICE_PRIVATE page. 0023 * HMM_PFN_WRITE - if the page memory can be written to (requires HMM_PFN_VALID) 0024 * HMM_PFN_ERROR - accessing the pfn is impossible and the device should 0025 * fail. ie poisoned memory, special pages, no vma, etc 0026 * 0027 * On input: 0028 * 0 - Return the current state of the page, do not fault it. 0029 * HMM_PFN_REQ_FAULT - The output must have HMM_PFN_VALID or hmm_range_fault() 0030 * will fail 0031 * HMM_PFN_REQ_WRITE - The output must have HMM_PFN_WRITE or hmm_range_fault() 0032 * will fail. Must be combined with HMM_PFN_REQ_FAULT. 0033 */ 0034 enum hmm_pfn_flags { 0035 /* Output fields and flags */ 0036 HMM_PFN_VALID = 1UL << (BITS_PER_LONG - 1), 0037 HMM_PFN_WRITE = 1UL << (BITS_PER_LONG - 2), 0038 HMM_PFN_ERROR = 1UL << (BITS_PER_LONG - 3), 0039 HMM_PFN_ORDER_SHIFT = (BITS_PER_LONG - 8), 0040 0041 /* Input flags */ 0042 HMM_PFN_REQ_FAULT = HMM_PFN_VALID, 0043 HMM_PFN_REQ_WRITE = HMM_PFN_WRITE, 0044 0045 HMM_PFN_FLAGS = 0xFFUL << HMM_PFN_ORDER_SHIFT, 0046 }; 0047 0048 /* 0049 * hmm_pfn_to_page() - return struct page pointed to by a device entry 0050 * 0051 * This must be called under the caller 'user_lock' after a successful 0052 * mmu_interval_read_begin(). The caller must have tested for HMM_PFN_VALID 0053 * already. 0054 */ 0055 static inline struct page *hmm_pfn_to_page(unsigned long hmm_pfn) 0056 { 0057 return pfn_to_page(hmm_pfn & ~HMM_PFN_FLAGS); 0058 } 0059 0060 /* 0061 * hmm_pfn_to_map_order() - return the CPU mapping size order 0062 * 0063 * This is optionally useful to optimize processing of the pfn result 0064 * array. It indicates that the page starts at the order aligned VA and is 0065 * 1<<order bytes long. Every pfn within an high order page will have the 0066 * same pfn flags, both access protections and the map_order. The caller must 0067 * be careful with edge cases as the start and end VA of the given page may 0068 * extend past the range used with hmm_range_fault(). 0069 * 0070 * This must be called under the caller 'user_lock' after a successful 0071 * mmu_interval_read_begin(). The caller must have tested for HMM_PFN_VALID 0072 * already. 0073 */ 0074 static inline unsigned int hmm_pfn_to_map_order(unsigned long hmm_pfn) 0075 { 0076 return (hmm_pfn >> HMM_PFN_ORDER_SHIFT) & 0x1F; 0077 } 0078 0079 /* 0080 * struct hmm_range - track invalidation lock on virtual address range 0081 * 0082 * @notifier: a mmu_interval_notifier that includes the start/end 0083 * @notifier_seq: result of mmu_interval_read_begin() 0084 * @start: range virtual start address (inclusive) 0085 * @end: range virtual end address (exclusive) 0086 * @hmm_pfns: array of pfns (big enough for the range) 0087 * @default_flags: default flags for the range (write, read, ... see hmm doc) 0088 * @pfn_flags_mask: allows to mask pfn flags so that only default_flags matter 0089 * @dev_private_owner: owner of device private pages 0090 */ 0091 struct hmm_range { 0092 struct mmu_interval_notifier *notifier; 0093 unsigned long notifier_seq; 0094 unsigned long start; 0095 unsigned long end; 0096 unsigned long *hmm_pfns; 0097 unsigned long default_flags; 0098 unsigned long pfn_flags_mask; 0099 void *dev_private_owner; 0100 }; 0101 0102 /* 0103 * Please see Documentation/mm/hmm.rst for how to use the range API. 0104 */ 0105 int hmm_range_fault(struct hmm_range *range); 0106 0107 /* 0108 * HMM_RANGE_DEFAULT_TIMEOUT - default timeout (ms) when waiting for a range 0109 * 0110 * When waiting for mmu notifiers we need some kind of time out otherwise we 0111 * could potentially wait for ever, 1000ms ie 1s sounds like a long time to 0112 * wait already. 0113 */ 0114 #define HMM_RANGE_DEFAULT_TIMEOUT 1000 0115 0116 #endif /* LINUX_HMM_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |