summaryrefslogtreecommitdiffstats
path: root/hw/ide
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2016-02-10 13:29:40 -0500
committerTimothy Pearson <tpearson@raptorengineering.com>2019-11-29 19:41:57 -0600
commit63b2e32bc3dc718a35c43a0da9ab522c8aacbbed (patch)
tree75b6717f26c06dcf9ceda6391b7818fa0591c2b9 /hw/ide
parent7b59145dc8a1f6c2202fbcca9064873e8e3488b3 (diff)
downloadhqemu-63b2e32bc3dc718a35c43a0da9ab522c8aacbbed.zip
hqemu-63b2e32bc3dc718a35c43a0da9ab522c8aacbbed.tar.gz
ahci: explicitly reject bad engine states on post_load
Currently, we let ahci_cond_start_engines reject weird configurations where either the DMA (CLB) or FIS engines are said to be started, but their matching on/off control bit is toggled off. There should be no way to achieve this, since any time you toggle the control bit off, the status bit should always follow synchronously. Preparing for a refactor in cond_start_engines, move the rejection logic straight up into post_load. Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 1454103689-13042-4-git-send-email-jsnow@redhat.com
Diffstat (limited to 'hw/ide')
-rw-r--r--hw/ide/ahci.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index ff338fe..9f4a672 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -218,10 +218,6 @@ static int ahci_cond_start_engines(AHCIDevice *ad, bool allow_stop)
} else if (pr->cmd & PORT_CMD_LIST_ON) {
if (allow_stop) {
ahci_unmap_clb_address(ad);
- } else {
- error_report("AHCI: DMA engine should be off, "
- "but appears to still be running");
- return -1;
}
}
@@ -234,10 +230,6 @@ static int ahci_cond_start_engines(AHCIDevice *ad, bool allow_stop)
} else if (pr->cmd & PORT_CMD_FIS_ON) {
if (allow_stop) {
ahci_unmap_fis_address(ad);
- } else {
- error_report("AHCI: FIS receive engine should be off, "
- "but appears to still be running");
- return -1;
}
}
@@ -1568,10 +1560,23 @@ static int ahci_state_post_load(void *opaque, int version_id)
int i, j;
struct AHCIDevice *ad;
NCQTransferState *ncq_tfs;
+ AHCIPortRegs *pr;
AHCIState *s = opaque;
for (i = 0; i < s->ports; i++) {
ad = &s->dev[i];
+ pr = &ad->port_regs;
+
+ if (!(pr->cmd & PORT_CMD_START) && (pr->cmd & PORT_CMD_LIST_ON)) {
+ error_report("AHCI: DMA engine should be off, but status bit "
+ "indicates it is still running.");
+ return -1;
+ }
+ if (!(pr->cmd & PORT_CMD_FIS_RX) && (pr->cmd & PORT_CMD_FIS_ON)) {
+ error_report("AHCI: FIS RX engine should be off, but status bit "
+ "indicates it is still running.");
+ return -1;
+ }
/* Only remap the CLB address if appropriate, disallowing a state
* transition from 'on' to 'off' it should be consistent here. */
OpenPOWER on IntegriCloud