From nobody Mon Aug 24 17:03:55 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hTHLh1bv5z6pdH0 for ; Mon, 24 Aug 2026 17:03:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hTHLh0BVRz3Dc1 for ; Mon, 24 Aug 2026 17:03:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787591036; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Iw87mGK3k0g5XAYxQDiNDtiA/JCODAu76Yx5W78CEMI=; b=QZZc/2KKsWK21IqKWggMZV98gzKuPcg0lDkGaAyAq2LvFPkvd7LJt9kJsY01VA4uJAVDvm MMFHuiDRkzmIVvi4RzHfX2n/DzYu3TjDi96c5vZH8SOcdaZ+03lWe2rGAItbHRDtOAe4Q5 XbRKfboOAQgzs436JAcju1Er8PDwOWMS3c84lbMFhW2WlqvhW2q3B8depciICWQsG+A867 RWFa6aq7pe6+ODtzLOAxNZCBvOIOYmRn241eEwQC2kiPhJiwA9xY/VdWsqbg8xS0jhzLjj dE+6xtmpiKETBM2Fu6f6GWjwV5k5SFjtGEs6lg33V5JdVzkOJoSmLE8Ii145vw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787591036; a=rsa-sha256; cv=none; b=ypXbTxbDk74ZQFm6NWkVnIYwTmSfmEZp+R6Ay9jwWxDzTXJ52PxCqcvtqZyCqhas7T1LQG B4bNh9wrdn281o2X0bOk9yAwzTNmIxbQ+NxbLekKwOEXF5YHDyb64aBy5N9dwlYTzHOjfq Ic0857ucT0A8unQs57wKBqW7/4wjDHMLCkWiYGHa09ExZF9s+VlZAoESuyJ70oLP3I0xjn 1SK9eL9lgIxXaztm754dSqzzbvSUFDoUJ2UIaggnELkhwoWfsgLPu4Foy7sGTxvlRmQMdR l52AfzM/A/vPWfDv8VDPOl7TJS/7CL5xXehVb968qeysYbn/yUHKfX1s0saOWg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787591036; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Iw87mGK3k0g5XAYxQDiNDtiA/JCODAu76Yx5W78CEMI=; b=qNTXdcXKOSsteh95+5FWjFA4OufuORrc6YiKNwg6yiz970Y17hdYWq4H9q1Y5sZzZcmb6O IcQIiK0ysw4tRt70SvAk/LpVlIFWsYlVNCMogtZVFsabnR2xMs9Y0yYA1429fschvdjIy4 byCDpBdh8OBT86ZFkCg2qdVr10AF633hbHaFWyDfNpfWYVpYs5Mj9PoK4gC0QEY+xexPaq gOLN3eZXLHIn7U6sgHZFmcyGgEVcV3xL7Gb9FeJkA3MF2cevednaA987xQWzE4U8ErLzip e0hzXvqDdTFw3A3WmvKh5ObdcQvFr3njccaKoOG1YB7a2n8AuCK2ddu5VetR+w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hTHLg5jXtz1CcB for ; Mon, 24 Aug 2026 17:03:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 24373 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 24 Aug 2026 17:03:55 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih From: Adrian Chadd Subject: git: 417d6470cbd4 - main - nvme: limit visible namespaces on Apple S3X List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 417d6470cbd40c26ddf8abb5ddf6ab5125e85e75 Auto-Submitted: auto-generated Date: Mon, 24 Aug 2026 17:03:55 +0000 Message-Id: <6a8c797b.24373.6044d1c0@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=417d6470cbd40c26ddf8abb5ddf6ab5125e85e75 commit 417d6470cbd40c26ddf8abb5ddf6ab5125e85e75 Author: Abdelkader Boudih AuthorDate: 2026-08-24 17:02:44 +0000 Commit: Adrian Chadd CommitDate: 2026-08-24 17:02:46 +0000 nvme: limit visible namespaces on Apple S3X The Apple S3X controller exposes internal namespaces beyond NSID 1 that aren't meant to be visible to the OS. Added QUIRK_APPLE_S3X_NS1_ONLY and nvme_ctrlr_num_namespaces()/nvme_ctrlr_nsid_visible() helpers, and route namespace construction, notification, and AER namespace-changed handling through them instead of a raw cdata.nn count. MFC after: 1 week Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D58844 --- sys/dev/nvme/nvme_ctrlr.c | 14 +++++++++++--- sys/dev/nvme/nvme_pci.c | 4 ++-- sys/dev/nvme/nvme_private.h | 18 ++++++++++++++++++ sys/dev/nvme/nvme_sim.c | 6 +++--- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index e8f5ce2a9f28..5c90e252b748 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -633,7 +633,7 @@ nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr) struct nvme_namespace *ns; uint32_t i; - for (i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + for (i = 0; i < nvme_ctrlr_num_namespaces(ctrlr); i++) { ns = &ctrlr->ns[i]; nvme_ns_construct(ns, i+1, ctrlr); } @@ -1172,6 +1172,12 @@ nvme_ctrlr_start_config_hook(void *arg) if (!ctrlr->is_failed) { device_t child; + if (bootverbose && + (ctrlr->quirks & QUIRK_APPLE_S3X_NS1_ONLY) != 0 && + ctrlr->cdata.nn > nvme_ctrlr_num_namespaces(ctrlr)) + nvme_printf(ctrlr, + "ignoring Apple-internal namespaces above NSID 1\n"); + ctrlr->is_initialized = true; child = device_add_child(ctrlr->dev, NULL, DEVICE_UNIT_ANY); device_set_ivars(child, ctrlr); @@ -1180,7 +1186,7 @@ nvme_ctrlr_start_config_hook(void *arg) /* * Now notify the child of all the known namepsaces */ - for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + for (int i = 0; i < nvme_ctrlr_num_namespaces(ctrlr); i++) { struct nvme_namespace *ns = &ctrlr->ns[i]; if (ns->data.nsze == 0) @@ -1333,6 +1339,8 @@ nvme_ctrlr_aer_task(void *arg, int pending) } nsl = (struct nvme_ns_list *)aer->log_page_buffer; for (int i = 0; i < nitems(nsl->ns) && nsl->ns[i] != 0; i++) { + if (!nvme_ctrlr_nsid_visible(ctrlr, nsl->ns[i])) + continue; /* * I think we need to query the name space here and see * if it went away, arrived, or changed in size and call @@ -1343,7 +1351,7 @@ nvme_ctrlr_aer_task(void *arg, int pending) NVME_NS_CHANGED(children[j], nsl->ns[i]); } if (nsl->ns[0] == 0 && ctrlr->quirks & QUIRK_EMPTY_NAMESPACE_CHANGED_LOG) { - for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) + for (int i = 0; i < nvme_ctrlr_num_namespaces(ctrlr); i++) for (int j = 0; j < n_children; j++) NVME_NS_CHANGED(children[j], i + 1); } diff --git a/sys/dev/nvme/nvme_pci.c b/sys/dev/nvme/nvme_pci.c index a448694de4f2..8ea31850d09b 100644 --- a/sys/dev/nvme/nvme_pci.c +++ b/sys/dev/nvme/nvme_pci.c @@ -98,8 +98,8 @@ static struct _pcsid { 0xa822144d, 0, 0, "Samsung PM1725a", QUIRK_DELAY_B4_CHK_RDY }, { 0x07f015ad, 0, 0, "VMware NVMe Controller" }, { 0x2003106b, 0, 0, "Apple S3X NVMe Controller", - QUIRK_APPLE_NO_ASYNC_EVENT | QUIRK_PCIE_FLR_ON_FATAL | - QUIRK_APPLE_S3X_SERIALIZE }, + QUIRK_APPLE_NO_ASYNC_EVENT | QUIRK_APPLE_S3X_NS1_ONLY | + QUIRK_PCIE_FLR_ON_FATAL | QUIRK_APPLE_S3X_SERIALIZE }, { 0x2005106b, 0, 0, "Apple ANS2 NVMe Controller (T2)", QUIRK_APPLE_IDENTIFY_CNS_BROKEN | QUIRK_APPLE_SHARED_CID_SPACE | QUIRK_APPLE_NO_ASYNC_EVENT | QUIRK_APPLE_SINGLE_VECTOR | diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index 181fd27e1ecd..f96729608ed5 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -234,6 +234,7 @@ struct nvme_controller { #define QUIRK_APPLE_NO_ASYNC_EVENT 0x40 /* Skip NVMe async event requests */ #define QUIRK_APPLE_SINGLE_VECTOR 0x80 /* Single MSI vector, one IO queue */ #define QUIRK_EMPTY_NAMESPACE_CHANGED_LOG 0x100 /* Change Namespace List Log is always empty */ +#define QUIRK_APPLE_S3X_NS1_ONLY 0x200 /* Ignore Apple-internal namespace 2 */ #define QUIRK_APPLE_128_BYTE_SQES 0x400 /* T2 uses 128-byte I/O SQEs */ #define QUIRK_PCIE_FLR_ON_FATAL 0x800 /* Use FLR for a fatal controller */ #define QUIRK_APPLE_S3X_SERIALIZE 0x1000 /* One S3X I/O at a time */ @@ -339,6 +340,23 @@ struct nvme_controller { counter_u64_t alignment_splits; }; +static inline uint32_t +nvme_ctrlr_num_namespaces(const struct nvme_controller *ctrlr) +{ + uint32_t nn; + + nn = min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); + if ((ctrlr->quirks & QUIRK_APPLE_S3X_NS1_ONLY) != 0) + nn = min(nn, 1U); + return (nn); +} + +static inline bool +nvme_ctrlr_nsid_visible(const struct nvme_controller *ctrlr, uint32_t nsid) +{ + return (nsid >= 1 && nsid <= nvme_ctrlr_num_namespaces(ctrlr)); +} + /* * Access the idx'th submission queue entry. * sqe_shift is 0 for standard 64-byte SQEs and 1 for 128-byte SQEs. diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index 8f6cef4109f0..a58bd2026575 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -199,7 +199,7 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb) cpi->hba_misc = PIM_UNMAPPED | PIM_NOSCAN; cpi->hba_eng_cnt = 0; cpi->max_target = 0; - cpi->max_lun = ctrlr->cdata.nn; + cpi->max_lun = nvme_ctrlr_num_namespaces(ctrlr); cpi->maxio = ctrlr->max_xfer_size; cpi->initiator_id = 0; cpi->bus_id = cam_sim_bus(sim); @@ -365,7 +365,7 @@ nvme_sim_attach(device_t dev) goto err3; } - for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + for (int i = 0; i < nvme_ctrlr_num_namespaces(ctrlr); i++) { struct nvme_namespace *ns = &ctrlr->ns[i]; if (ns->data.nsze == 0) @@ -388,7 +388,7 @@ nvme_sim_fail_all_ns(device_t dev) struct nvme_sim_softc *sc = device_get_softc(dev); struct nvme_controller *ctrlr = sc->s_ctrlr; - for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + for (int i = 0; i < nvme_ctrlr_num_namespaces(ctrlr); i++) { struct nvme_namespace *ns = &ctrlr->ns[i]; if (ns->data.nsze == 0)