.. | .. |
---|
1 | | -/** |
---|
| 1 | +/* |
---|
2 | 2 | * \file drm_memory.c |
---|
3 | 3 | * Memory management wrappers for DRM |
---|
4 | 4 | * |
---|
.. | .. |
---|
33 | 33 | * OTHER DEALINGS IN THE SOFTWARE. |
---|
34 | 34 | */ |
---|
35 | 35 | |
---|
36 | | -#include <linux/highmem.h> |
---|
37 | 36 | #include <linux/export.h> |
---|
38 | | -#include <drm/drmP.h> |
---|
| 37 | +#include <linux/highmem.h> |
---|
| 38 | +#include <linux/pci.h> |
---|
| 39 | +#include <linux/vmalloc.h> |
---|
| 40 | +#include <xen/xen.h> |
---|
| 41 | + |
---|
| 42 | +#include <drm/drm_agpsupport.h> |
---|
| 43 | +#include <drm/drm_cache.h> |
---|
| 44 | +#include <drm/drm_device.h> |
---|
| 45 | + |
---|
39 | 46 | #include "drm_legacy.h" |
---|
40 | 47 | |
---|
41 | 48 | #if IS_ENABLED(CONFIG_AGP) |
---|
.. | .. |
---|
51 | 58 | #endif |
---|
52 | 59 | |
---|
53 | 60 | static void *agp_remap(unsigned long offset, unsigned long size, |
---|
54 | | - struct drm_device * dev) |
---|
| 61 | + struct drm_device *dev) |
---|
55 | 62 | { |
---|
56 | 63 | unsigned long i, num_pages = |
---|
57 | 64 | PAGE_ALIGN(size) / PAGE_SIZE; |
---|
.. | .. |
---|
94 | 101 | } |
---|
95 | 102 | |
---|
96 | 103 | /** Wrapper around agp_free_memory() */ |
---|
97 | | -void drm_free_agp(struct agp_memory * handle, int pages) |
---|
| 104 | +void drm_free_agp(struct agp_memory *handle, int pages) |
---|
98 | 105 | { |
---|
99 | 106 | agp_free_memory(handle); |
---|
100 | 107 | } |
---|
101 | 108 | |
---|
102 | 109 | /** Wrapper around agp_bind_memory() */ |
---|
103 | | -int drm_bind_agp(struct agp_memory * handle, unsigned int start) |
---|
| 110 | +int drm_bind_agp(struct agp_memory *handle, unsigned int start) |
---|
104 | 111 | { |
---|
105 | 112 | return agp_bind_memory(handle, start); |
---|
106 | 113 | } |
---|
107 | 114 | |
---|
108 | 115 | /** Wrapper around agp_unbind_memory() */ |
---|
109 | | -int drm_unbind_agp(struct agp_memory * handle) |
---|
| 116 | +int drm_unbind_agp(struct agp_memory *handle) |
---|
110 | 117 | { |
---|
111 | 118 | return agp_unbind_memory(handle); |
---|
112 | 119 | } |
---|
113 | 120 | |
---|
114 | 121 | #else /* CONFIG_AGP */ |
---|
115 | 122 | static inline void *agp_remap(unsigned long offset, unsigned long size, |
---|
116 | | - struct drm_device * dev) |
---|
| 123 | + struct drm_device *dev) |
---|
117 | 124 | { |
---|
118 | 125 | return NULL; |
---|
119 | 126 | } |
---|
.. | .. |
---|
150 | 157 | } |
---|
151 | 158 | EXPORT_SYMBOL(drm_legacy_ioremapfree); |
---|
152 | 159 | |
---|
153 | | -u64 drm_get_max_iomem(void) |
---|
| 160 | +bool drm_need_swiotlb(int dma_bits) |
---|
154 | 161 | { |
---|
155 | 162 | struct resource *tmp; |
---|
156 | 163 | resource_size_t max_iomem = 0; |
---|
| 164 | + |
---|
| 165 | + /* |
---|
| 166 | + * Xen paravirtual hosts require swiotlb regardless of requested dma |
---|
| 167 | + * transfer size. |
---|
| 168 | + * |
---|
| 169 | + * NOTE: Really, what it requires is use of the dma_alloc_coherent |
---|
| 170 | + * allocator used in ttm_dma_populate() instead of |
---|
| 171 | + * ttm_populate_and_map_pages(), which bounce buffers so much in |
---|
| 172 | + * Xen it leads to swiotlb buffer exhaustion. |
---|
| 173 | + */ |
---|
| 174 | + if (xen_pv_domain()) |
---|
| 175 | + return true; |
---|
| 176 | + |
---|
| 177 | + /* |
---|
| 178 | + * Enforce dma_alloc_coherent when memory encryption is active as well |
---|
| 179 | + * for the same reasons as for Xen paravirtual hosts. |
---|
| 180 | + */ |
---|
| 181 | + if (mem_encrypt_active()) |
---|
| 182 | + return true; |
---|
157 | 183 | |
---|
158 | 184 | for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) { |
---|
159 | 185 | max_iomem = max(max_iomem, tmp->end); |
---|
160 | 186 | } |
---|
161 | 187 | |
---|
162 | | - return max_iomem; |
---|
| 188 | + return max_iomem > ((u64)1 << dma_bits); |
---|
163 | 189 | } |
---|
164 | | -EXPORT_SYMBOL(drm_get_max_iomem); |
---|
| 190 | +EXPORT_SYMBOL(drm_need_swiotlb); |
---|