Skip to main content

Choosing a mode

Mirrored from the FEMU repository

This page is hw/femu/docs/concepts/choosing-a-mode.md at FEMU 39a55eeb6 (2026-10-02), licensed GPL-2.0-or-later. Send corrections to the FEMU repository.

An NVMe femu device emulates one kind of SSD, chosen with femu_mode. Features such as Flexible Data Placement or several namespaces are added on top of a mode with more properties. The CXL SSD is a separate device type, femu-cxl-ssd, not a femu_mode.

If you set nothing, you get NoSSD: femu_mode defaults to 2.

femu_mode values​

ValueNameEmulates
0OCSSDAn Open-Channel SSD. The host runs the FTL. lver=1 selects Open-Channel 1.2, lver=2 (default) selects 2.0.
1BBSSDA conventional ("black-box") SSD with a device FTL, garbage collection and NAND timing.
2NoSSDAn NVMe drive with no media timing. Default.
3ZNSA Zoned Namespace SSD (NVMe Zoned Namespace command set).
4CSDA computational storage drive that runs programs next to the data, on top of the BBSSD FTL.
5KVA key-value SSD (NVMe Key Value command set).

Any other value fails realize with "femu_mode must be 0 (OpenChannel), 1 (black-box), 2 (no-SSD), 3 (zoned), 4 (computational storage) or 5 (key-value)". With femu_mode=0, an lver other than 1 or 2 fails too.

Decision table​

Choosing a mode: answer the questions top to bottom; the first yes names the mode, its femu_mode value and its launcher in hw/femu/scripts/.

Figure: Choosing a mode: answer the questions top to bottom; the first "yes" names the mode, its femu_mode value and its launcher in hw/femu/scripts/.

Settings are added to -device femu,... unless the row says otherwise. Each launcher is in hw/femu/scripts/. Each guide covers launch, configuration, guest-side use, refusals and troubleshooting for its mode or feature.

GoalMode or featureKey settingsLauncherGuide
Fastest emulated NVMe drive, for host software stack workNoSSDfemu_mode=2 (or nothing)run-nossd.shNoSSD
A conventional SSD with realistic latency, GC and write amplificationBBSSDfemu_mode=1; geometry nchs, luns_per_ch, pls_per_lun, blks_per_pl, pgs_per_blk; timing pg_rd_lat, pg_wr_lat, blk_er_latrun-blackbox.shBlackBox
A zoned drive for ZNS-aware filesystems and databasesZNSfemu_mode=3; zns_num_ch, zns_num_lun, zns_num_plane, zns_num_blk, zns_flash_typerun-zns.shZNS
Host-managed flash: your own FTL in the hostOCSSDfemu_mode=0, lver=2 (or 1); lnum_ch, lnum_lun, lnum_pln, lpgs_per_blkrun-whitebox.shOCSSD
Store and fetch values by key, with no file systemKVfemu_mode=5noneKV
Run filters or other programs inside the driveCSDfemu_mode=4, fdm_size (required), nr_cu, csd_program_dirrun-csd.shCSD
Steer writes to reclaim units to reduce write amplificationFDP on BBSSD-device femu-subsys,id=s0,fdp=on,fdp.nruh=N before the controller, then femu_mode=1,subsys=s0run-blackbox-fdp.shFDP
Several namespaces on one controller, possibly of different modesmulti-namespacenamespaces=N, optional namespace_sizes=..., namespace_modes=...noneSeveral namespaces
Create and delete namespaces from the guestNamespace Managementns_mgmt=on on a NoSSD or BBSSD controller; bbssd_ns_limit for BBSSDnoneNamespace management
Metadata and end-to-end protection informationmetadata, PImeta=8 (or more), mc, pi=onnoneMetadata and PI
SSD capacity that the guest uses as memory, with SSD timing on cache missesCXL SSD-device femu-cxl-ssd,volatile-memdev=... on a CXL topology; cache-pages, cache-policy, derrun-cxlssd.shCXL SSD; design note
The same CXL medium also as an NVMe block deviceCXL NVMe front endfemu-cxl-ssd first, then -device femu,femu_mode=1,cxl_ssd=<id>noneCXL NVMe link

Commas inside a property value are doubled on the QEMU command line, for example namespace_modes=bbssd,,znssd.

Which features combine​

The checks below are made at realize; a combination they refuse stops QEMU with an error naming the rule.

Flexible Data Placement. fdp=on is a property of femu-subsys. Only BBSSD has an FDP write path; other modes accept a subsystem with FDP, but placement then has no effect on where data goes. FDP requires a single controller in the subsystem, a single namespace (namespaces=1), fdp.nrg=1 and fdp.nruh from 1 to fdp.nru. It cannot be combined with a KV namespace, meta, Streams or a subsystem with ns_mgmt=on. A BBSSD controller under FDP also refuses buffer_size, hot_cold_sep, read_reclaim_limit, retention_limit_sec, ecc_retention_sec, trim_lat_ns, a mapping other than page and a gc_policy other than greedy.

Several namespaces and per-namespace modes. namespaces is 1 to 256. The backend of devsz_mb MiB is split evenly, or by namespace_sizes. namespace_modes lists one mode per namespace from nossd, bbssd, znssd, ocssd, csd and kvssd; without it every namespace runs femu_mode. Limits:

  • OCSSD supports one namespace only, and the controller must be OCSSD too.
  • At most one CSD namespace per controller.
  • ZNS, KV, BBSSD and NoSSD namespaces can be mixed.
  • meta and Streams need every namespace to be NoSSD or BBSSD.

Namespace Management. ns_mgmt=on takes effect only when the controller and every namespace are NoSSD, or every one is BBSSD; with other modes, or with dps, it is accepted and stays off. On a controller that joins a subsystem without ns_mgmt, it fails realize. To share namespaces between controllers, set ns_mgmt=on on the femu-subsys instead. A shared subsystem takes NoSSD or BBSSD controllers that all have the same mode, meta, mc, pi, dpc, nlbaf, vwc and oncs, and no Streams, dps or namespace_modes.

Metadata and protection information. meta (bytes per block) works on NoSSD and BBSSD namespaces only, not with FDP, and needs a matching mc bit. pi=on offers protection information types 1 to 3 when meta is at least 8; the guest selects one with Format NVM or Namespace Management. pi cannot be combined with power_loss or cxl_ssd.

CXL NVMe front end. A femu controller with cxl_ssd=<id> must be BBSSD with one namespace, and must not use namespace_modes, namespace_sizes, ns_mgmt, subsys, streams, power_loss, buffer_size, op_pcent, meta, pi or dps. The femu-cxl-ssd must come first on the command line and have ftl=on. Its geometry and timing apply; the controller's own are ignored, and devsz_mb must be left at its default or equal the CXL medium's size.

Other combinations.

  • Streams (streams=on): NoSSD or BBSSD, not with FDP or a shared subsystem; BBSSD needs mapping page or dftl.
  • Power-loss model (power_loss=on): BBSSD with buffer_size > 0, page-aligned namespaces, and no meta, pi, ns_mgmt, subsys, namespace_modes or cxl_ssd. Without vwc=1 the write buffer holds nothing, so there is nothing to lose.
  • ZNS needs a logical block size of 4 KiB or less (lba_index).

Every mode at a glance​

Modes against layers: the interface each mode offers, where its FTL runs, which timing model it uses, where its data lives and which thread charges its time; below, the features each mode supports (CUs are CSD compute units).

Figure: Modes against layers: the interface each mode offers, where its FTL runs, which timing model it uses, where its data lives and which thread charges its time; below, the features each mode supports (CUs are CSD compute units).

Generated from modes.py: how to turn each mode or feature on, the guest kernel and tools it needs, what the host needs, and what CI checks. requirements.md has the guest kernel configuration in more detail.

Mode or featureUse it forTurn it on withGuest kernelGuest toolsHost needsLauncherChecked
NoSSDfast NVMe device in DRAM, no flash timingfemu_mode=2 (the default)any with the NVMe drivernvme-cli, fionone beyond the common onesrun-nossd.shCI: realize, Identify, write and read back
BlackBox SSD (BBSSD)a commercial SSD: device FTL, GC, NAND timingfemu_mode=1any with the NVMe drivernvme-cli, fioabout 17 GiB free RAM for the launcher's 12 GiB devicerun-blackbox.shCI: realize, Identify, write and read back; guest: quick start, run end to end
Zoned Namespace (ZNS)zoned storage researchfemu_mode=35.9 or newer with CONFIG_BLK_DEV_ZONED=y; 4 KiB guest pagesnvme-cli 1.12 or newer for nvme znsnone beyond the common onesrun-zns.shCI: realize, Identify, write and read back
Open-Channel SSD 1.2host-managed FTL researchfemu_mode=0,lver=14.16 to 5.14 (LightNVM was removed in 5.15)LightNVM tools, or SPDK on newer kernelsnone beyond the common onesrun-whitebox.shCI: realize, Identify
Open-Channel SSD 2.0host-managed FTL researchfemu_mode=0 (lver=2 is the default)4.17 to 5.14 (LightNVM was removed in 5.15)LightNVM tools, or SPDK on newer kernelsnone beyond the common onesrun-whitebox.shCI: realize, Identify
Key-value SSD (KV)key-value store researchfemu_mode=56.0 or newer; no block device, the namespace is /dev/ngXnYnvme-cli io-passthru, hw/femu/scripts/kv-probe.cnone beyond the common onesnoneCI: realize, Identify, store and retrieve
Computational storage (CSD)running programs next to the datafemu_mode=4,fdm_size=<MiB>any with the NVMe driverhw/femu/tests/csd toolscsd_program_dir for shared-library programs; --enable-csd-ubpf build for eBPF programsrun-csd.shCI: realize, Identify, write and read back
Flexible Data Placement (FDP)placement hints on a BBSSDfemu-subsys,fdp=on,fdp.nruh=<n> and femu,femu_mode=1,subsys=<id>any with the NVMe driver; placement hints need passthrough or io_uring commandsnvme-cli with nvme fdpnone beyond the common onesrun-blackbox-fdp.shCI: realize, Identify, write and read back
Multiple namespacesseveral namespaces, each with its own modenamespaces=<n>, optionally namespace_sizes and namespace_modesany with the NVMe driver (ZNS namespaces need what ZNS needs)nvme-clinone beyond the common onesnoneCI: realize, Identify, write and read back
Namespace managementcreate, delete and attach namespaces at run timens_mgmt=on on a NoSSD or BBSSD controller; femu-subsys,ns_mgmt=on to share namespacesany with the NVMe drivernvme-cli create-ns, attach-nsnone beyond the common onesnoneCI: realize, Identify, write and read back
Metadata and protection informationper-block metadata, PI types 1 to 3meta=<bytes>,mc=<mask>, plus pi=on with meta of 8 or moreCONFIG_BLK_DEV_INTEGRITY=y to use metadata formats through the block layernvme-cli formatnone beyond the common onesnoneCI: realize, Identify, write and read back
CXL SSD, der=offCXL memory backed by flash, all accesses trappedfemu-cxl-ssd below pxb-cxl and cxl-rp on -machine q35,cxl=onCONFIG_CXL_BUS, CXL_PCI, CXL_ACPI, CXL_MEM, CXL_PORT, CXL_REGION, CXL_REGION_INVALIDATION_TEST (in a VM), DEV_DAX, DEV_DAX_CXL, DEV_DAX_KMEMcxl-cli, daxctl, ndctla build with CONFIG_CXL_MEM_DEVICErun-cxlssd.shCI: realize
CXL SSD, der=memslotcached pages mapped into the guest as KVM memory slotsder=memslot on femu-cxl-ssdas for der=offas for der=offKVM (TCG is refused)run-cxlssd.shCI: realize
CXL SSD, der=cyloncached pages mapped by a Cylon host kernelder=cylon,cylon-kernel-ack=on on femu-cxl-ssdas for der=offas for der=offCylon host kernel; KVM with EPT A/D bits and the TDP MMU; 4 KiB host pages; a shared, preallocated hugetlb backend. Without them the device warns and uses MMIOrun-cxlssd.shCI: realize
CXL caching API (CCA)guest pins, unpins and invalidates cached pagescca=on on femu-cxl-ssdas for der=off; a devdax regionhw/femu/tools/cca (ccactl, cca-test), run as rootas for der=offrun-cxlssd.shCI: realize
NVMe front end on a CXL SSDthe same media as CXL memory and as an NVMe namespacefemu,bus=pcie.0,femu_mode=1,cxl_ssd=<id> after the femu-cxl-ssdas for der=off, plus the NVMe driveras for der=off, plus nvme-clias for der=offnoneCI: realize, Identify, write and read back

The image built by make-guest-image.sh runs Linux 6.8 and covers every mode except OCSSD.