From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868174; cv=none; d=zohomail.com; s=zohoarc; b=em7GPRxgb59B7Z/RXiWRZ/NZ8wJmF9MM+f8frSIny3hMip2NxiWysrmuLG9HuSfdat1RADIrAXSWcBtGkJNA4CeZw5dnXozudYXKnwq17RtWjYgsSLyR8+cx15FIwfRfni4Ux3mp+SfXO4uB0ohCoRb3+m214cQEo5F+p8P+sk4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868174; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=WtvhKYN+ZUt6rDhVVmQmiflcDKFDLl5jJMNEdeicrys=; b=aXx8ROEG7ZHJ98EQMWFXgf67BMXEHW4t+NiSR1GzS9ey9l9KwUuoCsZ1KezT7KggyN0uruWJOCH8gncL/jFFyAztqU1Td45xmQHUn0S0OvBZUAYSaS/LPZAi51vob54FCdV2/dGJ/uYUs1dNAnaocPhQUGfQDUzn6bZlljgdcrw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868174437637.6080319519865; Fri, 19 Jun 2026 04:22:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIU-0002M2-VD; Fri, 19 Jun 2026 07:22:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIT-0002Jo-5h; Fri, 19 Jun 2026 07:22:05 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yD-G2; Fri, 19 Jun 2026 07:22:04 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHn-0089QU-1y; Fri, 19 Jun 2026 13:21:55 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=WtvhKYN+ZUt6rDhVVmQmiflcDKFDLl5jJMNEdeicrys=; b=wMOppAG5rgpM zd7q66xaDYPN7WBXklcCdNFHEgYhpoHyOlDSkyc0y75eWhMz87sg4ojnnaK//AKYk5MrvkDu5wW06 Kr0YG4fNYyWlmJcP0dRj2VB5ciX1Ul6YjfypP86xHHmToUgskkaPflY/wy59TjeAO9M2uj1+8gdJ+ do6HxtTqmBBMtt/aK6PT3CC4oDTJbS4wYEPv2ebUX6iiIiA4wBYjrimUfKSePagCw7oW830EiI3lL TWAjcVUoT7ZC9T6G8sBAClT8b5NcBLJnsZCAuv7Gj+1/xf/nOlsW5xF5FnyY8woKRO6q4IghTUzuA +1B5MobknXfdUHU5SMFSVA==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 1/9] hw/ide/ahci: cancel in-flight buffered reads on command engine restart Date: Fri, 19 Jun 2026 13:21:49 +0200 Message-ID: <20260619112158.304782-2-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868174857158500 Content-Type: text/plain; charset="utf-8" ATAPI CD reads are issued through ide_buffered_readv() (cd_read_sector() and ide_atapi_cmd_read_dma_cb() in hw/ide/atapi.c). The PIO path discards the returned aiocb; the DMA path stores it in s->bus->dma->aiocb. A guest can stop and restart a port's command engine (PxCMD.ST 1 -> 0 -> 1) while such a read is still in flight. Stopping the engine unmaps the command list (ahci_unmap_clb_address()) and restarting it re-maps the list and clears AHCIDevice.cur_cmd to NULL, but nothing tears down the outstanding read. This path does not run ide_reset(), so the drive's transfer state is preserved and the read still completes. Its callbacks then dereference the stale or NULL cur_cmd in the AHCI transfer helpers: PIO: cd_read_sector_cb() -> ide_atapi_cmd_reply_end() -> ide_transfer_start_norecurse() -> ahci_pio_transfer() DMA: ide_atapi_cmd_read_dma_cb() -> ahci_dma_rw_buf() -> ahci_populate_sglist() Both crash with a NULL cur_cmd; the PIO variant has been seen in the field. Cancel the outstanding I/O when the command list is unmapped, reusing ide_cancel_dma_sync() as the ATAPI DEVICE RESET command does. It runs the completion callback with -ECANCELED (which tears down s->bus->dma->aiocb for the DMA case) and orphans the buffered request, so the eventual asynchronous completion is a no-op. Merely setting the orphaned flag is not enough: it would leave s->bus->dma->aiocb pointing at a freed aiocb that a later reset would cancel. Fixes: 1d8c11d63154 ("ide: add support for IDEBufferedRequest") Signed-off-by: Denis V. Lunev --- hw/ide/ahci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index c2b4432b94..8e3684cd3c 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -740,6 +740,9 @@ static bool ahci_map_clb_address(AHCIDevice *ad) =20 static void ahci_unmap_clb_address(AHCIDevice *ad) { + /* Cancel in-flight reads that would complete against a cleared cur_cm= d. */ + ide_cancel_dma_sync(&ad->port.ifs[0]); + if (ad->lst =3D=3D NULL) { trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no); return; --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868241; cv=none; d=zohomail.com; s=zohoarc; b=DebFRBD1EL7QYcBVatJSqqigwlhDX7SLd5z0zwX7cM+s0fW3kL/rScfmHDPNrVlvMydiDzX2Q3ZBUiCO0OUM22SUii/9AhMK7qYKb54cdFAdbQUXnHGTUze4HsQgKW2Enf4L/ZgST7Kq4KqKNLtt1HzKtjCycNfLpFaOWZCBZjY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868241; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=gt4p8QtaMsOIKIQguzcq7jwj2LlSFWoBjngk0uOOFws=; b=J612NxFhlH3G76yXYc72FHR0Br5MJhWe/TZUxeV4emGJSJp3fUxCSkQNL8N0YilMYZ/wcYavg5aO2GiX/bqj5g5tdS8n4tdMj7jAIyirNcqO0z06laawc/daYXrXPKCdozPqxgxVdOnWs47r/huSWu1ZraFxmqb3/rwo4I72Yhw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868241699517.5629776628635; Fri, 19 Jun 2026 04:24:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIV-0002NI-Mk; Fri, 19 Jun 2026 07:22:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIT-0002Ju-CG; Fri, 19 Jun 2026 07:22:05 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yC-H4; Fri, 19 Jun 2026 07:22:05 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHn-0089QU-36; Fri, 19 Jun 2026 13:21:55 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=gt4p8QtaMsOIKIQguzcq7jwj2LlSFWoBjngk0uOOFws=; b=p8xq/cGBaoI3 cUYHZam7w81c0cwhR9j6hk12FdiJGjVsT+wo61ZmV+27s8e5+9DpkkdjD+/1kF5jFPjic+hZIx0Yy 142OYuqb/l1f9c+FAFwXSuFHs7wqoaxUGJCRQ7vq65mz1P4a9hG2lK18iGIcXtw9Pl05s7y3aASEr YESp3EHuXDtloxUjwh/S+owQLX/ayrV/QyW/EkM8GZ9kQQxYL1s0HezGI6v3L3gyagAQ19Vi3U/dc bBAjFI59hhPg9MCwggcMeQLVZPT9qsn3of0IvgQf3iCEcbqxBebxISm0DAGAEVKK8dVk8xmx4ztj/ CQLj0AJJ0m6vOM2MiC716w==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 2/9] tests/qtest/ahci: test ATAPI read completing after engine restart Date: Fri, 19 Jun 2026 13:21:50 +0200 Message-ID: <20260619112158.304782-3-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DIET_1=0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868243195158501 Content-Type: text/plain; charset="utf-8" Add a regression test for the crash that occurs when a buffered ATAPI read completes after the command engine has been restarted. Issue an ATAPI READ_10 against a blkdebug-backed CD, suspend the backend read so it stays in flight, stop and restart the port's command engine (which re-maps the command list and clears cur_cmd), then release the read. The PIO and DMA reply paths fault in different AHCI helpers (ahci_pio_transfer() vs ahci_dma_rw_buf()), so cover both. The DMA variant is the reliable guard: on engine restart check_cmd() can re-arm cur_cmd before the old read completes, so the PIO variant does not fault in every build. The test only asserts that qemu survives a subsequent register access; if the blkdebug breakpoint ever failed to park the read it would pass without exercising the bug, as with the existing break/resume tests. Signed-off-by: Denis V. Lunev --- tests/qtest/ahci-test.c | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 5c32ff2002..44799eea15 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -1625,6 +1625,69 @@ static void test_cdrom_pio_multi(void) ahci_test_cdrom_read10(3, false); } =20 +/* + * Regression test: a buffered ATAPI read completing after a command + * engine restart must not dereference the cleared cur_cmd. Cover both + * PIO and DMA; the DMA variant is the reliable guard. + */ +static void test_atapi_engine_restart_in_flight(bool dma) +{ + AHCIQState *ahci; + AHCICommand *cmd; + unsigned char *tx; + char *iso; + int fd; + uint8_t port; + uint64_t buffer; + uint64_t iso_size =3D (uint64_t)ATAPI_SECTOR_SIZE * 2; + + fd =3D prepare_iso(iso_size, &tx, &iso); + + ahci =3D ahci_boot_and_enable("-drive if=3Dnone,id=3Ddrive0," + "file=3Dblkdebug::%s,format=3Draw,readonly= =3Don " + "-M q35 " + "-device ide-cd,drive=3Ddrive0 ", iso); + port =3D ahci_port_select(ahci); + + buffer =3D ahci_alloc(ahci, ATAPI_SECTOR_SIZE); + qtest_memset(ahci->parent->qts, buffer, 0x00, ATAPI_SECTOR_SIZE); + + /* Suspend the next backend read so the ATAPI read stays in flight. */ + g_free(qtest_hmp(ahci->parent->qts, + "qemu-io drive0 \"break read_aio rd\"")); + + cmd =3D ahci_atapi_command_create(CMD_ATAPI_READ_10, ATAPI_SECTOR_SIZE, + dma); + ahci_command_adjust(cmd, 0, buffer, ATAPI_SECTOR_SIZE, 0); + ahci_command_commit(ahci, cmd, port); + ahci_command_issue_async(ahci, cmd); + + /* Stop and restart the command engine to re-map the command list. */ + ahci_px_clr(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST); + ahci_px_set(ahci, port, AHCI_PX_CMD, AHCI_PX_CMD_ST); + + g_free(qtest_hmp(ahci->parent->qts, "qemu-io drive0 \"resume rd\"")); + + /* Round-trip through the device to confirm qemu is still alive. */ + ahci_px_rreg(ahci, port, AHCI_PX_TFD); + + ahci_command_free(cmd); + ahci_free(ahci, buffer); + g_free(tx); + ahci_shutdown(ahci); + remove_iso(fd, iso); +} + +static void test_atapi_engine_restart_pio(void) +{ + test_atapi_engine_restart_in_flight(false); +} + +static void test_atapi_engine_restart_dma(void) +{ + test_atapi_engine_restart_in_flight(true); +} + /* Regression test: Test that a READ_CD command with a BCL of 0 but a size= of 0 * completes as a NOP instead of erroring out. */ static void test_atapi_bcl(void) @@ -2042,6 +2105,10 @@ int main(int argc, char **argv) =20 qtest_add_func("/ahci/cdrom/pio/bcl", test_atapi_bcl); qtest_add_func("/ahci/cdrom/eject", test_atapi_tray); + qtest_add_func("/ahci/cdrom/engine_restart/pio", + test_atapi_engine_restart_pio); + qtest_add_func("/ahci/cdrom/engine_restart/dma", + test_atapi_engine_restart_dma); =20 ret =3D g_test_run(); =20 --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868191; cv=none; d=zohomail.com; s=zohoarc; b=gncKVdAhtDMQVdhs0hxZJ13H2RJUCwXLiSsIECFPVxmQtuoR1FRKjpOpoviZSW9yWXZmFwdCknsKaZybzgD67b1H9VAtCYcCN7wE14jvp9Nwe0guYlaD4gVsTA0U/4i4Jpm4EgU15hYqIACk1H4m/zaRRlS7FJcLOEa5dI7FeY8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868191; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=HDmHPaxM6C21e+ZsQUic2L14EvzMb+/7ZwV5Ke4z/vU=; b=P5PkBXDMUOo0TR1SXbTdwzwegM5nQ75O9MKyz1s5tH1ZteaNG3UfOwqwejOmsnTzhZyrthqZaV2Ic6zdjuTY6aTxL62TwqUj2nEw3YfKTxW93perH1oC0SMDw7ctT8nnWqy+QLMNmVIxa7NUs0GzfmRUK3ofWXIGGzr7MbyNC2k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868191568937.7971997554503; Fri, 19 Jun 2026 04:23:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIZ-0002Pl-Dp; Fri, 19 Jun 2026 07:22:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIT-0002KV-QC; Fri, 19 Jun 2026 07:22:05 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yE-Gu; Fri, 19 Jun 2026 07:22:05 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHo-0089QU-11; Fri, 19 Jun 2026 13:21:56 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=HDmHPaxM6C21e+ZsQUic2L14EvzMb+/7ZwV5Ke4z/vU=; b=B+mLwiWjEoHw 0NnGsbqZwsiB35dtytjSjm10HXgO3j7UB1POLiU/95XBnvAHHyjMdU3FWV77yMnQVR7q0MEmSSpSg xxv7IAdcg/LcJH1oKeFhSqQZF64MeIQiLC+amhtmvKpl9Vek4Dd6hatKqh3whfii6TkUclNrssRAr LYyXA0YJVWc2Vvs7O0oucRvnnWaH+amRCH1YFBQXO3McZ8s7gzyhOdNjt0kLnGWfjSeEILdgCPexM 6SQTjas0+p/dX+zFBU+s8G7BMpy0bnNAJq33sJygeSovGeA7fhHPr5RJgIoGjFKm13I+e/ldOCsk2 WoqUgtugk4c06gjEY61J0w==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 3/9] tests/qtest/ide-test: parametrize the ATAPI CD-ROM read test Date: Fri, 19 Jun 2026 13:21:51 +0200 Message-ID: <20260619112158.304782-4-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868192960158500 Content-Type: text/plain; charset="utf-8" cdrom_pio_impl() and test_cdrom_dma() duplicate the same image setup and data-integrity check around two different transfer mechanisms. Fold them into a single cdrom_read_impl(nblocks, flags) helper, with a CDROM_PIO/CDROM_DMA flag selecting the transfer, so further read coverage can be added once for both paths. No functional change: /ide/cdrom/pio, pio_large and dma run exactly as before. Signed-off-by: Denis V. Lunev --- tests/qtest/ide-test.c | 146 +++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 78 deletions(-) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 721e78170b..0fcfd0688c 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -982,6 +982,7 @@ static void send_scsi_cdb_read10(QPCIDevice *dev, QPCIB= ar ide_bar, } } =20 + static void nsleep(QTestState *qts, int64_t nsecs) { const struct timespec val =3D { .tv_nsec =3D nsecs }; @@ -1034,8 +1035,12 @@ static void ide_wait_intr(QTestState *qts, int irq) g_assert_not_reached(); } =20 -static void cdrom_pio_impl(int nblocks) +#define CDROM_PIO 0 +#define CDROM_DMA (1 << 0) + +static void cdrom_read_impl(int nblocks, unsigned flags) { + bool dma =3D flags & CDROM_DMA; QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; @@ -1063,57 +1068,75 @@ static void cdrom_pio_impl(int nblocks) dev =3D get_pci_device(qts, &bmdma_bar, &ide_bar); qtest_irq_intercept_in(qts, "ioapic"); =20 - /* PACKET command on device 0 */ - qpci_io_writeb(dev, ide_bar, reg_device, 0); - qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF); - qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0x= FF)); - qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET); - /* HP0: Check_Status_A State */ - nsleep(qts, 400); - data =3D ide_wait_clear(qts, BSY); - /* HP1: Send_Packet State */ - assert_bit_set(data, DRQ | DRDY); - assert_bit_clear(data, ERR | DF | BSY); - - /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */ - send_scsi_cdb_read10(dev, ide_bar, 0, nblocks); - - /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes. - * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes. - * We allow an odd limit only when the remaining transfer size is - * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only - * request n blocks, so our request size is always even. - * For this reason, we assume there is never a hanging byte to fetch. = */ - g_assert(!(rxsize & 1)); - limit =3D BYTE_COUNT_LIMIT & ~1; - for (i =3D 0; i < DIV_ROUND_UP(rxsize, limit); i++) { - size_t offset =3D i * (limit / 2); - size_t rem =3D (rxsize / 2) - offset; - - /* HP3: INTRQ_Wait */ - ide_wait_intr(qts, IDE_PRIMARY_IRQ); + if (dma) { + uintptr_t guest_buf =3D guest_alloc(&guest_malloc, rxsize); + PrdtEntry prdt[1]; + + prdt[0].addr =3D cpu_to_le32(guest_buf); + prdt[0].size =3D cpu_to_le32(rxsize | PRDT_EOT); =20 - /* HP2: Check_Status_B (and clear IRQ) */ + send_dma_request_dev(qts, dev, bmdma_bar, ide_bar, CMD_PACKET, 0, + nblocks, prdt, ARRAY_SIZE(prdt), + send_scsi_cdb_read10); + + qtest_memread(qts, guest_buf, rx, rxsize); + } else { + /* PACKET command on device 0 */ + qpci_io_writeb(dev, ide_bar, reg_device, 0); + qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0x= FF); + qpci_io_writeb(dev, ide_bar, reg_lba_high, + (BYTE_COUNT_LIMIT >> 8 & 0xFF)); + qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET); + /* HP0: Check_Status_A State */ + nsleep(qts, 400); data =3D ide_wait_clear(qts, BSY); + /* HP1: Send_Packet State */ assert_bit_set(data, DRQ | DRDY); assert_bit_clear(data, ERR | DF | BSY); =20 - /* HP4: Transfer_Data */ - for (j =3D 0; j < MIN((limit / 2), rem); j++) { - rx[offset + j] =3D cpu_to_le16(qpci_io_readw(dev, ide_bar, - reg_data)); + /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */ + send_scsi_cdb_read10(dev, ide_bar, 0, nblocks); + + /* + * Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes. + * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 by= tes. + * We allow an odd limit only when the remaining transfer size is + * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can = only + * request n blocks, so our request size is always even. + * For this reason, we assume there is never a hanging byte to fet= ch. + */ + g_assert(!(rxsize & 1)); + limit =3D BYTE_COUNT_LIMIT & ~1; + for (i =3D 0; i < DIV_ROUND_UP(rxsize, limit); i++) { + size_t offset =3D i * (limit / 2); + size_t rem =3D (rxsize / 2) - offset; + + /* HP3: INTRQ_Wait */ + ide_wait_intr(qts, IDE_PRIMARY_IRQ); + + /* HP2: Check_Status_B (and clear IRQ) */ + data =3D ide_wait_clear(qts, BSY); + assert_bit_set(data, DRQ | DRDY); + assert_bit_clear(data, ERR | DF | BSY); + + /* HP4: Transfer_Data */ + for (j =3D 0; j < MIN((limit / 2), rem); j++) { + rx[offset + j] =3D cpu_to_le16(qpci_io_readw(dev, ide_bar, + reg_data)); + } } - } =20 - /* Check for final completion IRQ */ - ide_wait_intr(qts, IDE_PRIMARY_IRQ); + /* Check for final completion IRQ */ + ide_wait_intr(qts, IDE_PRIMARY_IRQ); =20 - /* Sanity check final state */ - data =3D ide_wait_clear(qts, DRQ); - assert_bit_set(data, DRDY); - assert_bit_clear(data, DRQ | ERR | DF | BSY); + /* Sanity check final state */ + data =3D ide_wait_clear(qts, DRQ); + assert_bit_set(data, DRDY); + assert_bit_clear(data, DRQ | ERR | DF | BSY); + } =20 g_assert_cmpint(memcmp(pattern, rx, rxsize), =3D=3D, 0); + g_free(pattern); g_free(rx); test_bmdma_teardown(qts); @@ -1122,51 +1145,18 @@ static void cdrom_pio_impl(int nblocks) =20 static void test_cdrom_pio(void) { - cdrom_pio_impl(1); + cdrom_read_impl(1, CDROM_PIO); } =20 static void test_cdrom_pio_large(void) { /* Test a few loops of the PIO DRQ mechanism. */ - cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE); + cdrom_read_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE, CDROM_PIO); } =20 - static void test_cdrom_dma(void) { - QTestState *qts; - static const size_t len =3D ATAPI_BLOCK_SIZE; - size_t ret; - char *pattern =3D g_malloc(ATAPI_BLOCK_SIZE * 16); - char *rx =3D g_malloc0(len); - uintptr_t guest_buf; - PrdtEntry prdt[1]; - FILE *fh; - - qts =3D ide_test_start( - "-drive if=3Dnone,file=3D%s,media=3Dcdrom,format=3Draw,id=3Dsr= 0,index=3D0 " - "-device ide-cd,drive=3Dsr0,bus=3Dide.0", tmp_path[0]); - qtest_irq_intercept_in(qts, "ioapic"); - - guest_buf =3D guest_alloc(&guest_malloc, len); - prdt[0].addr =3D cpu_to_le32(guest_buf); - prdt[0].size =3D cpu_to_le32(len | PRDT_EOT); - - generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE); - fh =3D fopen(tmp_path[0], "wb+"); - ret =3D fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh); - g_assert_cmpint(ret, =3D=3D, 16); - fclose(fh); - - send_dma_request(qts, CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10); - - /* Read back data from guest memory into local qtest memory */ - qtest_memread(qts, guest_buf, rx, len); - g_assert_cmpint(memcmp(pattern, rx, len), =3D=3D, 0); - - g_free(pattern); - g_free(rx); - test_bmdma_teardown(qts); + cdrom_read_impl(1, CDROM_DMA); } =20 int main(int argc, char **argv) --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868155; cv=none; d=zohomail.com; s=zohoarc; b=GDmwquetBWkwBVUp3q7bAmEaMJ+V446JCk4TLXflIgDRdEcAfcQvvgT80JZAQH+oIG7xP7kYyHcP0Qjt+3j56eWT58QtzOBCArAARwxtNifxIzNbg9Bo8k6/vkVZnD4JmxKmNwE2RkXcihCmt7JmdBZuQSSqQJ9ctsJWfGcmz68= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868155; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=J9ToOT6z/gq7DtSjqnTgcFtuRjS+7vrlrxcJw76UIi4=; b=aYaztALNAnT1isRstg7T6GjzBXuDgGvFCCWUQWLXKENRGG+1Wp5HEnspnzAms459RSNDusdVscWk3cjPHIMYy9lFj4DUBWQJyBt/w7nXpujn7NyjhvtX3xlSyWLmC+qls4WVdO952s7OYp4H55LQnmoprRb+KlHU9B7qOf7n/JU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868155751177.15837348838363; Fri, 19 Jun 2026 04:22:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIZ-0002Ph-BM; Fri, 19 Jun 2026 07:22:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIU-0002Lq-DS; Fri, 19 Jun 2026 07:22:06 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yG-EU; Fri, 19 Jun 2026 07:22:06 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHo-0089QU-29; Fri, 19 Jun 2026 13:21:56 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=J9ToOT6z/gq7DtSjqnTgcFtuRjS+7vrlrxcJw76UIi4=; b=TFtlyTMDuoz/ op4skxeFAFLV6Sy92M+hXP6s3gy1RgxH2go1+lOelJB+erb9r+Estzqn6d7L8Irh6avxodyxv+nvO R8s3g2e0sDV/WO4Wb6X+wzEiNPKErtcD5wn1WkcJlWUs3JvN/kq42dkCGfjX+Tm9fzc5uWchauC7p vjfA1vTtkIQu9MPggzpohl13PO1JWDKitSFOJSIVxjMEPZmcOtrobFtX9Cs04rbXO6E3XWUxAHNfQ ODCt4UugrmLEJdkigkFPJU5l+dVcP2ziVj3Tyi1LhDKtwY4VGo42RT3oZy/OEDHFC7pGnS/FWHDRT WSJEtUxpFFoRqOPoZmLDeg==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 4/9] tests/qtest/ide-test: add a multi-sector ATAPI DMA read test Date: Fri, 19 Jun 2026 13:21:52 +0200 Message-ID: <20260619112158.304782-5-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868157268158500 Content-Type: text/plain; charset="utf-8" test_cdrom_pio_large() already exercises a multi-sector PIO read. Add the DMA counterpart through the same cdrom_read_impl() helper so the multi-block ATAPI DMA read path gets equivalent coverage. Signed-off-by: Denis V. Lunev --- tests/qtest/ide-test.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 0fcfd0688c..2c674edf15 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -1159,6 +1159,11 @@ static void test_cdrom_dma(void) cdrom_read_impl(1, CDROM_DMA); } =20 +static void test_cdrom_dma_large(void) +{ + cdrom_read_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE, CDROM_DMA); +} + int main(int argc, char **argv) { const char *base; @@ -1218,6 +1223,7 @@ int main(int argc, char **argv) qtest_add_func("/ide/cdrom/pio", test_cdrom_pio); qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large); qtest_add_func("/ide/cdrom/dma", test_cdrom_dma); + qtest_add_func("/ide/cdrom/dma_large", test_cdrom_dma_large); =20 ret =3D g_test_run(); =20 --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868155; cv=none; d=zohomail.com; s=zohoarc; b=b489For6U2N1RHBgSikWx8ahVpLOOSbHWGHQxTKSUTMl9xKgtSfhk0vUJXS3pIJCpB4fv6X8+LTi/nj9Ih8Q49nRjFg5W9hNnf0dKiQYMp+8SZdYxqWVqVM1VgbCqOIIk/eZeK+KEmkDSaSV5LCb92UB0zOR74yciaISFzY6oL0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868155; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=zkUYs1RO/gg4tAwAsoVtitA0e/3+8CoANDRZvWgxYRg=; b=gdNPW/a8G1YvHskVN4ujsyNKatdJUMA2OqDWLwmktpx0qNhDAOTVCLg2dsXTN5Ju3mWtUxu+Juj6AHl3ERtmEVfHd9x3CTNol1E+x1igIXmMf81fPF6XAnjwWDShNQhXYvg+l29nhldaSN+6VFWHmfOPrDTqr/A2Tc8rGDBvuFM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868155804218.3679030017896; Fri, 19 Jun 2026 04:22:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIU-0002Km-2x; Fri, 19 Jun 2026 07:22:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIS-0002JJ-9o; Fri, 19 Jun 2026 07:22:04 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yH-GJ; Fri, 19 Jun 2026 07:22:04 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHp-0089QU-0B; Fri, 19 Jun 2026 13:21:56 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=zkUYs1RO/gg4tAwAsoVtitA0e/3+8CoANDRZvWgxYRg=; b=REla0Hi141Am aICZfnWb0neU4j5EJB6pGJYo7gODGKtL0/jaZenDwh1VYWJtcCgMynGrWXhrvbi9I8k6vGbNvSFBk A2cXxaC4TgIdQRFNe5too8ulpJacE8SKAD99aCNfENM+cSnCKdySLFprwNsjPa1fTcckGYQYk52c3 RPiTVomnMTF+bYXFb1Ez3Sn+c0fHiuHvemkXO6lIjTohZdVjtbO4gLnhVqcZbRSpKeZi6CCKFLjMa QP/GZ++lSC/coFFykn5xf3Z8opn2t+IKcc0qtdj3MPqOnp5TqieH5d8h0D91d0gPbFJDgip0Cfhpu jtMPgA+6PlsaNg1ZpAnrqw==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 5/9] tests/qtest/ide-test: cover raw (2352-byte) ATAPI CD reads Date: Fri, 19 Jun 2026 13:21:53 +0200 Message-ID: <20260619112158.304782-6-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868157268158501 Content-Type: text/plain; charset="utf-8" READ CD with the field-selector set to 0xf8 returns full 2352-byte raw sectors (sync + header + 2048 data + EDC/ECC), driving the ATAPI raw read path that READ10 never touches. Add a send_scsi_cdb_read_cd() helper and a CDROM_RAW flag to cdrom_read_impl(), then exercise both PIO and DMA. The PIO case uses a byte-count limit spanning several raw sectors so the device must rebuffer mid-burst, and each sector's 2048-byte payload is verified at its in-sector offset. Signed-off-by: Denis V. Lunev --- tests/qtest/ide-test.c | 75 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 2c674edf15..b36b0f8875 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -48,6 +48,10 @@ =20 #define ATAPI_BLOCK_SIZE 2048 =20 +/* Raw READ CD sector: 12 sync + 4 header + 2048 data + 288 EDC/ECC. */ +#define ATAPI_RAW_SIZE 2352 +#define ATAPI_RAW_DATA 16 + /* How many bytes to receive via ATAPI PIO at one time. * Must be less than 0xFFFF. */ #define BYTE_COUNT_LIMIT 5120 @@ -982,6 +986,40 @@ static void send_scsi_cdb_read10(QPCIDevice *dev, QPCI= Bar ide_bar, } } =20 +typedef struct ReadCDCDB { + uint8_t opcode; + uint8_t sector_type; + uint32_t lba; + uint8_t length[3]; + uint8_t main_channel; + uint8_t sub_channel; + uint8_t control; +} __attribute__((__packed__)) ReadCDCDB; + +static void send_scsi_cdb_read_cd(QPCIDevice *dev, QPCIBar ide_bar, + uint64_t lba, int nblocks) +{ + ReadCDCDB pkt =3D { }; + int i; + + g_assert_cmpint(lba, <=3D, UINT32_MAX); + g_assert_cmpint(nblocks, >=3D, 0); + g_assert_cmpint(nblocks, <=3D, 0xffffff); + + /* Construct SCSI CDB packet */ + pkt.opcode =3D 0xbe; + pkt.lba =3D cpu_to_be32(lba); + pkt.length[0] =3D (nblocks >> 16) & 0xff; + pkt.length[1] =3D (nblocks >> 8) & 0xff; + pkt.length[2] =3D nblocks & 0xff; + pkt.main_channel =3D 0xf8; /* sync + headers + user data + EDC/ECC: 23= 52 */ + + /* Send Packet */ + for (i =3D 0; i < sizeof(ReadCDCDB) / 2; i++) { + qpci_io_writew(dev, ide_bar, reg_data, + le16_to_cpu(((uint16_t *)&pkt)[i])); + } +} =20 static void nsleep(QTestState *qts, int64_t nsecs) { @@ -1037,10 +1075,12 @@ static void ide_wait_intr(QTestState *qts, int irq) =20 #define CDROM_PIO 0 #define CDROM_DMA (1 << 0) +#define CDROM_RAW (1 << 1) =20 static void cdrom_read_impl(int nblocks, unsigned flags) { bool dma =3D flags & CDROM_DMA; + bool raw =3D flags & CDROM_RAW; QTestState *qts; QPCIDevice *dev; QPCIBar bmdma_bar, ide_bar; @@ -1048,8 +1088,11 @@ static void cdrom_read_impl(int nblocks, unsigned fl= ags) int patt_blocks =3D MAX(16, nblocks); size_t patt_len =3D ATAPI_BLOCK_SIZE * patt_blocks; char *pattern =3D g_malloc(patt_len); - size_t rxsize =3D ATAPI_BLOCK_SIZE * nblocks; + unsigned xfer =3D raw ? ATAPI_RAW_SIZE : ATAPI_BLOCK_SIZE; + size_t rxsize =3D xfer * nblocks; uint16_t *rx =3D g_malloc0(rxsize); + void (*send_cdb)(QPCIDevice *, QPCIBar, uint64_t, int) =3D + raw ? send_scsi_cdb_read_cd : send_scsi_cdb_read10; int i, j; uint8_t data; uint16_t limit; @@ -1076,8 +1119,7 @@ static void cdrom_read_impl(int nblocks, unsigned fla= gs) prdt[0].size =3D cpu_to_le32(rxsize | PRDT_EOT); =20 send_dma_request_dev(qts, dev, bmdma_bar, ide_bar, CMD_PACKET, 0, - nblocks, prdt, ARRAY_SIZE(prdt), - send_scsi_cdb_read10); + nblocks, prdt, ARRAY_SIZE(prdt), send_cdb); =20 qtest_memread(qts, guest_buf, rx, rxsize); } else { @@ -1094,8 +1136,7 @@ static void cdrom_read_impl(int nblocks, unsigned fla= gs) assert_bit_set(data, DRQ | DRDY); assert_bit_clear(data, ERR | DF | BSY); =20 - /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */ - send_scsi_cdb_read10(dev, ide_bar, 0, nblocks); + send_cdb(dev, ide_bar, 0, nblocks); =20 /* * Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes. @@ -1135,7 +1176,17 @@ static void cdrom_read_impl(int nblocks, unsigned fl= ags) assert_bit_clear(data, DRQ | ERR | DF | BSY); } =20 - g_assert_cmpint(memcmp(pattern, rx, rxsize), =3D=3D, 0); + if (raw) { + /* The 2048-byte payload of each raw sector sits past its header. = */ + for (i =3D 0; i < nblocks; i++) { + uint8_t *sec =3D (uint8_t *)rx + i * ATAPI_RAW_SIZE + ATAPI_RA= W_DATA; + + g_assert_cmpint(memcmp(sec, pattern + i * ATAPI_BLOCK_SIZE, + ATAPI_BLOCK_SIZE), =3D=3D, 0); + } + } else { + g_assert_cmpint(memcmp(pattern, rx, rxsize), =3D=3D, 0); + } =20 g_free(pattern); g_free(rx); @@ -1164,6 +1215,16 @@ static void test_cdrom_dma_large(void) cdrom_read_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE, CDROM_DMA); } =20 +static void test_cdrom_pio_raw(void) +{ + cdrom_read_impl(4, CDROM_RAW); +} + +static void test_cdrom_dma_raw(void) +{ + cdrom_read_impl(4, CDROM_DMA | CDROM_RAW); +} + int main(int argc, char **argv) { const char *base; @@ -1224,6 +1285,8 @@ int main(int argc, char **argv) qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large); qtest_add_func("/ide/cdrom/dma", test_cdrom_dma); qtest_add_func("/ide/cdrom/dma_large", test_cdrom_dma_large); + qtest_add_func("/ide/cdrom/pio_raw", test_cdrom_pio_raw); + qtest_add_func("/ide/cdrom/dma_raw", test_cdrom_dma_raw); =20 ret =3D g_test_run(); =20 --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868180; cv=none; d=zohomail.com; s=zohoarc; b=dVEED76r671Mg9FwF6I9wH6YgCNnYzj1UMd2JWsmFigE4FgPA1e7IaeU24ziIu+WA7IUAiYeCUNtWMWcKecxerlrqVWyEzZ51VEjSU/SL1wYFEtS2Gvq6H3aRC3ywVIVy0DKNONTEXhc5JAtDp+Hze91PZ3MeNq/RqakKsQf2v8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868180; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=xzoMkOQugJtIBBm141jQ93a33yS86uwbmWxeZ2JxrdY=; b=d9miVz02W8i/gnh5XO+R53mnkPAMaFWYq1rUeHyN3BLxP5zdvgPFCPhM3RKXlrUf2rYyhDzZ8Y6r7Ibt0gAbnjEKrJz/KRg3GlSR9mqfuFi+VuP9GGhUdunivO8f5AX3r11dPWjGGORwp7X32W6o9K6ZemxU+bfm64TB9GsM9LU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868180817906.9066431513575; Fri, 19 Jun 2026 04:23:00 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIT-0002Jy-FF; Fri, 19 Jun 2026 07:22:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIR-0002JC-Uw; Fri, 19 Jun 2026 07:22:03 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yO-FJ; Fri, 19 Jun 2026 07:22:03 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHp-0089QU-1R; Fri, 19 Jun 2026 13:21:57 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=xzoMkOQugJtIBBm141jQ93a33yS86uwbmWxeZ2JxrdY=; b=lkWvIFE217DZ OmHkjqZL0ZjHdGyvaF8+2Kh94C89kQOEpErLxrAC61mDazD0P6rn613MAVrgkksqSzvkkH70bt2IY DF6z1RTckCWKZ33/li8jW82Zb1VJAiZ9TxrNAt5SOb4WQ1E8cCkdo0akfEo5nIL1E/+GpT08tDTlt I8jhFlKWLR3Wpe3tFEonFaJdr2JYheh068RoBM483mXMLXt2HGI3GZuXPvMCtK29jx5a3vaKMPM2J iErw6p8zW5lKpWvtJygYPAU+Vd9C1/HiwTVTu7YmA7oQ4w83QYtoOmzdaRnwpk333M6Fc6so9eVMO T7boTXPv0/rDzLZrsFjAMw==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 6/9] tests/qtest/libqos/ahci: support raw (2352-byte) READ CD Date: Fri, 19 Jun 2026 13:21:54 +0200 Message-ID: <20260619112158.304782-7-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868182907158500 Content-Type: text/plain; charset="utf-8" ahci_exec() always builds ATAPI commands with a 2048-byte logical sector size, so it cannot drive a READ CD that returns full 2352-byte raw sectors. Add an atapi_raw option that sets the READ CD field-selector to 0xf8 and the command's sector size to 2352 before the transfer is sized, so the derived block count stays correct while the buffer and byte counts cover the raw sectors. Signed-off-by: Denis V. Lunev --- tests/qtest/libqos/ahci.c | 5 +++++ tests/qtest/libqos/ahci.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/tests/qtest/libqos/ahci.c b/tests/qtest/libqos/ahci.c index 0621a6c477..e3019a1eca 100644 --- a/tests/qtest/libqos/ahci.c +++ b/tests/qtest/libqos/ahci.c @@ -707,6 +707,11 @@ void ahci_exec(AHCIQState *ahci, uint8_t port, if (opts->atapi) { uint16_t bcl =3D opts->set_bcl ? opts->bcl : ATAPI_SECTOR_SIZE; cmd =3D ahci_atapi_command_create(op, bcl, opts->atapi_dma); + if (opts->atapi_raw) { + /* request full 2352-byte raw sectors; sector_size must match = */ + cmd->atapi_cmd[9] =3D 0xf8; + cmd->sector_size =3D ATAPI_RAW_SECTOR_SIZE; + } } else { cmd =3D ahci_command_create(op); } diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h index a0487a1557..2a48a7523d 100644 --- a/tests/qtest/libqos/ahci.h +++ b/tests/qtest/libqos/ahci.h @@ -242,6 +242,7 @@ =20 #define AHCI_SECTOR_SIZE (512) #define ATAPI_SECTOR_SIZE (2048) +#define ATAPI_RAW_SECTOR_SIZE (2352) =20 #define AHCI_SIGNATURE_CDROM (0xeb140101) #define AHCI_SIGNATURE_DISK (0x00000101) @@ -485,6 +486,7 @@ typedef struct AHCIOpts { uint64_t buffer; /* Pointer to source or destination guest buffer */ bool atapi; /* ATAPI command? */ bool atapi_dma; /* Use DMA for ATAPI? */ + bool atapi_raw; /* READ CD returning 2352-byte raw sectors */ bool error; int (*pre_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *); int (*mid_cb)(AHCIQState*, AHCICommand*, const struct AHCIOpts *); --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868169; cv=none; d=zohomail.com; s=zohoarc; b=bM92sMuac23x8dC9vbwe2cy2ER8kYqN6sGEJHhIrOsbq/Q87shlWzbeVgDeZ5xePXd9mVH4zTQxavcpRFt9Qz7fh4pex8hnKXIvawLmOH/fMwvh0U5Re5GEMLva4gUCdEO+YDts9OXpZaCSS7bmgwPndK12p6pU/oG/HGGQzn/0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868169; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=s31N2WSzGJMifOsR5kGPV+f7nNm1CIU04brTAJY0Gk8=; b=aPlRuczVJdTx0w/4BL5tkNzhO7iiGAz1OwOMT9zq9CIXxYssuJscTHUzebppDv/7PLnkMZYvbyeXfyUPNIkYTlf2qPHeyPcXCcaaVoDa9WrXLB26KATs5A2L1fzyHRvoIJbYnr0cy+imDxfAz8CALA0APYQX1Qpvvv5pfupvNJ8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868169967386.4688005150722; Fri, 19 Jun 2026 04:22:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIZ-0002Pk-DG; Fri, 19 Jun 2026 07:22:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIT-0002KE-Jg; Fri, 19 Jun 2026 07:22:05 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIQ-0005yQ-Qd; Fri, 19 Jun 2026 07:22:05 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHp-0089QU-2Z; Fri, 19 Jun 2026 13:21:57 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=s31N2WSzGJMifOsR5kGPV+f7nNm1CIU04brTAJY0Gk8=; b=XTEBtmoY4jAt A+rtchLPwjbgyRKLPUhV19rtRerk+2iyfWkalEc2jU9t3MslykAkA9vm8yOeTp2WXAiq17glihCC1 Nh4AJFn3YlI6m9Gp3Du6d/6iNBQhsDUQxIqkaQv5XOAlzB9vkJSWnd7nYhVQZL7uJARo06bFlA0Cu 8TIsFmQvJD9YUmu5ackhForC8Vzh71XW8iMuXHqbd7nPVLetT37cIBvq+2jLI+LoC8HebofF55fhA aPoD7gTWb7kF8v/wRKiXkYS6lBD2ly99MViOiWGW8zrSsq61GaWip3s1SHm4sshcfpPbVo4J33UTP nekGaLch1RGixerqzAyJew==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 7/9] tests/qtest/ahci: cover raw (2352-byte) ATAPI CD reads Date: Fri, 19 Jun 2026 13:21:55 +0200 Message-ID: <20260619112158.304782-8-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868171108158500 Content-Type: text/plain; charset="utf-8" Add /ahci/cdrom/{pio,dma}/raw: read several sectors with READ CD in raw mode (atapi_raw), so the ATAPI 2352-byte unpack path is exercised through the AHCI delivery, which IDE coverage does not reach. Each sector's 2048-byte payload is verified at its in-sector offset. The PIO case uses a byte-count limit of one raw sector per DRQ burst: libqos asserts a one-sector PIO transfer, and the multi-sector unpack loop is already covered by the IDE raw test. Signed-off-by: Denis V. Lunev --- tests/qtest/ahci-test.c | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 44799eea15..58bc04b3ef 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -1565,6 +1565,31 @@ static int ahci_cb_cmp_buff(AHCIQState *ahci, AHCICo= mmand *cmd, return 0; } =20 +static int ahci_cb_cmp_raw(AHCIQState *ahci, AHCICommand *cmd, + const AHCIOpts *opts) +{ + unsigned char *tx =3D opts->opaque; + unsigned char *rx; + unsigned i, nsectors; + + if (!opts->size) { + return 0; + } + + nsectors =3D opts->size / ATAPI_RAW_SECTOR_SIZE; + rx =3D g_malloc0(opts->size); + qtest_bufread(ahci->parent->qts, opts->buffer, rx, opts->size); + /* Each raw sector carries its 2048-byte payload past a 16-byte header= . */ + for (i =3D 0; i < nsectors; i++) { + g_assert_cmphex(memcmp(rx + i * ATAPI_RAW_SECTOR_SIZE + 16, + tx + i * ATAPI_SECTOR_SIZE, + ATAPI_SECTOR_SIZE), =3D=3D, 0); + } + g_free(rx); + + return 0; +} + static void ahci_test_cdrom(int nsectors, bool dma, uint8_t cmd, bool override_bcl, uint16_t bcl) { @@ -1625,6 +1650,47 @@ static void test_cdrom_pio_multi(void) ahci_test_cdrom_read10(3, false); } =20 +static void ahci_test_cdrom_raw(int nsectors, bool dma) +{ + AHCIQState *ahci; + unsigned char *tx; + char *iso; + int fd; + AHCIOpts opts =3D { + .size =3D (uint64_t)ATAPI_RAW_SECTOR_SIZE * nsectors, + .atapi =3D true, + .atapi_dma =3D dma, + .atapi_raw =3D true, + .set_bcl =3D true, + .bcl =3D ATAPI_RAW_SECTOR_SIZE, /* one raw sector per DRQ burst */ + .post_cb =3D ahci_cb_cmp_raw, + }; + uint64_t iso_size =3D (uint64_t)ATAPI_SECTOR_SIZE * (nsectors + 1); + + fd =3D prepare_iso(iso_size, &tx, &iso); + opts.opaque =3D tx; + + ahci =3D ahci_boot_and_enable("-drive if=3Dnone,id=3Ddrive0,file=3D%s,= format=3Draw " + "-M q35 " + "-device ide-cd,drive=3Ddrive0 ", iso); + + ahci_exec(ahci, ahci_port_select(ahci), CMD_ATAPI_READ_CD, &opts); + + g_free(tx); + ahci_shutdown(ahci); + remove_iso(fd, iso); +} + +static void test_cdrom_dma_raw(void) +{ + ahci_test_cdrom_raw(3, true); +} + +static void test_cdrom_pio_raw(void) +{ + ahci_test_cdrom_raw(3, false); +} + /* * Regression test: a buffered ATAPI read completing after a command * engine restart must not dereference the cleared cur_cmd. Cover both @@ -2100,8 +2166,10 @@ int main(int argc, char **argv) =20 qtest_add_func("/ahci/cdrom/dma/single", test_cdrom_dma); qtest_add_func("/ahci/cdrom/dma/multi", test_cdrom_dma_multi); + qtest_add_func("/ahci/cdrom/dma/raw", test_cdrom_dma_raw); qtest_add_func("/ahci/cdrom/pio/single", test_cdrom_pio); qtest_add_func("/ahci/cdrom/pio/multi", test_cdrom_pio_multi); + qtest_add_func("/ahci/cdrom/pio/raw", test_cdrom_pio_raw); =20 qtest_add_func("/ahci/cdrom/pio/bcl", test_atapi_bcl); qtest_add_func("/ahci/cdrom/eject", test_atapi_tray); --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868214; cv=none; d=zohomail.com; s=zohoarc; b=H3iIbckxnCKqInlHX0hl+Q3BgkoLOgvOKl4CBA25zkRBUcMfAskcKodEnO03Q0+kqxG5R1hmrPG5vM7HsA347YJPNsZq5sluRXuneMKfYCrQxSrqA2hSYRb+OfknIZUW7CP/1nKQXjLv68X6fsBThr+KpmG4S2HZ3iEQpBTldfU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868214; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=tA6/5ZBKYLYlOlZRWUC1LLQ+x9a1lYmouQsEZiEXUIQ=; b=N9jX2n+PIVPUeZ+ahhI1ibRFrmO5fYwOpZblfgI+c45zhKe8MQSczwapOkSLAD+upP0bF/58Nl9mY+sx5c8XI8em9Y3VL6peA1QcW093GQ0RbrgXO94en02DIjqbt2msvpJhjO9bcp/lNr0PXyvOICZrdLTd5o4Z25TjQeJTUb4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868214581665.0460398110033; Fri, 19 Jun 2026 04:23:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIW-0002O3-Qw; Fri, 19 Jun 2026 07:22:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIV-0002MD-4p; Fri, 19 Jun 2026 07:22:07 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIR-0005yf-1D; Fri, 19 Jun 2026 07:22:06 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHq-0089QU-0W; Fri, 19 Jun 2026 13:21:58 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=tA6/5ZBKYLYlOlZRWUC1LLQ+x9a1lYmouQsEZiEXUIQ=; b=H1frHkRTV3zz JZC66ggyZhmdE5dT5nTRlNM7aID8dX6iibNwHRVKRDFsuhHyEyKgQ3PHl+PBSO2+yR4Jsf0Tnztnn +zTEfDk5V4pu84Y3fr3yldQc+Jp2KZ8ZDTQPdZqS9pwjMHIPsmyQnAgwE5VMd0E0rHrGzKNPrs6JQ lo49dNtbGMjFTwqpgKLJUboR1UIoMtVD92D6xS8yD627MULOR+UL1i1xv7h/lJo1ZP00THJws3cnr 0dauXhPu2TluY4riHxe/R4YEkTG9jNdAhNRe2lj1V+qjcsfkKEKwHvdue2mfhaPW+zaLFTwx0bIxH dSGTxdj2NkdJiwvgcb8ADQ==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 8/9] hw/ide/atapi: read the whole elementary transfer asynchronously Date: Fri, 19 Jun 2026 13:21:56 +0200 Message-ID: <20260619112158.304782-9-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868215112158500 Content-Type: text/plain; charset="utf-8" An ATAPI PIO read whose byte-count limit spans more than one CD sector must fetch the later sectors of a DRQ burst from inside the completion of the first, asynchronous read. cd_read_sector_sync() did this with a synchronous blk_pread(), which runs blk_wait_while_drained() before issuing the request. If a drain is in progress when that completion runs -- as happens when a guest reset reaches virtio_blk_stop_ioeventfd() -> bdrv_drain_all_begin() while an ATAPI read is in flight on the same QEMU -- the nested read is queued until the drained section ends while the outer completion still holds blk->in_flight. bdrv_drain_all_begin() then waits forever for that in_flight count to drop: the main loop is wedged in the drain with the BQL held, and every other QMP/monitor operation blocks behind it. Read the whole elementary transfer in a single asynchronous request up front instead, so no read is ever issued in the middle of a burst. cd_read_sector() now reads all the sectors a burst spans (the raw 2352-byte case is unpacked in place on completion) and cd_read_sector_sync() is removed. The DMA path already batched its reads and is unchanged. Signed-off-by: Denis V. Lunev --- hw/ide/atapi.c | 180 +++++++++++++++++++++++-------------------------- 1 file changed, 84 insertions(+), 96 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index a42b748521..0ea149ad8c 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -88,46 +88,14 @@ static void cd_data_to_raw(uint8_t *buf, int lba) memset(buf, 0, 288); } =20 -static int -cd_read_sector_sync(IDEState *s) -{ - int ret; - block_acct_start(blk_get_stats(s->blk), &s->acct, - ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ); - - trace_cd_read_sector_sync(s->lba); - - switch (s->cd_sector_size) { - case 2048: - ret =3D blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS, - ATAPI_SECTOR_SIZE, s->io_buffer, 0); - break; - case 2352: - ret =3D blk_pread(s->blk, (int64_t)s->lba << ATAPI_SECTOR_BITS, - ATAPI_SECTOR_SIZE, s->io_buffer + 16, 0); - if (ret >=3D 0) { - cd_data_to_raw(s->io_buffer, s->lba); - } - break; - default: - block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_READ); - return -EIO; - } - - if (ret < 0) { - block_acct_failed(blk_get_stats(s->blk), &s->acct); - } else { - block_acct_done(blk_get_stats(s->blk), &s->acct); - s->lba++; - s->io_buffer_index =3D 0; - } - - return ret; -} - static void cd_read_sector_cb(void *opaque, int ret) { IDEState *s =3D opaque; + int et =3D s->elementary_transfer_size; + int skip =3D s->io_buffer_index; + int nsec =3D DIV_ROUND_UP(skip + et, s->cd_sector_size); + uint8_t *buf; + int i; =20 trace_cd_read_sector_cb(s->lba, ret); =20 @@ -140,34 +108,64 @@ static void cd_read_sector_cb(void *opaque, int ret) block_acct_done(blk_get_stats(s->blk), &s->acct); =20 if (s->cd_sector_size =3D=3D 2352) { - cd_data_to_raw(s->io_buffer, s->lba); + /* unpack back-to-front so a sector never clobbers an unmoved one = */ + for (i =3D nsec - 1; i >=3D 0; i--) { + memmove(s->io_buffer + i * 2352 + 16, s->io_buffer + i * 2048, + ATAPI_SECTOR_SIZE); + cd_data_to_raw(s->io_buffer + i * 2352, s->lba + i); + } } =20 - s->lba++; - s->io_buffer_index =3D 0; s->status &=3D ~BUSY_STAT; =20 - ide_atapi_cmd_reply_end(s); + s->nsector =3D (s->nsector & ~7) | ATAPI_INT_REASON_IO; + s->lcyl =3D et & 0xff; + s->hcyl =3D (et >> 8) & 0xff; + ide_bus_set_irq(s->bus); + + /* a boundary sector shared with the next burst is re-read there */ + buf =3D s->io_buffer + skip; + s->packet_transfer_size -=3D et; + s->lba +=3D (skip + et) / s->cd_sector_size; + s->io_buffer_index =3D (skip + et) % s->cd_sector_size; + s->elementary_transfer_size =3D 0; + + if (ide_transfer_start_norecurse(s, buf, et, ide_atapi_cmd_reply_end))= { + ide_atapi_cmd_reply_end(s); + } } =20 +/* + * Read the whole elementary transfer (one DRQ burst) in a single async + * request. No read is issued mid-burst, so unlike the old synchronous + * rebuffer it cannot deadlock against a concurrent drain. + */ static int cd_read_sector(IDEState *s) { - void *buf; + int et =3D s->elementary_transfer_size; + int skip =3D s->io_buffer_index; + int nsec =3D DIV_ROUND_UP(skip + et, s->cd_sector_size); =20 if (s->cd_sector_size !=3D 2048 && s->cd_sector_size !=3D 2352) { block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_READ); return -EINVAL; } =20 - buf =3D (s->cd_sector_size =3D=3D 2352) ? s->io_buffer + 16 : s->io_bu= ffer; - qemu_iovec_init_buf(&s->qiov, buf, ATAPI_SECTOR_SIZE); + /* a burst is bounded by the byte count limit, so it fits io_buffer */ + assert(nsec * s->cd_sector_size <=3D s->io_buffer_total_len); + + /* + * Read the payload packed at the front of io_buffer; the 2352 raw cas= e is + * unpacked into place on completion. + */ + qemu_iovec_init_buf(&s->qiov, s->io_buffer, nsec * ATAPI_SECTOR_SIZE); =20 trace_cd_read_sector(s->lba); =20 block_acct_start(blk_get_stats(s->blk), &s->acct, - ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ); + nsec * ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ); =20 - ide_buffered_readv(s, (int64_t)s->lba << 2, &s->qiov, 4, + ide_buffered_readv(s, (int64_t)s->lba << 2, &s->qiov, nsec * 4, cd_read_sector_cb, s); =20 s->status |=3D BUSY_STAT; @@ -222,59 +220,49 @@ static uint16_t atapi_byte_count_limit(IDEState *s) void ide_atapi_cmd_reply_end(IDEState *s) { int byte_count_limit, size, ret; - while (s->packet_transfer_size > 0) { - trace_ide_atapi_cmd_reply_end(s, s->packet_transfer_size, - s->elementary_transfer_size, - s->io_buffer_index); - - /* see if a new sector must be read */ - if (s->lba !=3D -1 && s->io_buffer_index >=3D s->cd_sector_size) { - if (!s->elementary_transfer_size) { - ret =3D cd_read_sector(s); - if (ret < 0) { - ide_atapi_io_error(s, ret); - } - return; - } else { - /* rebuffering within an elementary transfer is - * only possible with a sync request because we - * end up with a race condition otherwise */ - ret =3D cd_read_sector_sync(s); - if (ret < 0) { - ide_atapi_io_error(s, ret); - return; - } + + trace_ide_atapi_cmd_reply_end(s, s->packet_transfer_size, + s->elementary_transfer_size, + s->io_buffer_index); + + if (s->lba !=3D -1 && s->packet_transfer_size > 0) { + byte_count_limit =3D atapi_byte_count_limit(s); + trace_ide_atapi_cmd_reply_end_bcl(s, byte_count_limit); + size =3D s->packet_transfer_size; + if (size > byte_count_limit) { + /* byte count limit must be even if this case */ + if (byte_count_limit & 1) { + byte_count_limit--; } + size =3D byte_count_limit; } - if (s->elementary_transfer_size > 0) { - /* there are some data left to transmit in this elementary - transfer */ - size =3D s->cd_sector_size - s->io_buffer_index; - if (size > s->elementary_transfer_size) - size =3D s->elementary_transfer_size; - } else { - /* a new transfer is needed */ - s->nsector =3D (s->nsector & ~7) | ATAPI_INT_REASON_IO; - ide_bus_set_irq(s->bus); - byte_count_limit =3D atapi_byte_count_limit(s); - trace_ide_atapi_cmd_reply_end_bcl(s, byte_count_limit); - size =3D s->packet_transfer_size; - if (size > byte_count_limit) { - /* byte count limit must be even if this case */ - if (byte_count_limit & 1) - byte_count_limit--; - size =3D byte_count_limit; - } - s->lcyl =3D size & 0xff; - s->hcyl =3D size >> 8; - s->elementary_transfer_size =3D size; - /* we cannot transmit more than one sector at a time */ - if (s->lba !=3D -1) { - if (size > (s->cd_sector_size - s->io_buffer_index)) - size =3D (s->cd_sector_size - s->io_buffer_index); + s->elementary_transfer_size =3D size; + ret =3D cd_read_sector(s); + if (ret < 0) { + ide_atapi_io_error(s, ret); + } + return; + } + + while (s->packet_transfer_size > 0) { + /* a new transfer is needed */ + s->nsector =3D (s->nsector & ~7) | ATAPI_INT_REASON_IO; + ide_bus_set_irq(s->bus); + byte_count_limit =3D atapi_byte_count_limit(s); + trace_ide_atapi_cmd_reply_end_bcl(s, byte_count_limit); + size =3D s->packet_transfer_size; + if (size > byte_count_limit) { + /* byte count limit must be even if this case */ + if (byte_count_limit & 1) { + byte_count_limit--; } - trace_ide_atapi_cmd_reply_end_new(s, s->status); + size =3D byte_count_limit; } + s->lcyl =3D size & 0xff; + s->hcyl =3D size >> 8; + s->elementary_transfer_size =3D size; + trace_ide_atapi_cmd_reply_end_new(s, s->status); + s->packet_transfer_size -=3D size; s->elementary_transfer_size -=3D size; s->io_buffer_index +=3D size; @@ -329,7 +317,7 @@ static void ide_atapi_cmd_read_pio(IDEState *s, int lba= , int nb_sectors, s->lba =3D lba; s->packet_transfer_size =3D nb_sectors * sector_size; s->elementary_transfer_size =3D 0; - s->io_buffer_index =3D sector_size; + s->io_buffer_index =3D 0; s->cd_sector_size =3D sector_size; =20 ide_atapi_cmd_reply_end(s); --=20 2.53.0 From nobody Sun Jul 26 12:31:22 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1781868206; cv=none; d=zohomail.com; s=zohoarc; b=U0ZjWyTPT4+ToBh66Ir9XM9BjqNk7wDv7DVDMiisY269crJJ5sWCu71LAGP8+u8YrZvnuD/jGMqrdJ7BI27wvuOmTpwYgvYISDhfRinT8ak8JOoTsGGGvTyWBeo8SrAypPSyAb3YFs3/TT+NnY73MI5fnwM+aNrBbzQkoKdz7s0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1781868206; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=EcG7lwoKzbBQiYpzdtpESFE9NrMuxzb5KF9kimIPY54=; b=GCcShBsbTMF8TY8lKiJFROiEvRPN/wKRI38YGsh5sSnaXIcBmtv63XQ6nk3NWIpgiBy28i6or8rmdzmcBEKpE/87D7+c1sPo2dBwIa4iCsCJUj8ikiNIGBG9uPdssj/AOQ/P2aUMqT2zLbec/oFSkKpG0HSV2/pNidB5WwLUo5U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1781868206558266.5310247943286; Fri, 19 Jun 2026 04:23:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1waXIW-0002OA-Tf; Fri, 19 Jun 2026 07:22:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIV-0002M8-00; Fri, 19 Jun 2026 07:22:07 -0400 Received: from relay.virtuozzo.com ([130.117.225.111]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1waXIR-0005yx-Hv; Fri, 19 Jun 2026 07:22:06 -0400 Received: from ch-demo-asa.virtuozzo.com ([130.117.225.8] helo=athena.sw.ru) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1waXHq-0089QU-1f; Fri, 19 Jun 2026 13:21:58 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=EcG7lwoKzbBQiYpzdtpESFE9NrMuxzb5KF9kimIPY54=; b=RB3X20Npl5bI auJLHKRzr85DHtsWv9wfnN+Z4W8YC4uiCH39sTt3jPHT0FnRYrV7DDNb8CYYkrgPJScebbcT+e++y W4gwyDH27mp/RGieT33qMNl+ZXcgnY1lb7zA/bK/vvTen2F5NaaR/BYChwnOmLBZ563OcfWB9HTdQ Vh+Liuv9I09lBo3zPKGK3i/XmiNv3iWzCcdHoLoMkfAP7D4gr0cJ0dyF/DEuCLIKcAY8tx3FqE8CQ BsoNt/scGvOHuPdWFfMbhJyJoNIRBNWoG3525YYcFmBXvbUNPaSDubgjJmN0467VFNUSFum9XVZV8 gJLSB92zwKwm9NmsK1EXUQ==; To: qemu-devel@nongnu.org Cc: jsnow@redhat.com, qemu-block@nongnu.org, "Denis V. Lunev" Subject: [PATCH 9/9] tests/qtest/ahci: regression test for ATAPI read vs. drain Date: Fri, 19 Jun 2026 13:21:57 +0200 Message-ID: <20260619112158.304782-10-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260619112158.304782-1-den@openvz.org> References: <20260619112158.304782-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: softfail client-ip=130.117.225.111; envelope-from=den@openvz.org; helo=relay.virtuozzo.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: "Denis V. Lunev" From: "Denis V. Lunev" via qemu development Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1781868207166158500 Content-Type: text/plain; charset="utf-8" Add /ahci/cdrom/drain/{pio,dma}: issue a multi-sector ATAPI read whose byte-count limit spans two sectors so the device must rebuffer in the middle of the DRQ burst, hold the backend read in flight with a blkdebug delay, and fire x-blockdev-set-iothread -- which runs bdrv_drain_all_begin() exactly like a guest reset does through virtio_blk_stop_ioeventfd(). On the unfixed PIO path the nested sector fetch is queued behind the drain and the main loop wedges, so the test hangs. The DMA variant never rebuffers and serves as a sanity twin. Signed-off-by: Denis V. Lunev --- tests/qtest/ahci-test.c | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c index 58bc04b3ef..71d23fe56a 100644 --- a/tests/qtest/ahci-test.c +++ b/tests/qtest/ahci-test.c @@ -1754,6 +1754,70 @@ static void test_atapi_engine_restart_dma(void) test_atapi_engine_restart_in_flight(true); } =20 +/* + * Regression test: a multi-sector ATAPI read fetches its later sectors fr= om + * inside the first read's completion; a concurrent drain (as a guest reset + * triggers via bdrv_drain_all_begin) must not wedge on that nested read. + * blkdebug keeps the read in flight across x-blockdev-set-iothread. + */ +static void test_atapi_drain_in_flight(bool dma) +{ + AHCIQState *ahci; + AHCICommand *cmd; + unsigned char *tx; + char *iso; + int fd; + uint8_t port; + uint64_t buffer; + uint16_t bcl =3D ATAPI_SECTOR_SIZE * 2; + uint64_t iso_size =3D (uint64_t)ATAPI_SECTOR_SIZE * 3; + + fd =3D prepare_iso(iso_size, &tx, &iso); + + /* 1s read delay: a wide margin so the drain starts before it complete= s */ + ahci =3D ahci_boot_and_enable( + "-blockdev driver=3Dfile,node-name=3Dfile0,filename=3D%s,read-only= =3Don " + "-blockdev driver=3Dblkdebug,node-name=3Dcd0,image=3Dfile0,read-on= ly=3Don," + "inject-error.0.event=3Dnone,inject-error.0.iotype=3Dread," + "inject-error.0.errno=3D0,inject-error.0.delay-ns=3D1000000000 " + "-M q35 " + "-device ide-cd,drive=3Dcd0 ", iso); + port =3D ahci_port_select(ahci); + + buffer =3D ahci_alloc(ahci, bcl); + qtest_memset(ahci->parent->qts, buffer, 0x00, bcl); + + cmd =3D ahci_atapi_command_create(CMD_ATAPI_READ_10, bcl, dma); + ahci_command_adjust(cmd, 0, buffer, bcl, 0); + ahci_command_commit(ahci, cmd, port); + ahci_command_issue_async(ahci, cmd); + + /* Drain (all nodes) while the delayed read is still in flight. */ + qtest_qmp_assert_success(ahci->parent->qts, + "{ 'execute': 'x-blockdev-set-iothread'," + " 'arguments': { 'node-name': 'cd0', 'iothread': null," + " 'force': true } }"); + + /* Round-trip through the device to confirm qemu is still alive. */ + ahci_px_rreg(ahci, port, AHCI_PX_TFD); + + ahci_command_free(cmd); + ahci_free(ahci, buffer); + g_free(tx); + ahci_shutdown(ahci); + remove_iso(fd, iso); +} + +static void test_atapi_drain_pio(void) +{ + test_atapi_drain_in_flight(false); +} + +static void test_atapi_drain_dma(void) +{ + test_atapi_drain_in_flight(true); +} + /* Regression test: Test that a READ_CD command with a BCL of 0 but a size= of 0 * completes as a NOP instead of erroring out. */ static void test_atapi_bcl(void) @@ -2177,6 +2241,8 @@ int main(int argc, char **argv) test_atapi_engine_restart_pio); qtest_add_func("/ahci/cdrom/engine_restart/dma", test_atapi_engine_restart_dma); + qtest_add_func("/ahci/cdrom/drain/pio", test_atapi_drain_pio); + qtest_add_func("/ahci/cdrom/drain/dma", test_atapi_drain_dma); =20 ret =3D g_test_run(); =20 --=20 2.53.0