Patchwork [RFC,v2] ahci: Add support for migration

login
register
mail settings
Submitter Andreas Färber
Date Aug. 9, 2012, 12:59 p.m.
Message ID <1344517195-3462-1-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/176078/
State New
Headers show

Comments

Andreas Färber - Aug. 9, 2012, 12:59 p.m.
Define generic VMState for AHCI and reuse it together with PCI for ICH
and on its own for the SysBus version.

Note: ICH9 initializes AHCI with 6 ports, which dynamically allocates
6 AHCIDevice structs. Thus we change the ports field type to uint32_t
for compatibility with VMState macros.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Cc: Alexander Graf <agraf@suse.de>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Juan Quintela <quintela@redhat.com>
Cc: Igor Mitsyanko <i.mitsyanko@samsung.com>
---
 hw/ide/ahci.c |   46 +++++++++++++++++++++++++++++++++++++++++++++-
 hw/ide/ahci.h |   12 +++++++++++-
 hw/ide/ich.c  |   11 ++++++++---
 3 files changed, 64 insertions(+), 5 deletions(-)
Jason Baron - Aug. 9, 2012, 2:49 p.m.
On Thu, Aug 09, 2012 at 02:59:54PM +0200, Andreas Färber wrote:
> Define generic VMState for AHCI and reuse it together with PCI for ICH
> and on its own for the SysBus version.
> 
> Note: ICH9 initializes AHCI with 6 ports, which dynamically allocates
> 6 AHCIDevice structs. Thus we change the ports field type to uint32_t
> for compatibility with VMState macros.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> Cc: Alexander Graf <agraf@suse.de>
> Cc: Jason Baron <jbaron@redhat.com>
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Juan Quintela <quintela@redhat.com>
> Cc: Igor Mitsyanko <i.mitsyanko@samsung.com>
> ---
>  hw/ide/ahci.c |   46 +++++++++++++++++++++++++++++++++++++++++++++-
>  hw/ide/ahci.h |   12 +++++++++++-
>  hw/ide/ich.c  |   11 ++++++++---
>  3 files changed, 64 insertions(+), 5 deletions(-)
> 

Thanks for doing this. My migration on q35 completes, but the disk is
not accessible. Didn't test piix. Console output below.

Thanks,

-Jason

[  154.721308] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6
frozen
[  154.725575] sr 1:0:0:0: CDB: Get event status notification: 4a 01 00
00 10 00 00 00 08 00
[  154.731372] ata2.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 0
pio 16392 in
[  154.731376]          res 40/00:00:00:00:00/00:00:00:00:00/a0 Emask
0x4 (timeout)
[  154.741430] ata2.00: status: { DRDY }
[  154.743852] ata2: hard resetting link
[  155.051647] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[  160.057127] ata2.00: qc timeout (cmd 0xa1)
[  160.059654] ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  160.062888] ata2.00: revalidation failed (errno=-5)
[  160.065515] ata2: hard resetting link
[  160.374607] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[  170.378547] ata2.00: qc timeout (cmd 0xa1)
[  170.381122] ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  170.384376] ata2.00: revalidation failed (errno=-5)
[  170.387039] ata2: limiting SATA link speed to 1.5 Gbps
[  170.389847] ata2: hard resetting link
[  170.698569] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[  194.747797] ata1.00: exception Emask 0x0 SAct 0x7 SErr 0x0 action 0x6
frozen
[  194.751971] ata1.00: failed command: READ FPDMA QUEUED
[  194.754759] ata1.00: cmd 60/20:00:00:5b:58/00:00:03:00:00/40 tag 0
ncq 16384 in
[  194.754763]          res 40/00:00:01:4f:c2/00:00:00:00:00/00 Emask
0x4 (timeout)
[  194.762483] ata1.00: status: { DRDY }
[  194.764532] ata1.00: failed command: WRITE FPDMA QUEUED
[  194.767363] ata1.00: cmd 61/08:08:f0:0c:0c/00:00:01:00:00/40 tag 1
ncq 4096 out
[  194.767367]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[  194.775189] ata1.00: status: { DRDY }
[  194.775196] ata1.00: failed command: WRITE FPDMA QUEUED
[  194.775208] ata1.00: cmd 61/10:10:48:d1:4e/00:00:02:00:00/40 tag 2
ncq 8192 out
[  194.775212]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x4 (timeout)
[  194.775217] ata1.00: status: { DRDY }
[  194.775264] ata1: hard resetting link
[  195.082621] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[  200.127437] ata1.00: qc timeout (cmd 0xec)
[  200.129918] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  200.133166] ata1.00: revalidation failed (errno=-5)
[  200.135848] ata1: hard resetting link
[  200.444624] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[  200.703371] ata2.00: qc timeout (cmd 0xa1)
[  200.705915] ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  200.709251] ata2.00: revalidation failed (errno=-5)
[  200.711910] ata2.00: disabled
[  200.713694] ata2: hard resetting link
[  201.021607] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[  201.025221] ata2: EH complete
[  210.472201] ata1.00: qc timeout (cmd 0xec)
[  210.474732] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  210.477955] ata1.00: revalidation failed (errno=-5)
[  210.480605] ata1: limiting SATA link speed to 1.5 Gbps
[  210.483380] ata1: hard resetting link
[  210.792615] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[  240.803170] ata1.00: qc timeout (cmd 0xec)
[  240.805723] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[  240.808987] ata1.00: revalidation failed (errno=-5)
[  240.811615] ata1.00: disabled
[  240.813323] ata1.00: device reported invalid CHS sector 0
[  240.816209] ata1.00: device reported invalid CHS sector 0
[  240.819185] ata1: hard resetting link
[  241.129616] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310)
[  241.133176] ata1: EH complete
[  241.134957] sd 0:0:0:0: [sda] Unhandled error code
[  241.135923] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.135923] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 02 4e d1 48 00 00
10 00
[  241.135923] end_request: I/O error, dev sda, sector 38719816
[  241.135923] sd 0:0:0:0: [sda] Unhandled error code
[  241.135923] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.135923] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 01 0c 0c f0 00 00
08 00
[  241.135923] end_request: I/O error, dev sda, sector 17566960
[  241.135923] Buffer I/O error on device dm-1, logical block 11166
[  241.135923] lost page write due to I/O error on dm-1
[  241.135923] sd 0:0:0:0: [sda] Unhandled error code
[  241.135923] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.135923] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 03 58 5b 00 00 00
20 00
[  241.135923] end_request: I/O error, dev sda, sector 56122112
[  241.135923] JBD2: Detected IO errors while flushing file data on
dm-1-8
[  241.185589] Aborting journal on device dm-1-8.
[  241.185627] sd 0:0:0:0: [sda] Unhandled error code
[  241.185637] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.185646] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 03 0e d0 50 00 00
08 00
[  241.185663] end_request: I/O error, dev sda, sector 51302480
[  241.185680] Buffer I/O error on device dm-1, logical block 4228106
[  241.185696] EXT4-fs warning (device dm-1): ext4_end_bio:250: I/O
error writing to inode 1045789 (offset 81920 size 4096 starting block
4228106)
[  241.185761] sd 0:0:0:0: [sda] Unhandled error code
[  241.185766] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.185772] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 01 0e d5 70 00 00
08 00
[  241.185784] end_request: I/O error, dev sda, sector 17749360
[  241.185791] Buffer I/O error on device dm-1, logical block 33966
[  241.185800] EXT4-fs warning (device dm-1): ext4_end_bio:250: I/O
error writing to inode 1044491 (offset 450560 size 4096 starting block
33966)
[  241.185888] sd 0:0:0:0: [sda] Unhandled error code
[  241.185897] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.185906] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 03 58 5b 00 00 00
08 00
[  241.185921] end_request: I/O error, dev sda, sector 56122112
[  241.249296] sd 0:0:0:0: [sda] Unhandled error code
[  241.249314] sd 0:0:0:0: [sda] Unhandled error code
[  241.249322] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.249329] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 02 4e d0 08 00 00
08 00
[  241.249341] end_request: I/O error, dev sda, sector 38719496
[  241.249351] Buffer I/O error on device dm-1, logical block 2655233
[  241.249355] lost page write due to I/O error on dm-1
[  241.249391] JBD2: I/O error detected when updating journal superblock
for dm-1-8.
[  241.249486] sd 0:0:0:0: [sda] Unhandled error code
[  241.249491] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.249497] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 01 0c 0c f0 00 00
08 00
[  241.249508] end_request: I/O error, dev sda, sector 17566960
[  241.249515] Buffer I/O error on device dm-1, logical block 11166
[  241.249519] lost page write due to I/O error on dm-1
[  241.249548] JBD2: Detected IO errors while flushing file data on
dm-1-8
[  241.297309] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.301667] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 01 0a b0 00 00 00
08 00
[  241.306263] end_request: I/O error, dev sda, sector 17477632
[  241.309301] Buffer I/O error on device dm-1, logical block 0
[  241.312289] lost page write due to I/O error on dm-1
[  241.315017] EXT4-fs error (device dm-1): ext4_journal_start_sb:327:
Detected aborted journal
[  241.319750] EXT4-fs (dm-1): Remounting filesystem read-only
[  241.322743] EXT4-fs (dm-1): previous I/O error to superblock detected
[  241.326344] sd 0:0:0:0: [sda] Unhandled error code
[  241.328934] sd 0:0:0:0: [sda]  Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK
[  241.333086] sd 0:0:0:0: [sda] CDB: Write(10): 2a 00 01 0a b0 00 00 00
08 00
[  241.337936] end_request: I/O error, dev sda, sector 17477632
[  241.340987] Buffer I/O error on device dm-1, logical block 0
[  241.344034] lost page write due to I/O error on dm-1

Patch

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index efea93f..08856fa 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1173,6 +1173,47 @@  void ahci_reset(AHCIState *s)
     }
 }
 
+static const VMStateDescription vmstate_ahci_device = {
+    .name = "ahci port",
+    .version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_IDE_BUS(port, AHCIDevice),
+        VMSTATE_UINT32(port_state, AHCIDevice),
+        VMSTATE_UINT32(finished, AHCIDevice),
+        VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
+        VMSTATE_UINT32(port_regs.lst_addr_hi, AHCIDevice),
+        VMSTATE_UINT32(port_regs.fis_addr, AHCIDevice),
+        VMSTATE_UINT32(port_regs.fis_addr_hi, AHCIDevice),
+        VMSTATE_UINT32(port_regs.irq_stat, AHCIDevice),
+        VMSTATE_UINT32(port_regs.irq_mask, AHCIDevice),
+        VMSTATE_UINT32(port_regs.cmd, AHCIDevice),
+        VMSTATE_UINT32(port_regs.tfdata, AHCIDevice),
+        VMSTATE_UINT32(port_regs.sig, AHCIDevice),
+        VMSTATE_UINT32(port_regs.scr_stat, AHCIDevice),
+        VMSTATE_UINT32(port_regs.scr_ctl, AHCIDevice),
+        VMSTATE_UINT32(port_regs.scr_err, AHCIDevice),
+        VMSTATE_UINT32(port_regs.scr_act, AHCIDevice),
+        VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+const VMStateDescription vmstate_ahci = {
+    .name = "ahci",
+    .version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_STRUCT_VARRAY_UINT32(dev, AHCIState, ports, 0,
+                                     vmstate_ahci_device, AHCIDevice),
+        VMSTATE_UINT32(control_regs.cap, AHCIState),
+        VMSTATE_UINT32(control_regs.ghc, AHCIState),
+        VMSTATE_UINT32(control_regs.irqstatus, AHCIState),
+        VMSTATE_UINT32(control_regs.impl, AHCIState),
+        VMSTATE_UINT32(control_regs.version, AHCIState),
+        VMSTATE_UINT32(idp_index, AHCIState),
+        VMSTATE_END_OF_LIST()
+    },
+};
+
 typedef struct SysbusAHCIState {
     SysBusDevice busdev;
     AHCIState ahci;
@@ -1181,7 +1222,10 @@  typedef struct SysbusAHCIState {
 
 static const VMStateDescription vmstate_sysbus_ahci = {
     .name = "sysbus-ahci",
-    .unmigratable = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_AHCI(ahci, AHCIPCIState),
+        VMSTATE_END_OF_LIST()
+    },
 };
 
 static void sysbus_ahci_reset(DeviceState *dev)
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 1200a56..e7ad1d9 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -297,7 +297,7 @@  typedef struct AHCIState {
     MemoryRegion idp;       /* Index-Data Pair I/O port space */
     unsigned idp_offset;    /* Offset of index in I/O port space */
     uint32_t idp_index;     /* Current IDP index */
-    int ports;
+    uint32_t ports;
     qemu_irq irq;
     DMAContext *dma;
 } AHCIState;
@@ -307,6 +307,16 @@  typedef struct AHCIPCIState {
     AHCIState ahci;
 } AHCIPCIState;
 
+extern const VMStateDescription vmstate_ahci;
+
+#define VMSTATE_AHCI(_field, _state) {                               \
+    .name       = (stringify(_field)),                               \
+    .size       = sizeof(AHCIState),                                 \
+    .vmsd       = &vmstate_ahci,                                     \
+    .flags      = VMS_STRUCT,                                        \
+    .offset     = vmstate_offset_value(_state, _field, AHCIState),   \
+}
+
 typedef struct NCQFrame {
     uint8_t fis_type;
     uint8_t c;
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 272b773..ae6f56f 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -79,9 +79,14 @@ 
 #define ICH9_IDP_INDEX          0x10
 #define ICH9_IDP_INDEX_LOG2     0x04
 
-static const VMStateDescription vmstate_ahci = {
+static const VMStateDescription vmstate_ich9_ahci = {
     .name = "ahci",
-    .unmigratable = 1,
+    .version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_PCI_DEVICE(card, AHCIPCIState),
+        VMSTATE_AHCI(ahci, AHCIPCIState),
+        VMSTATE_END_OF_LIST()
+    },
 };
 
 static void pci_ich9_reset(DeviceState *dev)
@@ -152,7 +157,7 @@  static void ich_ahci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
     k->revision = 0x02;
     k->class_id = PCI_CLASS_STORAGE_SATA;
-    dc->vmsd = &vmstate_ahci;
+    dc->vmsd = &vmstate_ich9_ahci;
     dc->reset = pci_ich9_reset;
 }