Merge tag 'kbuild-fixes-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/masahi...
[linux-2.6-block.git] / drivers / nvdimm / dimm_devs.c
CommitLineData
5b497af4 1// SPDX-License-Identifier: GPL-2.0-only
e6dfb2de
DW
2/*
3 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
e6dfb2de
DW
4 */
5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
d5d30d5a 6#include <linux/moduleparam.h>
4d88a97a 7#include <linux/vmalloc.h>
e6dfb2de 8#include <linux/device.h>
62232e45 9#include <linux/ndctl.h>
e6dfb2de
DW
10#include <linux/slab.h>
11#include <linux/io.h>
12#include <linux/fs.h>
13#include <linux/mm.h>
14#include "nd-core.h"
0ba1c634 15#include "label.h"
ca6a4657 16#include "pmem.h"
4d88a97a 17#include "nd.h"
e6dfb2de
DW
18
19static DEFINE_IDA(dimm_ida);
20
d5d30d5a
DW
21static bool noblk;
22module_param(noblk, bool, 0444);
23MODULE_PARM_DESC(noblk, "force disable BLK / local alias support");
24
4d88a97a
DW
25/*
26 * Retrieve bus and dimm handle and return if this bus supports
27 * get_config_data commands
28 */
aee65987 29int nvdimm_check_config_data(struct device *dev)
4d88a97a 30{
aee65987 31 struct nvdimm *nvdimm = to_nvdimm(dev);
4d88a97a 32
aee65987
TK
33 if (!nvdimm->cmd_mask ||
34 !test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) {
8f078b38 35 if (test_bit(NDD_ALIASING, &nvdimm->flags))
aee65987
TK
36 return -ENXIO;
37 else
38 return -ENOTTY;
39 }
4d88a97a
DW
40
41 return 0;
42}
43
44static int validate_dimm(struct nvdimm_drvdata *ndd)
45{
aee65987 46 int rc;
4d88a97a 47
aee65987
TK
48 if (!ndd)
49 return -EINVAL;
50
51 rc = nvdimm_check_config_data(ndd->dev);
52 if (rc)
d75f773c 53 dev_dbg(ndd->dev, "%ps: %s error: %d\n",
4d88a97a
DW
54 __builtin_return_address(0), __func__, rc);
55 return rc;
56}
57
58/**
59 * nvdimm_init_nsarea - determine the geometry of a dimm's namespace area
60 * @nvdimm: dimm to initialize
61 */
62int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd)
63{
64 struct nd_cmd_get_config_size *cmd = &ndd->nsarea;
65 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
66 struct nvdimm_bus_descriptor *nd_desc;
67 int rc = validate_dimm(ndd);
9d62ed96 68 int cmd_rc = 0;
4d88a97a
DW
69
70 if (rc)
71 return rc;
72
73 if (cmd->config_size)
74 return 0; /* already valid */
75
76 memset(cmd, 0, sizeof(*cmd));
77 nd_desc = nvdimm_bus->nd_desc;
9d62ed96
DW
78 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
79 ND_CMD_GET_CONFIG_SIZE, cmd, sizeof(*cmd), &cmd_rc);
80 if (rc < 0)
81 return rc;
82 return cmd_rc;
4d88a97a
DW
83}
84
2d657d17
AD
85int nvdimm_get_config_data(struct nvdimm_drvdata *ndd, void *buf,
86 size_t offset, size_t len)
4d88a97a
DW
87{
88 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
2d657d17 89 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
e7c5a571 90 int rc = validate_dimm(ndd), cmd_rc = 0;
4d88a97a 91 struct nd_cmd_get_config_data_hdr *cmd;
2d657d17 92 size_t max_cmd_size, buf_offset;
4d88a97a
DW
93
94 if (rc)
95 return rc;
96
2d657d17 97 if (offset + len > ndd->nsarea.config_size)
4d88a97a 98 return -ENXIO;
4d88a97a 99
2d657d17 100 max_cmd_size = min_t(u32, len, ndd->nsarea.max_xfer);
d11cf4a7 101 cmd = kvzalloc(max_cmd_size + sizeof(*cmd), GFP_KERNEL);
4d88a97a
DW
102 if (!cmd)
103 return -ENOMEM;
104
2d657d17
AD
105 for (buf_offset = 0; len;
106 len -= cmd->in_length, buf_offset += cmd->in_length) {
107 size_t cmd_size;
108
109 cmd->in_offset = offset + buf_offset;
110 cmd->in_length = min(max_cmd_size, len);
111
112 cmd_size = sizeof(*cmd) + cmd->in_length;
113
4d88a97a 114 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
2d657d17 115 ND_CMD_GET_CONFIG_DATA, cmd, cmd_size, &cmd_rc);
e7c5a571
DW
116 if (rc < 0)
117 break;
118 if (cmd_rc < 0) {
119 rc = cmd_rc;
4d88a97a
DW
120 break;
121 }
2d657d17
AD
122
123 /* out_buf should be valid, copy it into our output buffer */
124 memcpy(buf + buf_offset, cmd->out_buf, cmd->in_length);
4d88a97a 125 }
d11cf4a7 126 kvfree(cmd);
4d88a97a
DW
127
128 return rc;
129}
130
f524bf27
DW
131int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
132 void *buf, size_t len)
133{
f524bf27
DW
134 size_t max_cmd_size, buf_offset;
135 struct nd_cmd_set_config_hdr *cmd;
e7c5a571 136 int rc = validate_dimm(ndd), cmd_rc = 0;
f524bf27
DW
137 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
138 struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
139
140 if (rc)
141 return rc;
142
f524bf27
DW
143 if (offset + len > ndd->nsarea.config_size)
144 return -ENXIO;
145
d11cf4a7
DW
146 max_cmd_size = min_t(u32, len, ndd->nsarea.max_xfer);
147 cmd = kvzalloc(max_cmd_size + sizeof(*cmd) + sizeof(u32), GFP_KERNEL);
f524bf27
DW
148 if (!cmd)
149 return -ENOMEM;
150
151 for (buf_offset = 0; len; len -= cmd->in_length,
152 buf_offset += cmd->in_length) {
153 size_t cmd_size;
f524bf27
DW
154
155 cmd->in_offset = offset + buf_offset;
156 cmd->in_length = min(max_cmd_size, len);
157 memcpy(cmd->in_buf, buf + buf_offset, cmd->in_length);
158
159 /* status is output in the last 4-bytes of the command buffer */
160 cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32);
f524bf27
DW
161
162 rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
e7c5a571
DW
163 ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc);
164 if (rc < 0)
165 break;
166 if (cmd_rc < 0) {
167 rc = cmd_rc;
f524bf27
DW
168 break;
169 }
170 }
d11cf4a7 171 kvfree(cmd);
f524bf27
DW
172
173 return rc;
174}
175
42237e39
DW
176void nvdimm_set_aliasing(struct device *dev)
177{
178 struct nvdimm *nvdimm = to_nvdimm(dev);
179
8f078b38
DW
180 set_bit(NDD_ALIASING, &nvdimm->flags);
181}
182
183void nvdimm_set_locked(struct device *dev)
184{
185 struct nvdimm *nvdimm = to_nvdimm(dev);
186
187 set_bit(NDD_LOCKED, &nvdimm->flags);
42237e39
DW
188}
189
d34cb808
DW
190void nvdimm_clear_locked(struct device *dev)
191{
192 struct nvdimm *nvdimm = to_nvdimm(dev);
193
194 clear_bit(NDD_LOCKED, &nvdimm->flags);
195}
196
e6dfb2de
DW
197static void nvdimm_release(struct device *dev)
198{
199 struct nvdimm *nvdimm = to_nvdimm(dev);
200
201 ida_simple_remove(&dimm_ida, nvdimm->id);
202 kfree(nvdimm);
203}
204
205static struct device_type nvdimm_device_type = {
206 .name = "nvdimm",
207 .release = nvdimm_release,
208};
209
62232e45 210bool is_nvdimm(struct device *dev)
e6dfb2de
DW
211{
212 return dev->type == &nvdimm_device_type;
213}
214
215struct nvdimm *to_nvdimm(struct device *dev)
216{
217 struct nvdimm *nvdimm = container_of(dev, struct nvdimm, dev);
218
219 WARN_ON(!is_nvdimm(dev));
220 return nvdimm;
221}
222EXPORT_SYMBOL_GPL(to_nvdimm);
223
047fc8a1
RZ
224struct nvdimm *nd_blk_region_to_dimm(struct nd_blk_region *ndbr)
225{
226 struct nd_region *nd_region = &ndbr->nd_region;
227 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
228
229 return nd_mapping->nvdimm;
230}
231EXPORT_SYMBOL_GPL(nd_blk_region_to_dimm);
232
ca6a4657
DW
233unsigned long nd_blk_memremap_flags(struct nd_blk_region *ndbr)
234{
235 /* pmem mapping properties are private to libnvdimm */
236 return ARCH_MEMREMAP_PMEM;
237}
238EXPORT_SYMBOL_GPL(nd_blk_memremap_flags);
239
bf9bccc1
DW
240struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping)
241{
242 struct nvdimm *nvdimm = nd_mapping->nvdimm;
243
244 WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm->dev));
245
246 return dev_get_drvdata(&nvdimm->dev);
247}
248EXPORT_SYMBOL(to_ndd);
249
250void nvdimm_drvdata_release(struct kref *kref)
251{
252 struct nvdimm_drvdata *ndd = container_of(kref, typeof(*ndd), kref);
253 struct device *dev = ndd->dev;
254 struct resource *res, *_r;
255
426824d6 256 dev_dbg(dev, "trace\n");
bf9bccc1
DW
257 nvdimm_bus_lock(dev);
258 for_each_dpa_resource_safe(ndd, res, _r)
259 nvdimm_free_dpa(ndd, res);
260 nvdimm_bus_unlock(dev);
261
a06a7576 262 kvfree(ndd->data);
bf9bccc1
DW
263 kfree(ndd);
264 put_device(dev);
265}
266
267void get_ndd(struct nvdimm_drvdata *ndd)
268{
269 kref_get(&ndd->kref);
270}
271
272void put_ndd(struct nvdimm_drvdata *ndd)
273{
274 if (ndd)
275 kref_put(&ndd->kref, nvdimm_drvdata_release);
276}
277
e6dfb2de
DW
278const char *nvdimm_name(struct nvdimm *nvdimm)
279{
280 return dev_name(&nvdimm->dev);
281}
282EXPORT_SYMBOL_GPL(nvdimm_name);
283
ba9c8dd3
DW
284struct kobject *nvdimm_kobj(struct nvdimm *nvdimm)
285{
286 return &nvdimm->dev.kobj;
287}
288EXPORT_SYMBOL_GPL(nvdimm_kobj);
289
e3654eca
DW
290unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm)
291{
292 return nvdimm->cmd_mask;
293}
294EXPORT_SYMBOL_GPL(nvdimm_cmd_mask);
295
e6dfb2de
DW
296void *nvdimm_provider_data(struct nvdimm *nvdimm)
297{
62232e45
DW
298 if (nvdimm)
299 return nvdimm->provider_data;
300 return NULL;
e6dfb2de
DW
301}
302EXPORT_SYMBOL_GPL(nvdimm_provider_data);
303
62232e45
DW
304static ssize_t commands_show(struct device *dev,
305 struct device_attribute *attr, char *buf)
306{
307 struct nvdimm *nvdimm = to_nvdimm(dev);
308 int cmd, len = 0;
309
e3654eca 310 if (!nvdimm->cmd_mask)
62232e45
DW
311 return sprintf(buf, "\n");
312
e3654eca 313 for_each_set_bit(cmd, &nvdimm->cmd_mask, BITS_PER_LONG)
62232e45
DW
314 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
315 len += sprintf(buf + len, "\n");
316 return len;
317}
318static DEVICE_ATTR_RO(commands);
319
efbf6f50
DW
320static ssize_t flags_show(struct device *dev,
321 struct device_attribute *attr, char *buf)
322{
323 struct nvdimm *nvdimm = to_nvdimm(dev);
324
325 return sprintf(buf, "%s%s\n",
326 test_bit(NDD_ALIASING, &nvdimm->flags) ? "alias " : "",
327 test_bit(NDD_LOCKED, &nvdimm->flags) ? "lock " : "");
328}
329static DEVICE_ATTR_RO(flags);
330
eaf96153
DW
331static ssize_t state_show(struct device *dev, struct device_attribute *attr,
332 char *buf)
333{
334 struct nvdimm *nvdimm = to_nvdimm(dev);
335
336 /*
337 * The state may be in the process of changing, userspace should
338 * quiesce probing if it wants a static answer
339 */
340 nvdimm_bus_lock(dev);
341 nvdimm_bus_unlock(dev);
342 return sprintf(buf, "%s\n", atomic_read(&nvdimm->busy)
343 ? "active" : "idle");
344}
345static DEVICE_ATTR_RO(state);
346
0ba1c634
DW
347static ssize_t available_slots_show(struct device *dev,
348 struct device_attribute *attr, char *buf)
349{
350 struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
351 ssize_t rc;
352 u32 nfree;
353
354 if (!ndd)
355 return -ENXIO;
356
357 nvdimm_bus_lock(dev);
358 nfree = nd_label_nfree(ndd);
359 if (nfree - 1 > nfree) {
360 dev_WARN_ONCE(dev, 1, "we ate our last label?\n");
361 nfree = 0;
362 } else
363 nfree--;
364 rc = sprintf(buf, "%d\n", nfree);
365 nvdimm_bus_unlock(dev);
366 return rc;
367}
368static DEVICE_ATTR_RO(available_slots);
369
3c13e2ac 370__weak ssize_t security_show(struct device *dev,
f2989396
DJ
371 struct device_attribute *attr, char *buf)
372{
373 struct nvdimm *nvdimm = to_nvdimm(dev);
374
375 switch (nvdimm->sec.state) {
376 case NVDIMM_SECURITY_DISABLED:
377 return sprintf(buf, "disabled\n");
378 case NVDIMM_SECURITY_UNLOCKED:
379 return sprintf(buf, "unlocked\n");
380 case NVDIMM_SECURITY_LOCKED:
381 return sprintf(buf, "locked\n");
382 case NVDIMM_SECURITY_FROZEN:
383 return sprintf(buf, "frozen\n");
384 case NVDIMM_SECURITY_OVERWRITE:
385 return sprintf(buf, "overwrite\n");
89fa9d8e
DJ
386 default:
387 return -ENOTTY;
f2989396
DJ
388 }
389
390 return -ENOTTY;
391}
37833fb7 392
89fa9d8e
DJ
393#define OPS \
394 C( OP_FREEZE, "freeze", 1), \
395 C( OP_DISABLE, "disable", 2), \
396 C( OP_UPDATE, "update", 3), \
397 C( OP_ERASE, "erase", 2), \
398 C( OP_OVERWRITE, "overwrite", 2), \
399 C( OP_MASTER_UPDATE, "master_update", 3), \
400 C( OP_MASTER_ERASE, "master_erase", 2)
03b65b22
DJ
401#undef C
402#define C(a, b, c) a
403enum nvdimmsec_op_ids { OPS };
404#undef C
405#define C(a, b, c) { b, c }
406static struct {
407 const char *name;
408 int args;
409} ops[] = { OPS };
410#undef C
411
412#define SEC_CMD_SIZE 32
413#define KEY_ID_SIZE 10
414
37833fb7
DJ
415static ssize_t __security_store(struct device *dev, const char *buf, size_t len)
416{
417 struct nvdimm *nvdimm = to_nvdimm(dev);
418 ssize_t rc;
03b65b22
DJ
419 char cmd[SEC_CMD_SIZE+1], keystr[KEY_ID_SIZE+1],
420 nkeystr[KEY_ID_SIZE+1];
421 unsigned int key, newkey;
422 int i;
37833fb7
DJ
423
424 if (atomic_read(&nvdimm->busy))
425 return -EBUSY;
426
03b65b22
DJ
427 rc = sscanf(buf, "%"__stringify(SEC_CMD_SIZE)"s"
428 " %"__stringify(KEY_ID_SIZE)"s"
429 " %"__stringify(KEY_ID_SIZE)"s",
430 cmd, keystr, nkeystr);
431 if (rc < 1)
432 return -EINVAL;
433 for (i = 0; i < ARRAY_SIZE(ops); i++)
434 if (sysfs_streq(cmd, ops[i].name))
435 break;
436 if (i >= ARRAY_SIZE(ops))
437 return -EINVAL;
438 if (ops[i].args > 1)
439 rc = kstrtouint(keystr, 0, &key);
440 if (rc >= 0 && ops[i].args > 2)
441 rc = kstrtouint(nkeystr, 0, &newkey);
442 if (rc < 0)
443 return rc;
444
445 if (i == OP_FREEZE) {
37833fb7
DJ
446 dev_dbg(dev, "freeze\n");
447 rc = nvdimm_security_freeze(nvdimm);
03b65b22
DJ
448 } else if (i == OP_DISABLE) {
449 dev_dbg(dev, "disable %u\n", key);
450 rc = nvdimm_security_disable(nvdimm, key);
d2a4ac73
DJ
451 } else if (i == OP_UPDATE) {
452 dev_dbg(dev, "update %u %u\n", key, newkey);
89fa9d8e 453 rc = nvdimm_security_update(nvdimm, key, newkey, NVDIMM_USER);
64e77c8c
DJ
454 } else if (i == OP_ERASE) {
455 dev_dbg(dev, "erase %u\n", key);
89fa9d8e 456 rc = nvdimm_security_erase(nvdimm, key, NVDIMM_USER);
7d988097
DJ
457 } else if (i == OP_OVERWRITE) {
458 dev_dbg(dev, "overwrite %u\n", key);
459 rc = nvdimm_security_overwrite(nvdimm, key);
89fa9d8e
DJ
460 } else if (i == OP_MASTER_UPDATE) {
461 dev_dbg(dev, "master_update %u %u\n", key, newkey);
462 rc = nvdimm_security_update(nvdimm, key, newkey,
463 NVDIMM_MASTER);
464 } else if (i == OP_MASTER_ERASE) {
465 dev_dbg(dev, "master_erase %u\n", key);
466 rc = nvdimm_security_erase(nvdimm, key,
467 NVDIMM_MASTER);
37833fb7
DJ
468 } else
469 return -EINVAL;
470
471 if (rc == 0)
472 rc = len;
473 return rc;
37833fb7
DJ
474}
475
476static ssize_t security_store(struct device *dev,
477 struct device_attribute *attr, const char *buf, size_t len)
478
479{
480 ssize_t rc;
481
482 /*
483 * Require all userspace triggered security management to be
484 * done while probing is idle and the DIMM is not in active use
485 * in any region.
486 */
87a30e1f 487 nd_device_lock(dev);
37833fb7
DJ
488 nvdimm_bus_lock(dev);
489 wait_nvdimm_bus_probe_idle(dev);
490 rc = __security_store(dev, buf, len);
491 nvdimm_bus_unlock(dev);
87a30e1f 492 nd_device_unlock(dev);
37833fb7
DJ
493
494 return rc;
495}
496static DEVICE_ATTR_RW(security);
f2989396 497
62232e45 498static struct attribute *nvdimm_attributes[] = {
eaf96153 499 &dev_attr_state.attr,
efbf6f50 500 &dev_attr_flags.attr,
62232e45 501 &dev_attr_commands.attr,
0ba1c634 502 &dev_attr_available_slots.attr,
f2989396 503 &dev_attr_security.attr,
62232e45
DW
504 NULL,
505};
506
f2989396
DJ
507static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n)
508{
509 struct device *dev = container_of(kobj, typeof(*dev), kobj);
510 struct nvdimm *nvdimm = to_nvdimm(dev);
511
512 if (a != &dev_attr_security.attr)
513 return a->mode;
514 if (nvdimm->sec.state < 0)
515 return 0;
37833fb7 516 /* Are there any state mutation ops? */
d2a4ac73 517 if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable
64e77c8c 518 || nvdimm->sec.ops->change_key
7d988097
DJ
519 || nvdimm->sec.ops->erase
520 || nvdimm->sec.ops->overwrite)
37833fb7
DJ
521 return a->mode;
522 return 0444;
f2989396
DJ
523}
524
62232e45
DW
525struct attribute_group nvdimm_attribute_group = {
526 .attrs = nvdimm_attributes,
f2989396 527 .is_visible = nvdimm_visible,
62232e45
DW
528};
529EXPORT_SYMBOL_GPL(nvdimm_attribute_group);
530
d6548ae4
DJ
531struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
532 void *provider_data, const struct attribute_group **groups,
533 unsigned long flags, unsigned long cmd_mask, int num_flush,
f2989396
DJ
534 struct resource *flush_wpq, const char *dimm_id,
535 const struct nvdimm_security_ops *sec_ops)
e6dfb2de
DW
536{
537 struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL);
538 struct device *dev;
539
540 if (!nvdimm)
541 return NULL;
542
543 nvdimm->id = ida_simple_get(&dimm_ida, 0, 0, GFP_KERNEL);
544 if (nvdimm->id < 0) {
545 kfree(nvdimm);
546 return NULL;
547 }
d6548ae4
DJ
548
549 nvdimm->dimm_id = dimm_id;
e6dfb2de 550 nvdimm->provider_data = provider_data;
d5d30d5a
DW
551 if (noblk)
552 flags |= 1 << NDD_NOBLK;
e6dfb2de 553 nvdimm->flags = flags;
e3654eca 554 nvdimm->cmd_mask = cmd_mask;
e5ae3b25
DW
555 nvdimm->num_flush = num_flush;
556 nvdimm->flush_wpq = flush_wpq;
eaf96153 557 atomic_set(&nvdimm->busy, 0);
e6dfb2de
DW
558 dev = &nvdimm->dev;
559 dev_set_name(dev, "nmem%d", nvdimm->id);
560 dev->parent = &nvdimm_bus->dev;
561 dev->type = &nvdimm_device_type;
62232e45 562 dev->devt = MKDEV(nvdimm_major, nvdimm->id);
e6dfb2de 563 dev->groups = groups;
f2989396 564 nvdimm->sec.ops = sec_ops;
7d988097
DJ
565 nvdimm->sec.overwrite_tmo = 0;
566 INIT_DELAYED_WORK(&nvdimm->dwork, nvdimm_security_overwrite_query);
f2989396
DJ
567 /*
568 * Security state must be initialized before device_add() for
569 * attribute visibility.
570 */
89fa9d8e
DJ
571 /* get security state and extended (master) state */
572 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
573 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
4d88a97a 574 nd_device_register(dev);
e6dfb2de
DW
575
576 return nvdimm;
577}
d6548ae4 578EXPORT_SYMBOL_GPL(__nvdimm_create);
4d88a97a 579
1cd73865 580static void shutdown_security_notify(void *data)
7d988097 581{
1cd73865
DW
582 struct nvdimm *nvdimm = data;
583
584 sysfs_put(nvdimm->sec.overwrite_state);
585}
586
587int nvdimm_security_setup_events(struct device *dev)
588{
589 struct nvdimm *nvdimm = to_nvdimm(dev);
590
591 if (nvdimm->sec.state < 0 || !nvdimm->sec.ops
592 || !nvdimm->sec.ops->overwrite)
593 return 0;
594 nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, "security");
7d988097 595 if (!nvdimm->sec.overwrite_state)
1cd73865
DW
596 return -ENOMEM;
597
598 return devm_add_action_or_reset(dev, shutdown_security_notify, nvdimm);
7d988097
DJ
599}
600EXPORT_SYMBOL_GPL(nvdimm_security_setup_events);
601
602int nvdimm_in_overwrite(struct nvdimm *nvdimm)
603{
604 return test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags);
605}
606EXPORT_SYMBOL_GPL(nvdimm_in_overwrite);
607
37833fb7
DJ
608int nvdimm_security_freeze(struct nvdimm *nvdimm)
609{
610 int rc;
611
612 WARN_ON_ONCE(!is_nvdimm_bus_locked(&nvdimm->dev));
613
614 if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze)
615 return -EOPNOTSUPP;
616
617 if (nvdimm->sec.state < 0)
618 return -EIO;
619
7d988097
DJ
620 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
621 dev_warn(&nvdimm->dev, "Overwrite operation in progress.\n");
622 return -EBUSY;
623 }
624
37833fb7 625 rc = nvdimm->sec.ops->freeze(nvdimm);
89fa9d8e 626 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
37833fb7
DJ
627
628 return rc;
629}
630
762d067d 631int alias_dpa_busy(struct device *dev, void *data)
a1f3e4d6 632{
fe514739 633 resource_size_t map_end, blk_start, new;
a1f3e4d6
DW
634 struct blk_alloc_info *info = data;
635 struct nd_mapping *nd_mapping;
636 struct nd_region *nd_region;
637 struct nvdimm_drvdata *ndd;
638 struct resource *res;
639 int i;
640
c9e582aa 641 if (!is_memory(dev))
a1f3e4d6
DW
642 return 0;
643
644 nd_region = to_nd_region(dev);
645 for (i = 0; i < nd_region->ndr_mappings; i++) {
646 nd_mapping = &nd_region->mapping[i];
647 if (nd_mapping->nvdimm == info->nd_mapping->nvdimm)
648 break;
649 }
650
651 if (i >= nd_region->ndr_mappings)
652 return 0;
653
654 ndd = to_ndd(nd_mapping);
655 map_end = nd_mapping->start + nd_mapping->size - 1;
656 blk_start = nd_mapping->start;
762d067d
DW
657
658 /*
659 * In the allocation case ->res is set to free space that we are
660 * looking to validate against PMEM aliasing collision rules
661 * (i.e. BLK is allocated after all aliased PMEM).
662 */
663 if (info->res) {
664 if (info->res->start >= nd_mapping->start
665 && info->res->start < map_end)
666 /* pass */;
667 else
668 return 0;
669 }
670
a1f3e4d6
DW
671 retry:
672 /*
673 * Find the free dpa from the end of the last pmem allocation to
fe514739 674 * the end of the interleave-set mapping.
a1f3e4d6 675 */
a1f3e4d6 676 for_each_dpa_resource(ndd, res) {
fe514739
DW
677 if (strncmp(res->name, "pmem", 4) != 0)
678 continue;
a1f3e4d6
DW
679 if ((res->start >= blk_start && res->start < map_end)
680 || (res->end >= blk_start
681 && res->end <= map_end)) {
fe514739
DW
682 new = max(blk_start, min(map_end + 1, res->end + 1));
683 if (new != blk_start) {
684 blk_start = new;
685 goto retry;
686 }
a1f3e4d6
DW
687 }
688 }
689
762d067d
DW
690 /* update the free space range with the probed blk_start */
691 if (info->res && blk_start > info->res->start) {
692 info->res->start = max(info->res->start, blk_start);
693 if (info->res->start > info->res->end)
694 info->res->end = info->res->start - 1;
695 return 1;
696 }
697
fe514739 698 info->available -= blk_start - nd_mapping->start;
762d067d 699
a1f3e4d6
DW
700 return 0;
701}
702
1b40e09a
DW
703/**
704 * nd_blk_available_dpa - account the unused dpa of BLK region
705 * @nd_mapping: container of dpa-resource-root + labels
706 *
a1f3e4d6
DW
707 * Unlike PMEM, BLK namespaces can occupy discontiguous DPA ranges, but
708 * we arrange for them to never start at an lower dpa than the last
709 * PMEM allocation in an aliased region.
1b40e09a 710 */
a1f3e4d6 711resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
1b40e09a 712{
a1f3e4d6
DW
713 struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
714 struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1b40e09a 715 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
a1f3e4d6
DW
716 struct blk_alloc_info info = {
717 .nd_mapping = nd_mapping,
718 .available = nd_mapping->size,
762d067d 719 .res = NULL,
a1f3e4d6 720 };
1b40e09a
DW
721 struct resource *res;
722
723 if (!ndd)
724 return 0;
725
a1f3e4d6 726 device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
1b40e09a 727
a1f3e4d6
DW
728 /* now account for busy blk allocations in unaliased dpa */
729 for_each_dpa_resource(ndd, res) {
730 if (strncmp(res->name, "blk", 3) != 0)
731 continue;
fe514739 732 info.available -= resource_size(res);
a1f3e4d6
DW
733 }
734
735 return info.available;
1b40e09a
DW
736}
737
12e3129e
KB
738/**
739 * nd_pmem_max_contiguous_dpa - For the given dimm+region, return the max
740 * contiguous unallocated dpa range.
741 * @nd_region: constrain available space check to this reference region
742 * @nd_mapping: container of dpa-resource-root + labels
743 */
744resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
745 struct nd_mapping *nd_mapping)
746{
747 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
748 struct nvdimm_bus *nvdimm_bus;
749 resource_size_t max = 0;
750 struct resource *res;
751
752 /* if a dimm is disabled the available capacity is zero */
753 if (!ndd)
754 return 0;
755
756 nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
757 if (__reserve_free_pmem(&nd_region->dev, nd_mapping->nvdimm))
758 return 0;
759 for_each_dpa_resource(ndd, res) {
760 if (strcmp(res->name, "pmem-reserve") != 0)
761 continue;
762 if (resource_size(res) > max)
763 max = resource_size(res);
764 }
765 release_free_pmem(nvdimm_bus, nd_mapping);
766 return max;
767}
768
bf9bccc1
DW
769/**
770 * nd_pmem_available_dpa - for the given dimm+region account unallocated dpa
771 * @nd_mapping: container of dpa-resource-root + labels
772 * @nd_region: constrain available space check to this reference region
773 * @overlap: calculate available space assuming this level of overlap
774 *
775 * Validate that a PMEM label, if present, aligns with the start of an
776 * interleave set and truncate the available size at the lowest BLK
777 * overlap point.
778 *
779 * The expectation is that this routine is called multiple times as it
780 * probes for the largest BLK encroachment for any single member DIMM of
781 * the interleave set. Once that value is determined the PMEM-limit for
782 * the set can be established.
783 */
784resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
785 struct nd_mapping *nd_mapping, resource_size_t *overlap)
786{
787 resource_size_t map_start, map_end, busy = 0, available, blk_start;
788 struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
789 struct resource *res;
790 const char *reason;
791
792 if (!ndd)
793 return 0;
794
795 map_start = nd_mapping->start;
796 map_end = map_start + nd_mapping->size - 1;
797 blk_start = max(map_start, map_end + 1 - *overlap);
a1f3e4d6 798 for_each_dpa_resource(ndd, res) {
bf9bccc1
DW
799 if (res->start >= map_start && res->start < map_end) {
800 if (strncmp(res->name, "blk", 3) == 0)
a1f3e4d6
DW
801 blk_start = min(blk_start,
802 max(map_start, res->start));
803 else if (res->end > map_end) {
bf9bccc1
DW
804 reason = "misaligned to iset";
805 goto err;
a1f3e4d6 806 } else
bf9bccc1 807 busy += resource_size(res);
bf9bccc1
DW
808 } else if (res->end >= map_start && res->end <= map_end) {
809 if (strncmp(res->name, "blk", 3) == 0) {
810 /*
811 * If a BLK allocation overlaps the start of
812 * PMEM the entire interleave set may now only
813 * be used for BLK.
814 */
815 blk_start = map_start;
a1f3e4d6
DW
816 } else
817 busy += resource_size(res);
bf9bccc1
DW
818 } else if (map_start > res->start && map_start < res->end) {
819 /* total eclipse of the mapping */
820 busy += nd_mapping->size;
821 blk_start = map_start;
822 }
a1f3e4d6 823 }
bf9bccc1
DW
824
825 *overlap = map_end + 1 - blk_start;
826 available = blk_start - map_start;
827 if (busy < available)
828 return available - busy;
829 return 0;
830
831 err:
bf9bccc1
DW
832 nd_dbg_dpa(nd_region, ndd, res, "%s\n", reason);
833 return 0;
834}
835
4a826c83
DW
836void nvdimm_free_dpa(struct nvdimm_drvdata *ndd, struct resource *res)
837{
838 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev));
839 kfree(res->name);
840 __release_region(&ndd->dpa, res->start, resource_size(res));
841}
842
843struct resource *nvdimm_allocate_dpa(struct nvdimm_drvdata *ndd,
844 struct nd_label_id *label_id, resource_size_t start,
845 resource_size_t n)
846{
847 char *name = kmemdup(label_id, sizeof(*label_id), GFP_KERNEL);
848 struct resource *res;
849
850 if (!name)
851 return NULL;
852
853 WARN_ON_ONCE(!is_nvdimm_bus_locked(ndd->dev));
854 res = __request_region(&ndd->dpa, start, n, name, 0);
855 if (!res)
856 kfree(name);
857 return res;
858}
859
bf9bccc1
DW
860/**
861 * nvdimm_allocated_dpa - sum up the dpa currently allocated to this label_id
862 * @nvdimm: container of dpa-resource-root + labels
863 * @label_id: dpa resource name of the form {pmem|blk}-<human readable uuid>
864 */
865resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
866 struct nd_label_id *label_id)
867{
868 resource_size_t allocated = 0;
869 struct resource *res;
870
871 for_each_dpa_resource(ndd, res)
872 if (strcmp(res->name, label_id->id) == 0)
873 allocated += resource_size(res);
874
875 return allocated;
876}
877
4d88a97a
DW
878static int count_dimms(struct device *dev, void *c)
879{
880 int *count = c;
881
882 if (is_nvdimm(dev))
883 (*count)++;
884 return 0;
885}
886
887int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count)
888{
889 int count = 0;
890 /* Flush any possible dimm registration failures */
891 nd_synchronize();
892
893 device_for_each_child(&nvdimm_bus->dev, &count, count_dimms);
426824d6 894 dev_dbg(&nvdimm_bus->dev, "count: %d\n", count);
4d88a97a
DW
895 if (count != dimm_count)
896 return -ENXIO;
897 return 0;
898}
899EXPORT_SYMBOL_GPL(nvdimm_bus_check_dimm_count);
b354aba0
DW
900
901void __exit nvdimm_devs_exit(void)
902{
903 ida_destroy(&dimm_ida);
904}