qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ns.c (20418B)


      1 /*
      2  * QEMU NVM Express Virtual Namespace
      3  *
      4  * Copyright (c) 2019 CNEX Labs
      5  * Copyright (c) 2020 Samsung Electronics
      6  *
      7  * Authors:
      8  *  Klaus Jensen      <k.jensen@samsung.com>
      9  *
     10  * This work is licensed under the terms of the GNU GPL, version 2. See the
     11  * COPYING file in the top-level directory.
     12  *
     13  */
     14 
     15 #include "qemu/osdep.h"
     16 #include "qemu/units.h"
     17 #include "qemu/error-report.h"
     18 #include "qapi/error.h"
     19 #include "sysemu/sysemu.h"
     20 #include "sysemu/block-backend.h"
     21 
     22 #include "nvme.h"
     23 #include "trace.h"
     24 
     25 #define MIN_DISCARD_GRANULARITY (4 * KiB)
     26 #define NVME_DEFAULT_ZONE_SIZE   (128 * MiB)
     27 
     28 void nvme_ns_init_format(NvmeNamespace *ns)
     29 {
     30     NvmeIdNs *id_ns = &ns->id_ns;
     31     BlockDriverInfo bdi;
     32     int npdg, ret;
     33     int64_t nlbas;
     34 
     35     ns->lbaf = id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(id_ns->flbas)];
     36     ns->lbasz = 1 << ns->lbaf.ds;
     37 
     38     nlbas = ns->size / (ns->lbasz + ns->lbaf.ms);
     39 
     40     id_ns->nsze = cpu_to_le64(nlbas);
     41 
     42     /* no thin provisioning */
     43     id_ns->ncap = id_ns->nsze;
     44     id_ns->nuse = id_ns->ncap;
     45 
     46     ns->moff = nlbas << ns->lbaf.ds;
     47 
     48     npdg = ns->blkconf.discard_granularity / ns->lbasz;
     49 
     50     ret = bdrv_get_info(blk_bs(ns->blkconf.blk), &bdi);
     51     if (ret >= 0 && bdi.cluster_size > ns->blkconf.discard_granularity) {
     52         npdg = bdi.cluster_size / ns->lbasz;
     53     }
     54 
     55     id_ns->npda = id_ns->npdg = npdg - 1;
     56 }
     57 
     58 static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
     59 {
     60     static uint64_t ns_count;
     61     NvmeIdNs *id_ns = &ns->id_ns;
     62     NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm;
     63     uint8_t ds;
     64     uint16_t ms;
     65     int i;
     66 
     67     ns->csi = NVME_CSI_NVM;
     68     ns->status = 0x0;
     69 
     70     ns->id_ns.dlfeat = 0x1;
     71 
     72     /* support DULBE and I/O optimization fields */
     73     id_ns->nsfeat |= (0x4 | 0x10);
     74 
     75     if (ns->params.shared) {
     76         id_ns->nmic |= NVME_NMIC_NS_SHARED;
     77     }
     78 
     79     /* Substitute a missing EUI-64 by an autogenerated one */
     80     ++ns_count;
     81     if (!ns->params.eui64 && ns->params.eui64_default) {
     82         ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT;
     83     }
     84 
     85     /* simple copy */
     86     id_ns->mssrl = cpu_to_le16(ns->params.mssrl);
     87     id_ns->mcl = cpu_to_le32(ns->params.mcl);
     88     id_ns->msrc = ns->params.msrc;
     89     id_ns->eui64 = cpu_to_be64(ns->params.eui64);
     90 
     91     ds = 31 - clz32(ns->blkconf.logical_block_size);
     92     ms = ns->params.ms;
     93 
     94     id_ns->mc = NVME_ID_NS_MC_EXTENDED | NVME_ID_NS_MC_SEPARATE;
     95 
     96     if (ms && ns->params.mset) {
     97         id_ns->flbas |= NVME_ID_NS_FLBAS_EXTENDED;
     98     }
     99 
    100     id_ns->dpc = 0x1f;
    101     id_ns->dps = ns->params.pi;
    102     if (ns->params.pi && ns->params.pil) {
    103         id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT;
    104     }
    105 
    106     ns->pif = ns->params.pif;
    107 
    108     static const NvmeLBAF lbaf[16] = {
    109         [0] = { .ds =  9           },
    110         [1] = { .ds =  9, .ms =  8 },
    111         [2] = { .ds =  9, .ms = 16 },
    112         [3] = { .ds =  9, .ms = 64 },
    113         [4] = { .ds = 12           },
    114         [5] = { .ds = 12, .ms =  8 },
    115         [6] = { .ds = 12, .ms = 16 },
    116         [7] = { .ds = 12, .ms = 64 },
    117     };
    118 
    119     ns->nlbaf = 8;
    120 
    121     memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
    122 
    123     for (i = 0; i < ns->nlbaf; i++) {
    124         NvmeLBAF *lbaf = &id_ns->lbaf[i];
    125         if (lbaf->ds == ds) {
    126             if (lbaf->ms == ms) {
    127                 id_ns->flbas |= i;
    128                 goto lbaf_found;
    129             }
    130         }
    131     }
    132 
    133     /* add non-standard lba format */
    134     id_ns->lbaf[ns->nlbaf].ds = ds;
    135     id_ns->lbaf[ns->nlbaf].ms = ms;
    136     ns->nlbaf++;
    137 
    138     id_ns->flbas |= i;
    139 
    140 
    141 lbaf_found:
    142     id_ns_nvm->elbaf[i] = (ns->pif & 0x3) << 7;
    143     id_ns->nlbaf = ns->nlbaf - 1;
    144     nvme_ns_init_format(ns);
    145 
    146     return 0;
    147 }
    148 
    149 static int nvme_ns_init_blk(NvmeNamespace *ns, Error **errp)
    150 {
    151     bool read_only;
    152 
    153     if (!blkconf_blocksizes(&ns->blkconf, errp)) {
    154         return -1;
    155     }
    156 
    157     read_only = !blk_supports_write_perm(ns->blkconf.blk);
    158     if (!blkconf_apply_backend_options(&ns->blkconf, read_only, false, errp)) {
    159         return -1;
    160     }
    161 
    162     if (ns->blkconf.discard_granularity == -1) {
    163         ns->blkconf.discard_granularity =
    164             MAX(ns->blkconf.logical_block_size, MIN_DISCARD_GRANULARITY);
    165     }
    166 
    167     ns->size = blk_getlength(ns->blkconf.blk);
    168     if (ns->size < 0) {
    169         error_setg_errno(errp, -ns->size, "could not get blockdev size");
    170         return -1;
    171     }
    172 
    173     return 0;
    174 }
    175 
    176 static int nvme_ns_zoned_check_calc_geometry(NvmeNamespace *ns, Error **errp)
    177 {
    178     uint64_t zone_size, zone_cap;
    179 
    180     /* Make sure that the values of ZNS properties are sane */
    181     if (ns->params.zone_size_bs) {
    182         zone_size = ns->params.zone_size_bs;
    183     } else {
    184         zone_size = NVME_DEFAULT_ZONE_SIZE;
    185     }
    186     if (ns->params.zone_cap_bs) {
    187         zone_cap = ns->params.zone_cap_bs;
    188     } else {
    189         zone_cap = zone_size;
    190     }
    191     if (zone_cap > zone_size) {
    192         error_setg(errp, "zone capacity %"PRIu64"B exceeds "
    193                    "zone size %"PRIu64"B", zone_cap, zone_size);
    194         return -1;
    195     }
    196     if (zone_size < ns->lbasz) {
    197         error_setg(errp, "zone size %"PRIu64"B too small, "
    198                    "must be at least %zuB", zone_size, ns->lbasz);
    199         return -1;
    200     }
    201     if (zone_cap < ns->lbasz) {
    202         error_setg(errp, "zone capacity %"PRIu64"B too small, "
    203                    "must be at least %zuB", zone_cap, ns->lbasz);
    204         return -1;
    205     }
    206 
    207     /*
    208      * Save the main zone geometry values to avoid
    209      * calculating them later again.
    210      */
    211     ns->zone_size = zone_size / ns->lbasz;
    212     ns->zone_capacity = zone_cap / ns->lbasz;
    213     ns->num_zones = le64_to_cpu(ns->id_ns.nsze) / ns->zone_size;
    214 
    215     /* Do a few more sanity checks of ZNS properties */
    216     if (!ns->num_zones) {
    217         error_setg(errp,
    218                    "insufficient drive capacity, must be at least the size "
    219                    "of one zone (%"PRIu64"B)", zone_size);
    220         return -1;
    221     }
    222 
    223     return 0;
    224 }
    225 
    226 static void nvme_ns_zoned_init_state(NvmeNamespace *ns)
    227 {
    228     uint64_t start = 0, zone_size = ns->zone_size;
    229     uint64_t capacity = ns->num_zones * zone_size;
    230     NvmeZone *zone;
    231     int i;
    232 
    233     ns->zone_array = g_new0(NvmeZone, ns->num_zones);
    234     if (ns->params.zd_extension_size) {
    235         ns->zd_extensions = g_malloc0(ns->params.zd_extension_size *
    236                                       ns->num_zones);
    237     }
    238 
    239     QTAILQ_INIT(&ns->exp_open_zones);
    240     QTAILQ_INIT(&ns->imp_open_zones);
    241     QTAILQ_INIT(&ns->closed_zones);
    242     QTAILQ_INIT(&ns->full_zones);
    243 
    244     zone = ns->zone_array;
    245     for (i = 0; i < ns->num_zones; i++, zone++) {
    246         if (start + zone_size > capacity) {
    247             zone_size = capacity - start;
    248         }
    249         zone->d.zt = NVME_ZONE_TYPE_SEQ_WRITE;
    250         nvme_set_zone_state(zone, NVME_ZONE_STATE_EMPTY);
    251         zone->d.za = 0;
    252         zone->d.zcap = ns->zone_capacity;
    253         zone->d.zslba = start;
    254         zone->d.wp = start;
    255         zone->w_ptr = start;
    256         start += zone_size;
    257     }
    258 
    259     ns->zone_size_log2 = 0;
    260     if (is_power_of_2(ns->zone_size)) {
    261         ns->zone_size_log2 = 63 - clz64(ns->zone_size);
    262     }
    263 }
    264 
    265 static void nvme_ns_init_zoned(NvmeNamespace *ns)
    266 {
    267     NvmeIdNsZoned *id_ns_z;
    268     int i;
    269 
    270     nvme_ns_zoned_init_state(ns);
    271 
    272     id_ns_z = g_new0(NvmeIdNsZoned, 1);
    273 
    274     /* MAR/MOR are zeroes-based, FFFFFFFFFh means no limit */
    275     id_ns_z->mar = cpu_to_le32(ns->params.max_active_zones - 1);
    276     id_ns_z->mor = cpu_to_le32(ns->params.max_open_zones - 1);
    277     id_ns_z->zoc = 0;
    278     id_ns_z->ozcs = ns->params.cross_zone_read ?
    279         NVME_ID_NS_ZONED_OZCS_RAZB : 0x00;
    280 
    281     for (i = 0; i <= ns->id_ns.nlbaf; i++) {
    282         id_ns_z->lbafe[i].zsze = cpu_to_le64(ns->zone_size);
    283         id_ns_z->lbafe[i].zdes =
    284             ns->params.zd_extension_size >> 6; /* Units of 64B */
    285     }
    286 
    287     if (ns->params.zrwas) {
    288         ns->zns.numzrwa = ns->params.numzrwa ?
    289             ns->params.numzrwa : ns->num_zones;
    290 
    291         ns->zns.zrwas = ns->params.zrwas >> ns->lbaf.ds;
    292         ns->zns.zrwafg = ns->params.zrwafg >> ns->lbaf.ds;
    293 
    294         id_ns_z->ozcs |= NVME_ID_NS_ZONED_OZCS_ZRWASUP;
    295         id_ns_z->zrwacap = NVME_ID_NS_ZONED_ZRWACAP_EXPFLUSHSUP;
    296 
    297         id_ns_z->numzrwa = cpu_to_le32(ns->params.numzrwa);
    298         id_ns_z->zrwas = cpu_to_le16(ns->zns.zrwas);
    299         id_ns_z->zrwafg = cpu_to_le16(ns->zns.zrwafg);
    300     }
    301 
    302     id_ns_z->ozcs = cpu_to_le16(id_ns_z->ozcs);
    303 
    304     ns->csi = NVME_CSI_ZONED;
    305     ns->id_ns.nsze = cpu_to_le64(ns->num_zones * ns->zone_size);
    306     ns->id_ns.ncap = ns->id_ns.nsze;
    307     ns->id_ns.nuse = ns->id_ns.ncap;
    308 
    309     /*
    310      * The device uses the BDRV_BLOCK_ZERO flag to determine the "deallocated"
    311      * status of logical blocks. Since the spec defines that logical blocks
    312      * SHALL be deallocated when then zone is in the Empty or Offline states,
    313      * we can only support DULBE if the zone size is a multiple of the
    314      * calculated NPDG.
    315      */
    316     if (ns->zone_size % (ns->id_ns.npdg + 1)) {
    317         warn_report("the zone size (%"PRIu64" blocks) is not a multiple of "
    318                     "the calculated deallocation granularity (%d blocks); "
    319                     "DULBE support disabled",
    320                     ns->zone_size, ns->id_ns.npdg + 1);
    321 
    322         ns->id_ns.nsfeat &= ~0x4;
    323     }
    324 
    325     ns->id_ns_zoned = id_ns_z;
    326 }
    327 
    328 static void nvme_clear_zone(NvmeNamespace *ns, NvmeZone *zone)
    329 {
    330     uint8_t state;
    331 
    332     zone->w_ptr = zone->d.wp;
    333     state = nvme_get_zone_state(zone);
    334     if (zone->d.wp != zone->d.zslba ||
    335         (zone->d.za & NVME_ZA_ZD_EXT_VALID)) {
    336         if (state != NVME_ZONE_STATE_CLOSED) {
    337             trace_pci_nvme_clear_ns_close(state, zone->d.zslba);
    338             nvme_set_zone_state(zone, NVME_ZONE_STATE_CLOSED);
    339         }
    340         nvme_aor_inc_active(ns);
    341         QTAILQ_INSERT_HEAD(&ns->closed_zones, zone, entry);
    342     } else {
    343         trace_pci_nvme_clear_ns_reset(state, zone->d.zslba);
    344         if (zone->d.za & NVME_ZA_ZRWA_VALID) {
    345             zone->d.za &= ~NVME_ZA_ZRWA_VALID;
    346             ns->zns.numzrwa++;
    347         }
    348         nvme_set_zone_state(zone, NVME_ZONE_STATE_EMPTY);
    349     }
    350 }
    351 
    352 /*
    353  * Close all the zones that are currently open.
    354  */
    355 static void nvme_zoned_ns_shutdown(NvmeNamespace *ns)
    356 {
    357     NvmeZone *zone, *next;
    358 
    359     QTAILQ_FOREACH_SAFE(zone, &ns->closed_zones, entry, next) {
    360         QTAILQ_REMOVE(&ns->closed_zones, zone, entry);
    361         nvme_aor_dec_active(ns);
    362         nvme_clear_zone(ns, zone);
    363     }
    364     QTAILQ_FOREACH_SAFE(zone, &ns->imp_open_zones, entry, next) {
    365         QTAILQ_REMOVE(&ns->imp_open_zones, zone, entry);
    366         nvme_aor_dec_open(ns);
    367         nvme_aor_dec_active(ns);
    368         nvme_clear_zone(ns, zone);
    369     }
    370     QTAILQ_FOREACH_SAFE(zone, &ns->exp_open_zones, entry, next) {
    371         QTAILQ_REMOVE(&ns->exp_open_zones, zone, entry);
    372         nvme_aor_dec_open(ns);
    373         nvme_aor_dec_active(ns);
    374         nvme_clear_zone(ns, zone);
    375     }
    376 
    377     assert(ns->nr_open_zones == 0);
    378 }
    379 
    380 static int nvme_ns_check_constraints(NvmeNamespace *ns, Error **errp)
    381 {
    382     unsigned int pi_size;
    383 
    384     if (!ns->blkconf.blk) {
    385         error_setg(errp, "block backend not configured");
    386         return -1;
    387     }
    388 
    389     if (ns->params.pi) {
    390         if (ns->params.pi > NVME_ID_NS_DPS_TYPE_3) {
    391             error_setg(errp, "invalid 'pi' value");
    392             return -1;
    393         }
    394 
    395         switch (ns->params.pif) {
    396         case NVME_PI_GUARD_16:
    397             pi_size = 8;
    398             break;
    399         case NVME_PI_GUARD_64:
    400             pi_size = 16;
    401             break;
    402         default:
    403             error_setg(errp, "invalid 'pif'");
    404             return -1;
    405         }
    406 
    407         if (ns->params.ms < pi_size) {
    408             error_setg(errp, "at least %u bytes of metadata required to "
    409                        "enable protection information", pi_size);
    410             return -1;
    411         }
    412     }
    413 
    414     if (ns->params.nsid > NVME_MAX_NAMESPACES) {
    415         error_setg(errp, "invalid namespace id (must be between 0 and %d)",
    416                    NVME_MAX_NAMESPACES);
    417         return -1;
    418     }
    419 
    420     if (ns->params.zoned) {
    421         if (ns->params.max_active_zones) {
    422             if (ns->params.max_open_zones > ns->params.max_active_zones) {
    423                 error_setg(errp, "max_open_zones (%u) exceeds "
    424                            "max_active_zones (%u)", ns->params.max_open_zones,
    425                            ns->params.max_active_zones);
    426                 return -1;
    427             }
    428 
    429             if (!ns->params.max_open_zones) {
    430                 ns->params.max_open_zones = ns->params.max_active_zones;
    431             }
    432         }
    433 
    434         if (ns->params.zd_extension_size) {
    435             if (ns->params.zd_extension_size & 0x3f) {
    436                 error_setg(errp, "zone descriptor extension size must be a "
    437                            "multiple of 64B");
    438                 return -1;
    439             }
    440             if ((ns->params.zd_extension_size >> 6) > 0xff) {
    441                 error_setg(errp,
    442                            "zone descriptor extension size is too large");
    443                 return -1;
    444             }
    445         }
    446 
    447         if (ns->params.zrwas) {
    448             if (ns->params.zrwas % ns->blkconf.logical_block_size) {
    449                 error_setg(errp, "zone random write area size (zoned.zrwas "
    450                            "%"PRIu64") must be a multiple of the logical "
    451                            "block size (logical_block_size %"PRIu32")",
    452                            ns->params.zrwas, ns->blkconf.logical_block_size);
    453                 return -1;
    454             }
    455 
    456             if (ns->params.zrwafg == -1) {
    457                 ns->params.zrwafg = ns->blkconf.logical_block_size;
    458             }
    459 
    460             if (ns->params.zrwas % ns->params.zrwafg) {
    461                 error_setg(errp, "zone random write area size (zoned.zrwas "
    462                            "%"PRIu64") must be a multiple of the zone random "
    463                            "write area flush granularity (zoned.zrwafg, "
    464                            "%"PRIu64")", ns->params.zrwas, ns->params.zrwafg);
    465                 return -1;
    466             }
    467 
    468             if (ns->params.max_active_zones) {
    469                 if (ns->params.numzrwa > ns->params.max_active_zones) {
    470                     error_setg(errp, "number of zone random write area "
    471                                "resources (zoned.numzrwa, %d) must be less "
    472                                "than or equal to maximum active resources "
    473                                "(zoned.max_active_zones, %d)",
    474                                ns->params.numzrwa,
    475                                ns->params.max_active_zones);
    476                     return -1;
    477                 }
    478             }
    479         }
    480     }
    481 
    482     return 0;
    483 }
    484 
    485 int nvme_ns_setup(NvmeNamespace *ns, Error **errp)
    486 {
    487     if (nvme_ns_check_constraints(ns, errp)) {
    488         return -1;
    489     }
    490 
    491     if (nvme_ns_init_blk(ns, errp)) {
    492         return -1;
    493     }
    494 
    495     if (nvme_ns_init(ns, errp)) {
    496         return -1;
    497     }
    498     if (ns->params.zoned) {
    499         if (nvme_ns_zoned_check_calc_geometry(ns, errp) != 0) {
    500             return -1;
    501         }
    502         nvme_ns_init_zoned(ns);
    503     }
    504 
    505     return 0;
    506 }
    507 
    508 void nvme_ns_drain(NvmeNamespace *ns)
    509 {
    510     blk_drain(ns->blkconf.blk);
    511 }
    512 
    513 void nvme_ns_shutdown(NvmeNamespace *ns)
    514 {
    515     blk_flush(ns->blkconf.blk);
    516     if (ns->params.zoned) {
    517         nvme_zoned_ns_shutdown(ns);
    518     }
    519 }
    520 
    521 void nvme_ns_cleanup(NvmeNamespace *ns)
    522 {
    523     if (ns->params.zoned) {
    524         g_free(ns->id_ns_zoned);
    525         g_free(ns->zone_array);
    526         g_free(ns->zd_extensions);
    527     }
    528 }
    529 
    530 static void nvme_ns_unrealize(DeviceState *dev)
    531 {
    532     NvmeNamespace *ns = NVME_NS(dev);
    533 
    534     nvme_ns_drain(ns);
    535     nvme_ns_shutdown(ns);
    536     nvme_ns_cleanup(ns);
    537 }
    538 
    539 static void nvme_ns_realize(DeviceState *dev, Error **errp)
    540 {
    541     NvmeNamespace *ns = NVME_NS(dev);
    542     BusState *s = qdev_get_parent_bus(dev);
    543     NvmeCtrl *n = NVME(s->parent);
    544     NvmeSubsystem *subsys = n->subsys;
    545     uint32_t nsid = ns->params.nsid;
    546     int i;
    547 
    548     if (!n->subsys) {
    549         /* If no subsys, the ns cannot be attached to more than one ctrl. */
    550         ns->params.shared = false;
    551         if (ns->params.detached) {
    552             error_setg(errp, "detached requires that the nvme device is "
    553                        "linked to an nvme-subsys device");
    554             return;
    555         }
    556     } else {
    557         /*
    558          * If this namespace belongs to a subsystem (through a link on the
    559          * controller device), reparent the device.
    560          */
    561         if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) {
    562             return;
    563         }
    564     }
    565 
    566     if (nvme_ns_setup(ns, errp)) {
    567         return;
    568     }
    569 
    570     if (!nsid) {
    571         for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
    572             if (nvme_ns(n, i) || nvme_subsys_ns(subsys, i)) {
    573                 continue;
    574             }
    575 
    576             nsid = ns->params.nsid = i;
    577             break;
    578         }
    579 
    580         if (!nsid) {
    581             error_setg(errp, "no free namespace id");
    582             return;
    583         }
    584     } else {
    585         if (nvme_ns(n, nsid) || nvme_subsys_ns(subsys, nsid)) {
    586             error_setg(errp, "namespace id '%d' already allocated", nsid);
    587             return;
    588         }
    589     }
    590 
    591     if (subsys) {
    592         subsys->namespaces[nsid] = ns;
    593 
    594         if (ns->params.detached) {
    595             return;
    596         }
    597 
    598         if (ns->params.shared) {
    599             for (i = 0; i < ARRAY_SIZE(subsys->ctrls); i++) {
    600                 NvmeCtrl *ctrl = subsys->ctrls[i];
    601 
    602                 if (ctrl && ctrl != SUBSYS_SLOT_RSVD) {
    603                     nvme_attach_ns(ctrl, ns);
    604                 }
    605             }
    606 
    607             return;
    608         }
    609     }
    610 
    611     nvme_attach_ns(n, ns);
    612 }
    613 
    614 static Property nvme_ns_props[] = {
    615     DEFINE_BLOCK_PROPERTIES(NvmeNamespace, blkconf),
    616     DEFINE_PROP_BOOL("detached", NvmeNamespace, params.detached, false),
    617     DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, true),
    618     DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
    619     DEFINE_PROP_UUID_NODEFAULT("uuid", NvmeNamespace, params.uuid),
    620     DEFINE_PROP_UINT64("eui64", NvmeNamespace, params.eui64, 0),
    621     DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0),
    622     DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0),
    623     DEFINE_PROP_UINT8("pi", NvmeNamespace, params.pi, 0),
    624     DEFINE_PROP_UINT8("pil", NvmeNamespace, params.pil, 0),
    625     DEFINE_PROP_UINT8("pif", NvmeNamespace, params.pif, 0),
    626     DEFINE_PROP_UINT16("mssrl", NvmeNamespace, params.mssrl, 128),
    627     DEFINE_PROP_UINT32("mcl", NvmeNamespace, params.mcl, 128),
    628     DEFINE_PROP_UINT8("msrc", NvmeNamespace, params.msrc, 127),
    629     DEFINE_PROP_BOOL("zoned", NvmeNamespace, params.zoned, false),
    630     DEFINE_PROP_SIZE("zoned.zone_size", NvmeNamespace, params.zone_size_bs,
    631                      NVME_DEFAULT_ZONE_SIZE),
    632     DEFINE_PROP_SIZE("zoned.zone_capacity", NvmeNamespace, params.zone_cap_bs,
    633                      0),
    634     DEFINE_PROP_BOOL("zoned.cross_read", NvmeNamespace,
    635                      params.cross_zone_read, false),
    636     DEFINE_PROP_UINT32("zoned.max_active", NvmeNamespace,
    637                        params.max_active_zones, 0),
    638     DEFINE_PROP_UINT32("zoned.max_open", NvmeNamespace,
    639                        params.max_open_zones, 0),
    640     DEFINE_PROP_UINT32("zoned.descr_ext_size", NvmeNamespace,
    641                        params.zd_extension_size, 0),
    642     DEFINE_PROP_UINT32("zoned.numzrwa", NvmeNamespace, params.numzrwa, 0),
    643     DEFINE_PROP_SIZE("zoned.zrwas", NvmeNamespace, params.zrwas, 0),
    644     DEFINE_PROP_SIZE("zoned.zrwafg", NvmeNamespace, params.zrwafg, -1),
    645     DEFINE_PROP_BOOL("eui64-default", NvmeNamespace, params.eui64_default,
    646                      false),
    647     DEFINE_PROP_END_OF_LIST(),
    648 };
    649 
    650 static void nvme_ns_class_init(ObjectClass *oc, void *data)
    651 {
    652     DeviceClass *dc = DEVICE_CLASS(oc);
    653 
    654     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
    655 
    656     dc->bus_type = TYPE_NVME_BUS;
    657     dc->realize = nvme_ns_realize;
    658     dc->unrealize = nvme_ns_unrealize;
    659     device_class_set_props(dc, nvme_ns_props);
    660     dc->desc = "Virtual NVMe namespace";
    661 }
    662 
    663 static void nvme_ns_instance_init(Object *obj)
    664 {
    665     NvmeNamespace *ns = NVME_NS(obj);
    666     char *bootindex = g_strdup_printf("/namespace@%d,0", ns->params.nsid);
    667 
    668     device_add_bootindex_property(obj, &ns->bootindex, "bootindex",
    669                                   bootindex, DEVICE(obj));
    670 
    671     g_free(bootindex);
    672 }
    673 
    674 static const TypeInfo nvme_ns_info = {
    675     .name = TYPE_NVME_NS,
    676     .parent = TYPE_DEVICE,
    677     .class_init = nvme_ns_class_init,
    678     .instance_size = sizeof(NvmeNamespace),
    679     .instance_init = nvme_ns_instance_init,
    680 };
    681 
    682 static void nvme_ns_register_types(void)
    683 {
    684     type_register_static(&nvme_ns_info);
    685 }
    686 
    687 type_init(nvme_ns_register_types)