From patchwork Wed Feb 10 19:38:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 8274321 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 77CB59F38B for ; Wed, 10 Feb 2016 19:45:20 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C7B65201EF for ; Wed, 10 Feb 2016 19:45:19 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 065B120173 for ; Wed, 10 Feb 2016 19:45:19 +0000 (UTC) Received: from localhost ([::1]:42511 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTahS-0002oZ-G2 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 10 Feb 2016 14:45:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54330) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTaaq-0008Ga-15 for qemu-devel@nongnu.org; Wed, 10 Feb 2016 14:38:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aTaao-0003C9-QJ for qemu-devel@nongnu.org; Wed, 10 Feb 2016 14:38:27 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42416) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aTaao-0003Bt-2T for qemu-devel@nongnu.org; Wed, 10 Feb 2016 14:38:26 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id AF1995A44; Wed, 10 Feb 2016 19:38:25 +0000 (UTC) Received: from scv.usersys.redhat.com (vpn-56-231.rdu2.redhat.com [10.10.56.231]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1AJc9AJ016300; Wed, 10 Feb 2016 14:38:24 -0500 From: John Snow To: qemu-devel@nongnu.org Date: Wed, 10 Feb 2016 14:38:09 -0500 Message-Id: <1455133089-31903-13-git-send-email-jsnow@redhat.com> In-Reply-To: <1455133089-31903-1-git-send-email-jsnow@redhat.com> References: <1455133089-31903-1-git-send-email-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: peter.maydell@linaro.org, jsnow@redhat.com Subject: [Qemu-devel] [PULL 11/11] ahci: prohibit "restarting" the FIS or CLB engines X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If the FIS or DMA engines are already started, do not allow them to be "restarted." As a side-effect of this change, the migration post-load routine must be modified to cope. If the engines are listed as "on" in the migrated registers, they must be cleared to allow the startup routine to see the transition from "off" to "on". As a second side-effect, the extra argument to ahci_cond_engine_start is removed in favor of consistent behavior. Signed-off-by: John Snow Message-id: 1454103689-13042-5-git-send-email-jsnow@redhat.com --- hw/ide/ahci.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 9f4a672..f244bc0 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -199,38 +199,38 @@ static void map_page(AddressSpace *as, uint8_t **ptr, uint64_t addr, * Check the cmd register to see if we should start or stop * the DMA or FIS RX engines. * - * @ad: Device to engage. - * @allow_stop: Allow device to transition from started to stopped? - * 'no' is useful for migration post_load, which does not expect a transition. + * @ad: Device to dis/engage. * * @return 0 on success, -1 on error. */ -static int ahci_cond_start_engines(AHCIDevice *ad, bool allow_stop) +static int ahci_cond_start_engines(AHCIDevice *ad) { AHCIPortRegs *pr = &ad->port_regs; + bool cmd_start = pr->cmd & PORT_CMD_START; + bool cmd_on = pr->cmd & PORT_CMD_LIST_ON; + bool fis_start = pr->cmd & PORT_CMD_FIS_RX; + bool fis_on = pr->cmd & PORT_CMD_FIS_ON; - if (pr->cmd & PORT_CMD_START) { + if (cmd_start && !cmd_on) { if (!ahci_map_clb_address(ad)) { + pr->cmd &= ~PORT_CMD_START; error_report("AHCI: Failed to start DMA engine: " "bad command list buffer address"); return -1; } - } else if (pr->cmd & PORT_CMD_LIST_ON) { - if (allow_stop) { - ahci_unmap_clb_address(ad); - } + } else if (!cmd_start && cmd_on) { + ahci_unmap_clb_address(ad); } - if (pr->cmd & PORT_CMD_FIS_RX) { + if (fis_start && !fis_on) { if (!ahci_map_fis_address(ad)) { + pr->cmd &= ~PORT_CMD_FIS_RX; error_report("AHCI: Failed to start FIS receive engine: " "bad FIS receive buffer address"); return -1; } - } else if (pr->cmd & PORT_CMD_FIS_ON) { - if (allow_stop) { - ahci_unmap_fis_address(ad); - } + } else if (!fis_start && fis_on) { + ahci_unmap_fis_address(ad); } return 0; @@ -272,8 +272,8 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) pr->cmd = (pr->cmd & PORT_CMD_RO_MASK) | (val & ~(PORT_CMD_RO_MASK|PORT_CMD_ICC_MASK)); - /* Check FIS RX and CLB engines, allow transition to false: */ - ahci_cond_start_engines(&s->dev[port], true); + /* Check FIS RX and CLB engines */ + ahci_cond_start_engines(&s->dev[port]); /* XXX usually the FIS would be pending on the bus here and issuing deferred until the OS enables FIS receival. @@ -1578,9 +1578,10 @@ static int ahci_state_post_load(void *opaque, int version_id) return -1; } - /* Only remap the CLB address if appropriate, disallowing a state - * transition from 'on' to 'off' it should be consistent here. */ - if (ahci_cond_start_engines(ad, false) != 0) { + /* After a migrate, the DMA/FIS engines are "off" and + * need to be conditionally restarted */ + pr->cmd &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON); + if (ahci_cond_start_engines(ad) != 0) { return -1; }