IanSeyler wrote:...However I get an invalid opcode when using NSID 0x1. Any other NSID gives an Invalid NSID error:
Code: Select all
pci_nvme_io_cmd cid 0 nsid 0x1 sqid 1 opc 0x2 opname 'NVME_NVM_CMD_READ'
pci_nvme_err_invalid_opc invalid opcode 0x2
pci_nvme_enqueue_req_completion cid 0 cqid 1 dw0 0x0 dw1 0x0 status 0x4001
pci_nvme_err_req_status cid 0 nsid 0 status 0x4001 opc 0x2
pci_nvme_irq_masked IRQ is masked
The status is 0x4001, which under qemu is
Qemu is most likely returning the error from
this location inside its nvme_io_cmd function.
That is, the bit CSUPP within the Commands Supported and Effects Data Structure for opcode# 2 is not set. The source contains functions such as nvme_select_iocs_ns, which are responsible for selecting the appropriate iocs, at the time of attachment, or of start of the controller. Either an attachment is not performed, or the state at the start of the controller may cause qemu to select empty IOCS.
---
Qemu can be instrumented with fprintf's at selected locations and built, for greater debuggability, like so:
Code: Select all
# /home/user/src/qemu is the source
$ mkdir /home/user/src/bin
$ cd /home/user/src/bin
$ ../qemu/configure --prefix=/home/user/tools/qemu --target-list=x86_64-softmmu
$ make -j4 install
Edit: Qemu sets bits 0, 6, and 7 within CAP.CSS field. Based on the BareMetal nvme driver, that causes CC.CSS to be 0b111, which very likely results in selecting the empty IOCS.
According to the spec, for CC.CSS,
If CAP.CSS bit 7 is set to ‘1’, then the value 111b indicates that only the Admin
Command Set is supported and that no I/O Command Set or I/O Command Set
specific Admin commands are supported. When only the Admin Command Set
is supported, any command submitted on an I/O Submission Queue and any
I/O Command Set specific Admin command submitted on the Admin
Submission Queue is completed with status Invalid Command Opcode. If
CAP.CSS bit 7 is cleared to ‘0’, then the value of 111b is reserved.
The wordings above allow themselves to be read as if CC.CSS can be set to a value != 7 even when CAP.CSS bit 7 is 1.
Otherwise, this might well be a bug in Qemu, though you can work around, for now, by setting CC.CSS to a supported value other than 7.
Linux checks for CAP_CSS_CSI (6) first, and if set, selects CC_CSS_CSI. If not, it selects CC_CSS_NVM. It doesn't seem to bother itself with the admin-only CAP_CSS bit.
Edit2: OpenBSD and FreeBSD seem to set CC_CSS == 0, without checking capabilities, afaics.
Edit3: SeaBios checks for CAP_CSS_NVM, and if not set, errors out. Otherwise, it too sets CC.CSS = 0.