hw/nvme: connect SPDM over NVMe Security Send/Recv
This patch extends the existing support we have for NVMe with only DoE to also add support to SPDM over the NVMe Security Send/Recv commands. With the new definition of the `spdm-trans` argument, users can specify `spdm_trans=nvme` or `spdm_trans=doe`. This allows us to select the SPDM transport respectively. SPDM over the NVMe Security Send/Recv commands are defined in the DMTF DSP0286. Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Klaus Jensen <k.jensen@samsung.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> [k.jensen: fix declaration in case statement; fix quotes in docs] Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
parent
3d8412c2fb
commit
7f2eeccb4b
3 changed files with 46 additions and 13 deletions
|
|
@ -98,7 +98,7 @@ Then you can add this to your QEMU command line:
|
|||
.. code-block:: shell
|
||||
|
||||
-drive file=blknvme,if=none,id=mynvme,format=raw \
|
||||
-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
|
||||
-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323,spdm_trans=doe
|
||||
|
||||
At which point QEMU will try to connect to the SPDM server.
|
||||
|
||||
|
|
@ -113,7 +113,13 @@ of the default. So the entire QEMU command might look like this
|
|||
-append "root=/dev/vda console=ttyS0" \
|
||||
-net none -nographic \
|
||||
-drive file=blknvme,if=none,id=mynvme,format=raw \
|
||||
-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
|
||||
-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323,spdm_trans=doe
|
||||
|
||||
The ``spdm_trans`` argument defines the underlying transport type that is
|
||||
emulated by QEMU. For an PCIe NVMe controller, both "doe" and "nvme" are
|
||||
supported. Where, "doe" does SPDM transport over the PCIe extended capability
|
||||
Data Object Exchange (DOE), and "nvme" uses the NVMe Admin Security
|
||||
Send/Receive commands to implement the SPDM transport.
|
||||
|
||||
.. _DMTF:
|
||||
https://www.dmtf.org/standards/SPDM
|
||||
|
|
|
|||
|
|
@ -8943,19 +8943,33 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
|
|||
|
||||
pcie_cap_deverr_init(pci_dev);
|
||||
|
||||
/* DOE Initialisation */
|
||||
/* SPDM Initialisation */
|
||||
if (pci_dev->spdm_port) {
|
||||
uint16_t doe_offset = n->params.sriov_max_vfs ?
|
||||
PCI_CONFIG_SPACE_SIZE + PCI_ARI_SIZEOF
|
||||
: PCI_CONFIG_SPACE_SIZE;
|
||||
uint16_t doe_offset = PCI_CONFIG_SPACE_SIZE;
|
||||
|
||||
pcie_doe_init(pci_dev, &pci_dev->doe_spdm, doe_offset,
|
||||
doe_spdm_prot, true, 0);
|
||||
switch (pci_dev->spdm_trans) {
|
||||
case SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE:
|
||||
if (n->params.sriov_max_vfs) {
|
||||
doe_offset += PCI_ARI_SIZEOF;
|
||||
}
|
||||
|
||||
pci_dev->doe_spdm.spdm_socket = spdm_socket_connect(pci_dev->spdm_port,
|
||||
errp);
|
||||
pcie_doe_init(pci_dev, &pci_dev->doe_spdm, doe_offset,
|
||||
doe_spdm_prot, true, 0);
|
||||
|
||||
if (pci_dev->doe_spdm.spdm_socket < 0) {
|
||||
pci_dev->doe_spdm.spdm_socket =
|
||||
spdm_socket_connect(pci_dev->spdm_port, errp);
|
||||
|
||||
if (pci_dev->doe_spdm.spdm_socket < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SPDM_SOCKET_TRANSPORT_TYPE_NVME:
|
||||
n->spdm_socket = spdm_socket_connect(pci_dev->spdm_port, errp);
|
||||
if (n->spdm_socket < 0) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -9246,9 +9260,14 @@ static void nvme_exit(PCIDevice *pci_dev)
|
|||
g_free(n->cmb.buf);
|
||||
}
|
||||
|
||||
/* Only one of the `spdm_socket`s below should have been setup */
|
||||
assert(!(pci_dev->doe_spdm.spdm_socket > 0 && n->spdm_socket >= 0));
|
||||
if (pci_dev->doe_spdm.spdm_socket > 0) {
|
||||
spdm_socket_close(pci_dev->doe_spdm.spdm_socket,
|
||||
SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE);
|
||||
} else if (n->spdm_socket >= 0) {
|
||||
spdm_socket_close(pci_dev->doe_spdm.spdm_socket,
|
||||
SPDM_SOCKET_TRANSPORT_TYPE_NVME);
|
||||
}
|
||||
|
||||
if (n->pmr.dev) {
|
||||
|
|
@ -9303,6 +9322,8 @@ static const Property nvme_props[] = {
|
|||
false),
|
||||
DEFINE_PROP_UINT16("mqes", NvmeCtrl, params.mqes, 0x7ff),
|
||||
DEFINE_PROP_UINT16("spdm_port", PCIDevice, spdm_port, 0),
|
||||
DEFINE_PROP_SPDM_TRANS("spdm_trans", PCIDevice, spdm_trans,
|
||||
SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE),
|
||||
DEFINE_PROP_BOOL("ctratt.mem", NvmeCtrl, params.ctratt.mem, false),
|
||||
DEFINE_PROP_BOOL("atomic.dn", NvmeCtrl, params.atomic_dn, 0),
|
||||
DEFINE_PROP_UINT16("atomic.awun", NvmeCtrl, params.atomic_awun, 0),
|
||||
|
|
@ -9378,7 +9399,9 @@ static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
|
|||
{
|
||||
uint16_t old_num_vfs = pcie_sriov_num_vfs(dev);
|
||||
|
||||
if (pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE)) {
|
||||
/* DOE is only initialised if SPDM over DOE is used */
|
||||
if (pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE) &&
|
||||
dev->spdm_trans == SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE) {
|
||||
pcie_doe_write_config(&dev->doe_spdm, address, val, len);
|
||||
}
|
||||
pci_default_write_config(dev, address, val, len);
|
||||
|
|
@ -9389,7 +9412,9 @@ static void nvme_pci_write_config(PCIDevice *dev, uint32_t address,
|
|||
static uint32_t nvme_pci_read_config(PCIDevice *dev, uint32_t address, int len)
|
||||
{
|
||||
uint32_t val;
|
||||
if (dev->spdm_port && pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE)) {
|
||||
|
||||
if (dev->spdm_port && pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE) &&
|
||||
(dev->spdm_trans == SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE)) {
|
||||
if (pcie_doe_read_config(&dev->doe_spdm, address, len, &val)) {
|
||||
return val;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/pcie.h"
|
||||
#include "hw/pci/pcie_doe.h"
|
||||
#include "system/spdm-socket.h"
|
||||
|
||||
#define TYPE_PCI_DEVICE "pci-device"
|
||||
typedef struct PCIDeviceClass PCIDeviceClass;
|
||||
|
|
@ -166,6 +167,7 @@ struct PCIDevice {
|
|||
|
||||
/* SPDM */
|
||||
uint16_t spdm_port;
|
||||
SpdmTransportType spdm_trans;
|
||||
|
||||
/* DOE */
|
||||
DOECap doe_spdm;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue