at v4.10 4.4 kB view raw
1/* 2 * Copyright(c) 2015 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 */ 13#ifndef __PMEM_H__ 14#define __PMEM_H__ 15 16#include <linux/io.h> 17#include <linux/uio.h> 18 19#ifdef CONFIG_ARCH_HAS_PMEM_API 20#define ARCH_MEMREMAP_PMEM MEMREMAP_WB 21#include <asm/pmem.h> 22#else 23#define ARCH_MEMREMAP_PMEM MEMREMAP_WT 24/* 25 * These are simply here to enable compilation, all call sites gate 26 * calling these symbols with arch_has_pmem_api() and redirect to the 27 * implementation in asm/pmem.h. 28 */ 29static inline void arch_memcpy_to_pmem(void *dst, const void *src, size_t n) 30{ 31 BUG(); 32} 33 34static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n) 35{ 36 BUG(); 37 return -EFAULT; 38} 39 40static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, 41 struct iov_iter *i) 42{ 43 BUG(); 44 return 0; 45} 46 47static inline void arch_clear_pmem(void *addr, size_t size) 48{ 49 BUG(); 50} 51 52static inline void arch_wb_cache_pmem(void *addr, size_t size) 53{ 54 BUG(); 55} 56 57static inline void arch_invalidate_pmem(void *addr, size_t size) 58{ 59 BUG(); 60} 61#endif 62 63static inline bool arch_has_pmem_api(void) 64{ 65 return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API); 66} 67 68/* 69 * memcpy_from_pmem - read from persistent memory with error handling 70 * @dst: destination buffer 71 * @src: source buffer 72 * @size: transfer length 73 * 74 * Returns 0 on success negative error code on failure. 75 */ 76static inline int memcpy_from_pmem(void *dst, void const *src, size_t size) 77{ 78 if (arch_has_pmem_api()) 79 return arch_memcpy_from_pmem(dst, src, size); 80 else 81 memcpy(dst, src, size); 82 return 0; 83} 84 85/** 86 * memcpy_to_pmem - copy data to persistent memory 87 * @dst: destination buffer for the copy 88 * @src: source buffer for the copy 89 * @n: length of the copy in bytes 90 * 91 * Perform a memory copy that results in the destination of the copy 92 * being effectively evicted from, or never written to, the processor 93 * cache hierarchy after the copy completes. After memcpy_to_pmem() 94 * data may still reside in cpu or platform buffers, so this operation 95 * must be followed by a blkdev_issue_flush() on the pmem block device. 96 */ 97static inline void memcpy_to_pmem(void *dst, const void *src, size_t n) 98{ 99 if (arch_has_pmem_api()) 100 arch_memcpy_to_pmem(dst, src, n); 101 else 102 memcpy(dst, src, n); 103} 104 105/** 106 * copy_from_iter_pmem - copy data from an iterator to PMEM 107 * @addr: PMEM destination address 108 * @bytes: number of bytes to copy 109 * @i: iterator with source data 110 * 111 * Copy data from the iterator 'i' to the PMEM buffer starting at 'addr'. 112 * See blkdev_issue_flush() note for memcpy_to_pmem(). 113 */ 114static inline size_t copy_from_iter_pmem(void *addr, size_t bytes, 115 struct iov_iter *i) 116{ 117 if (arch_has_pmem_api()) 118 return arch_copy_from_iter_pmem(addr, bytes, i); 119 return copy_from_iter_nocache(addr, bytes, i); 120} 121 122/** 123 * clear_pmem - zero a PMEM memory range 124 * @addr: virtual start address 125 * @size: number of bytes to zero 126 * 127 * Write zeros into the memory range starting at 'addr' for 'size' bytes. 128 * See blkdev_issue_flush() note for memcpy_to_pmem(). 129 */ 130static inline void clear_pmem(void *addr, size_t size) 131{ 132 if (arch_has_pmem_api()) 133 arch_clear_pmem(addr, size); 134 else 135 memset(addr, 0, size); 136} 137 138/** 139 * invalidate_pmem - flush a pmem range from the cache hierarchy 140 * @addr: virtual start address 141 * @size: bytes to invalidate (internally aligned to cache line size) 142 * 143 * For platforms that support clearing poison this flushes any poisoned 144 * ranges out of the cache 145 */ 146static inline void invalidate_pmem(void *addr, size_t size) 147{ 148 if (arch_has_pmem_api()) 149 arch_invalidate_pmem(addr, size); 150} 151 152/** 153 * wb_cache_pmem - write back processor cache for PMEM memory range 154 * @addr: virtual start address 155 * @size: number of bytes to write back 156 * 157 * Write back the processor cache range starting at 'addr' for 'size' bytes. 158 * See blkdev_issue_flush() note for memcpy_to_pmem(). 159 */ 160static inline void wb_cache_pmem(void *addr, size_t size) 161{ 162 if (arch_has_pmem_api()) 163 arch_wb_cache_pmem(addr, size); 164} 165#endif /* __PMEM_H__ */