Device property reference
This page is hw/femu/docs/reference/properties.md at FEMU 39a55eeb6 (2026-10-02), licensed GPL-2.0-or-later. Send corrections to the FEMU repository.
Every property of the FEMU devices, as the binary reports it. ./qemu-system-x86_64 -device femu,help prints the same descriptions at the terminal. Properties are set on the command line, for example -device femu,femu_mode=1,devsz_mb=4096, and only before the device is realized; the QOM properties that can be read or changed while the guest runs are in runtime-properties.md.
Mode names follow femu_mode: OCSSD (0), bbssd (1, black box), NoSSD (2), ZNS (3), CSD (4) and KV (5). CSD builds the bbssd FTL, so the bbssd geometry, timing and FTL properties apply to it; KV uses only the bbssd geometry and NAND timing. Each description names the modes it applies to.
Devices:
femu: NVMe controllerfemu-subsys: NVMe subsystemfemu-cxl-ssd: CXL Type-3 SSD- Test-only properties
- Environment variables
femu: NVMe controller
-device femu has 145 properties of its own and 1 QOM property listed in runtime-properties.md.
Mode, capacity and namespaces
| Property | Type | Default | Description |
|---|---|---|---|
femu_mode | uint8 | 2 | Emulated SSD type: 0 OCSSD (Open-Channel), 1 bbssd (black-box FTL), 2 NoSSD (no media timing), 3 ZNS, 4 CSD (computational), 5 KV; other values fail realize |
devsz_mb | uint32 | 1024 | Size of the host memory backend in MiB, split across namespaces unless namespace_sizes is set; bbssd with op_pcent sizes from the NAND geometry instead |
namespaces | uint32 | 1 | Number of namespaces created at boot, 1 to 256; OCSSD and FDP support only 1 |
namespace_sizes | str | unset | Comma-separated size in bytes of each namespace (QEMU size syntax such as 4G,2G), one non-empty entry per namespace, summing to at most the backend; unset splits the backend evenly |
namespace_modes | str | unset | Comma-separated mode of each namespace from nossd, bbssd, znssd, ocssd, csd and kvssd, one entry per namespace; unset gives every namespace femu_mode |
op_pcent | uint32 | 0 | Over-provisioning in percent for bbssd: back the device with the full NAND capacity and expose capacity/(1 + op_pcent/100); 0 keeps devsz_mb sizing, not with cxl_ssd |
subsys | link<femu-subsys> | unset | ID of a femu-subsys device to join, created before this controller; needed for FDP, shared namespaces and the Endurance Group log |
cxl_ssd | link<femu-cxl-ssd> | unset | ID of a femu-cxl-ssd, listed before this controller, whose memory and FTL this bbssd controller serves as its one namespace |
pel_file | str | unset | Host file that keeps the Persistent Event Log and power cycle count across runs, created if missing; a corrupt or incompatible file fails realize |
serial | str | unset | No effect, kept for compatibility; Identify Controller reports a serial number FEMU generates. Setting it warns at realize |
Queues, pollers and interrupts
| Property | Type | Default | Description |
|---|---|---|---|
queues | uint32 | 8 | Number of I/O submission and completion queue pairs, 1 to 2047; MSI-X vectors are queues + 1 |
entries | uint32 | 2047 | Value reported as CAP.MQES (0's based), 1 to 65534; the controller accepts queues of up to entries + 1 entries |
max_sqes | uint8 | 6 | Submission queue entry size as a power of two (Identify SQES); must be 6, 64-byte entries |
max_cqes | uint8 | 4 | Completion queue entry size as a power of two (Identify CQES); must be 4, 16-byte entries |
stride | uint8 | 0 | Doorbell stride (CAP.DSTRD): doorbells are 4 << stride bytes apart, 0 to 12 |
multipoller_enabled | uint8 | 0 | 0 runs one poller thread for all I/O queues; 1 runs ceil(queues / poller_ratio) pollers, each owning a round-robin share of the queues; other values fail realize |
poller_ratio | uint32 | 1 | I/O queues per poller thread when multipoller_enabled=1; 0 is treated as 1, one poller per queue |
hiops_inline | bool | on | NoSSD only: performance option, on by default; set off only when debugging |
aerl | uint8 | 3 | Asynchronous Event Request Limit (Identify AERL, 0's based): the controller holds up to aerl + 1 outstanding requests |
elpe | uint8 | 3 | Error Log Page Entries (Identify ELPE, 0's based): the Error Information log keeps the newest elpe + 1 entries |
mdts | uint8 | 10 | Maximum Data Transfer Size as a power of two of the minimum memory page size (2^(12 + mpsmin + mdts) bytes); 0 means no limit |
intc | uint8 | 0 | Initial Coalescing Disable bit (0 or 1) of the Interrupt Vector Configuration feature; the value is reported, interrupts are not coalesced |
intc_thresh | uint8 | 0 | Initial aggregation threshold of the Interrupt Coalescing feature; the value is reported, interrupts are not coalesced |
intc_time | uint8 | 0 | Initial aggregation time, in 100 microsecond units, of the Interrupt Coalescing feature; the value is reported, interrupts are not coalesced |
Controller identity and capabilities
| Property | Type | Default | Description |
|---|---|---|---|
vid | uint16 | 7453 | PCI vendor ID, also reported as the Identify Controller PCI Vendor ID |
did | uint16 | 7967 | PCI device ID of the controller function |
acl | uint8 | 3 | Abort Command Limit reported in Identify Controller (0's based); it does not change how Abort is handled |
cqr | uint8 | 1 | CAP.CQR: 1 requires physically contiguous queues, 0 allows PRP-list queues |
vwc | uint8 | 0 | 1 advertises a volatile write cache, which the host can turn off with feature 06h to stop bbssd buffering writes; 0 advertises none and refuses feature 06h. Flush drains the bbssd write buffer either way; 0 or 1 |
temperature | uint16 | 323 | Composite temperature in kelvin reported by the SMART log and compared with the temperature threshold feature; default 323 (50 C) |
mpsmin | uint8 | 0 | CAP.MPSMIN: smallest host memory page size as 2^(12 + mpsmin) bytes; must not exceed mpsmax |
mpsmax | uint8 | 0 | CAP.MPSMAX: largest host memory page size as 2^(12 + mpsmax) bytes, from mpsmin to 15 |
oacs | uint16 | 2 | Optional Admin Command Support; only bit 1 (Format NVM, 0x2) may be set, and clearing it refuses Format NVM |
oncs | uint16 | 20 | Optional NVM Command Support bit mask: 0x1 Compare, 0x2 Write Uncorrectable, 0x4 Dataset Management, 0x8 Write Zeroes, 0x10 Save/Select, 0x80 Verify, 0x100 Copy; Timestamp is always added |
sgl | bool | off | Advertise and accept address scatter gather lists for data transfer; OCSSD ignores it |
cmbsz | uint32 | 0 | Controller Memory Buffer size register; 0 means no buffer, otherwise the size field times the unit must be a non-zero power of two |
cmbloc | uint32 | 0 | Controller Memory Buffer location register; its BAR field must be 2 when cmbsz is set |
LBA formats, metadata and protection
| Property | Type | Default | Description |
|---|---|---|---|
nlbaf | uint8 | 5 | Number of LBA formats, 1 to 16 (at most 8 with meta): 512-byte blocks doubling with each format |
lba_index | uint8 | 0 | LBA format the namespaces boot with, below nlbaf; ZNS needs a block size of 4 KiB or less |
extended | uint8 | 0 | 1 boots with metadata interleaved with the data (extended LBAs); needs bit 0 of mc; 0 or 1 |
meta | uint8 | 0 | Metadata bytes per logical block, NoSSD and bbssd only, not with FDP, dpc or dps; each format is then also offered with metadata |
mc | uint8 | 0 | Metadata Capabilities bit mask: bit 0 interleaved (extended LBAs), bit 1 separate buffer; required when meta is set |
pi | bool | off | Offer end-to-end protection information types 1 to 3 when meta is at least 8 bytes and allow Format and Create to select them; not with power_loss or cxl_ssd |
dpc | uint8 | 0 | Data Protection Capabilities reported in Identify Namespace when pi is off; must be 0 with meta |
dps | uint8 | 0 | Data Protection Type Settings reported in Identify Namespace; a non-zero value needs 8 bytes of metadata, which meta refuses, so leave it 0 and use pi |
ms | uint8 | 16 | No effect, kept for compatibility; meta sets the metadata size. A value other than the default warns at realize |
ms_max | uint8 | 64 | No effect, kept for compatibility; OCSSD 2.0 reports a single LBA format. A value other than the default warns at realize |
dlfeat | uint8 | 1 | No effect, kept for compatibility; Identify Namespace always reports DLFEAT 0x9 (deallocated blocks read as zeroes). A value other than the default warns at realize |
Namespace management, streams and power loss
| Property | Type | Default | Description |
|---|---|---|---|
ns_mgmt | bool | off | Enable Namespace Management and Attachment on a standalone NoSSD or bbssd controller whose namespaces all run femu_mode with dps 0, otherwise it stays off without an error; with a shared subsystem use femu-subsys ns_mgmt |
bbssd_ns_limit | uint32 | 4 | Most bbssd namespaces that may be allocated with ns_mgmt, including detached ones, 1 to 256 and at least namespaces; each has its own FTL |
streams | bool | off | Enable the Streams directive; bbssd separates streams per FTL page (SWS) and needs page or dftl mapping, NoSSD has no placement effect; not with FDP or a shared subsystem |
streams.max | uint16 | 8 | Number of stream slots with streams=on, 1 to 32; bbssd reserves streams.max + 1 lines for them |
power_loss | bool | off | bbssd: roll back writes still in the write buffer on a simulated power cut and enable simulate-power-loss; needs buffer_size > 0, vwc=1, page-aligned namespaces, and no meta, pi, ns_mgmt, subsys, namespace_modes or cxl_ssd |
NAND geometry (bbssd, CSD, KV)
| Property | Type | Default | Description |
|---|---|---|---|
secsz | int32 | 512 | bbssd, CSD, KV: sector size in bytes, greater than 0 |
secs_per_pg | int32 | 8 | bbssd, CSD, KV: sectors per NAND page, 1 to 256 |
pgs_per_blk | int32 | 256 | bbssd, CSD, KV: pages per NAND block, 1 to 65536, at most 512 with nand_cell_type |
blks_per_pl | int32 | 256 | bbssd, CSD, KV: blocks per plane, 1 to 65536; also the number of lines (superblocks) |
pls_per_lun | int32 | 1 | bbssd, CSD, KV: planes per LUN, 1 to 16 |
luns_per_ch | int32 | 8 | bbssd, CSD, KV: LUNs (dies) per channel, 1 to 128 |
nchs | int32 | 8 | bbssd, CSD, KV: number of channels, 1 to 4096; the total sector count must fit in a signed 32-bit integer |
NAND timing (bbssd, CSD, KV)
| Property | Type | Default | Description |
|---|---|---|---|
pg_rd_lat | int32 | 40000 | bbssd, CSD, KV: NAND page read time in ns when nand_cell_type is 0 |
pg_wr_lat | int32 | 200000 | bbssd, CSD, KV: NAND page program time in ns when nand_cell_type is 0 |
blk_er_lat | int32 | 2000000 | bbssd, CSD, KV: NAND block erase time in ns when nand_cell_type is 0 |
ch_xfer_lat | int32 | 0 | Channel transfer time per page in ns: the data phase for bbssd, CSD and KV when pg_xfer_lat is 0, and the OCSSD 1.2 transfer time with oc12_channel_timing |
cmd_addr_lat | int32 | 0 | bbssd, CSD, KV: command and address phase on the channel bus in ns; the bus is modelled only when this, pg_xfer_lat (or ch_xfer_lat) or status_lat is non-zero |
pg_xfer_lat | int32 | 0 | bbssd, CSD, KV: page data transfer phase on the channel bus in ns; 0 uses ch_xfer_lat |
status_lat | int32 | 0 | bbssd, CSD, KV: status read phase on the channel bus in ns |
tplpbsy | int32 | 0 | No effect, kept for compatibility; programs are issued one plane at a time. A value other than the default warns at realize |
tplrbsy | int32 | 0 | No effect, kept for compatibility; reads are issued one plane at a time. A value other than the default warns at realize |
tplebsy | int32 | 0 | bbssd, CSD, KV: busy time in ns between the planes of a multi-plane erase, which garbage collection issues when pls_per_lun > 1 |
trcbsy | int32 | 0 | No effect, kept for compatibility; no mode enables the cache read model. A value other than the default warns at realize |
trim_lat_ns | int32 | 0 | bbssd, CSD: time in ns charged per Dataset Management deallocate range; refused with FDP |
pe_suspend | int32 | 0 | bbssd, CSD, KV: non-zero lets a read suspend a program or erase on its LUN instead of waiting for it to finish |
tsusp_ns | int32 | 0 | bbssd, CSD, KV: overhead in ns added to a read that suspends a program or erase, 0 or more |
nand_cell_type | uint8 | 0 | bbssd, CSD, KV: 0 uses the flat pg_rd_lat, pg_wr_lat and blk_er_lat; 1 SLC, 2 MLC, 3 TLC or 4 QLC uses built-in per-page-type timing (other values fall back to 0) |
cell_pages | int32 | 0 | bbssd, CSD, KV: bits per cell (pages per wordline) for the pgtype_lat model, 0 to 5; 0 with pgtype_lat means 3 |
pgtype_lat | int32 | 0 | bbssd, CSD, KV: non-zero scales the program time by page type (lower to upper) using cell_pages, when nand_cell_type is 0 |
Reliability and wear
| Property | Type | Default | Description |
|---|---|---|---|
ecc_step_ns | int32 | 0 | bbssd, CSD, KV: extra read time in ns per ECC tier, one tier per 750 erases of the block plus one per ecc_retention_sec of data age, at most 4 tiers; 0 turns the model off |
ecc_retention_sec | int32 | 0 | bbssd, CSD, KV: data age in seconds that adds one ECC tier, with ecc_step_ns; 0 counts wear only; refused with FDP |
pe_cycles_rated | uint32 | 0 | bbssd, CSD, KV: rated program/erase cycles used for SMART Percentage Used; 0 takes the rating of nand_cell_type, or reports none |
nand_bad_blocks | uint32 | 0 | bbssd, CSD, KV: blocks marked bad at start, capped at the block count, which lowers SMART Available Spare |
err_read_unc_ppm | uint32 | 0 | bbssd, CSD: reads per million that fail as Unrecovered Read Error, injected at a fixed period; 0 disables |
err_write_fail_ppm | uint32 | 0 | bbssd, CSD and ZNS: writes per million that fail, injected at a fixed period (a ZNS zone then goes read-only); 0 disables |
read_reclaim_limit | int32 | 0 | bbssd, CSD: when a host read finds its block has taken this many reads since its erase, that line is queued and rewritten on a following write, one line at a time; 0 disables, refused with FDP |
retention_limit_sec | int32 | 0 | bbssd, CSD: when a host read hits a line filled at least this many seconds earlier, the line is queued and rewritten on a following write; 0 disables, refused with FDP |
Garbage collection, mapping and caches
| Property | Type | Default | Description |
|---|---|---|---|
gc_thres_pcent | int32 | 75 | bbssd, CSD: percent of lines in use at which background garbage collection starts, 1 to 100; KV uses it only as the fraction of NAND usable for values |
gc_thres_pcent_high | int32 | 95 | bbssd, CSD: percent of lines in use at which garbage collection is forced, from gc_thres_pcent to 100; under FDP it keeps at least one reclaim unit free unless it is 100 |
gc_policy | str | unset | bbssd, CSD without FDP: line victim policy, one of greedy, random, cost-benefit, fifo or d-choice; unset is greedy |
gc_strategy | int32 | 0 | bbssd with FDP: reclaim unit victim strategy, 0 greedy, 1 cost-benefit, 2 random or 4 per-handle |
mapping | str | unset | bbssd, CSD: logical-to-physical mapping scheme, one of page, dftl, hybrid or fast; unset is page, and FDP supports only page |
mapping_cache_mb | uint32 | 0 | bbssd, CSD with mapping=dftl: size of the cached mapping table in MiB; 0 means 4 |
read_cache_mb | uint32 | 0 | bbssd, CSD: size of the DRAM read cache in MiB; 0 disables it |
cache_evict | str | unset | bbssd, CSD: read cache eviction policy, one of clock, random, lru or arc; unset is clock |
hot_cold_sep | bool | off | bbssd, CSD with mapping page or dftl: write overwrites of mapped pages to separate hot lines; refused with FDP |
buffer_size | int32 | 0 | bbssd, CSD: DRAM write buffer capacity in NAND pages, not bytes; 0 programs every write directly |
buffer_thres_pcent | int32 | 90 | bbssd, CSD: buffer fill level in percent at which buffered pages are written to NAND, 1 to 100 when buffer_size > 0 |
fdp_trim_erase_all | int32 | 0 | bbssd with FDP: non-zero makes a deallocate reset every reclaim unit instead of the given ranges |
debug_ftl | bool | off | bbssd, CSD, KV: print a message when a page is programmed while not free or invalidated while not valid, and print merge counts for hybrid and fast mapping |
Host link and controller firmware
| Property | Type | Default | Description |
|---|---|---|---|
pcie_bandwidth_mbps | uint32 | 0 | Host link bandwidth in MB/s (10^6 bytes); each Read or Write is charged its transfer time on a per-direction link queue; 0 disables the bandwidth charge |
pcie_prop_delay_ns | uint32 | 0 | Host link propagation delay in ns added to each Read or Write after its link transfer; 0 disables it |
fw_cpu_ns | uint64 | 0 | Controller firmware time in ns charged to each Read, Write and Zone Append, serialized on one modelled core; 0 disables it |
ZNS
| Property | Type | Default | Description |
|---|---|---|---|
zns_num_ch | uint8 | 2 | ZNS: number of channels, 1 to 128 |
zns_num_lun | uint8 | 4 | ZNS: LUNs (dies) per channel, 1 or more |
zns_num_plane | uint8 | 2 | ZNS: planes per LUN, 1 to 8; the program unit grows with it |
zns_num_blk | uint8 | 32 | ZNS: blocks per plane, 1 or more; the zone count is zns_num_blk times zns_num_ch divided by the zone width and zns_num_plane |
zns_flash_type | int32 | 4 | ZNS: cell type, 1 SLC, 2 MLC, 3 TLC, 4 QLC or 5 PLC; MLC and PLC have no built-in timing and need zns_pg_rd_lat, zns_pg_wr_lat and zns_blk_er_lat |
zns_pg_rd_lat | int64 | 0 | ZNS: page read time in ns, 0 or more; 0 uses the built-in time of zns_flash_type |
zns_pg_wr_lat | int64 | 0 | ZNS: page program time in ns, 0 or more; 0 uses the built-in time of zns_flash_type |
zns_blk_er_lat | int64 | 0 | ZNS: block erase time in ns, 0 or more; 0 uses the built-in time of zns_flash_type |
zns_cmd_addr_lat | int64 | 0 | ZNS: command and address phase on the channel bus in ns, 0 or more |
zns_pg_xfer_lat | int64 | 0 | ZNS: page data transfer phase on the channel bus in ns, 0 or more |
zns_status_lat | int64 | 0 | ZNS: status read phase on the channel bus in ns, 0 or more |
zns_pe_suspend | int32 | 0 | ZNS: non-zero lets a read suspend a program or erase on its plane |
zns_tsusp_ns | int64 | 0 | ZNS: overhead in ns added to a read that suspends a program or erase, 0 or more |
zns_max_active | uint32 | 0 | ZNS: Maximum Active Resources (zones), at most the zone count; 0 means no limit |
zns_max_open | uint32 | 0 | ZNS: Maximum Open Resources (zones), at most the zone count and zns_max_active; 0 means no limit |
zns_num_wc | uint32 | 0 | ZNS: number of zone write caches; 0 uses zns_max_open, or 3 when that is 0 |
zns_zd_ext_size | uint32 | 0 | ZNS: zone descriptor extension size in bytes, a multiple of 64 up to 16320; 0 means none |
zns_num_conv_zones | uint32 | 0 | ZNS: number of leading conventional zones, which take random writes; capped at the zone count |
zns_zone_cap | size | 0 | ZNS: zone capacity in bytes, at least one logical block and at most the zone size; 0 means the zone size |
zns_chnls_per_zone | uint32 | 0 | ZNS: channels one zone spans (zone width), dividing zns_num_ch; 0 means all channels |
zns_zrwa_size | uint64 | 0 | ZNS: Zone Random Write Area size in logical blocks, at most 65535 and a multiple of zns_zrwafg_size; 0 disables ZRWA |
zns_zrwafg_size | uint64 | 0 | ZNS: ZRWA flush granularity in logical blocks, 1 to 65535 with ZRWA and 0 without; the zone capacity must be a multiple of it |
zns_zrwa_num | uint32 | 0 | ZNS: number of zones that may hold a ZRWA at once, 1 or more with ZRWA and 0 without |
zns_cross_zone_read | bool | off | ZNS: allow reads that cross zone boundaries (Read Across Zone Boundaries) |
zns_zasl_bs | uint32 | 131072 | ZNS: Zone Append size limit in bytes, a power-of-two multiple of 4 KiB; 0 follows mdts |
OCSSD (Open-Channel)
| Property | Type | Default | Description |
|---|---|---|---|
lver | uint8 | 2 | OCSSD: Open-Channel version, 1 for 1.2 or 2 for 2.0; other values fail realize |
flash_type | uint8 | 2 | OCSSD: cell type for the built-in timing tables, 1 SLC, 2 MLC, 3 TLC or 4 QLC; other values fail realize |
oc12_channel_timing | bool | off | OCSSD 1.2: charge channel transfer time for each page accessed, scaled by the sectors used out of lsecs_per_pg; ch_xfer_lat sets ns per page and 0 uses the flash_type value; off, transfers take no time |
lsec_size | uint16 | 4096 | OCSSD 1.2: sector size in bytes reported in the geometry, greater than 0 in both versions; data moves at the namespace block size, and OCSSD 2.0 always uses 4096 |
lsecs_per_pg | uint8 | 4 | OCSSD: sectors per page, greater than 0 |
lpgs_per_blk | uint16 | 512 | OCSSD: pages per block, greater than 0 and at most 512 for OCSSD 1.2 |
lmax_sec_per_rq | uint8 | 64 | OCSSD 1.2: most sectors in one vector command; OCSSD 2.0 uses 64 |
lnum_ch | uint8 | 2 | OCSSD: channels (2.0 groups), 1 to 32, with lnum_ch * lnum_lun at most 128 |
lnum_lun | uint8 | 8 | OCSSD: LUNs (2.0 parallel units) per channel, 1 or more, with lnum_ch * lnum_lun at most 128 |
lnum_pln | uint8 | 2 | OCSSD: planes per LUN, greater than 0; OCSSD 1.2 accepts 1, 2 or 4 |
lmetasize | uint16 | 16 | OCSSD 1.2: out-of-band metadata bytes per sector; OCSSD 2.0 uses 16 |
learly_reset | uint8 | 0 | OCSSD 2.0: non-zero reports the early reset capability, so the host may reset a chunk it has not filled |
CSD (computational storage)
| Property | Type | Default | Description |
|---|---|---|---|
fdm_size | uint64 | 0 | CSD: functional data memory size in MiB; required, greater than 0 |
nr_cu | uint8 | 4 | CSD: number of compute units, 1 to 64; programs wait for the first free unit |
nr_thread | uint8 | 4 | No effect, kept for CEMU compatibility; CSD still refuses 0. A value other than the default warns at realize |
time_slice | uint64 | 200000 | No effect, kept for CEMU compatibility. A value other than the default warns at realize |
context_switch_time | uint64 | 200 | No effect, kept for CEMU compatibility. A value other than the default warns at realize |
csf_runtime_scale | uint16 | 3 | CSD: non-zero multiplier applied to the host run time of a program that sets neither a runtime nor its own scale |
csd_program_dir | str | unset | CSD: host directory that shared-object and uBPF programs are loaded from, named by a file name with no slash that must resolve inside it; unset allows only the built-in phantom program type |
Generic PCI device properties
Common to every QEMU PCI device and documented by QEMU: acpi-index, addr, busnr, failover_pair_id, multifunction, rombar, romfile, romsize, sriov-pf.
QEMU's internal compatibility properties (x-max-bounce-buffer-size, x-pcie-ari-nextfn-1, x-pcie-err-unc-mask, x-pcie-ext-tag, x-pcie-extcap-init, x-pcie-lnksta-dllla) are not listed.
femu-subsys: NVMe subsystem
-device femu-subsys has 8 properties of its own.
Shared namespaces
| Property | Type | Default | Description |
|---|---|---|---|
ns_mgmt | bool | off | Keep one namespace table and one backend in the subsystem, shared by every controller that names it with subsys=; NoSSD and bbssd controllers only, and not with fdp |
nqn | str | unset | Subsystem name reported as nqn.2019-08.org.qemu:<nqn> by controllers that share namespaces through this subsystem; unset uses the device id |
Flexible Data Placement
| Property | Type | Default | Description |
|---|---|---|---|
fdp | bool | off | Enable Flexible Data Placement in endurance group 1 for controllers that join this subsystem; only bbssd places data by reclaim unit |
fdp.runs | size | 0 | Reclaim unit size in bytes; 0 means 96 MiB, and a bbssd controller accepts only 0 or the size of one superblock, which it then uses |
fdp.nrg | uint32 | 1 | Number of FDP reclaim groups; must be 1, placement into other groups is not implemented |
fdp.nruh | uint16 | 0 | Number of FDP reclaim unit handles (placement handles), from 1 to fdp.nru; must be set when fdp=on |
fdp.nru | uint64 | 128 | Number of reclaim units in each reclaim group, from fdp.nruh to 65536; bbssd uses at most one per superblock and needs at least 2 * fdp.nruh + 1 of them, and the namespace must fit in the units left once each handle has one open, each Persistently Isolated handle one to collect into, and forced collection its free ones |
fdp.isolation_mode | uint32 | 0 | 0 makes every reclaim unit handle Persistently Isolated; any other value makes the last handle Initially Isolated |
femu-cxl-ssd: CXL Type-3 SSD
-device femu-cxl-ssd has 24 properties of its own, 10 inherited from cxl-type3 and 50 QOM properties listed in runtime-properties.md.
Cache
| Property | Type | Default | Description |
|---|---|---|---|
cache-pages | uint32 | 1024 | Number of 4 KiB pages the device cache holds; 0 sends every access to the media, otherwise at most the media page count and divisible by cache-ways |
cache-policy | str | unset | Cache replacement policy, one of fifo, lifo, clock or s3-fifo; unset is fifo |
NAND geometry and timing
| Property | Type | Default | Description |
|---|---|---|---|
ftl | bool | on | Charge cache misses and write-backs to the FTL and NAND model; off keeps memory behaviour with no media timing and cannot be linked to an NVMe controller |
channels | uint32 | 4 | Number of NAND channels, 1 to 4096 |
luns-per-channel | uint32 | 4 | NAND LUNs per channel, 1 to 128, with one plane per LUN |
pages-per-block | uint32 | 256 | 4 KiB pages per NAND block, 1 to 65536 |
blocks-per-plane | uint32 | 0 | NAND blocks per plane, 2 to 65536 and enough to cover the media; 0 sizes it to 5/4 of the media plus 4 blocks per plane |
gc-threshold | uint32 | 75 | Percent of lines in use at which background garbage collection starts, 1 to 100 |
gc-threshold-high | uint32 | 95 | Percent of lines in use at which garbage collection is forced, from gc-threshold to 100 |
read-ns | uint64 | 40000 | NAND page read time in ns, at most one second |
program-ns | uint64 | 200000 | NAND page program time in ns, at most one second |
erase-ns | uint64 | 2000000 | NAND block erase time in ns, at most one second |
channel-ns | uint64 | 0 | NAND channel transfer time per page in ns, at most one second |
cylon-first-touch-program | bool | off | Charge a NAND program instead of a free read when a read reaches a page the FTL has never mapped, as the Cylon experiments do |
cylon-free-writeback | bool | off | Write dirty pages back on eviction and flush with no NAND program and no media time, as the Cylon experiments do |
Direct mapping (DER)
| Property | Type | Default | Description |
|---|---|---|---|
der | str | unset | Direct mapping of cached pages into the guest: off (MMIO only, the default), memslot (KVM memory slot aliases, not under TCG) or cylon (a Cylon host kernel) |
der-replace-rate | uint32 | 64 | With der=memslot and no free alias (1024 shared by all devices, fewer if KVM has fewer free slots), the most aliases per second a repeatedly missing page may displace; 0 disables replacement |
cylon-kernel-ack | bool | off | Must be on with der=cylon to state that the host runs a Cylon kernel with the dual-slot fixes; the device does not check it |
concurrent-misses | OnOffAuto | auto | Let misses to different pages wait for the media together; auto does so only while direct mapping is active |
Caching API, control channel and logs
| Property | Type | Default | Description |
|---|---|---|---|
cca | bool | off | Expose the caching API on BAR 5 (pin, unpin, invalidate, uncached ranges, query) and start its worker thread |
lsa-control | bool | off | Accept experiment control commands through Get LSA on an internal 128 MiB label area; trusted guests only, and not with an lsa backend |
log-dir | str | unset | Host directory for cxlssd-stats.log, cxlssd-io-N.log and cxlssd-spt.log; unset is the working directory |
tracefs-dir | str | unset | Host tracefs directory whose tracing control commands 91 and 81 write; unset, those commands change nothing on the host |
log-limit | size | 67108864 (64 MiB) | Size limit in bytes for each log file the device writes; 0 opens no I/O log and takes no statistics appends |
Inherited from cxl-type3
These belong to QEMU's cxl-type3 device. The descriptions say how femu-cxl-ssd treats them.
| Property | Type | Default | Description |
|---|---|---|---|
cdat | str | unset | Host file holding the CDAT table returned over DOE; unset builds a table from the backends; femu-cxl-ssd leaves it unchanged |
lsa | link<memory-backend> | unset | Label storage area backend served by Get and Set LSA; femu-cxl-ssd accepts it only with lsa-control=off |
memdev | link<memory-backend> | unset | Legacy persistent memory backend of cxl-type3; femu-cxl-ssd refuses it at realize |
num-dc-regions | uint8 | 0 | Number of dynamic capacity regions; femu-cxl-ssd requires it to stay 0 |
persistent-memdev | link<memory-backend> | unset | Persistent memory backend of cxl-type3; femu-cxl-ssd refuses it at realize |
sn | uint64 | 18446744073709551615 | PCIe Device Serial Number; the default (2^64 - 1) means unset, which gives no serial number capability; femu-cxl-ssd leaves it unchanged |
volatile-dc-memdev | link<memory-backend> | unset | Dynamic capacity memory backend; femu-cxl-ssd refuses it at realize |
volatile-memdev | link<memory-backend> | unset | Required: ID of the host memory backend that holds the device data, a non-zero multiple of 256 MiB, at most 120 GiB; der=cylon needs a hugetlbfs file backend with share=on and prealloc=on, or direct mapping falls back to MMIO with a warning |
x-speed | PCIELinkSpeed | 32 | PCIe link speed the device reports; femu-cxl-ssd leaves it unchanged and its timing does not depend on it |
x-width | PCIELinkWidth | 16 | PCIe link width the device reports; femu-cxl-ssd leaves it unchanged and its timing does not depend on it |
Generic PCI device properties
Common to every QEMU PCI device and documented by QEMU: acpi-index, addr, busnr, failover_pair_id, multifunction, rombar, romfile, romsize, sriov-pf.
QEMU's internal compatibility properties (x-max-bounce-buffer-size, x-pcie-ari-nextfn-1, x-pcie-err-unc-mask, x-pcie-ext-tag, x-pcie-extcap-init, x-pcie-lnksta-dllla) are not listed.
Test-only properties
These exist only when QEMU runs under qtest (-accel qtest) and serve FEMU's own tests. They are not part of the user interface.
femu:x-ftl-check,x-ns-test,x-oc12-clock,x-stream-testfemu-cxl-ssd:test-change-dpa,test-media-disabled,test-slot-reservation
Environment variables
FEMU reads these variables from the environment of the QEMU process. They are
debugging and host-placement aids, not device configuration, so they have no
-device property. When QEMU runs under sudo, pass them through, for example
sudo FEMU_EXP_LOG=1 ./run-blackbox.sh or sudo -E.
| Variable | Read by | Effect |
|---|---|---|
FEMU_MBE_INTERLEAVE | memory backend, every mode (hw/femu/backend/dram.c) | on interleaves the backend memory across NUMA nodes 0 and 1; 0 or 1 binds it to that node. Other values are ignored with a message. Unset leaves the host default policy. |
FEMU_FDP_DEBUG | bbssd FTL (hw/femu/bbssd/ftl.c) | Any value, even empty, prints FDP placement and reclaim traces to stderr. |
FEMU_EXP_LOG | bbssd FTL (hw/femu/bbssd/ftl-exp.c) | A non-empty value prints [EXP] lines to stderr that trace the writes, overwrites, deallocations, garbage collection moves and erases of pages whose data contains FEMU_SECRET; without FEMU_SECRET nothing is traced. |
FEMU_SECRET | bbssd FTL (hw/femu/bbssd/ftl-exp.c) | A non-empty marker string that selects the pages FEMU_EXP_LOG traces. |
FEMU_DUMP_LPN | bbssd FTL (hw/femu/bbssd/ftl-exp.c) | A logical page number (decimal or 0x hex) whose backend page is hex-dumped to stderr on every read not served from the write buffer, independent of FEMU_EXP_LOG. |
FEMU_KV_SELFTEST | KV FTL (hw/femu/kvssd/kvssd-ftl.c) | Any value runs the KV FTL self-test once at realize and logs the result. |