diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/hmm.h | 4 | ||||
| -rw-r--r-- | include/linux/ioport.h | 1 | ||||
| -rw-r--r-- | include/linux/memremap.h | 21 | ||||
| -rw-r--r-- | include/linux/mm.h | 20 |
4 files changed, 36 insertions, 10 deletions
diff --git a/include/linux/hmm.h b/include/linux/hmm.h index 67a03b20a2db..6d3b0b4fed4e 100644 --- a/include/linux/hmm.h +++ b/include/linux/hmm.h | |||
| @@ -327,7 +327,7 @@ int hmm_vma_fault(struct vm_area_struct *vma, | |||
| 327 | #endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ | 327 | #endif /* IS_ENABLED(CONFIG_HMM_MIRROR) */ |
| 328 | 328 | ||
| 329 | 329 | ||
| 330 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) | 330 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC) |
| 331 | struct hmm_devmem; | 331 | struct hmm_devmem; |
| 332 | 332 | ||
| 333 | struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma, | 333 | struct page *hmm_vma_alloc_locked_page(struct vm_area_struct *vma, |
| @@ -494,7 +494,7 @@ struct hmm_device { | |||
| 494 | */ | 494 | */ |
| 495 | struct hmm_device *hmm_device_new(void *drvdata); | 495 | struct hmm_device *hmm_device_new(void *drvdata); |
| 496 | void hmm_device_put(struct hmm_device *hmm_device); | 496 | void hmm_device_put(struct hmm_device *hmm_device); |
| 497 | #endif /* IS_ENABLED(CONFIG_DEVICE_PRIVATE) */ | 497 | #endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ |
| 498 | 498 | ||
| 499 | 499 | ||
| 500 | /* Below are for HMM internal use only! Not to be used by device driver! */ | 500 | /* Below are for HMM internal use only! Not to be used by device driver! */ |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 3a4f69137bc2..f5cf32e80041 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
| @@ -131,6 +131,7 @@ enum { | |||
| 131 | IORES_DESC_PERSISTENT_MEMORY = 4, | 131 | IORES_DESC_PERSISTENT_MEMORY = 4, |
| 132 | IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5, | 132 | IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5, |
| 133 | IORES_DESC_DEVICE_PRIVATE_MEMORY = 6, | 133 | IORES_DESC_DEVICE_PRIVATE_MEMORY = 6, |
| 134 | IORES_DESC_DEVICE_PUBLIC_MEMORY = 7, | ||
| 134 | }; | 135 | }; |
| 135 | 136 | ||
| 136 | /* helpers to define resources */ | 137 | /* helpers to define resources */ |
diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 8aa6b82679e2..f8ee1c73ad2d 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h | |||
| @@ -57,10 +57,18 @@ static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start) | |||
| 57 | * | 57 | * |
| 58 | * A more complete discussion of unaddressable memory may be found in | 58 | * A more complete discussion of unaddressable memory may be found in |
| 59 | * include/linux/hmm.h and Documentation/vm/hmm.txt. | 59 | * include/linux/hmm.h and Documentation/vm/hmm.txt. |
| 60 | * | ||
| 61 | * MEMORY_DEVICE_PUBLIC: | ||
| 62 | * Device memory that is cache coherent from device and CPU point of view. This | ||
| 63 | * is use on platform that have an advance system bus (like CAPI or CCIX). A | ||
| 64 | * driver can hotplug the device memory using ZONE_DEVICE and with that memory | ||
| 65 | * type. Any page of a process can be migrated to such memory. However no one | ||
| 66 | * should be allow to pin such memory so that it can always be evicted. | ||
| 60 | */ | 67 | */ |
| 61 | enum memory_type { | 68 | enum memory_type { |
| 62 | MEMORY_DEVICE_HOST = 0, | 69 | MEMORY_DEVICE_HOST = 0, |
| 63 | MEMORY_DEVICE_PRIVATE, | 70 | MEMORY_DEVICE_PRIVATE, |
| 71 | MEMORY_DEVICE_PUBLIC, | ||
| 64 | }; | 72 | }; |
| 65 | 73 | ||
| 66 | /* | 74 | /* |
| @@ -92,6 +100,8 @@ enum memory_type { | |||
| 92 | * The page_free() callback is called once the page refcount reaches 1 | 100 | * The page_free() callback is called once the page refcount reaches 1 |
| 93 | * (ZONE_DEVICE pages never reach 0 refcount unless there is a refcount bug. | 101 | * (ZONE_DEVICE pages never reach 0 refcount unless there is a refcount bug. |
| 94 | * This allows the device driver to implement its own memory management.) | 102 | * This allows the device driver to implement its own memory management.) |
| 103 | * | ||
| 104 | * For MEMORY_DEVICE_PUBLIC only the page_free() callback matter. | ||
| 95 | */ | 105 | */ |
| 96 | typedef int (*dev_page_fault_t)(struct vm_area_struct *vma, | 106 | typedef int (*dev_page_fault_t)(struct vm_area_struct *vma, |
| 97 | unsigned long addr, | 107 | unsigned long addr, |
| @@ -134,6 +144,12 @@ static inline bool is_device_private_page(const struct page *page) | |||
| 134 | return is_zone_device_page(page) && | 144 | return is_zone_device_page(page) && |
| 135 | page->pgmap->type == MEMORY_DEVICE_PRIVATE; | 145 | page->pgmap->type == MEMORY_DEVICE_PRIVATE; |
| 136 | } | 146 | } |
| 147 | |||
| 148 | static inline bool is_device_public_page(const struct page *page) | ||
| 149 | { | ||
| 150 | return is_zone_device_page(page) && | ||
| 151 | page->pgmap->type == MEMORY_DEVICE_PUBLIC; | ||
| 152 | } | ||
| 137 | #else | 153 | #else |
| 138 | static inline void *devm_memremap_pages(struct device *dev, | 154 | static inline void *devm_memremap_pages(struct device *dev, |
| 139 | struct resource *res, struct percpu_ref *ref, | 155 | struct resource *res, struct percpu_ref *ref, |
| @@ -157,6 +173,11 @@ static inline bool is_device_private_page(const struct page *page) | |||
| 157 | { | 173 | { |
| 158 | return false; | 174 | return false; |
| 159 | } | 175 | } |
| 176 | |||
| 177 | static inline bool is_device_public_page(const struct page *page) | ||
| 178 | { | ||
| 179 | return false; | ||
| 180 | } | ||
| 160 | #endif | 181 | #endif |
| 161 | 182 | ||
| 162 | /** | 183 | /** |
diff --git a/include/linux/mm.h b/include/linux/mm.h index eccdab4bb44a..de66a1127db4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -800,15 +800,16 @@ static inline bool is_zone_device_page(const struct page *page) | |||
| 800 | } | 800 | } |
| 801 | #endif | 801 | #endif |
| 802 | 802 | ||
| 803 | #ifdef CONFIG_DEVICE_PRIVATE | 803 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC) |
| 804 | void put_zone_device_private_page(struct page *page); | 804 | void put_zone_device_private_or_public_page(struct page *page); |
| 805 | #else | 805 | #else |
| 806 | static inline void put_zone_device_private_page(struct page *page) | 806 | static inline void put_zone_device_private_or_public_page(struct page *page) |
| 807 | { | 807 | { |
| 808 | } | 808 | } |
| 809 | #endif | 809 | #endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */ |
| 810 | 810 | ||
| 811 | static inline bool is_device_private_page(const struct page *page); | 811 | static inline bool is_device_private_page(const struct page *page); |
| 812 | static inline bool is_device_public_page(const struct page *page); | ||
| 812 | 813 | ||
| 813 | DECLARE_STATIC_KEY_FALSE(device_private_key); | 814 | DECLARE_STATIC_KEY_FALSE(device_private_key); |
| 814 | 815 | ||
| @@ -834,8 +835,9 @@ static inline void put_page(struct page *page) | |||
| 834 | * include/linux/memremap.h and HMM for details. | 835 | * include/linux/memremap.h and HMM for details. |
| 835 | */ | 836 | */ |
| 836 | if (static_branch_unlikely(&device_private_key) && | 837 | if (static_branch_unlikely(&device_private_key) && |
| 837 | unlikely(is_device_private_page(page))) { | 838 | unlikely(is_device_private_page(page) || |
| 838 | put_zone_device_private_page(page); | 839 | is_device_public_page(page))) { |
| 840 | put_zone_device_private_or_public_page(page); | ||
| 839 | return; | 841 | return; |
| 840 | } | 842 | } |
| 841 | 843 | ||
| @@ -1224,8 +1226,10 @@ struct zap_details { | |||
| 1224 | pgoff_t last_index; /* Highest page->index to unmap */ | 1226 | pgoff_t last_index; /* Highest page->index to unmap */ |
| 1225 | }; | 1227 | }; |
| 1226 | 1228 | ||
| 1227 | struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, | 1229 | struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr, |
| 1228 | pte_t pte); | 1230 | pte_t pte, bool with_public_device); |
| 1231 | #define vm_normal_page(vma, addr, pte) _vm_normal_page(vma, addr, pte, false) | ||
| 1232 | |||
| 1229 | struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, | 1233 | struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, |
| 1230 | pmd_t pmd); | 1234 | pmd_t pmd); |
| 1231 | 1235 | ||
