From 07897bdcba2081b114b06a5140189f4738999395 Mon Sep 17 00:00:00 2001 From: Chuck Tuffli Date: Mon, 20 Jul 2020 00:38:21 +0000 Subject: [PATCH] MFC r362763 bhyve: add NVMe Feature Interrupt Vector Config --- usr.sbin/bhyve/pci_nvme.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index 02034cd612a..c3066166ba2 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -356,6 +356,10 @@ static void nvme_feature_num_queues(struct pci_nvme_softc *, struct nvme_feature_obj *, struct nvme_command *, struct nvme_completion *); +static void nvme_feature_iv_config(struct pci_nvme_softc *, + struct nvme_feature_obj *, + struct nvme_command *, + struct nvme_completion *); static __inline void cpywithpad(char *dst, size_t dst_size, const char *src, char pad) @@ -612,6 +616,8 @@ pci_nvme_init_features(struct pci_nvme_softc *sc) sc->feat[NVME_FEAT_LBA_RANGE_TYPE].namespace_specific = true; sc->feat[NVME_FEAT_ERROR_RECOVERY].namespace_specific = true; sc->feat[NVME_FEAT_NUMBER_OF_QUEUES].set = nvme_feature_num_queues; + sc->feat[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION].set = + nvme_feature_iv_config; } static void @@ -1275,6 +1281,39 @@ nvme_feature_invalid_cb(struct pci_nvme_softc *sc, pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); } +static void +nvme_feature_iv_config(struct pci_nvme_softc *sc, + struct nvme_feature_obj *feat, + struct nvme_command *command, + struct nvme_completion *compl) +{ + uint32_t i; + uint32_t cdw11 = command->cdw11; + uint16_t iv; + bool cd; + + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + + iv = cdw11 & 0xffff; + cd = cdw11 & (1 << 16); + + if (iv > (sc->max_queues + 1)) { + return; + } + + /* No Interrupt Coalescing (i.e. not Coalescing Disable) for Admin Q */ + if ((iv == 0) && !cd) + return; + + /* Requested Interrupt Vector must be used by a CQ */ + for (i = 0; i < sc->num_cqueues + 1; i++) { + if (sc->compl_queues[i].intr_vec == iv) { + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + } + } + +} + static void nvme_feature_num_queues(struct pci_nvme_softc *sc, struct nvme_feature_obj *feat, -- 2.45.0