aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/dimm_devs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvdimm/dimm_devs.c')
-rw-r--r--drivers/nvdimm/dimm_devs.c134
1 files changed, 31 insertions, 103 deletions
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index 29a065e769ea..196aa44c4936 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -372,106 +372,26 @@ __weak ssize_t security_show(struct device *dev,
372{ 372{
373 struct nvdimm *nvdimm = to_nvdimm(dev); 373 struct nvdimm *nvdimm = to_nvdimm(dev);
374 374
375 switch (nvdimm->sec.state) { 375 if (test_bit(NVDIMM_SECURITY_DISABLED, &nvdimm->sec.flags))
376 case NVDIMM_SECURITY_DISABLED:
377 return sprintf(buf, "disabled\n"); 376 return sprintf(buf, "disabled\n");
378 case NVDIMM_SECURITY_UNLOCKED: 377 if (test_bit(NVDIMM_SECURITY_UNLOCKED, &nvdimm->sec.flags))
379 return sprintf(buf, "unlocked\n"); 378 return sprintf(buf, "unlocked\n");
380 case NVDIMM_SECURITY_LOCKED: 379 if (test_bit(NVDIMM_SECURITY_LOCKED, &nvdimm->sec.flags))
381 return sprintf(buf, "locked\n"); 380 return sprintf(buf, "locked\n");
382 case NVDIMM_SECURITY_FROZEN: 381 if (test_bit(NVDIMM_SECURITY_OVERWRITE, &nvdimm->sec.flags))
383 return sprintf(buf, "frozen\n");
384 case NVDIMM_SECURITY_OVERWRITE:
385 return sprintf(buf, "overwrite\n"); 382 return sprintf(buf, "overwrite\n");
386 default:
387 return -ENOTTY;
388 }
389
390 return -ENOTTY; 383 return -ENOTTY;
391} 384}
392 385
393#define OPS \ 386static ssize_t frozen_show(struct device *dev,
394 C( OP_FREEZE, "freeze", 1), \ 387 struct device_attribute *attr, char *buf)
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)
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
415static ssize_t __security_store(struct device *dev, const char *buf, size_t len)
416{ 388{
417 struct nvdimm *nvdimm = to_nvdimm(dev); 389 struct nvdimm *nvdimm = to_nvdimm(dev);
418 ssize_t rc;
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;
423 390
424 if (atomic_read(&nvdimm->busy)) 391 return sprintf(buf, "%d\n", test_bit(NVDIMM_SECURITY_FROZEN,
425 return -EBUSY; 392 &nvdimm->sec.flags));
426
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) {
446 dev_dbg(dev, "freeze\n");
447 rc = nvdimm_security_freeze(nvdimm);
448 } else if (i == OP_DISABLE) {
449 dev_dbg(dev, "disable %u\n", key);
450 rc = nvdimm_security_disable(nvdimm, key);
451 } else if (i == OP_UPDATE) {
452 dev_dbg(dev, "update %u %u\n", key, newkey);
453 rc = nvdimm_security_update(nvdimm, key, newkey, NVDIMM_USER);
454 } else if (i == OP_ERASE) {
455 dev_dbg(dev, "erase %u\n", key);
456 rc = nvdimm_security_erase(nvdimm, key, NVDIMM_USER);
457 } else if (i == OP_OVERWRITE) {
458 dev_dbg(dev, "overwrite %u\n", key);
459 rc = nvdimm_security_overwrite(nvdimm, key);
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);
468 } else
469 return -EINVAL;
470
471 if (rc == 0)
472 rc = len;
473 return rc;
474} 393}
394static DEVICE_ATTR_RO(frozen);
475 395
476static ssize_t security_store(struct device *dev, 396static ssize_t security_store(struct device *dev,
477 struct device_attribute *attr, const char *buf, size_t len) 397 struct device_attribute *attr, const char *buf, size_t len)
@@ -487,7 +407,7 @@ static ssize_t security_store(struct device *dev,
487 nd_device_lock(dev); 407 nd_device_lock(dev);
488 nvdimm_bus_lock(dev); 408 nvdimm_bus_lock(dev);
489 wait_nvdimm_bus_probe_idle(dev); 409 wait_nvdimm_bus_probe_idle(dev);
490 rc = __security_store(dev, buf, len); 410 rc = nvdimm_security_store(dev, buf, len);
491 nvdimm_bus_unlock(dev); 411 nvdimm_bus_unlock(dev);
492 nd_device_unlock(dev); 412 nd_device_unlock(dev);
493 413
@@ -501,6 +421,7 @@ static struct attribute *nvdimm_attributes[] = {
501 &dev_attr_commands.attr, 421 &dev_attr_commands.attr,
502 &dev_attr_available_slots.attr, 422 &dev_attr_available_slots.attr,
503 &dev_attr_security.attr, 423 &dev_attr_security.attr,
424 &dev_attr_frozen.attr,
504 NULL, 425 NULL,
505}; 426};
506 427
@@ -509,17 +430,24 @@ static umode_t nvdimm_visible(struct kobject *kobj, struct attribute *a, int n)
509 struct device *dev = container_of(kobj, typeof(*dev), kobj); 430 struct device *dev = container_of(kobj, typeof(*dev), kobj);
510 struct nvdimm *nvdimm = to_nvdimm(dev); 431 struct nvdimm *nvdimm = to_nvdimm(dev);
511 432
512 if (a != &dev_attr_security.attr) 433 if (a != &dev_attr_security.attr && a != &dev_attr_frozen.attr)
513 return a->mode; 434 return a->mode;
514 if (nvdimm->sec.state < 0) 435 if (!nvdimm->sec.flags)
515 return 0; 436 return 0;
516 /* Are there any state mutation ops? */ 437
517 if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable 438 if (a == &dev_attr_security.attr) {
518 || nvdimm->sec.ops->change_key 439 /* Are there any state mutation ops (make writable)? */
519 || nvdimm->sec.ops->erase 440 if (nvdimm->sec.ops->freeze || nvdimm->sec.ops->disable
520 || nvdimm->sec.ops->overwrite) 441 || nvdimm->sec.ops->change_key
442 || nvdimm->sec.ops->erase
443 || nvdimm->sec.ops->overwrite)
444 return a->mode;
445 return 0444;
446 }
447
448 if (nvdimm->sec.ops->freeze)
521 return a->mode; 449 return a->mode;
522 return 0444; 450 return 0;
523} 451}
524 452
525struct attribute_group nvdimm_attribute_group = { 453struct attribute_group nvdimm_attribute_group = {
@@ -569,8 +497,8 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus,
569 * attribute visibility. 497 * attribute visibility.
570 */ 498 */
571 /* get security state and extended (master) state */ 499 /* get security state and extended (master) state */
572 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); 500 nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
573 nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER); 501 nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER);
574 nd_device_register(dev); 502 nd_device_register(dev);
575 503
576 return nvdimm; 504 return nvdimm;
@@ -588,7 +516,7 @@ int nvdimm_security_setup_events(struct device *dev)
588{ 516{
589 struct nvdimm *nvdimm = to_nvdimm(dev); 517 struct nvdimm *nvdimm = to_nvdimm(dev);
590 518
591 if (nvdimm->sec.state < 0 || !nvdimm->sec.ops 519 if (!nvdimm->sec.flags || !nvdimm->sec.ops
592 || !nvdimm->sec.ops->overwrite) 520 || !nvdimm->sec.ops->overwrite)
593 return 0; 521 return 0;
594 nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, "security"); 522 nvdimm->sec.overwrite_state = sysfs_get_dirent(dev->kobj.sd, "security");
@@ -614,7 +542,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
614 if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze) 542 if (!nvdimm->sec.ops || !nvdimm->sec.ops->freeze)
615 return -EOPNOTSUPP; 543 return -EOPNOTSUPP;
616 544
617 if (nvdimm->sec.state < 0) 545 if (!nvdimm->sec.flags)
618 return -EIO; 546 return -EIO;
619 547
620 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) { 548 if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
@@ -623,7 +551,7 @@ int nvdimm_security_freeze(struct nvdimm *nvdimm)
623 } 551 }
624 552
625 rc = nvdimm->sec.ops->freeze(nvdimm); 553 rc = nvdimm->sec.ops->freeze(nvdimm);
626 nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER); 554 nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER);
627 555
628 return rc; 556 return rc;
629} 557}