Linux s390 Architecture development
 help / color / mirror / Atom feed
From: Stefan Haberland <sth@linux.ibm.com>
To: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org,
	Jan Hoeppner <hoeppner@linux.ibm.com>,
	linux-s390@vger.kernel.org, Heiko Carstens <hca@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Christian Borntraeger <borntraeger@de.ibm.com>
Subject: [PATCH 19/19] s390/dasd: Read cached unit address and LSS in the CCW build path
Date: Wed,  5 Aug 2026 13:16:12 +0200	[thread overview]
Message-ID: <20260805111612.1285190-20-sth@linux.ibm.com> (raw)
In-Reply-To: <20260805111612.1285190-1-sth@linux.ibm.com>

The CCW build path (prefix_LRE, the full-track prefix and dso_ras) read the
base address and LSS straight from conf.ned. That buffer is freed and
reallocated by the reload worker (do_reload_device - dasd_eckd_read_conf -
dasd_eckd_clear_conf_data), so a configuration change concurrent with I/O
can free conf.ned while a request is being built.
Use-after-free reported by KASAN in prefix_LRE.

Read the cached copies instead.
The unit address is already kept in uid.real_unit_addr, and the LSS is now
cached in ned_lss. Both are refreshed under the ccwdev lock in
dasd_eckd_generate_uid whenever the configuration is (re)read.
Also fix for prepare for read subsystem data (prssd) users.

Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
---
 drivers/s390/block/dasd_eckd.c | 26 ++++++++++++++++----------
 drivers/s390/block/dasd_eckd.h |  8 ++++++++
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 5c1f328b7c8d..fd23ac25a7da 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -589,8 +589,9 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
 		return -EINVAL;
 	}
 	pfxdata->format = format;
-	pfxdata->base_address = basepriv->conf.ned->unit_addr;
-	pfxdata->base_lss = basepriv->conf.ned->ID;
+	/* cached copies - conf.ned may be freed under us by the reload worker */
+	pfxdata->base_address = READ_ONCE(basepriv->ned_ua);
+	pfxdata->base_lss = READ_ONCE(basepriv->ned_lss);
 	pfxdata->validity.define_extent = 1;
 
 	/* private uid is kept up to date, conf_data may be outdated */
@@ -807,6 +808,9 @@ static int dasd_eckd_generate_uid(struct dasd_device *device)
 		return -ENODEV;
 	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
 	create_uid(&private->conf, &private->uid);
+	/* cache LSS and unit address for the lockless CCW-build path */
+	WRITE_ONCE(private->ned_lss, private->conf.ned->ID);
+	WRITE_ONCE(private->ned_ua, private->conf.ned->unit_addr);
 	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 	return 0;
 }
@@ -1632,8 +1636,8 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device)
 	prssdp = cqr->data;
 	prssdp->order = PSF_ORDER_PRSSD;
 	prssdp->suborder = PSF_SUBORDER_VSQ;	/* Volume Storage Query */
-	prssdp->lss = private->conf.ned->ID;
-	prssdp->volume = private->conf.ned->unit_addr;
+	prssdp->lss = READ_ONCE(private->ned_lss);
+	prssdp->volume = READ_ONCE(private->ned_ua);
 
 	ccw = cqr->cpaddr;
 	ccw->cmd_code = DASD_ECKD_CCW_PSF;
@@ -4250,8 +4254,9 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,
 	if (!req && features->feature[56] & 0x01 && !copy_relation)
 		ras_data->op_flags.guarantee_init = 1;
 
-	ras_data->lss = private->conf.ned->ID;
-	ras_data->dev_addr = private->conf.ned->unit_addr;
+	/* cached copies - conf.ned may be freed under us by the reload worker */
+	ras_data->lss = READ_ONCE(private->ned_lss);
+	ras_data->dev_addr = READ_ONCE(private->ned_ua);
 	ras_data->nr_exts = nr_exts;
 
 	if (by_extent) {
@@ -4822,8 +4827,9 @@ static int prepare_itcw(struct itcw *itcw,
 	lredata = &pfxdata->locate_record;
 
 	pfxdata->format = 1; /* PFX with LRE */
-	pfxdata->base_address = basepriv->conf.ned->unit_addr;
-	pfxdata->base_lss = basepriv->conf.ned->ID;
+	/* cached copies - conf.ned may be freed under us by the reload worker */
+	pfxdata->base_address = READ_ONCE(basepriv->ned_ua);
+	pfxdata->base_lss = READ_ONCE(basepriv->ned_lss);
 	pfxdata->validity.define_extent = 1;
 
 	/* private uid is kept up to date, conf_data may be outdated */
@@ -6905,8 +6911,8 @@ static int dasd_eckd_query_host_access(struct dasd_device *device,
 	prssdp->order = PSF_ORDER_PRSSD;
 	prssdp->suborder = PSF_SUBORDER_QHA;	/* query host access */
 	/* LSS and Volume that will be queried */
-	prssdp->lss = private->conf.ned->ID;
-	prssdp->volume = private->conf.ned->unit_addr;
+	prssdp->lss = READ_ONCE(private->ned_lss);
+	prssdp->volume = READ_ONCE(private->ned_ua);
 	/* all other bytes of prssdp must be zero */
 
 	ccw = cqr->cpaddr;
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 30745f62402b..8e6f09e9ca7e 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -736,6 +736,14 @@ struct dasd_eckd_private {
 
 	/* alias management */
 	struct dasd_uid uid;
+	/*
+	 * Cached copies of conf.ned->ID (the LSS) and conf.ned->unit_addr,
+	 * refreshed under ccwdev_lock. Kept outside uid because create_uid()
+	 * memsets uid before repopulating it, which would expose a transient
+	 * zero to the lockless CCW-build readers.
+	 */
+	__u8 ned_lss;
+	__u8 ned_ua;
 	struct alias_pav_group *pavgroup;
 	struct alias_lcu *lcu;
 	int count;
-- 
2.53.0


  parent reply	other threads:[~2026-08-05 11:16 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-05 11:15 [PATCH 00/19] s390/dasd: ESE Performance improvements Stefan Haberland
2026-08-05 11:15 ` [PATCH 01/19] s390/dasd: Do not complete a failed ESE read as successful Stefan Haberland
2026-08-05 11:48   ` sashiko-bot
2026-08-05 11:15 ` [PATCH 02/19] s390/dasd: Propagate partial completion length across ERP recovery Stefan Haberland
2026-08-05 12:17   ` sashiko-bot
2026-08-05 11:15 ` [PATCH 03/19] s390/dasd: Guard sysfs discipline callbacks against unallocated private data Stefan Haberland
2026-08-05 12:44   ` sashiko-bot
2026-08-05 11:15 ` [PATCH 04/19] s390/dasd: Snapshot intrc before freeing the request block Stefan Haberland
2026-08-05 13:06   ` sashiko-bot
2026-08-05 11:15 ` [PATCH 05/19] s390/dasd: Optimize max blocks per request for track alignment Stefan Haberland
2026-08-05 13:10   ` sashiko-bot
2026-08-05 11:15 ` [PATCH 06/19] s390/dasd: Use GFP_KERNEL in dasd_alloc_device() Stefan Haberland
2026-08-05 13:17   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 07/19] s390/dasd: Add defines for the Extended Address Volume track address Stefan Haberland
2026-08-05 13:19   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 08/19] s390/dasd: Add infrastructure for ESE full-track write Stefan Haberland
2026-08-05 14:02   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 09/19] s390/dasd: Add range-based format-track collision detection Stefan Haberland
2026-08-05 15:11   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 10/19] s390/dasd: Extend prepare_itcw() to support WRITE_FULL_TRACK Stefan Haberland
2026-08-05 15:39   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 11/19] s390/dasd: Add dasd_eckd_build_cp_tpm_writefulltrack() Stefan Haberland
2026-08-05 15:53   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 12/19] s390/dasd: Use WRITE_FULL_TRACK in ESE format handler Stefan Haberland
2026-08-05 16:21   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 13/19] s390/dasd: Add full_track_bias to control fulltrack write mode Stefan Haberland
2026-08-05 16:41   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 14/19] s390/dasd: Derive adaptive ESE fulltrack heuristic from ft_bias Stefan Haberland
2026-08-05 16:48   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 15/19] s390/dasd: Stamp a format label into newly formatted volumes Stefan Haberland
2026-08-05 17:14   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 16/19] s390/dasd: Detect ESE volumes from the on-disk format label Stefan Haberland
2026-08-05 19:34   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 17/19] s390/dasd: Report ESE capability and format mode at device online Stefan Haberland
2026-08-05 19:44   ` sashiko-bot
2026-08-05 11:16 ` [PATCH 18/19] s390/dasd: Re-enable discard support for ESE volumes Stefan Haberland
2026-08-05 20:04   ` sashiko-bot
2026-08-05 11:16 ` Stefan Haberland [this message]
2026-08-05 20:31   ` [PATCH 19/19] s390/dasd: Read cached unit address and LSS in the CCW build path sashiko-bot
2026-08-05 12:32 ` [PATCH 00/19] s390/dasd: ESE Performance improvements Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260805111612.1285190-20-sth@linux.ibm.com \
    --to=sth@linux.ibm.com \
    --cc=axboe@kernel.dk \
    --cc=borntraeger@de.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=hoeppner@linux.ibm.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox