Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

swiotlb: add a SWIOTLB_ANY flag to lift the low memory restriction

Power SVM wants to allocate a swiotlb buffer that is not restricted to
low memory for the trusted hypervisor scheme. Consolidate the support
for this into the swiotlb_init interface by adding a new flag.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tested-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>

+14 -35
-4
arch/powerpc/include/asm/svm.h
··· 15 15 return mfmsr() & MSR_S; 16 16 } 17 17 18 - void __init svm_swiotlb_init(void); 19 - 20 18 void dtl_cache_ctor(void *addr); 21 19 #define get_dtl_cache_ctor() (is_secure_guest() ? dtl_cache_ctor : NULL) 22 20 ··· 24 26 { 25 27 return false; 26 28 } 27 - 28 - static inline void svm_swiotlb_init(void) {} 29 29 30 30 #define get_dtl_cache_ctor() NULL 31 31
+1
arch/powerpc/include/asm/swiotlb.h
··· 9 9 #include <linux/swiotlb.h> 10 10 11 11 extern unsigned int ppc_swiotlb_enable; 12 + extern unsigned int ppc_swiotlb_flags; 12 13 13 14 #ifdef CONFIG_SWIOTLB 14 15 void swiotlb_detect_4g(void);
+1
arch/powerpc/kernel/dma-swiotlb.c
··· 10 10 #include <asm/swiotlb.h> 11 11 12 12 unsigned int ppc_swiotlb_enable; 13 + unsigned int ppc_swiotlb_flags; 13 14 14 15 void __init swiotlb_detect_4g(void) 15 16 {
+1 -4
arch/powerpc/mm/mem.c
··· 249 249 * back to to-down. 250 250 */ 251 251 memblock_set_bottom_up(true); 252 - if (is_secure_guest()) 253 - svm_swiotlb_init(); 254 - else 255 - swiotlb_init(ppc_swiotlb_enable, 0); 252 + swiotlb_init(ppc_swiotlb_enable, ppc_swiotlb_flags); 256 253 #endif 257 254 258 255 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+1 -25
arch/powerpc/platforms/pseries/svm.c
··· 28 28 * need to use the SWIOTLB buffer for DMA even if dma_capable() says 29 29 * otherwise. 30 30 */ 31 - swiotlb_force = SWIOTLB_FORCE; 31 + ppc_swiotlb_flags |= SWIOTLB_ANY | SWIOTLB_FORCE; 32 32 33 33 /* Share the SWIOTLB buffer with the host. */ 34 34 swiotlb_update_mem_attributes(); ··· 36 36 return 0; 37 37 } 38 38 machine_early_initcall(pseries, init_svm); 39 - 40 - /* 41 - * Initialize SWIOTLB. Essentially the same as swiotlb_init(), except that it 42 - * can allocate the buffer anywhere in memory. Since the hypervisor doesn't have 43 - * any addressing limitation, we don't need to allocate it in low addresses. 44 - */ 45 - void __init svm_swiotlb_init(void) 46 - { 47 - unsigned char *vstart; 48 - unsigned long bytes, io_tlb_nslabs; 49 - 50 - io_tlb_nslabs = (swiotlb_size_or_default() >> IO_TLB_SHIFT); 51 - io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); 52 - 53 - bytes = io_tlb_nslabs << IO_TLB_SHIFT; 54 - 55 - vstart = memblock_alloc(PAGE_ALIGN(bytes), PAGE_SIZE); 56 - if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, false)) 57 - return; 58 - 59 - 60 - memblock_free(vstart, PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); 61 - panic("SVM: Cannot allocate SWIOTLB buffer"); 62 - } 63 39 64 40 int set_memory_encrypted(unsigned long addr, int numpages) 65 41 {
+1
include/linux/swiotlb.h
··· 15 15 16 16 #define SWIOTLB_VERBOSE (1 << 0) /* verbose initialization */ 17 17 #define SWIOTLB_FORCE (1 << 1) /* force bounce buffering */ 18 + #define SWIOTLB_ANY (1 << 2) /* allow any memory for the buffer */ 18 19 19 20 /* 20 21 * Maximum allowable number of contiguous slabs to map,
+9 -2
kernel/dma/swiotlb.c
··· 266 266 if (swiotlb_force_disable) 267 267 return; 268 268 269 - /* Get IO TLB memory from the low pages */ 270 - tlb = memblock_alloc_low(bytes, PAGE_SIZE); 269 + /* 270 + * By default allocate the bounce buffer memory from low memory, but 271 + * allow to pick a location everywhere for hypervisors with guest 272 + * memory encryption. 273 + */ 274 + if (flags & SWIOTLB_ANY) 275 + tlb = memblock_alloc(bytes, PAGE_SIZE); 276 + else 277 + tlb = memblock_alloc_low(bytes, PAGE_SIZE); 271 278 if (!tlb) 272 279 goto fail; 273 280 if (swiotlb_init_with_tbl(tlb, default_nslabs, flags))