Incidencia #31857

4GB境界を跨ぐメモリをvm1に割り当てると、vm1の再起動時にAHCIがタイムアウトする

Abrir Fecha: 2013-08-08 20:32 Última actualización: 2013-08-31 23:11

Informador:
Propietario:
(Ninguno)
Tipo:
Estado:
Cerrado
Componente:
(Ninguno)
Hito:
(Ninguno)
Prioridad:
5 - Medium
Gravedad:
5 - Medium
Resolución:
Fixed
Fichero:
Ninguno

Details

4GB境界を跨ぐメモリをvm1に割り当てると、vm1の再起動時にAHCIがタイムアウトする。

 ./install_to_usb.sh -c 'vm0.boot_int18 vm=vm0,vm1 vm1.mem=80000000-21f5fffff vm1.cpu=4,6 vm1.pci=00:1c.7,00:1c.5 shell=0' /dev/sdd
AHCI controller at a0.0, iobase f7c00000, irq 255
AHCI: cap 0xeb32ffa1, ports_impl 0x3
AHCI/0: probing
AHCI/0: link down
AHCI/1: probing
AHCI/1: link up
WARNING - Timeout at ahci_command:172!
Scan for option roms
Searching bootorder for: HALT
Space available for UMB: c0000-ee800, f0000-f1c40
Returned 57344 bytes of ZoneHigh
e820 map has 7 items:
  0: 0000000000000000 - 000000000009fc00 = 1 RAM
  1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED
  2: 00000000000f0000 - 0000000000100000 = 2 RESERVED
  3: 0000000000100000 - 00000000ceffe000 = 1 RAM
  4: 00000000ceffe000 - 00000000cf000000 = 2 RESERVED
  5: 00000000fffc0000 - 0000000100000000 = 2 RESERVED
  6: 0000000100000000 - 0000000196040000 = 1 RAM
Unable to lock ram - bridge not found
enter handle_19:
  NULL
Booting from Floppy...
Boot failed: could not read the boot disk

enter handle_18:
  NULL
Booting from Hard Disk...
Boot failed: could not read the boot disk

enter handle_18:
  NULL
No bootable device.  Retrying in 60 seconds.

> sendint
sendint> vtddump
send 0 to vtddump
VT-d fault status 0x00000000
VT-d fault status 0x00000003
VT-d fault record[0] 0x8000000500000500_00000001CEFE3000

Ticket History (3/5 Histories)

2013-08-08 20:32 Updated by: yuichi_xy
  • New Ticket "4GB境界を跨ぐメモリをvm1に割り当てると、vm1の再起動時にAHCIがタイムアウトする" created
2013-08-31 21:37 Updated by: yuichi_xy
Comentario

AHCIドライバが実行するコマンドのアドレスと、IOMMUがページフォールトしたアドレスが一致していた。

AHCI controller at a0.0, iobase f7c00000, irq 255
AHCI/1: send cmd ... cmd 0x0xcefe3c00 buffer 0x0x00006ba4

> sendint
sendint> vtddump
send 0 to vtddump
VT-d fault status 0x00000000
VT-d fault status 0x00000003
VT-d fault record[0] 0x8000000500000500_00000001CEFE3000
--- bios/src/ahci.c     (リビジョン 108)
+++ bios/src/ahci.c     (作業コピー)
@@ -135,7 +135,7 @@
     SET_LOWFLAT(list[0].base,   ((u32)(cmd)));
     SET_LOWFLAT(list[0].baseu,  0);
 
-    dprintf(8, "AHCI/%d: send cmd ...\n", pnr);
+    dprintf(1, "AHCI/%d: send cmd ... cmd 0x%p buffer 0x%p\n", pnr, cmd, buffer);
     intbits = ahci_port_readl(ctrl, pnr, PORT_IRQ_STAT);
     if (intbits)
         ahci_port_writel(ctrl, pnr, PORT_IRQ_STAT, intbits);
2013-08-31 21:43 Updated by: yuichi_xy
Comentario

yuichi_xy への返信

AHCIドライバが実行するコマンドのアドレスと、IOMMUがページフォールトしたアドレスが一致していた。

一致していると思ったら、不一致だった。 AHCIドライバが実行するコマンドのアドレスは 0xcefe3c00 で、IOMMU がページフォールトしたアドレスは 0x1cefe3000 だった。 IOMMU がページフォールトしたアドレスが 4GB 超えのアドレスになった原因を調査する必要がある。

{{{ AHCI controller at a0.0, iobase f7c00000, irq 255 AHCI/1: send cmd ... cmd 0x0xcefe3c00 buffer 0x0x00006ba4

sendint

sendint> vtddump send 0 to vtddump VT-d fault status 0x00000000 VT-d fault status 0x00000003 VT-d fault record0 0x8000000500000500_00000001CEFE3000 }}} {{{ --- bios/src/ahci.c (リビジョン 108) +++ bios/src/ahci.c (作業コピー) @@ -135,7 +135,7 @@ SET_LOWFLAT(list0.base, ((u32)(cmd))); SET_LOWFLAT(list0.baseu, 0); - dprintf(8, "AHCI/%d: send cmd ...\n", pnr); + dprintf(1, "AHCI/%d: send cmd ... cmd 0x%p buffer 0x%p\n", pnr, cmd, buffer); intbits = ahci_port_readl(ctrl, pnr, PORT_IRQ_STAT); if (intbits) ahci_port_writel(ctrl, pnr, PORT_IRQ_STAT, intbits); }}}

2013-08-31 22:54 Updated by: yuichi_xy
Comentario

コマンドのアドレスは、コマンドリストに格納されるが、上位32ビットを示す baseu は 0 に設定されている。

ahci.c

// submit ahci command + wait for result                                        
static int ahci_command(struct ahci_port_s *port, int iswrite, int isatapi,
                        void *buffer, u32 bsize)
{
    u32 val, status, success, flags, intbits, error;
    struct ahci_ctrl_s *ctrl = GET_GLOBAL(port->ctrl);
    struct ahci_cmd_s  *cmd  = GET_GLOBAL(port->cmd);
    struct ahci_fis_s  *fis  = GET_GLOBAL(port->fis);
    struct ahci_list_s *list = GET_GLOBAL(port->list);
    u32 pnr                  = GET_GLOBAL(port->pnr);
    u64 end;

    SET_LOWFLAT(cmd->fis.reg,       0x27);
    SET_LOWFLAT(cmd->fis.pmp_type,  (1 << 7)); /* cmd fis */
    SET_LOWFLAT(cmd->prdt[0].base,  ((u32)buffer));
    SET_LOWFLAT(cmd->prdt[0].baseu, 0);
    SET_LOWFLAT(cmd->prdt[0].flags, bsize-1);

    flags = ((1 << 16) | /* one prd entry */
             (iswrite ? (1 << 6) : 0) |
             (isatapi ? (1 << 5) : 0) |
             (5 << 0)); /* fis length (dwords) */
    SET_LOWFLAT(list[0].flags,  flags);
    SET_LOWFLAT(list[0].bytes,  0);
    SET_LOWFLAT(list[0].base,   ((u32)(cmd)));
    SET_LOWFLAT(list[0].baseu,  0);                <-------- ここ

2013-08-31 23:11 Updated by: yuichi_xy
  • Resolución Update from Ninguno to Fixed
  • Estado Update from Open to Cerrado
  • Ticket Close date is changed to 2013-08-31 23:11
Comentario

AHCI ドライバのソースコードを調査していたところ、 BIOS の AHCI ドライバが、コマンドリストや FIS のアドレスを設定する時に、上位 32 ビットのアドレスを設定していないことに気づきました。

r110 で 0 に設定するようにしたところ、 AHCI のタイムアウトが発生しなくなりました。

vm1 の再起動時、 Secondary Bus Reset を発行しているので、コマンドリストや FIS のアドレスもクリアされると考えていたのですが、クリアされないようです。

Attachment File List

No attachments

Editar

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Entrar