mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-nvme-20250227' of https://gitlab.com/birkelund/qemu into staging
nvme queue # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmfAMFEACgkQTeGvMW1P # DenstAf9GuLVxVUhKDlAJwyRl9Z3lrPMkKwoYF2B75fmqJhW0wZh5VSh6z/s5Qx7 # h/5soFrAMlcZPg5FO0OkY9d4psPlDHBPnuGqX2zLxx0zZnpC/QThSa6hzmETDwfv # mXEMA/AnXar9MqjrbeR2QjVRphP9mzWpaK7JLmvX9KYvMVxqXSEq5TuylbIeyBQ5 # rSWlVnuKvVLRVtavDpZjHAk5q6CgO1nQ0N3IyIjZmllphCgrJVX5PMtiLur3dPSF # nYv2TR3uZJmlHR9qsFEc1aIBKNSBhwBJljRuIJe+yFTI8rxCClNlqMQOfgBJp4z6 # GYHm0w0p0NLn/V5dTqLsJoHs20u46A== # =703u # -----END PGP SIGNATURE----- # gpg: Signature made Thu 27 Feb 2025 17:28:49 HKT # 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 * tag 'pull-nvme-20250227' of https://gitlab.com/birkelund/qemu: hw/nvme: remove nvme_aio_err() hw/nvme: set error status code explicitly for misc commands hw/nvme: only set command abort requested when cancelled due to Abort hw/nvme: rework csi handling hw/nvme: be compliant wrt. dsm processing limits nvme: fix iocs status code values hw/nvme: add knob for doorbell buffer config support hw/nvme: make oacs dynamic hw/nvme: always initialize a subsystem hw/nvme: Add OCP SMART / Health Information Extended Log Page Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -53,6 +53,13 @@ parameters.
|
||||
Vendor ID. Set this to ``on`` to revert to the unallocated Intel ID
|
||||
previously used.
|
||||
|
||||
``ocp`` (default: ``off``)
|
||||
The Open Compute Project defines the Datacenter NVMe SSD Specification that
|
||||
sits on top of NVMe. It describes additional commands and NVMe behaviors
|
||||
specific for the Datacenter. When this option is ``on`` OCP features such as
|
||||
the SMART / Health information extended log become available in the
|
||||
controller. We emulate version 5 of this log page.
|
||||
|
||||
Additional Namespaces
|
||||
---------------------
|
||||
|
||||
|
||||
+287
-173
File diff suppressed because it is too large
Load Diff
+14
-48
@@ -727,25 +727,14 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
|
||||
uint32_t nsid = ns->params.nsid;
|
||||
int i;
|
||||
|
||||
if (!n->subsys) {
|
||||
/* If no subsys, the ns cannot be attached to more than one ctrl. */
|
||||
ns->params.shared = false;
|
||||
if (ns->params.detached) {
|
||||
error_setg(errp, "detached requires that the nvme device is "
|
||||
"linked to an nvme-subsys device");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If this namespace belongs to a subsystem (through a link on the
|
||||
* controller device), reparent the device.
|
||||
*/
|
||||
if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) {
|
||||
return;
|
||||
}
|
||||
ns->subsys = subsys;
|
||||
ns->endgrp = &subsys->endgrp;
|
||||
assert(subsys);
|
||||
|
||||
/* reparent to subsystem bus */
|
||||
if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) {
|
||||
return;
|
||||
}
|
||||
ns->subsys = subsys;
|
||||
ns->endgrp = &subsys->endgrp;
|
||||
|
||||
if (nvme_ns_setup(ns, errp)) {
|
||||
return;
|
||||
@@ -753,7 +742,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
if (!nsid) {
|
||||
for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
|
||||
if (nvme_ns(n, i) || nvme_subsys_ns(subsys, i)) {
|
||||
if (nvme_subsys_ns(subsys, i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -765,38 +754,15 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
|
||||
error_setg(errp, "no free namespace id");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (nvme_ns(n, nsid) || nvme_subsys_ns(subsys, nsid)) {
|
||||
error_setg(errp, "namespace id '%d' already allocated", nsid);
|
||||
return;
|
||||
}
|
||||
} else if (nvme_subsys_ns(subsys, nsid)) {
|
||||
error_setg(errp, "namespace id '%d' already allocated", nsid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (subsys) {
|
||||
subsys->namespaces[nsid] = ns;
|
||||
subsys->namespaces[nsid] = ns;
|
||||
|
||||
ns->id_ns.endgid = cpu_to_le16(0x1);
|
||||
ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
|
||||
|
||||
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 && ctrl != SUBSYS_SLOT_RSVD) {
|
||||
nvme_attach_ns(ctrl, ns);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nvme_attach_ns(n, ns);
|
||||
ns->id_ns.endgid = cpu_to_le16(0x1);
|
||||
ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
|
||||
}
|
||||
|
||||
static const Property nvme_ns_props[] = {
|
||||
|
||||
+10
-1
@@ -237,7 +237,6 @@ typedef struct NvmeNamespace {
|
||||
NvmeLBAF lbaf;
|
||||
unsigned int nlbaf;
|
||||
size_t lbasz;
|
||||
const uint32_t *iocs;
|
||||
uint8_t csi;
|
||||
uint16_t status;
|
||||
int attached;
|
||||
@@ -539,12 +538,14 @@ typedef struct NvmeParams {
|
||||
bool auto_transition_zones;
|
||||
bool legacy_cmb;
|
||||
bool ioeventfd;
|
||||
bool dbcs;
|
||||
uint16_t sriov_max_vfs;
|
||||
uint16_t sriov_vq_flexible;
|
||||
uint16_t sriov_vi_flexible;
|
||||
uint32_t sriov_max_vq_per_vf;
|
||||
uint32_t sriov_max_vi_per_vf;
|
||||
bool msix_exclusive_bar;
|
||||
bool ocp;
|
||||
|
||||
struct {
|
||||
bool mem;
|
||||
@@ -583,6 +584,14 @@ typedef struct NvmeCtrl {
|
||||
uint64_t dbbuf_eis;
|
||||
bool dbbuf_enabled;
|
||||
|
||||
struct {
|
||||
uint32_t acs[256];
|
||||
struct {
|
||||
uint32_t nvm[256];
|
||||
uint32_t zoned[256];
|
||||
} iocs;
|
||||
} cse;
|
||||
|
||||
struct {
|
||||
MemoryRegion mem;
|
||||
uint8_t *buf;
|
||||
|
||||
+55
-8
@@ -142,9 +142,9 @@ enum NvmeCapMask {
|
||||
((cap) |= (uint64_t)((val) & CAP_CMBS_MASK) << CAP_CMBS_SHIFT)
|
||||
|
||||
enum NvmeCapCss {
|
||||
NVME_CAP_CSS_NVM = 1 << 0,
|
||||
NVME_CAP_CSS_CSI_SUPP = 1 << 6,
|
||||
NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
|
||||
NVME_CAP_CSS_NCSS = 1 << 0,
|
||||
NVME_CAP_CSS_IOCSS = 1 << 6,
|
||||
NVME_CAP_CSS_NOIOCSS = 1 << 7,
|
||||
};
|
||||
|
||||
enum NvmeCcShift {
|
||||
@@ -177,7 +177,7 @@ enum NvmeCcMask {
|
||||
|
||||
enum NvmeCcCss {
|
||||
NVME_CC_CSS_NVM = 0x0,
|
||||
NVME_CC_CSS_CSI = 0x6,
|
||||
NVME_CC_CSS_ALL = 0x6,
|
||||
NVME_CC_CSS_ADMIN_ONLY = 0x7,
|
||||
};
|
||||
|
||||
@@ -906,8 +906,7 @@ enum NvmeStatusCodes {
|
||||
NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
|
||||
NVME_INVALID_USE_OF_CMB = 0x0012,
|
||||
NVME_INVALID_PRP_OFFSET = 0x0013,
|
||||
NVME_CMD_SET_CMB_REJECTED = 0x002b,
|
||||
NVME_INVALID_CMD_SET = 0x002c,
|
||||
NVME_COMMAND_INTERRUPTED = 0x0021,
|
||||
NVME_FDP_DISABLED = 0x0029,
|
||||
NVME_INVALID_PHID_LIST = 0x002a,
|
||||
NVME_LBA_RANGE = 0x0080,
|
||||
@@ -940,6 +939,10 @@ enum NvmeStatusCodes {
|
||||
NVME_INVALID_SEC_CTRL_STATE = 0x0120,
|
||||
NVME_INVALID_NUM_RESOURCES = 0x0121,
|
||||
NVME_INVALID_RESOURCE_ID = 0x0122,
|
||||
NVME_IOCS_NOT_SUPPORTED = 0x0129,
|
||||
NVME_IOCS_NOT_ENABLED = 0x012a,
|
||||
NVME_IOCS_COMBINATION_REJECTED = 0x012b,
|
||||
NVME_INVALID_IOCS = 0x012c,
|
||||
NVME_CONFLICTING_ATTRS = 0x0180,
|
||||
NVME_INVALID_PROT_INFO = 0x0181,
|
||||
NVME_WRITE_TO_RO = 0x0182,
|
||||
@@ -1015,6 +1018,40 @@ typedef struct QEMU_PACKED NvmeSmartLog {
|
||||
uint8_t reserved2[320];
|
||||
} NvmeSmartLog;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeSmartLogExtended {
|
||||
uint64_t physical_media_units_written[2];
|
||||
uint64_t physical_media_units_read[2];
|
||||
uint64_t bad_user_blocks;
|
||||
uint64_t bad_system_nand_blocks;
|
||||
uint64_t xor_recovery_count;
|
||||
uint64_t uncorrectable_read_error_count;
|
||||
uint64_t soft_ecc_error_count;
|
||||
uint64_t end2end_correction_counts;
|
||||
uint8_t system_data_percent_used;
|
||||
uint8_t refresh_counts[7];
|
||||
uint64_t user_data_erase_counts;
|
||||
uint16_t thermal_throttling_stat_and_count;
|
||||
uint16_t dssd_spec_version[3];
|
||||
uint64_t pcie_correctable_error_count;
|
||||
uint32_t incomplete_shutdowns;
|
||||
uint32_t rsvd116;
|
||||
uint8_t percent_free_blocks;
|
||||
uint8_t rsvd121[7];
|
||||
uint16_t capacity_health;
|
||||
uint8_t nvme_errata_ver;
|
||||
uint8_t rsvd131[5];
|
||||
uint64_t unaligned_io;
|
||||
uint64_t security_ver_num;
|
||||
uint64_t total_nuse;
|
||||
uint64_t plp_start_count[2];
|
||||
uint64_t endurance_estimate[2];
|
||||
uint64_t pcie_retraining_count;
|
||||
uint64_t power_state_change_count;
|
||||
uint8_t rsvd208[286];
|
||||
uint16_t log_page_version;
|
||||
uint64_t log_page_guid[2];
|
||||
} NvmeSmartLogExtended;
|
||||
|
||||
#define NVME_SMART_WARN_MAX 6
|
||||
enum NvmeSmartWarn {
|
||||
NVME_SMART_SPARE = 1 << 0,
|
||||
@@ -1052,6 +1089,12 @@ enum NvmeLogIdentifier {
|
||||
NVME_LOG_FDP_RUH_USAGE = 0x21,
|
||||
NVME_LOG_FDP_STATS = 0x22,
|
||||
NVME_LOG_FDP_EVENTS = 0x23,
|
||||
NVME_LOG_VENDOR_START = 0xc0,
|
||||
NVME_LOG_VENDOR_END = 0xff,
|
||||
};
|
||||
|
||||
enum NvmeOcpLogIdentifier {
|
||||
NVME_OCP_EXTENDED_SMART_INFO = 0xc0,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmePSD {
|
||||
@@ -1167,6 +1210,8 @@ typedef struct NvmeIdCtrlZoned {
|
||||
uint8_t rsvd1[4095];
|
||||
} NvmeIdCtrlZoned;
|
||||
|
||||
#define NVME_ID_CTRL_NVM_DMRL_MAX 255
|
||||
|
||||
typedef struct NvmeIdCtrlNvm {
|
||||
uint8_t vsl;
|
||||
uint8_t wzsl;
|
||||
@@ -1192,9 +1237,10 @@ enum NvmeIdCtrlOacs {
|
||||
NVME_OACS_SECURITY = 1 << 0,
|
||||
NVME_OACS_FORMAT = 1 << 1,
|
||||
NVME_OACS_FW = 1 << 2,
|
||||
NVME_OACS_NS_MGMT = 1 << 3,
|
||||
NVME_OACS_NMS = 1 << 3,
|
||||
NVME_OACS_DIRECTIVES = 1 << 5,
|
||||
NVME_OACS_DBBUF = 1 << 8,
|
||||
NVME_OACS_VMS = 1 << 7,
|
||||
NVME_OACS_DBCS = 1 << 8,
|
||||
};
|
||||
|
||||
enum NvmeIdCtrlOncs {
|
||||
@@ -1899,6 +1945,7 @@ static inline void _nvme_check_size(void)
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLogExtended) != 512);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeEffectsLog) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrlZoned) != 4096);
|
||||
|
||||
Reference in New Issue
Block a user