From 532033361430d8e5f0d51294a59ee92cdb4e783b Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Fri, 4 Nov 2011 14:11:34 +0100 Subject: [PATCH] ahci: prevent compiler memory access misordering While no problems have been observed in practice yet, modern compilers may reorder memory access operations, and that could lead to problems with memory-mapped I/O typically done by drivers. This patch prevents any potentially problematic reordering by the compiler in the AHCI driver. --- drivers/ahci/ahci.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/ahci/ahci.c b/drivers/ahci/ahci.c index 0ecf1d602..09bffce4c 100644 --- a/drivers/ahci/ahci.c +++ b/drivers/ahci/ahci.c @@ -116,7 +116,7 @@ /* Host Bus Adapter (HBA) state. */ PRIVATE struct { - u32_t *base; /* base address of memory-mapped registers */ + volatile u32_t *base; /* base address of memory-mapped registers */ size_t size; /* size of memory-mapped register area */ int nr_ports; /* addressable number of ports (1..NR_PORTS) */ @@ -131,7 +131,7 @@ PRIVATE struct port_state { int state; /* port state */ unsigned int flags; /* port flags */ - u32_t *reg; /* memory-mapped port registers */ + volatile u32_t *reg; /* memory-mapped port registers */ u8_t *mem_base; /* primary memory buffer virtual address */ phys_bytes mem_phys; /* primary memory buffer physical address */ @@ -1573,6 +1573,11 @@ PRIVATE void port_issue(struct port_state *ps, int cmd, clock_t timeout) ps->reg[AHCI_PORT_SERR] = ~0L; ps->reg[AHCI_PORT_IS] = ~0L; + /* Make sure that the compiler does not delay any previous write + * operations until after the write to the CI register. + */ + __insn_barrier(); + /* Tell the controller that a new command is ready. */ ps->reg[AHCI_PORT_CI] = (1L << cmd); @@ -1909,7 +1914,8 @@ PRIVATE void ahci_stop(void) ahci_reset(); - if ((r = vm_unmap_phys(SELF, hba_state.base, hba_state.size)) != OK) + if ((r = vm_unmap_phys(SELF, (void *) hba_state.base, + hba_state.size)) != OK) panic("unable to unmap HBA memory: %d", r); if ((r = sys_irqrmpolicy(&hba_state.hook_id)) != OK) -- 2.44.0