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

Configure Feed

Select the types of activity you want to include in your feed.

docs: nvdimm: convert to ReST

Rename the nvdimm documentation files to ReST, add an
index for them and adjust in order to produce a nice html
output via the Sphinx build system.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Acked-by: Dan Williams <dan.j.williams@intel.com>

+379 -281
+76 -64
Documentation/nvdimm/btt.txt Documentation/nvdimm/btt.rst
··· 1 + ============================= 1 2 BTT - Block Translation Table 2 3 ============================= 3 4 4 5 5 6 1. Introduction 6 - --------------- 7 + =============== 7 8 8 9 Persistent memory based storage is able to perform IO at byte (or more 9 10 accurately, cache line) granularity. However, we often want to expose such ··· 26 25 27 26 28 27 2. Static Layout 29 - ---------------- 28 + ================ 30 29 31 30 The underlying storage on which a BTT can be laid out is not limited in any way. 32 31 The BTT, however, splits the available space into chunks of up to 512 GiB, ··· 34 33 35 34 Each arena follows the same layout for its metadata, and all references in an 36 35 arena are internal to it (with the exception of one field that points to the 37 - next arena). The following depicts the "On-disk" metadata layout: 36 + next arena). The following depicts the "On-disk" metadata layout:: 38 37 39 38 40 - Backing Store +-------> Arena 41 - +---------------+ | +------------------+ 42 - | | | | Arena info block | 43 - | Arena 0 +---+ | 4K | 44 - | 512G | +------------------+ 45 - | | | | 46 - +---------------+ | | 47 - | | | | 48 - | Arena 1 | | Data Blocks | 49 - | 512G | | | 50 - | | | | 51 - +---------------+ | | 52 - | . | | | 53 - | . | | | 54 - | . | | | 55 - | | | | 56 - | | | | 57 - +---------------+ +------------------+ 58 - | | 59 - | BTT Map | 60 - | | 61 - | | 62 - +------------------+ 63 - | | 64 - | BTT Flog | 65 - | | 66 - +------------------+ 67 - | Info block copy | 68 - | 4K | 69 - +------------------+ 39 + Backing Store +-------> Arena 40 + +---------------+ | +------------------+ 41 + | | | | Arena info block | 42 + | Arena 0 +---+ | 4K | 43 + | 512G | +------------------+ 44 + | | | | 45 + +---------------+ | | 46 + | | | | 47 + | Arena 1 | | Data Blocks | 48 + | 512G | | | 49 + | | | | 50 + +---------------+ | | 51 + | . | | | 52 + | . | | | 53 + | . | | | 54 + | | | | 55 + | | | | 56 + +---------------+ +------------------+ 57 + | | 58 + | BTT Map | 59 + | | 60 + | | 61 + +------------------+ 62 + | | 63 + | BTT Flog | 64 + | | 65 + +------------------+ 66 + | Info block copy | 67 + | 4K | 68 + +------------------+ 70 69 71 70 72 71 3. Theory of Operation 73 - ---------------------- 72 + ====================== 74 73 75 74 76 75 a. The BTT Map ··· 80 79 block. Each map entry is 32 bits. The two most significant bits are special 81 80 flags, and the remaining form the internal block number. 82 81 82 + ======== ============================================================= 83 83 Bit Description 84 - 31 - 30 : Error and Zero flags - Used in the following way: 85 - Bit Description 86 - 31 30 87 - ----------------------------------------------------------------------- 88 - 00 Initial state. Reads return zeroes; Premap = Postmap 89 - 01 Zero state: Reads return zeroes 90 - 10 Error state: Reads fail; Writes clear 'E' bit 91 - 11 Normal Block – has valid postmap 84 + ======== ============================================================= 85 + 31 - 30 Error and Zero flags - Used in the following way: 92 86 87 + == == ==================================================== 88 + 31 30 Description 89 + == == ==================================================== 90 + 0 0 Initial state. Reads return zeroes; Premap = Postmap 91 + 0 1 Zero state: Reads return zeroes 92 + 1 0 Error state: Reads fail; Writes clear 'E' bit 93 + 1 1 Normal Block – has valid postmap 94 + == == ==================================================== 93 95 94 - 29 - 0 : Mappings to internal 'postmap' blocks 96 + 29 - 0 Mappings to internal 'postmap' blocks 97 + ======== ============================================================= 95 98 96 99 97 100 Some of the terminology that will be subsequently used: 98 101 99 - External LBA : LBA as made visible to upper layers. 100 - ABA : Arena Block Address - Block offset/number within an arena 101 - Premap ABA : The block offset into an arena, which was decided upon by range 102 + ============ ================================================================ 103 + External LBA LBA as made visible to upper layers. 104 + ABA Arena Block Address - Block offset/number within an arena 105 + Premap ABA The block offset into an arena, which was decided upon by range 102 106 checking the External LBA 103 - Postmap ABA : The block number in the "Data Blocks" area obtained after 107 + Postmap ABA The block number in the "Data Blocks" area obtained after 104 108 indirection from the map 105 - nfree : The number of free blocks that are maintained at any given time. 109 + nfree The number of free blocks that are maintained at any given time. 106 110 This is the number of concurrent writes that can happen to the 107 111 arena. 112 + ============ ================================================================ 108 113 109 114 110 115 For example, after adding a BTT, we surface a disk of 1024G. We get a read for ··· 128 121 maintained in the form of the BTT flog. 'Flog' is a combination of the words 129 122 "free list" and "log". The flog contains 'nfree' entries, and an entry contains: 130 123 131 - lba : The premap ABA that is being written to 132 - old_map : The old postmap ABA - after 'this' write completes, this will be a 124 + ======== ===================================================================== 125 + lba The premap ABA that is being written to 126 + old_map The old postmap ABA - after 'this' write completes, this will be a 133 127 free block. 134 - new_map : The new postmap ABA. The map will up updated to reflect this 128 + new_map The new postmap ABA. The map will up updated to reflect this 135 129 lba->postmap_aba mapping, but we log it here in case we have to 136 130 recover. 137 - seq : Sequence number to mark which of the 2 sections of this flog entry is 131 + seq Sequence number to mark which of the 2 sections of this flog entry is 138 132 valid/newest. It cycles between 01->10->11->01 (binary) under normal 139 133 operation, with 00 indicating an uninitialized state. 140 - lba' : alternate lba entry 141 - old_map': alternate old postmap entry 142 - new_map': alternate new postmap entry 143 - seq' : alternate sequence number. 134 + lba' alternate lba entry 135 + old_map' alternate old postmap entry 136 + new_map' alternate new postmap entry 137 + seq' alternate sequence number. 138 + ======== ===================================================================== 144 139 145 140 Each of the above fields is 32-bit, making one entry 32 bytes. Entries are also 146 141 padded to 64 bytes to avoid cache line sharing or aliasing. Flog updates are ··· 156 147 157 148 While 'nfree' describes the number of concurrent IOs an arena can process 158 149 concurrently, 'nlanes' is the number of IOs the BTT device as a whole can 159 - process. 160 - nlanes = min(nfree, num_cpus) 150 + process:: 151 + 152 + nlanes = min(nfree, num_cpus) 153 + 161 154 A lane number is obtained at the start of any IO, and is used for indexing into 162 155 all the on-disk and in-memory data structures for the duration of the IO. If 163 156 there are more CPUs than the max number of available lanes, than lanes are ··· 191 180 -------------------------------------- 192 181 193 182 Consider a case where two writer threads are writing to the same LBA. There can 194 - be a race in the following sequence of steps: 183 + be a race in the following sequence of steps:: 195 184 196 - free[lane] = map[premap_aba] 197 - map[premap_aba] = postmap_aba 185 + free[lane] = map[premap_aba] 186 + map[premap_aba] = postmap_aba 198 187 199 188 Both threads can update their respective free[lane] with the same old, freed 200 189 postmap_aba. This has made the layout inconsistent by losing a free entry, and ··· 213 202 through all the entries, and for each lane, of the set of two possible 214 203 'sections', we always look at the most recent one only (based on the sequence 215 204 number). The reconstruction rules/steps are simple: 205 + 216 206 - Read map[log_entry.lba]. 217 207 - If log_entry.new matches the map entry, then log_entry.old is free. 218 208 - If log_entry.new does not match the map entry, then log_entry.new is free. ··· 240 228 1. Convert external LBA to Arena number + pre-map ABA 241 229 2. Get a lane (and take lane_lock) 242 230 3. Use lane to index into in-memory free list and obtain a new block, next flog 243 - index, next sequence number 231 + index, next sequence number 244 232 4. Scan the RTT to check if free block is present, and spin/wait if it is. 245 233 5. Write data to this free block 246 234 6. Read map to get the existing post-map ABA entry for this pre-map ABA ··· 257 245 An arena would be in an error state if any of the metadata is corrupted 258 246 irrecoverably, either due to a bug or a media error. The following conditions 259 247 indicate an error: 248 + 260 249 - Info block checksum does not match (and recovering from the copy also fails) 261 250 - All internal available blocks are not uniquely and entirely addressed by the 262 251 sum of mapped blocks and free blocks (from the BTT flog). ··· 276 263 (pmem, or blk mode). The easiest way to set up such a namespace is using the 277 264 'ndctl' utility [1]: 278 265 279 - For example, the ndctl command line to setup a btt with a 4k sector size is: 266 + For example, the ndctl command line to setup a btt with a 4k sector size is:: 280 267 281 268 ndctl create-namespace -f -e namespace0.0 -m sector -l 4k 282 269 283 270 See ndctl create-namespace --help for more options. 284 271 285 272 [1]: https://github.com/pmem/ndctl 286 -
+12
Documentation/nvdimm/index.rst
··· 1 + :orphan: 2 + 3 + =================================== 4 + Non-Volatile Memory Device (NVDIMM) 5 + =================================== 6 + 7 + .. toctree:: 8 + :maxdepth: 1 9 + 10 + nvdimm 11 + btt 12 + security
+287 -215
Documentation/nvdimm/nvdimm.txt Documentation/nvdimm/nvdimm.rst
··· 1 - LIBNVDIMM: Non-Volatile Devices 2 - libnvdimm - kernel / libndctl - userspace helper library 3 - linux-nvdimm@lists.01.org 4 - v13 1 + =============================== 2 + LIBNVDIMM: Non-Volatile Devices 3 + =============================== 5 4 5 + libnvdimm - kernel / libndctl - userspace helper library 6 + 7 + linux-nvdimm@lists.01.org 8 + 9 + Version 13 10 + 11 + .. contents: 6 12 7 13 Glossary 8 14 Overview ··· 46 40 47 41 48 42 Glossary 49 - -------- 43 + ======== 50 44 51 - PMEM: A system-physical-address range where writes are persistent. A 52 - block device composed of PMEM is capable of DAX. A PMEM address range 53 - may span an interleave of several DIMMs. 45 + PMEM: 46 + A system-physical-address range where writes are persistent. A 47 + block device composed of PMEM is capable of DAX. A PMEM address range 48 + may span an interleave of several DIMMs. 54 49 55 - BLK: A set of one or more programmable memory mapped apertures provided 56 - by a DIMM to access its media. This indirection precludes the 57 - performance benefit of interleaving, but enables DIMM-bounded failure 58 - modes. 50 + BLK: 51 + A set of one or more programmable memory mapped apertures provided 52 + by a DIMM to access its media. This indirection precludes the 53 + performance benefit of interleaving, but enables DIMM-bounded failure 54 + modes. 59 55 60 - DPA: DIMM Physical Address, is a DIMM-relative offset. With one DIMM in 61 - the system there would be a 1:1 system-physical-address:DPA association. 62 - Once more DIMMs are added a memory controller interleave must be 63 - decoded to determine the DPA associated with a given 64 - system-physical-address. BLK capacity always has a 1:1 relationship 65 - with a single-DIMM's DPA range. 56 + DPA: 57 + DIMM Physical Address, is a DIMM-relative offset. With one DIMM in 58 + the system there would be a 1:1 system-physical-address:DPA association. 59 + Once more DIMMs are added a memory controller interleave must be 60 + decoded to determine the DPA associated with a given 61 + system-physical-address. BLK capacity always has a 1:1 relationship 62 + with a single-DIMM's DPA range. 66 63 67 - DAX: File system extensions to bypass the page cache and block layer to 68 - mmap persistent memory, from a PMEM block device, directly into a 69 - process address space. 64 + DAX: 65 + File system extensions to bypass the page cache and block layer to 66 + mmap persistent memory, from a PMEM block device, directly into a 67 + process address space. 70 68 71 - DSM: Device Specific Method: ACPI method to to control specific 72 - device - in this case the firmware. 69 + DSM: 70 + Device Specific Method: ACPI method to to control specific 71 + device - in this case the firmware. 73 72 74 - DCR: NVDIMM Control Region Structure defined in ACPI 6 Section 5.2.25.5. 75 - It defines a vendor-id, device-id, and interface format for a given DIMM. 73 + DCR: 74 + NVDIMM Control Region Structure defined in ACPI 6 Section 5.2.25.5. 75 + It defines a vendor-id, device-id, and interface format for a given DIMM. 76 76 77 - BTT: Block Translation Table: Persistent memory is byte addressable. 78 - Existing software may have an expectation that the power-fail-atomicity 79 - of writes is at least one sector, 512 bytes. The BTT is an indirection 80 - table with atomic update semantics to front a PMEM/BLK block device 81 - driver and present arbitrary atomic sector sizes. 77 + BTT: 78 + Block Translation Table: Persistent memory is byte addressable. 79 + Existing software may have an expectation that the power-fail-atomicity 80 + of writes is at least one sector, 512 bytes. The BTT is an indirection 81 + table with atomic update semantics to front a PMEM/BLK block device 82 + driver and present arbitrary atomic sector sizes. 82 83 83 - LABEL: Metadata stored on a DIMM device that partitions and identifies 84 - (persistently names) storage between PMEM and BLK. It also partitions 85 - BLK storage to host BTTs with different parameters per BLK-partition. 86 - Note that traditional partition tables, GPT/MBR, are layered on top of a 87 - BLK or PMEM device. 84 + LABEL: 85 + Metadata stored on a DIMM device that partitions and identifies 86 + (persistently names) storage between PMEM and BLK. It also partitions 87 + BLK storage to host BTTs with different parameters per BLK-partition. 88 + Note that traditional partition tables, GPT/MBR, are layered on top of a 89 + BLK or PMEM device. 88 90 89 91 90 92 Overview 91 - -------- 93 + ======== 92 94 93 95 The LIBNVDIMM subsystem provides support for three types of NVDIMMs, namely, 94 96 PMEM, BLK, and NVDIMM devices that can simultaneously support both PMEM ··· 110 96 for exclusive access via one mode a time. 111 97 112 98 Supporting Documents 113 - ACPI 6: http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf 114 - NVDIMM Namespace: http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf 115 - DSM Interface Example: http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf 116 - Driver Writer's Guide: http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf 99 + -------------------- 100 + 101 + ACPI 6: 102 + http://www.uefi.org/sites/default/files/resources/ACPI_6.0.pdf 103 + NVDIMM Namespace: 104 + http://pmem.io/documents/NVDIMM_Namespace_Spec.pdf 105 + DSM Interface Example: 106 + http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf 107 + Driver Writer's Guide: 108 + http://pmem.io/documents/NVDIMM_Driver_Writers_Guide.pdf 117 109 118 110 Git Trees 119 - LIBNVDIMM: https://git.kernel.org/cgit/linux/kernel/git/djbw/nvdimm.git 120 - LIBNDCTL: https://github.com/pmem/ndctl.git 121 - PMEM: https://github.com/01org/prd 111 + --------- 112 + 113 + LIBNVDIMM: 114 + https://git.kernel.org/cgit/linux/kernel/git/djbw/nvdimm.git 115 + LIBNDCTL: 116 + https://github.com/pmem/ndctl.git 117 + PMEM: 118 + https://github.com/01org/prd 122 119 123 120 124 121 LIBNVDIMM PMEM and BLK 125 - ------------------ 122 + ====================== 126 123 127 124 Prior to the arrival of the NFIT, non-volatile memory was described to a 128 125 system in various ad-hoc ways. Usually only the bare minimum was ··· 147 122 device driver: 148 123 149 124 1. PMEM (nd_pmem.ko): Drives a system-physical-address range. This 150 - range is contiguous in system memory and may be interleaved (hardware 151 - memory controller striped) across multiple DIMMs. When interleaved the 152 - platform may optionally provide details of which DIMMs are participating 153 - in the interleave. 125 + range is contiguous in system memory and may be interleaved (hardware 126 + memory controller striped) across multiple DIMMs. When interleaved the 127 + platform may optionally provide details of which DIMMs are participating 128 + in the interleave. 154 129 155 - Note that while LIBNVDIMM describes system-physical-address ranges that may 156 - alias with BLK access as ND_NAMESPACE_PMEM ranges and those without 157 - alias as ND_NAMESPACE_IO ranges, to the nd_pmem driver there is no 158 - distinction. The different device-types are an implementation detail 159 - that userspace can exploit to implement policies like "only interface 160 - with address ranges from certain DIMMs". It is worth noting that when 161 - aliasing is present and a DIMM lacks a label, then no block device can 162 - be created by default as userspace needs to do at least one allocation 163 - of DPA to the PMEM range. In contrast ND_NAMESPACE_IO ranges, once 164 - registered, can be immediately attached to nd_pmem. 130 + Note that while LIBNVDIMM describes system-physical-address ranges that may 131 + alias with BLK access as ND_NAMESPACE_PMEM ranges and those without 132 + alias as ND_NAMESPACE_IO ranges, to the nd_pmem driver there is no 133 + distinction. The different device-types are an implementation detail 134 + that userspace can exploit to implement policies like "only interface 135 + with address ranges from certain DIMMs". It is worth noting that when 136 + aliasing is present and a DIMM lacks a label, then no block device can 137 + be created by default as userspace needs to do at least one allocation 138 + of DPA to the PMEM range. In contrast ND_NAMESPACE_IO ranges, once 139 + registered, can be immediately attached to nd_pmem. 165 140 166 141 2. BLK (nd_blk.ko): This driver performs I/O using a set of platform 167 - defined apertures. A set of apertures will access just one DIMM. 168 - Multiple windows (apertures) allow multiple concurrent accesses, much like 169 - tagged-command-queuing, and would likely be used by different threads or 170 - different CPUs. 142 + defined apertures. A set of apertures will access just one DIMM. 143 + Multiple windows (apertures) allow multiple concurrent accesses, much like 144 + tagged-command-queuing, and would likely be used by different threads or 145 + different CPUs. 171 146 172 - The NFIT specification defines a standard format for a BLK-aperture, but 173 - the spec also allows for vendor specific layouts, and non-NFIT BLK 174 - implementations may have other designs for BLK I/O. For this reason 175 - "nd_blk" calls back into platform-specific code to perform the I/O. 176 - One such implementation is defined in the "Driver Writer's Guide" and "DSM 177 - Interface Example". 147 + The NFIT specification defines a standard format for a BLK-aperture, but 148 + the spec also allows for vendor specific layouts, and non-NFIT BLK 149 + implementations may have other designs for BLK I/O. For this reason 150 + "nd_blk" calls back into platform-specific code to perform the I/O. 151 + 152 + One such implementation is defined in the "Driver Writer's Guide" and "DSM 153 + Interface Example". 178 154 179 155 180 156 Why BLK? 181 - -------- 157 + ======== 182 158 183 159 While PMEM provides direct byte-addressable CPU-load/store access to 184 160 NVDIMM storage, it does not provide the best system RAS (recovery, ··· 188 162 to a corrupted address through an BLK-aperture causes that block window 189 163 to raise an error status in a register. The latter is more aligned with 190 164 the standard error model that host-bus-adapter attached disks present. 165 + 191 166 Also, if an administrator ever wants to replace a memory it is easier to 192 167 service a system at DIMM module boundaries. Compare this to PMEM where 193 168 data could be interleaved in an opaque hardware specific manner across 194 169 several DIMMs. 195 170 196 171 PMEM vs BLK 172 + ----------- 173 + 197 174 BLK-apertures solve these RAS problems, but their presence is also the 198 175 major contributing factor to the complexity of the ND subsystem. They 199 176 complicate the implementation because PMEM and BLK alias in DPA space. ··· 214 185 extents. 215 186 216 187 BLK-REGIONs, PMEM-REGIONs, Atomic Sectors, and DAX 217 - -------------------------------------------------- 188 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 218 189 219 190 One of the few 220 191 reasons to allow multiple BLK namespaces per REGION is so that each 221 192 BLK-namespace can be configured with a BTT with unique atomic sector 222 193 sizes. While a PMEM device can host a BTT the LABEL specification does 223 194 not provide for a sector size to be specified for a PMEM namespace. 195 + 224 196 This is due to the expectation that the primary usage model for PMEM is 225 197 via DAX, and the BTT is incompatible with DAX. However, for the cases 226 198 where an application or filesystem still needs atomic sector update ··· 230 200 231 201 232 202 Example NVDIMM Platform 233 - ----------------------- 203 + ======================= 234 204 235 205 For the remainder of this document the following diagram will be 236 - referenced for any example sysfs layouts. 206 + referenced for any example sysfs layouts:: 237 207 238 208 239 - (a) (b) DIMM BLK-REGION 240 - +-------------------+--------+--------+--------+ 241 - +------+ | pm0.0 | blk2.0 | pm1.0 | blk2.1 | 0 region2 242 - | imc0 +--+- - - region0- - - +--------+ +--------+ 243 - +--+---+ | pm0.0 | blk3.0 | pm1.0 | blk3.1 | 1 region3 244 - | +-------------------+--------v v--------+ 245 - +--+---+ | | 246 - | cpu0 | region1 247 - +--+---+ | | 248 - | +----------------------------^ ^--------+ 249 - +--+---+ | blk4.0 | pm1.0 | blk4.0 | 2 region4 250 - | imc1 +--+----------------------------| +--------+ 251 - +------+ | blk5.0 | pm1.0 | blk5.0 | 3 region5 252 - +----------------------------+--------+--------+ 209 + (a) (b) DIMM BLK-REGION 210 + +-------------------+--------+--------+--------+ 211 + +------+ | pm0.0 | blk2.0 | pm1.0 | blk2.1 | 0 region2 212 + | imc0 +--+- - - region0- - - +--------+ +--------+ 213 + +--+---+ | pm0.0 | blk3.0 | pm1.0 | blk3.1 | 1 region3 214 + | +-------------------+--------v v--------+ 215 + +--+---+ | | 216 + | cpu0 | region1 217 + +--+---+ | | 218 + | +----------------------------^ ^--------+ 219 + +--+---+ | blk4.0 | pm1.0 | blk4.0 | 2 region4 220 + | imc1 +--+----------------------------| +--------+ 221 + +------+ | blk5.0 | pm1.0 | blk5.0 | 3 region5 222 + +----------------------------+--------+--------+ 253 223 254 224 In this platform we have four DIMMs and two memory controllers in one 255 225 socket. Each unique interface (BLK or PMEM) to DPA space is identified 256 226 by a region device with a dynamically assigned id (REGION0 - REGION5). 257 227 258 228 1. The first portion of DIMM0 and DIMM1 are interleaved as REGION0. A 259 - single PMEM namespace is created in the REGION0-SPA-range that spans most 260 - of DIMM0 and DIMM1 with a user-specified name of "pm0.0". Some of that 261 - interleaved system-physical-address range is reclaimed as BLK-aperture 262 - accessed space starting at DPA-offset (a) into each DIMM. In that 263 - reclaimed space we create two BLK-aperture "namespaces" from REGION2 and 264 - REGION3 where "blk2.0" and "blk3.0" are just human readable names that 265 - could be set to any user-desired name in the LABEL. 229 + single PMEM namespace is created in the REGION0-SPA-range that spans most 230 + of DIMM0 and DIMM1 with a user-specified name of "pm0.0". Some of that 231 + interleaved system-physical-address range is reclaimed as BLK-aperture 232 + accessed space starting at DPA-offset (a) into each DIMM. In that 233 + reclaimed space we create two BLK-aperture "namespaces" from REGION2 and 234 + REGION3 where "blk2.0" and "blk3.0" are just human readable names that 235 + could be set to any user-desired name in the LABEL. 266 236 267 237 2. In the last portion of DIMM0 and DIMM1 we have an interleaved 268 - system-physical-address range, REGION1, that spans those two DIMMs as 269 - well as DIMM2 and DIMM3. Some of REGION1 is allocated to a PMEM namespace 270 - named "pm1.0", the rest is reclaimed in 4 BLK-aperture namespaces (for 271 - each DIMM in the interleave set), "blk2.1", "blk3.1", "blk4.0", and 272 - "blk5.0". 238 + system-physical-address range, REGION1, that spans those two DIMMs as 239 + well as DIMM2 and DIMM3. Some of REGION1 is allocated to a PMEM namespace 240 + named "pm1.0", the rest is reclaimed in 4 BLK-aperture namespaces (for 241 + each DIMM in the interleave set), "blk2.1", "blk3.1", "blk4.0", and 242 + "blk5.0". 273 243 274 244 3. The portion of DIMM2 and DIMM3 that do not participate in the REGION1 275 - interleaved system-physical-address range (i.e. the DPA address past 276 - offset (b) are also included in the "blk4.0" and "blk5.0" namespaces. 277 - Note, that this example shows that BLK-aperture namespaces don't need to 278 - be contiguous in DPA-space. 245 + interleaved system-physical-address range (i.e. the DPA address past 246 + offset (b) are also included in the "blk4.0" and "blk5.0" namespaces. 247 + Note, that this example shows that BLK-aperture namespaces don't need to 248 + be contiguous in DPA-space. 279 249 280 250 This bus is provided by the kernel under the device 281 251 /sys/devices/platform/nfit_test.0 when CONFIG_NFIT_TEST is enabled and ··· 284 254 285 255 286 256 LIBNVDIMM Kernel Device Model and LIBNDCTL Userspace API 287 - ---------------------------------------------------- 257 + ======================================================== 288 258 289 259 What follows is a description of the LIBNVDIMM sysfs layout and a 290 260 corresponding object hierarchy diagram as viewed through the LIBNDCTL ··· 293 263 test. 294 264 295 265 LIBNDCTL: Context 266 + ----------------- 267 + 296 268 Every API call in the LIBNDCTL library requires a context that holds the 297 269 logging parameters and other library instance state. The library is 298 270 based on the libabc template: 299 - https://git.kernel.org/cgit/linux/kernel/git/kay/libabc.git 271 + 272 + https://git.kernel.org/cgit/linux/kernel/git/kay/libabc.git 300 273 301 274 LIBNDCTL: instantiate a new library context example 275 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 276 + 277 + :: 302 278 303 279 struct ndctl_ctx *ctx; 304 280 ··· 314 278 return NULL; 315 279 316 280 LIBNVDIMM/LIBNDCTL: Bus 317 - ------------------- 281 + ----------------------- 318 282 319 283 A bus has a 1:1 relationship with an NFIT. The current expectation for 320 284 ACPI based systems is that there is only ever one platform-global NFIT. ··· 324 288 test. 325 289 326 290 LIBNVDIMM: control class device in /sys/class 291 + --------------------------------------------- 327 292 328 293 This character device accepts DSM messages to be passed to DIMM 329 - identified by its NFIT handle. 294 + identified by its NFIT handle:: 330 295 331 296 /sys/class/nd/ndctl0 332 297 |-- dev ··· 337 300 338 301 339 302 LIBNVDIMM: bus 303 + -------------- 304 + 305 + :: 340 306 341 307 struct nvdimm_bus *nvdimm_bus_register(struct device *parent, 342 308 struct nvdimm_bus_descriptor *nfit_desc); 309 + 310 + :: 343 311 344 312 /sys/devices/platform/nfit_test.0/ndbus0 345 313 |-- commands ··· 366 324 `-- wait_probe 367 325 368 326 LIBNDCTL: bus enumeration example 369 - Find the bus handle that describes the bus from Example NVDIMM Platform 327 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 328 + 329 + Find the bus handle that describes the bus from Example NVDIMM Platform:: 370 330 371 331 static struct ndctl_bus *get_bus_by_provider(struct ndctl_ctx *ctx, 372 332 const char *provider) ··· 386 342 387 343 388 344 LIBNVDIMM/LIBNDCTL: DIMM (NMEM) 389 - --------------------------- 345 + ------------------------------- 390 346 391 347 The DIMM device provides a character device for sending commands to 392 348 hardware, and it is a container for LABELs. If the DIMM is defined by ··· 399 355 be physical DIMMs, so we use a more generic name. 400 356 401 357 LIBNVDIMM: DIMM (NMEM) 358 + ^^^^^^^^^^^^^^^^^^^^^^ 359 + 360 + :: 402 361 403 362 struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, 404 363 const struct attribute_group **groups, unsigned long flags, 405 364 unsigned long *dsm_mask); 365 + 366 + :: 406 367 407 368 /sys/devices/platform/nfit_test.0/ndbus0 408 369 |-- nmem0 ··· 433 384 434 385 435 386 LIBNDCTL: DIMM enumeration example 387 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 436 388 437 389 Note, in this example we are assuming NFIT-defined DIMMs which are 438 390 identified by an "nfit_handle" a 32-bit value where: 439 - Bit 3:0 DIMM number within the memory channel 440 - Bit 7:4 memory channel number 441 - Bit 11:8 memory controller ID 442 - Bit 15:12 socket ID (within scope of a Node controller if node controller is present) 443 - Bit 27:16 Node Controller ID 444 - Bit 31:28 Reserved 391 + 392 + - Bit 3:0 DIMM number within the memory channel 393 + - Bit 7:4 memory channel number 394 + - Bit 11:8 memory controller ID 395 + - Bit 15:12 socket ID (within scope of a Node controller if node 396 + controller is present) 397 + - Bit 27:16 Node Controller ID 398 + - Bit 31:28 Reserved 399 + 400 + :: 445 401 446 402 static struct ndctl_dimm *get_dimm_by_handle(struct ndctl_bus *bus, 447 403 unsigned int handle) ··· 467 413 dimm = get_dimm_by_handle(bus, DIMM_HANDLE(0, 0, 0, 0, 0)); 468 414 469 415 LIBNVDIMM/LIBNDCTL: Region 470 - ---------------------- 416 + -------------------------- 471 417 472 418 A generic REGION device is registered for each PMEM range or BLK-aperture 473 419 set. Per the example there are 6 regions: 2 PMEM and 4 BLK-aperture ··· 489 435 at the 'add' event, and finally, the optional "spa_index" is provided in 490 436 the case where the region is defined by a SPA. 491 437 492 - LIBNVDIMM: region 438 + LIBNVDIMM: region:: 493 439 494 440 struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus, 495 441 struct nd_region_desc *ndr_desc); 496 442 struct nd_region *nvdimm_blk_region_create(struct nvdimm_bus *nvdimm_bus, 497 443 struct nd_region_desc *ndr_desc); 444 + 445 + :: 498 446 499 447 /sys/devices/platform/nfit_test.0/ndbus0 500 448 |-- region0 ··· 524 468 [..] 525 469 526 470 LIBNDCTL: region enumeration example 471 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 527 472 528 473 Sample region retrieval routines based on NFIT-unique data like 529 474 "spa_index" (interleave set id) for PMEM and "nfit_handle" (dimm id) for 530 - BLK. 475 + BLK:: 531 476 532 477 static struct ndctl_region *get_pmem_region_by_spa_index(struct ndctl_bus *bus, 533 478 unsigned int spa_index) ··· 575 518 region-attributes for four reasons: 576 519 577 520 1. There are already more than two REGION and "namespace" types. For 578 - PMEM there are two subtypes. As mentioned previously we have PMEM where 579 - the constituent DIMM devices are known and anonymous PMEM. For BLK 580 - regions the NFIT specification already anticipates vendor specific 581 - implementations. The exact distinction of what a region contains is in 582 - the region-attributes not the region-name or the region-devtype. 521 + PMEM there are two subtypes. As mentioned previously we have PMEM where 522 + the constituent DIMM devices are known and anonymous PMEM. For BLK 523 + regions the NFIT specification already anticipates vendor specific 524 + implementations. The exact distinction of what a region contains is in 525 + the region-attributes not the region-name or the region-devtype. 583 526 584 527 2. A region with zero child-namespaces is a possible configuration. For 585 - example, the NFIT allows for a DCR to be published without a 586 - corresponding BLK-aperture. This equates to a DIMM that can only accept 587 - control/configuration messages, but no i/o through a descendant block 588 - device. Again, this "type" is advertised in the attributes ('mappings' 589 - == 0) and the name does not tell you much. 528 + example, the NFIT allows for a DCR to be published without a 529 + corresponding BLK-aperture. This equates to a DIMM that can only accept 530 + control/configuration messages, but no i/o through a descendant block 531 + device. Again, this "type" is advertised in the attributes ('mappings' 532 + == 0) and the name does not tell you much. 590 533 591 534 3. What if a third major interface type arises in the future? Outside 592 - of vendor specific implementations, it's not difficult to envision a 593 - third class of interface type beyond BLK and PMEM. With a generic name 594 - for the REGION level of the device-hierarchy old userspace 595 - implementations can still make sense of new kernel advertised 596 - region-types. Userspace can always rely on the generic region 597 - attributes like "mappings", "size", etc and the expected child devices 598 - named "namespace". This generic format of the device-model hierarchy 599 - allows the LIBNVDIMM and LIBNDCTL implementations to be more uniform and 600 - future-proof. 535 + of vendor specific implementations, it's not difficult to envision a 536 + third class of interface type beyond BLK and PMEM. With a generic name 537 + for the REGION level of the device-hierarchy old userspace 538 + implementations can still make sense of new kernel advertised 539 + region-types. Userspace can always rely on the generic region 540 + attributes like "mappings", "size", etc and the expected child devices 541 + named "namespace". This generic format of the device-model hierarchy 542 + allows the LIBNVDIMM and LIBNDCTL implementations to be more uniform and 543 + future-proof. 601 544 602 545 4. There are more robust mechanisms for determining the major type of a 603 - region than a device name. See the next section, How Do I Determine the 604 - Major Type of a Region? 546 + region than a device name. See the next section, How Do I Determine the 547 + Major Type of a Region? 605 548 606 549 How Do I Determine the Major Type of a Region? 607 550 ---------------------------------------------- ··· 610 553 looking at the kernel header (/usr/include/linux/ndctl.h) to decode the 611 554 "nstype" integer attribute, here are some other options. 612 555 613 - 1. module alias lookup: 556 + 1. module alias lookup 557 + ^^^^^^^^^^^^^^^^^^^^^^ 614 558 615 559 The whole point of region/namespace device type differentiation is to 616 560 decide which block-device driver will attach to a given LIBNVDIMM namespace. ··· 627 569 the resulting namespaces. The output from module resolution is more 628 570 accurate than a region-name or region-devtype. 629 571 630 - 2. udev: 572 + 2. udev 573 + ^^^^^^^ 631 574 632 - The kernel "devtype" is registered in the udev database 633 - # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region0 634 - P: /devices/platform/nfit_test.0/ndbus0/region0 635 - E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region0 636 - E: DEVTYPE=nd_pmem 637 - E: MODALIAS=nd:t2 638 - E: SUBSYSTEM=nd 575 + The kernel "devtype" is registered in the udev database:: 639 576 640 - # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region4 641 - P: /devices/platform/nfit_test.0/ndbus0/region4 642 - E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region4 643 - E: DEVTYPE=nd_blk 644 - E: MODALIAS=nd:t3 645 - E: SUBSYSTEM=nd 577 + # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region0 578 + P: /devices/platform/nfit_test.0/ndbus0/region0 579 + E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region0 580 + E: DEVTYPE=nd_pmem 581 + E: MODALIAS=nd:t2 582 + E: SUBSYSTEM=nd 583 + 584 + # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region4 585 + P: /devices/platform/nfit_test.0/ndbus0/region4 586 + E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region4 587 + E: DEVTYPE=nd_blk 588 + E: MODALIAS=nd:t3 589 + E: SUBSYSTEM=nd 646 590 647 591 ...and is available as a region attribute, but keep in mind that the 648 592 "devtype" does not indicate sub-type variations and scripts should 649 593 really be understanding the other attributes. 650 594 651 - 3. type specific attributes: 595 + 3. type specific attributes 596 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 652 597 653 598 As it currently stands a BLK-aperture region will never have a 654 599 "nfit/spa_index" attribute, but neither will a non-NFIT PMEM region. A ··· 661 600 662 601 663 602 LIBNVDIMM/LIBNDCTL: Namespace 664 - ------------------------- 603 + ----------------------------- 665 604 666 605 A REGION, after resolving DPA aliasing and LABEL specified boundaries, 667 606 surfaces one or more "namespace" devices. The arrival of a "namespace" ··· 669 608 and register a disk/block device. 670 609 671 610 LIBNVDIMM: namespace 611 + ^^^^^^^^^^^^^^^^^^^^ 612 + 672 613 Here is a sample layout from the three major types of NAMESPACE where 673 614 namespace0.0 represents DIMM-info-backed PMEM (note that it has a 'uuid' 674 615 attribute), namespace2.0 represents a BLK namespace (note it has a 675 616 'sector_size' attribute) that, and namespace6.0 represents an anonymous 676 617 PMEM namespace (note that has no 'uuid' attribute due to not support a 677 - LABEL). 618 + LABEL):: 678 619 679 620 /sys/devices/platform/nfit_test.0/ndbus0/region0/namespace0.0 680 621 |-- alt_name ··· 719 656 `-- uevent 720 657 721 658 LIBNDCTL: namespace enumeration example 659 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 722 660 Namespaces are indexed relative to their parent region, example below. 723 661 These indexes are mostly static from boot to boot, but subsystem makes 724 662 no guarantees in this regard. For a static namespace identifier use its 725 663 'uuid' attribute. 726 664 727 - static struct ndctl_namespace *get_namespace_by_id(struct ndctl_region *region, 728 - unsigned int id) 729 - { 730 - struct ndctl_namespace *ndns; 665 + :: 731 666 732 - ndctl_namespace_foreach(region, ndns) 733 - if (ndctl_namespace_get_id(ndns) == id) 734 - return ndns; 667 + static struct ndctl_namespace 668 + *get_namespace_by_id(struct ndctl_region *region, unsigned int id) 669 + { 670 + struct ndctl_namespace *ndns; 735 671 736 - return NULL; 737 - } 672 + ndctl_namespace_foreach(region, ndns) 673 + if (ndctl_namespace_get_id(ndns) == id) 674 + return ndns; 675 + 676 + return NULL; 677 + } 738 678 739 679 LIBNDCTL: namespace creation example 680 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 681 + 740 682 Idle namespaces are automatically created by the kernel if a given 741 683 region has enough available capacity to create a new namespace. 742 684 Namespace instantiation involves finding an idle namespace and 743 685 configuring it. For the most part the setting of namespace attributes 744 686 can occur in any order, the only constraint is that 'uuid' must be set 745 687 before 'size'. This enables the kernel to track DPA allocations 746 - internally with a static identifier. 688 + internally with a static identifier:: 747 689 748 - static int configure_namespace(struct ndctl_region *region, 749 - struct ndctl_namespace *ndns, 750 - struct namespace_parameters *parameters) 751 - { 752 - char devname[50]; 690 + static int configure_namespace(struct ndctl_region *region, 691 + struct ndctl_namespace *ndns, 692 + struct namespace_parameters *parameters) 693 + { 694 + char devname[50]; 753 695 754 - snprintf(devname, sizeof(devname), "namespace%d.%d", 755 - ndctl_region_get_id(region), paramaters->id); 696 + snprintf(devname, sizeof(devname), "namespace%d.%d", 697 + ndctl_region_get_id(region), paramaters->id); 756 698 757 - ndctl_namespace_set_alt_name(ndns, devname); 758 - /* 'uuid' must be set prior to setting size! */ 759 - ndctl_namespace_set_uuid(ndns, paramaters->uuid); 760 - ndctl_namespace_set_size(ndns, paramaters->size); 761 - /* unlike pmem namespaces, blk namespaces have a sector size */ 762 - if (parameters->lbasize) 763 - ndctl_namespace_set_sector_size(ndns, parameters->lbasize); 764 - ndctl_namespace_enable(ndns); 765 - } 699 + ndctl_namespace_set_alt_name(ndns, devname); 700 + /* 'uuid' must be set prior to setting size! */ 701 + ndctl_namespace_set_uuid(ndns, paramaters->uuid); 702 + ndctl_namespace_set_size(ndns, paramaters->size); 703 + /* unlike pmem namespaces, blk namespaces have a sector size */ 704 + if (parameters->lbasize) 705 + ndctl_namespace_set_sector_size(ndns, parameters->lbasize); 706 + ndctl_namespace_enable(ndns); 707 + } 766 708 767 709 768 710 Why the Term "namespace"? 711 + ^^^^^^^^^^^^^^^^^^^^^^^^^ 769 712 770 713 1. Why not "volume" for instance? "volume" ran the risk of confusing 771 - ND (libnvdimm subsystem) to a volume manager like device-mapper. 714 + ND (libnvdimm subsystem) to a volume manager like device-mapper. 772 715 773 716 2. The term originated to describe the sub-devices that can be created 774 - within a NVME controller (see the nvme specification: 775 - http://www.nvmexpress.org/specifications/), and NFIT namespaces are 776 - meant to parallel the capabilities and configurability of 777 - NVME-namespaces. 717 + within a NVME controller (see the nvme specification: 718 + http://www.nvmexpress.org/specifications/), and NFIT namespaces are 719 + meant to parallel the capabilities and configurability of 720 + NVME-namespaces. 778 721 779 722 780 723 LIBNVDIMM/LIBNDCTL: Block Translation Table "btt" 781 - --------------------------------------------- 724 + ------------------------------------------------- 782 725 783 726 A BTT (design document: http://pmem.io/2014/09/23/btt.html) is a stacked 784 727 block device driver that fronts either the whole block device or a 785 728 partition of a block device emitted by either a PMEM or BLK NAMESPACE. 786 729 787 730 LIBNVDIMM: btt layout 731 + ^^^^^^^^^^^^^^^^^^^^^ 732 + 788 733 Every region will start out with at least one BTT device which is the 789 734 seed device. To activate it set the "namespace", "uuid", and 790 735 "sector_size" attributes and then bind the device to the nd_pmem or 791 - nd_blk driver depending on the region type. 736 + nd_blk driver depending on the region type:: 792 737 793 738 /sys/devices/platform/nfit_test.1/ndbus0/region0/btt0/ 794 739 |-- namespace ··· 810 739 `-- uuid 811 740 812 741 LIBNDCTL: btt creation example 742 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 743 + 813 744 Similar to namespaces an idle BTT device is automatically created per 814 745 region. Each time this "seed" btt device is configured and enabled a new 815 746 seed is created. Creating a BTT configuration involves two steps of 816 - finding and idle BTT and assigning it to consume a PMEM or BLK namespace. 747 + finding and idle BTT and assigning it to consume a PMEM or BLK namespace:: 817 748 818 749 static struct ndctl_btt *get_idle_btt(struct ndctl_region *region) 819 750 { ··· 860 787 ------------------------ 861 788 862 789 For the given example above, here is the view of the objects as seen by the 863 - LIBNDCTL API: 864 - +---+ 865 - |CTX| +---------+ +--------------+ +---------------+ 866 - +-+-+ +-> REGION0 +---> NAMESPACE0.0 +--> PMEM8 "pm0.0" | 867 - | | +---------+ +--------------+ +---------------+ 868 - +-------+ | | +---------+ +--------------+ +---------------+ 869 - | DIMM0 <-+ | +-> REGION1 +---> NAMESPACE1.0 +--> PMEM6 "pm1.0" | 870 - +-------+ | | | +---------+ +--------------+ +---------------+ 871 - | DIMM1 <-+ +-v--+ | +---------+ +--------------+ +---------------+ 872 - +-------+ +-+BUS0+---> REGION2 +-+-> NAMESPACE2.0 +--> ND6 "blk2.0" | 873 - | DIMM2 <-+ +----+ | +---------+ | +--------------+ +----------------------+ 874 - +-------+ | | +-> NAMESPACE2.1 +--> ND5 "blk2.1" | BTT2 | 875 - | DIMM3 <-+ | +--------------+ +----------------------+ 876 - +-------+ | +---------+ +--------------+ +---------------+ 877 - +-> REGION3 +-+-> NAMESPACE3.0 +--> ND4 "blk3.0" | 878 - | +---------+ | +--------------+ +----------------------+ 879 - | +-> NAMESPACE3.1 +--> ND3 "blk3.1" | BTT1 | 880 - | +--------------+ +----------------------+ 881 - | +---------+ +--------------+ +---------------+ 882 - +-> REGION4 +---> NAMESPACE4.0 +--> ND2 "blk4.0" | 883 - | +---------+ +--------------+ +---------------+ 884 - | +---------+ +--------------+ +----------------------+ 885 - +-> REGION5 +---> NAMESPACE5.0 +--> ND1 "blk5.0" | BTT0 | 886 - +---------+ +--------------+ +---------------+------+ 790 + LIBNDCTL API:: 887 791 888 - 792 + +---+ 793 + |CTX| +---------+ +--------------+ +---------------+ 794 + +-+-+ +-> REGION0 +---> NAMESPACE0.0 +--> PMEM8 "pm0.0" | 795 + | | +---------+ +--------------+ +---------------+ 796 + +-------+ | | +---------+ +--------------+ +---------------+ 797 + | DIMM0 <-+ | +-> REGION1 +---> NAMESPACE1.0 +--> PMEM6 "pm1.0" | 798 + +-------+ | | | +---------+ +--------------+ +---------------+ 799 + | DIMM1 <-+ +-v--+ | +---------+ +--------------+ +---------------+ 800 + +-------+ +-+BUS0+---> REGION2 +-+-> NAMESPACE2.0 +--> ND6 "blk2.0" | 801 + | DIMM2 <-+ +----+ | +---------+ | +--------------+ +----------------------+ 802 + +-------+ | | +-> NAMESPACE2.1 +--> ND5 "blk2.1" | BTT2 | 803 + | DIMM3 <-+ | +--------------+ +----------------------+ 804 + +-------+ | +---------+ +--------------+ +---------------+ 805 + +-> REGION3 +-+-> NAMESPACE3.0 +--> ND4 "blk3.0" | 806 + | +---------+ | +--------------+ +----------------------+ 807 + | +-> NAMESPACE3.1 +--> ND3 "blk3.1" | BTT1 | 808 + | +--------------+ +----------------------+ 809 + | +---------+ +--------------+ +---------------+ 810 + +-> REGION4 +---> NAMESPACE4.0 +--> ND2 "blk4.0" | 811 + | +---------+ +--------------+ +---------------+ 812 + | +---------+ +--------------+ +----------------------+ 813 + +-> REGION5 +---> NAMESPACE5.0 +--> ND1 "blk5.0" | BTT0 | 814 + +---------+ +--------------+ +---------------+------+
+3 -1
Documentation/nvdimm/security.txt Documentation/nvdimm/security.rst
··· 1 - NVDIMM SECURITY 1 + =============== 2 + NVDIMM Security 2 3 =============== 3 4 4 5 1. Introduction ··· 139 138 by the extended security status. 140 139 141 140 [1]: http://pmem.io/documents/NVDIMM_DSM_Interface-V1.8.pdf 141 + 142 142 [2]: http://www.t13.org/documents/UploadedDocuments/docs2006/e05179r4-ACS-SecurityClarifications.pdf
+1 -1
drivers/nvdimm/Kconfig
··· 33 33 Documentation/admin-guide/kernel-parameters.rst). This driver converts 34 34 these persistent memory ranges into block devices that are 35 35 capable of DAX (direct-access) file system mappings. See 36 - Documentation/nvdimm/nvdimm.txt for more details. 36 + Documentation/nvdimm/nvdimm.rst for more details. 37 37 38 38 Say Y if you want to use an NVDIMM 39 39