• David Jeffery's avatar
    libata: prevent HSM state change race between ISR and PIO · 1dd95dfd
    David Jeffery authored
    commit ce7514526742c0898b837d4395f515b79dfb5a12 upstream.
    
    It is possible for ata_sff_flush_pio_task() to set ap->hsm_task_state to
    HSM_ST_IDLE in between the time __ata_sff_port_intr() checks for HSM_ST_IDLE
    and before it calls ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG().
    
    This problem is hard to reproduce making this patch hard to verify, but this
    fix will prevent the race.
    
    I have not been able to reproduce the problem, but here is a crash dump from
    a 2.6.32 kernel.
    
    On examining the ata port's state, its hsm_task_state field has a value of HSM_ST_IDLE:
    
    crash> struct ata_port.hsm_task_state ffff881c1121c000
      hsm_task_state = 0
    
    Normally, this should not be possible as ata_sff_hsm_move() was called from ata_sff_host_intr(),
    which checks hsm_task_state and won't call ata_sff_hsm_move() if it has a HSM_ST_IDLE value.
    
    PID: 11053  TASK: ffff8816e846cae0  CPU: 0   COMMAND: "sshd"
     #0 [ffff88008ba03960] machine_kexec at ffffffff81038f3b
     #1 [ffff88008ba039c0] crash_kexec at ffffffff810c5d92
     #2 [ffff88008ba03a90] oops_end at ffffffff8152b510
     #3 [ffff88008ba03ac0] die at ffffffff81010e0b
     #4 [ffff88008ba03af0] do_trap at ffffffff8152ad74
     #5 [ffff88008ba03b50] do_invalid_op at ffffffff8100cf95
     #6 [ffff88008ba03bf0] invalid_op at ffffffff8100bf9b
        [exception RIP: ata_sff_hsm_move+317]
        RIP: ffffffff813a77ad  RSP: ffff88008ba03ca0  RFLAGS: 00010097
        RAX: 0000000000000000  RBX: ffff881c1121dc60  RCX: 0000000000000000
        RDX: ffff881c1121dd10  RSI: ffff881c1121dc60  RDI: ffff881c1121c000
        RBP: ffff88008ba03d00   R8: 0000000000000000   R9: 000000000000002e
        R10: 000000000001003f  R11: 000000000000009b  R12: ffff881c1121c000
        R13: 0000000000000000  R14: 0000000000000050  R15: ffff881c1121dd78
        ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
     #7 [ffff88008ba03d08] ata_sff_host_intr at ffffffff813a7fbd
     #8 [ffff88008ba03d38] ata_sff_interrupt at ffffffff813a821e
     #9 [ffff88008ba03d78] handle_IRQ_event at ffffffff810e6ec0
    1dd95dfd
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
acard-ahci.c Loading commit data...
ahci.c Loading commit data...
ahci.h Loading commit data...
ahci_platform.c Loading commit data...
ata_generic.c Loading commit data...
ata_piix.c Loading commit data...
libahci.c Loading commit data...
libata-acpi.c Loading commit data...
libata-core.c Loading commit data...
libata-eh.c Loading commit data...
libata-pmp.c Loading commit data...
libata-scsi.c Loading commit data...
libata-sff.c Loading commit data...
libata-transport.c Loading commit data...
libata-transport.h Loading commit data...
libata-zpodd.c Loading commit data...
libata.h Loading commit data...
pata_acpi.c Loading commit data...
pata_ali.c Loading commit data...
pata_amd.c Loading commit data...
pata_arasan_cf.c Loading commit data...
pata_artop.c Loading commit data...
pata_at32.c Loading commit data...
pata_at91.c Loading commit data...
pata_atiixp.c Loading commit data...
pata_atp867x.c Loading commit data...
pata_bf54x.c Loading commit data...
pata_cmd640.c Loading commit data...
pata_cmd64x.c Loading commit data...
pata_cs5520.c Loading commit data...
pata_cs5530.c Loading commit data...
pata_cs5535.c Loading commit data...
pata_cs5536.c Loading commit data...
pata_cypress.c Loading commit data...
pata_efar.c Loading commit data...
pata_ep93xx.c Loading commit data...
pata_hpt366.c Loading commit data...
pata_hpt37x.c Loading commit data...
pata_hpt3x2n.c Loading commit data...
pata_hpt3x3.c Loading commit data...
pata_icside.c Loading commit data...
pata_imx.c Loading commit data...
pata_isapnp.c Loading commit data...
pata_it8213.c Loading commit data...
pata_it821x.c Loading commit data...
pata_ixp4xx_cf.c Loading commit data...
pata_jmicron.c Loading commit data...
pata_legacy.c Loading commit data...
pata_macio.c Loading commit data...
pata_marvell.c Loading commit data...
pata_mpc52xx.c Loading commit data...
pata_mpiix.c Loading commit data...
pata_netcell.c Loading commit data...
pata_ninja32.c Loading commit data...
pata_ns87410.c Loading commit data...
pata_ns87415.c Loading commit data...
pata_octeon_cf.c Loading commit data...
pata_of_platform.c Loading commit data...
pata_oldpiix.c Loading commit data...
pata_opti.c Loading commit data...
pata_optidma.c Loading commit data...
pata_palmld.c Loading commit data...
pata_pcmcia.c Loading commit data...
pata_pdc2027x.c Loading commit data...
pata_pdc202xx_old.c Loading commit data...
pata_piccolo.c Loading commit data...
pata_platform.c Loading commit data...
pata_pxa.c Loading commit data...
pata_radisys.c Loading commit data...
pata_rb532_cf.c Loading commit data...
pata_rdc.c Loading commit data...
pata_rz1000.c Loading commit data...
pata_samsung_cf.c Loading commit data...
pata_sc1200.c Loading commit data...
pata_scc.c Loading commit data...
pata_sch.c Loading commit data...
pata_serverworks.c Loading commit data...
pata_sil680.c Loading commit data...
pata_sis.c Loading commit data...
pata_sl82c105.c Loading commit data...
pata_triflex.c Loading commit data...
pata_via.c Loading commit data...
pdc_adma.c Loading commit data...
sata_dwc_460ex.c Loading commit data...
sata_fsl.c Loading commit data...
sata_highbank.c Loading commit data...
sata_inic162x.c Loading commit data...
sata_mv.c Loading commit data...
sata_nv.c Loading commit data...
sata_promise.c Loading commit data...
sata_promise.h Loading commit data...
sata_qstor.c Loading commit data...
sata_rcar.c Loading commit data...
sata_sil.c Loading commit data...
sata_sil24.c Loading commit data...
sata_sis.c Loading commit data...
sata_svw.c Loading commit data...
sata_sx4.c Loading commit data...
sata_uli.c Loading commit data...
sata_via.c Loading commit data...
sata_vsc.c Loading commit data...
sis.h Loading commit data...