Signed-off-by: Ayush Mishra <ayush....@samsung.com> --- hw/nvme/ctrl.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ include/block/nvme.h | 21 +++++++++++++++ 2 files changed, 84 insertions(+)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 93c950b5b2..5ef2282fd2 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -252,6 +252,24 @@ static const bool nvme_feature_support[NVME_FID_MAX] = { [NVME_FDP_EVENTS] = true, }; +static const uint32_t nvme_fid_supp_effects[NVME_FID_MAX] = { + [NVME_ARBITRATION] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_POWER_MANAGEMENT] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_TEMPERATURE_THRESHOLD] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_ERROR_RECOVERY] = NVME_EFFECTS_CSUPP | NVME_NMSP_SCOPE, + [NVME_VOLATILE_WRITE_CACHE] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_NUMBER_OF_QUEUES] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_INTERRUPT_COALESCING] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_INTERRUPT_VECTOR_CONF] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_WRITE_ATOMICITY] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_ASYNCHRONOUS_EVENT_CONF] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_TIMESTAMP] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_HOST_BEHAVIOR_SUPPORT] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_COMMAND_SET_PROFILE] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE, + [NVME_FDP_MODE] = NVME_EFFECTS_CSUPP | NVME_ENDURANCE_SCOPE, + [NVME_FDP_EVENTS] = NVME_EFFECTS_CSUPP, +}; + static const uint32_t nvme_feature_cap[NVME_FID_MAX] = { [NVME_TEMPERATURE_THRESHOLD] = NVME_FEAT_CAP_CHANGE, [NVME_ERROR_RECOVERY] = NVME_FEAT_CAP_CHANGE | NVME_FEAT_CAP_NS, @@ -5086,6 +5104,47 @@ static uint16_t nvme_endgrp_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, return nvme_c2h(n, (uint8_t *)&info + off, buf_len, req); } +static uint16_t nvme_log_fid_supp_effects_log(NvmeCtrl *n, uint8_t csi, + uint32_t buf_len, uint64_t off, NvmeRequest *req) +{ + NvmeFidSuppLog log = {}; + const uint32_t *supp_fid = NULL; + uint32_t trans_len; + bool ot = le32_to_cpu(req->cmd.cdw14) >> 23; + + if (off >= sizeof(log) || (ot == 1 && (off * 4 >= sizeof(log)))) { + trace_pci_nvme_err_invalid_log_page_offset(off, sizeof(log)); + return NVME_INVALID_FIELD | NVME_DNR; + } + + switch (NVME_CC_CSS(ldl_le_p(&n->bar.cc))) { + case NVME_CC_CSS_NVM: + supp_fid = nvme_fid_supp_effects; + /* fall through */ + case NVME_CC_CSS_ADMIN_ONLY: + break; + case NVME_CC_CSS_ALL: + switch (csi) { + case NVME_CSI_NVM: + supp_fid = nvme_fid_supp_effects; + break; + case NVME_CSI_ZONED: + break; + } + } + + if (ot == 1) { + off *= 4; + } + + if (supp_fid) { + memcpy(log.fis, supp_fid, sizeof(log.fis)); + } + + trans_len = MIN(sizeof(log) - off, buf_len); + + return nvme_c2h(n, ((uint8_t *)&log) + off, trans_len, req); +} static uint16_t nvme_fw_log_info(NvmeCtrl *n, uint32_t buf_len, uint64_t off, NvmeRequest *req) @@ -5506,6 +5565,8 @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req) return nvme_cmd_effects(n, csi, len, off, req); case NVME_LOG_ENDGRP: return nvme_endgrp_info(n, rae, len, off, req); + case NVME_LOG_FID_SUPP_EFFECTS: + return nvme_log_fid_supp_effects_log(n, csi, len, off, req); case NVME_LOG_FDP_CONFS: return nvme_fdp_confs(n, lspi, len, off, req); case NVME_LOG_FDP_RUH_USAGE: @@ -8930,6 +8991,8 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev) n->supplogpage[NVME_LOG_CHANGED_NSLIST].lsupp_ios = NVME_LID_SUPP; n->supplogpage[NVME_LOG_CMD_EFFECTS].lsupp_ios = NVME_LID_SUPP; n->supplogpage[NVME_LOG_ENDGRP].lsupp_ios = NVME_LID_SUPP; + n->supplogpage[NVME_LOG_FID_SUPP_EFFECTS].lsupp_ios = NVME_LID_SUPP + | NVME_INDEX_OFF_SUPP; n->supplogpage[NVME_LOG_FDP_CONFS].lsupp_ios = NVME_LID_SUPP; n->supplogpage[NVME_LOG_FDP_RUH_USAGE].lsupp_ios = NVME_LID_SUPP; n->supplogpage[NVME_LOG_FDP_STATS].lsupp_ios = NVME_LID_SUPP; diff --git a/include/block/nvme.h b/include/block/nvme.h index c38422b38d..0ba69477a0 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -1068,6 +1068,10 @@ typedef struct NvmeEffectsLog { uint8_t resv[2048]; } NvmeEffectsLog; +typedef struct NvmeFidSuppLog { + uint32_t fis[256]; +} NvmeFidSuppLog; + enum { NVME_CMD_EFF_CSUPP = 1 << 0, NVME_CMD_EFF_LBCC = 1 << 1, @@ -1086,6 +1090,7 @@ enum NvmeLogIdentifier { NVME_LOG_CHANGED_NSLIST = 0x04, NVME_LOG_CMD_EFFECTS = 0x05, NVME_LOG_ENDGRP = 0x09, + NVME_LOG_FID_SUPP_EFFECTS = 0x12, NVME_LOG_FDP_CONFS = 0x20, NVME_LOG_FDP_RUH_USAGE = 0x21, NVME_LOG_FDP_STATS = 0x22, @@ -1364,6 +1369,22 @@ typedef enum NvmeFeatureCap { NVME_FEAT_CAP_CHANGE = 1 << 2, } NvmeFeatureCap; +typedef enum NvmeFidSuppEffects { + NVME_EFFECTS_CSUPP = 1 << 0, + NVME_EFFECTS_UDCC = 1 << 1, + NVME_EFFECTS_NCC = 1 << 2, + NVME_EFFECTS_NIC = 1 << 3, + NVME_EFFECTS_CCC = 1 << 4, + NVME_EFFECTS_UUID_SEL = 1 << 19, + NVME_NMSP_SCOPE = 1 << 20, + NVME_CTRL_SCOPE = 1 << 21, + NVME_NVM_SET_SCOPE = 1 << 22, + NVME_ENDURANCE_SCOPE = 1 << 23, + NVME_DOMAIN_SCOPE = 1 << 24, + NVME_SUBSYSTEM_SCOPE = 1 << 25, + NVME_CTRL_DATA_QUEUE = 1 << 26, +} NvmeFidSuppEffects; + typedef enum NvmeGetFeatureSelect { NVME_GETFEAT_SELECT_CURRENT = 0x0, NVME_GETFEAT_SELECT_DEFAULT = 0x1, -- 2.43.0