mirror of https://github.com/xemu-project/xemu.git
emulated nvme fixes for -rc3
v3: - removed unnecessary deprecation warning v2: - added missing patches -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmBt4hEACgkQTeGvMW1P DeknCAf9H6rYJoiA/ELlQCBXtNZZExl5pqCCaN2kgUixwA5TuW4/OST2ClmThRoo RA5XdDQoATYloB6XaL5Mm+uXI7wiRrNe3WLDZsqIBRmLrLb7Vl7fH+MsO4m3dHrQ zBi4Zg2oHit8eTrhI6tUHmNdHEWyt+74bG/vVxd+wi1inXtTI3naNSoLU9ZxCZ+t 99otl4jjeqQJS/SOtHJlw2e3qPIxkTXxgFvAWITrbBxQuac1fA0jJ0CVWFCgxipv VCM7VNsinrQL/RYiknMM/O72QhnQfs90jEBr7vNsAs9zIsv4q23TFXsjRzFpVi4W h3kTb4a9OM1PPDcYDeKt3yhXmsmakg== =36si -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/nvme/tags/nvme-fixes-20210407-pull-request' into staging emulated nvme fixes for -rc3 v3: - removed unnecessary deprecation warning v2: - added missing patches # gpg: Signature made Wed 07 Apr 2021 17:47:13 BST # gpg: using RSA key 522833AA75E2DCE6A24766C04DE1AF316D4F0DE9 # gpg: Good signature from "Klaus Jensen <its@irrelevant.dk>" [unknown] # gpg: aka "Klaus Jensen <k.jensen@samsung.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: DDCA 4D9C 9EF9 31CC 3468 4272 63D5 6FC5 E55D A838 # Subkey fingerprint: 5228 33AA 75E2 DCE6 A247 66C0 4DE1 AF31 6D4F 0DE9 * remotes/nvme/tags/nvme-fixes-20210407-pull-request: hw/block/nvme: fix out-of-bounds read in nvme_subsys_ctrl hw/block/nvme: fix assert crash in nvme_subsys_ns hw/block/nvme: fix ns attachment out-of-bounds read hw/block/nvme: add missing copyright headers hw/block/nvme: fix handling of private namespaces hw/block/nvme: update dmsrl limit on namespace detachment hw/block/nvme: fix warning about legacy namespace configuration hw/block/nvme: fix the nsid 'invalid' value hw/block/nvme: fix missing string representation for ns attachment hw/block/nvme: fix pi constraint check Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1b7dabccd0
|
@ -1,3 +1,13 @@
|
|||
/*
|
||||
* QEMU NVM Express End-to-End Data Protection support
|
||||
*
|
||||
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Klaus Jensen <k.jensen@samsung.com>
|
||||
* Gollu Appalanaidu <anaidu.gollu@samsung.com>
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "sysemu/dma.h"
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
/*
|
||||
* QEMU NVM Express End-to-End Data Protection support
|
||||
*
|
||||
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Authors:
|
||||
* Klaus Jensen <k.jensen@samsung.com>
|
||||
* Gollu Appalanaidu <anaidu.gollu@samsung.com>
|
||||
*/
|
||||
|
||||
#ifndef HW_NVME_DIF_H
|
||||
#define HW_NVME_DIF_H
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
|||
/* support DULBE and I/O optimization fields */
|
||||
id_ns->nsfeat |= (0x4 | 0x10);
|
||||
|
||||
if (nvme_ns_shared(ns)) {
|
||||
if (ns->params.shared) {
|
||||
id_ns->nmic |= NVME_NMIC_NS_SHARED;
|
||||
}
|
||||
|
||||
|
@ -387,25 +387,46 @@ static void nvme_zoned_ns_shutdown(NvmeNamespace *ns)
|
|||
assert(ns->nr_open_zones == 0);
|
||||
}
|
||||
|
||||
static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp)
|
||||
static int nvme_ns_check_constraints(NvmeCtrl *n, NvmeNamespace *ns,
|
||||
Error **errp)
|
||||
{
|
||||
if (!ns->blkconf.blk) {
|
||||
error_setg(errp, "block backend not configured");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns->params.pi && !ns->params.ms) {
|
||||
if (ns->params.pi && ns->params.ms < 8) {
|
||||
error_setg(errp, "at least 8 bytes of metadata required to enable "
|
||||
"protection information");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns->params.nsid > NVME_MAX_NAMESPACES) {
|
||||
error_setg(errp, "invalid namespace id (must be between 0 and %d)",
|
||||
NVME_MAX_NAMESPACES);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!n->subsys) {
|
||||
if (ns->params.detached) {
|
||||
error_setg(errp, "detached requires that the nvme device is "
|
||||
"linked to an nvme-subsys device");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ns->params.shared) {
|
||||
error_setg(errp, "shared requires that the nvme device is "
|
||||
"linked to an nvme-subsys device");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvme_ns_setup(NvmeNamespace *ns, Error **errp)
|
||||
int nvme_ns_setup(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
if (nvme_ns_check_constraints(ns, errp)) {
|
||||
if (nvme_ns_check_constraints(n, ns, errp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -453,27 +474,62 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
|
|||
NvmeNamespace *ns = NVME_NS(dev);
|
||||
BusState *s = qdev_get_parent_bus(dev);
|
||||
NvmeCtrl *n = NVME(s->parent);
|
||||
NvmeSubsystem *subsys = n->subsys;
|
||||
uint32_t nsid = ns->params.nsid;
|
||||
int i;
|
||||
|
||||
if (nvme_ns_setup(ns, errp)) {
|
||||
if (nvme_ns_setup(n, ns, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ns->subsys) {
|
||||
if (nvme_subsys_register_ns(ns, errp)) {
|
||||
if (!nsid) {
|
||||
for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
|
||||
if (nvme_ns(n, i) || nvme_subsys_ns(subsys, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsid = ns->params.nsid = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nsid) {
|
||||
error_setg(errp, "no free namespace id");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (nvme_register_namespace(n, ns, errp)) {
|
||||
if (nvme_ns(n, nsid) || nvme_subsys_ns(subsys, nsid)) {
|
||||
error_setg(errp, "namespace id '%d' already allocated", nsid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (subsys) {
|
||||
subsys->namespaces[nsid] = ns;
|
||||
|
||||
if (ns->params.detached) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ns->params.shared) {
|
||||
for (i = 0; i < ARRAY_SIZE(subsys->ctrls); i++) {
|
||||
NvmeCtrl *ctrl = subsys->ctrls[i];
|
||||
|
||||
if (ctrl) {
|
||||
nvme_attach_ns(ctrl, ns);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nvme_attach_ns(n, ns);
|
||||
}
|
||||
|
||||
static Property nvme_ns_props[] = {
|
||||
DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
|
||||
DEFINE_PROP_LINK("subsys", NvmeNamespace, subsys, TYPE_NVME_SUBSYS,
|
||||
NvmeSubsystem *),
|
||||
DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false),
|
||||
DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, false),
|
||||
DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
|
||||
DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
|
||||
DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0),
|
||||
|
|
|
@ -29,6 +29,7 @@ typedef struct NvmeZone {
|
|||
|
||||
typedef struct NvmeNamespaceParams {
|
||||
bool detached;
|
||||
bool shared;
|
||||
uint32_t nsid;
|
||||
QemuUUID uuid;
|
||||
|
||||
|
@ -60,8 +61,8 @@ typedef struct NvmeNamespace {
|
|||
const uint32_t *iocs;
|
||||
uint8_t csi;
|
||||
uint16_t status;
|
||||
int attached;
|
||||
|
||||
NvmeSubsystem *subsys;
|
||||
QTAILQ_ENTRY(NvmeNamespace) entry;
|
||||
|
||||
NvmeIdNsZoned *id_ns_zoned;
|
||||
|
@ -96,12 +97,7 @@ static inline uint32_t nvme_nsid(NvmeNamespace *ns)
|
|||
return ns->params.nsid;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline bool nvme_ns_shared(NvmeNamespace *ns)
|
||||
{
|
||||
return !!ns->subsys;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline NvmeLBAF *nvme_ns_lbaf(NvmeNamespace *ns)
|
||||
|
@ -225,7 +221,7 @@ static inline void nvme_aor_dec_active(NvmeNamespace *ns)
|
|||
}
|
||||
|
||||
void nvme_ns_init_format(NvmeNamespace *ns);
|
||||
int nvme_ns_setup(NvmeNamespace *ns, Error **errp);
|
||||
int nvme_ns_setup(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
|
||||
void nvme_ns_drain(NvmeNamespace *ns);
|
||||
void nvme_ns_shutdown(NvmeNamespace *ns);
|
||||
void nvme_ns_cleanup(NvmeNamespace *ns);
|
||||
|
|
|
@ -43,34 +43,6 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp)
|
|||
return cntlid;
|
||||
}
|
||||
|
||||
int nvme_subsys_register_ns(NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
NvmeSubsystem *subsys = ns->subsys;
|
||||
NvmeCtrl *n;
|
||||
uint32_t nsid = nvme_nsid(ns);
|
||||
int i;
|
||||
|
||||
assert(nsid && nsid <= NVME_SUBSYS_MAX_NAMESPACES);
|
||||
|
||||
if (subsys->namespaces[nsid]) {
|
||||
error_setg(errp, "namespace %d already registerd to subsy %s",
|
||||
nvme_nsid(ns), subsys->parent_obj.id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
subsys->namespaces[nsid] = ns;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(subsys->ctrls); i++) {
|
||||
n = subsys->ctrls[i];
|
||||
|
||||
if (n && nvme_register_namespace(n, ns, errp)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvme_subsys_setup(NvmeSubsystem *subsys)
|
||||
{
|
||||
const char *nqn = subsys->params.nqn ?
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
|
||||
|
||||
#define NVME_SUBSYS_MAX_CTRLS 32
|
||||
#define NVME_SUBSYS_MAX_NAMESPACES 256
|
||||
#define NVME_MAX_NAMESPACES 256
|
||||
|
||||
typedef struct NvmeCtrl NvmeCtrl;
|
||||
typedef struct NvmeNamespace NvmeNamespace;
|
||||
|
@ -24,7 +24,7 @@ typedef struct NvmeSubsystem {
|
|||
|
||||
NvmeCtrl *ctrls[NVME_SUBSYS_MAX_CTRLS];
|
||||
/* Allocated namespaces for this subsystem */
|
||||
NvmeNamespace *namespaces[NVME_SUBSYS_MAX_NAMESPACES + 1];
|
||||
NvmeNamespace *namespaces[NVME_MAX_NAMESPACES + 1];
|
||||
|
||||
struct {
|
||||
char *nqn;
|
||||
|
@ -32,12 +32,11 @@ typedef struct NvmeSubsystem {
|
|||
} NvmeSubsystem;
|
||||
|
||||
int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
|
||||
int nvme_subsys_register_ns(NvmeNamespace *ns, Error **errp);
|
||||
|
||||
static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
|
||||
uint32_t cntlid)
|
||||
{
|
||||
if (!subsys) {
|
||||
if (!subsys || cntlid >= NVME_SUBSYS_MAX_CTRLS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -50,12 +49,10 @@ static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
|
|||
static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
|
||||
uint32_t nsid)
|
||||
{
|
||||
if (!subsys) {
|
||||
if (!subsys || !nsid || nsid > NVME_MAX_NAMESPACES) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(nsid && nsid <= NVME_SUBSYS_MAX_NAMESPACES);
|
||||
|
||||
return subsys->namespaces[nsid];
|
||||
}
|
||||
|
||||
|
|
142
hw/block/nvme.c
142
hw/block/nvme.c
|
@ -93,10 +93,13 @@
|
|||
*
|
||||
* nvme namespace device parameters
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* - `subsys`
|
||||
* If given, the namespace will be attached to all controllers in the
|
||||
* subsystem. Otherwise, `bus` must be given to attach this namespace to a
|
||||
* specific controller as a non-shared namespace.
|
||||
* - `shared`
|
||||
* When the parent nvme device (as defined explicitly by the 'bus' parameter
|
||||
* or implicitly by the most recently defined NvmeBus) is linked to an
|
||||
* nvme-subsys device, the namespace will be attached to all controllers in
|
||||
* the subsystem. If set to 'off' (the default), the namespace will remain a
|
||||
* private namespace and may only be attached to a single controller at a
|
||||
* time.
|
||||
*
|
||||
* - `detached`
|
||||
* This parameter is only valid together with the `subsys` parameter. If left
|
||||
|
@ -4242,7 +4245,7 @@ static uint16_t nvme_identify_ns_attached_list(NvmeCtrl *n, NvmeRequest *req)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!nvme_ns_is_attached(ctrl, ns)) {
|
||||
if (!nvme_ns(ctrl, c->nsid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4868,6 +4871,21 @@ static uint16_t nvme_aer(NvmeCtrl *n, NvmeRequest *req)
|
|||
return NVME_NO_COMPLETE;
|
||||
}
|
||||
|
||||
static void nvme_update_dmrsl(NvmeCtrl *n)
|
||||
{
|
||||
int nsid;
|
||||
|
||||
for (nsid = 1; nsid <= NVME_MAX_NAMESPACES; nsid++) {
|
||||
NvmeNamespace *ns = nvme_ns(n, nsid);
|
||||
if (!ns) {
|
||||
continue;
|
||||
}
|
||||
|
||||
n->dmrsl = MIN_NON_ZERO(n->dmrsl,
|
||||
BDRV_REQUEST_MAX_BYTES / nvme_l2b(ns, 1));
|
||||
}
|
||||
}
|
||||
|
||||
static void __nvme_select_ns_iocs(NvmeCtrl *n, NvmeNamespace *ns);
|
||||
static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req)
|
||||
{
|
||||
|
@ -4884,6 +4902,10 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req)
|
|||
|
||||
trace_pci_nvme_ns_attachment(nvme_cid(req), dw10 & 0xf);
|
||||
|
||||
if (!nvme_nsid_valid(n, nsid)) {
|
||||
return NVME_INVALID_NSID | NVME_DNR;
|
||||
}
|
||||
|
||||
ns = nvme_subsys_ns(n->subsys, nsid);
|
||||
if (!ns) {
|
||||
return NVME_INVALID_FIELD | NVME_DNR;
|
||||
|
@ -4898,6 +4920,7 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req)
|
|||
return NVME_NS_CTRL_LIST_INVALID | NVME_DNR;
|
||||
}
|
||||
|
||||
*nr_ids = MIN(*nr_ids, NVME_CONTROLLER_LIST_SIZE - 1);
|
||||
for (i = 0; i < *nr_ids; i++) {
|
||||
ctrl = nvme_subsys_ctrl(n->subsys, ids[i]);
|
||||
if (!ctrl) {
|
||||
|
@ -4905,18 +4928,25 @@ static uint16_t nvme_ns_attachment(NvmeCtrl *n, NvmeRequest *req)
|
|||
}
|
||||
|
||||
if (attach) {
|
||||
if (nvme_ns_is_attached(ctrl, ns)) {
|
||||
if (nvme_ns(ctrl, nsid)) {
|
||||
return NVME_NS_ALREADY_ATTACHED | NVME_DNR;
|
||||
}
|
||||
|
||||
nvme_ns_attach(ctrl, ns);
|
||||
if (ns->attached && !ns->params.shared) {
|
||||
return NVME_NS_PRIVATE | NVME_DNR;
|
||||
}
|
||||
|
||||
nvme_attach_ns(ctrl, ns);
|
||||
__nvme_select_ns_iocs(ctrl, ns);
|
||||
} else {
|
||||
if (!nvme_ns_is_attached(ctrl, ns)) {
|
||||
if (!nvme_ns(ctrl, nsid)) {
|
||||
return NVME_NS_NOT_ATTACHED | NVME_DNR;
|
||||
}
|
||||
|
||||
nvme_ns_detach(ctrl, ns);
|
||||
ctrl->namespaces[nsid - 1] = NULL;
|
||||
ns->attached--;
|
||||
|
||||
nvme_update_dmrsl(ctrl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5805,9 +5835,10 @@ static void nvme_check_constraints(NvmeCtrl *n, Error **errp)
|
|||
params->max_ioqpairs = params->num_queues - 1;
|
||||
}
|
||||
|
||||
if (n->conf.blk) {
|
||||
warn_report("drive property is deprecated; "
|
||||
"please use an nvme-ns device instead");
|
||||
if (n->namespace.blkconf.blk && n->subsys) {
|
||||
error_setg(errp, "subsystem support is unavailable with legacy "
|
||||
"namespace ('drive' property)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->max_ioqpairs < 1 ||
|
||||
|
@ -5870,75 +5901,6 @@ static void nvme_init_state(NvmeCtrl *n)
|
|||
n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1);
|
||||
}
|
||||
|
||||
static int nvme_attach_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
if (nvme_ns_is_attached(n, ns)) {
|
||||
error_setg(errp,
|
||||
"namespace %d is already attached to controller %d",
|
||||
nvme_nsid(ns), n->cntlid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nvme_ns_attach(n, ns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
uint32_t nsid = nvme_nsid(ns);
|
||||
|
||||
if (nsid > NVME_MAX_NAMESPACES) {
|
||||
error_setg(errp, "invalid namespace id (must be between 0 and %d)",
|
||||
NVME_MAX_NAMESPACES);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!nsid) {
|
||||
for (int i = 1; i <= n->num_namespaces; i++) {
|
||||
if (!nvme_ns(n, i)) {
|
||||
nsid = ns->params.nsid = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nsid) {
|
||||
error_setg(errp, "no free namespace id");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (n->namespaces[nsid - 1]) {
|
||||
error_setg(errp, "namespace id '%d' is already in use", nsid);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
trace_pci_nvme_register_namespace(nsid);
|
||||
|
||||
/*
|
||||
* If subsys is not given, namespae is always attached to the controller
|
||||
* because there's no subsystem to manage namespace allocation.
|
||||
*/
|
||||
if (!n->subsys) {
|
||||
if (ns->params.detached) {
|
||||
error_setg(errp,
|
||||
"detached needs nvme-subsys specified nvme or nvme-ns");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nvme_attach_namespace(n, ns, errp);
|
||||
} else {
|
||||
if (!ns->params.detached) {
|
||||
return nvme_attach_namespace(n, ns, errp);
|
||||
}
|
||||
}
|
||||
|
||||
n->dmrsl = MIN_NON_ZERO(n->dmrsl,
|
||||
BDRV_REQUEST_MAX_BYTES / nvme_l2b(ns, 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvme_init_cmb(NvmeCtrl *n, PCIDevice *pci_dev)
|
||||
{
|
||||
uint64_t cmb_size = n->params.cmb_size_mb * MiB;
|
||||
|
@ -6168,6 +6130,18 @@ static int nvme_init_subsys(NvmeCtrl *n, Error **errp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns)
|
||||
{
|
||||
uint32_t nsid = ns->params.nsid;
|
||||
assert(nsid && nsid <= NVME_MAX_NAMESPACES);
|
||||
|
||||
n->namespaces[nsid - 1] = ns;
|
||||
ns->attached++;
|
||||
|
||||
n->dmrsl = MIN_NON_ZERO(n->dmrsl,
|
||||
BDRV_REQUEST_MAX_BYTES / nvme_l2b(ns, 1));
|
||||
}
|
||||
|
||||
static void nvme_realize(PCIDevice *pci_dev, Error **errp)
|
||||
{
|
||||
NvmeCtrl *n = NVME(pci_dev);
|
||||
|
@ -6199,13 +6173,11 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
|
|||
ns = &n->namespace;
|
||||
ns->params.nsid = 1;
|
||||
|
||||
if (nvme_ns_setup(ns, errp)) {
|
||||
if (nvme_ns_setup(n, ns, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (nvme_register_namespace(n, ns, errp)) {
|
||||
return;
|
||||
}
|
||||
nvme_attach_ns(n, ns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,9 @@
|
|||
#include "nvme-subsys.h"
|
||||
#include "nvme-ns.h"
|
||||
|
||||
#define NVME_MAX_NAMESPACES 256
|
||||
|
||||
#define NVME_DEFAULT_ZONE_SIZE (128 * MiB)
|
||||
#define NVME_DEFAULT_MAX_ZA_SIZE (128 * KiB)
|
||||
|
||||
/*
|
||||
* Subsystem namespace list for allocated namespaces should be larger than
|
||||
* attached namespace list in a controller.
|
||||
*/
|
||||
QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_SUBSYS_MAX_NAMESPACES);
|
||||
|
||||
typedef struct NvmeParams {
|
||||
char *serial;
|
||||
uint32_t num_queues; /* deprecated since 5.1 */
|
||||
|
@ -86,6 +78,7 @@ static inline const char *nvme_adm_opc_str(uint8_t opc)
|
|||
case NVME_ADM_CMD_SET_FEATURES: return "NVME_ADM_CMD_SET_FEATURES";
|
||||
case NVME_ADM_CMD_GET_FEATURES: return "NVME_ADM_CMD_GET_FEATURES";
|
||||
case NVME_ADM_CMD_ASYNC_EV_REQ: return "NVME_ADM_CMD_ASYNC_EV_REQ";
|
||||
case NVME_ADM_CMD_NS_ATTACHMENT: return "NVME_ADM_CMD_NS_ATTACHMENT";
|
||||
case NVME_ADM_CMD_FORMAT_NVM: return "NVME_ADM_CMD_FORMAT_NVM";
|
||||
default: return "NVME_ADM_CMD_UNKNOWN";
|
||||
}
|
||||
|
@ -165,7 +158,6 @@ typedef struct NvmeCtrl {
|
|||
NvmeBar bar;
|
||||
NvmeParams params;
|
||||
NvmeBus bus;
|
||||
BlockConf conf;
|
||||
|
||||
uint16_t cntlid;
|
||||
bool qs_created;
|
||||
|
@ -234,35 +226,6 @@ static inline NvmeNamespace *nvme_ns(NvmeCtrl *n, uint32_t nsid)
|
|||
return n->namespaces[nsid - 1];
|
||||
}
|
||||
|
||||
static inline bool nvme_ns_is_attached(NvmeCtrl *n, NvmeNamespace *ns)
|
||||
{
|
||||
int nsid;
|
||||
|
||||
for (nsid = 1; nsid <= n->num_namespaces; nsid++) {
|
||||
if (nvme_ns(n, nsid) == ns) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void nvme_ns_attach(NvmeCtrl *n, NvmeNamespace *ns)
|
||||
{
|
||||
uint32_t nsid = nvme_nsid(ns);
|
||||
assert(nsid && nsid <= NVME_MAX_NAMESPACES);
|
||||
|
||||
n->namespaces[nsid - 1] = ns;
|
||||
}
|
||||
|
||||
static inline void nvme_ns_detach(NvmeCtrl *n, NvmeNamespace *ns)
|
||||
{
|
||||
uint32_t nsid = nvme_nsid(ns);
|
||||
assert(nsid && nsid <= NVME_MAX_NAMESPACES);
|
||||
|
||||
n->namespaces[nsid - 1] = NULL;
|
||||
}
|
||||
|
||||
static inline NvmeCQueue *nvme_cq(NvmeRequest *req)
|
||||
{
|
||||
NvmeSQueue *sq = req->sq;
|
||||
|
@ -291,7 +254,7 @@ typedef enum NvmeTxDirection {
|
|||
NVME_TX_DIRECTION_FROM_DEVICE = 1,
|
||||
} NvmeTxDirection;
|
||||
|
||||
int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp);
|
||||
void nvme_attach_ns(NvmeCtrl *n, NvmeNamespace *ns);
|
||||
uint16_t nvme_bounce_data(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
|
||||
NvmeTxDirection dir, NvmeRequest *req);
|
||||
uint16_t nvme_bounce_mdata(NvmeCtrl *n, uint8_t *ptr, uint32_t len,
|
||||
|
|
|
@ -51,7 +51,6 @@ hd_geometry_guess(void *blk, uint32_t cyls, uint32_t heads, uint32_t secs, int t
|
|||
|
||||
# nvme.c
|
||||
# nvme traces for successful events
|
||||
pci_nvme_register_namespace(uint32_t nsid) "nsid %"PRIu32""
|
||||
pci_nvme_irq_msix(uint32_t vector) "raising MSI-X IRQ vector %u"
|
||||
pci_nvme_irq_pin(void) "pulsing IRQ pin"
|
||||
pci_nvme_irq_masked(void) "IRQ is masked"
|
||||
|
|
|
@ -847,6 +847,7 @@ enum NvmeStatusCodes {
|
|||
NVME_FEAT_NOT_NS_SPEC = 0x010f,
|
||||
NVME_FW_REQ_SUSYSTEM_RESET = 0x0110,
|
||||
NVME_NS_ALREADY_ATTACHED = 0x0118,
|
||||
NVME_NS_PRIVATE = 0x0119,
|
||||
NVME_NS_NOT_ATTACHED = 0x011A,
|
||||
NVME_NS_CTRL_LIST_INVALID = 0x011C,
|
||||
NVME_CONFLICTING_ATTRS = 0x0180,
|
||||
|
|
Loading…
Reference in New Issue