^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ndctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/nd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "label.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "nd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int nvdimm_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct nvdimm_drvdata *ndd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) rc = nvdimm_security_setup_events(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) dev_err(dev, "security event setup failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) rc = nvdimm_check_config_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* not required for non-aliased nvdimm, ex. NVDIMM-N */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (rc == -ENOTTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * The locked status bit reflects explicit status codes from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * label reading commands, revalidate it each time the driver is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * activated and re-reads the label area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) nvdimm_clear_locked(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!ndd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dev_set_drvdata(dev, ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ndd->dpa.name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ndd->ns_current = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ndd->ns_next = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ndd->dpa.start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ndd->dpa.end = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ndd->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) get_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) kref_init(&ndd->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Attempt to unlock, if the DIMM supports security commands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * otherwise the locked indication is determined by explicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * status codes from the label reading commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) rc = nvdimm_security_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_dbg(dev, "failed to unlock dimm: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * EACCES failures reading the namespace label-area-properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * are interpreted as the DIMM capacity being locked but the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * namespace labels themselves being accessible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) rc = nvdimm_init_nsarea(ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (rc == -EACCES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * See nvdimm_namespace_common_probe() where we fail to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * allow namespaces to probe while the DIMM is locked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * but we do allow for namespace enumeration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) nvdimm_set_locked(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * EACCES failures reading the namespace label-data are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * interpreted as the label area being locked in addition to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * DIMM capacity. We fail the dimm probe to prevent regions from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * attempting to parse the label area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) rc = nd_label_data_init(ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (rc == -EACCES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) nvdimm_set_locked(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dev_dbg(dev, "config data size: %d\n", ndd->nsarea.config_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) nvdimm_bus_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ndd->ns_current >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rc = nd_label_reserve_dpa(ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) nvdimm_set_labeling(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) nvdimm_bus_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) put_ndd(ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int nvdimm_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!ndd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) nvdimm_bus_lock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dev_set_drvdata(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) nvdimm_bus_unlock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) put_ndd(ndd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static struct nd_device_driver nvdimm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .probe = nvdimm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .remove = nvdimm_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .name = "nvdimm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .type = ND_DRIVER_DIMM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int __init nvdimm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return nd_driver_register(&nvdimm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void nvdimm_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) driver_unregister(&nvdimm_driver.drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) MODULE_ALIAS_ND_DEVICE(ND_DEVICE_DIMM);