o3: Fix issue with LLSC ordering and speculation

This patch unlocks the cpu-local monitor when the CPU sees a snoop to a locked
address. Previously we relied on the cache to handle the locking for us, however
some users on the gem5 mailing list reported a case where the cpu speculatively
executes a ll operation after a pending sc operation in the pipeline and that
makes the cache monitor valid. This should handle that case by invaliding the
local monitor.
This commit is contained in:
Ali Saidi
2013-01-07 13:05:33 -05:00
parent 5146a69835
commit 69d419f313
7 changed files with 126 additions and 1 deletions

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
@@ -47,10 +59,32 @@
#include "arch/alpha/registers.hh"
#include "base/misc.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
namespace AlphaISA {
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
// If we see a snoop come into the CPU and we currently have an LLSC
// operation pending we need to clear the lock flag if it is to the same
// cache line.
if (!xc->readMiscReg(MISCREG_LOCKFLAG))
return;
Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
Addr snoop_addr = pkt->getAddr();
assert((cacheBlockMask & snoop_addr) == snoop_addr);
if (locked_addr == snoop_addr)
xc->setMiscReg(MISCREG_LOCKFLAG, false);
}
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2006 The Regents of The University of Michigan
* Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
@@ -41,10 +53,27 @@
*/
#include "arch/arm/miscregs.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
namespace ArmISA
{
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
if (!xc->readMiscReg(MISCREG_LOCKFLAG))
return;
Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
Addr snoop_addr = pkt->getAddr();
assert((cacheBlockMask & snoop_addr) == snoop_addr);
if (locked_addr == snoop_addr)
xc->setMiscReg(MISCREG_LOCKFLAG, false);
}
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2006-2007 The Regents of The University of Michigan
* All rights reserved.
*
@@ -41,10 +53,27 @@
#include "base/misc.hh"
#include "base/trace.hh"
#include "debug/LLSC.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
namespace MipsISA
{
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
if (!xc->readMiscReg(MISCREG_LLFLAG))
return;
Addr locked_addr = xc->readMiscReg(MISCREG_LLADDR) & cacheBlockMask;
Addr snoop_addr = pkt->getAddr();
assert((cacheBlockMask & snoop_addr) == snoop_addr);
if (locked_addr == snoop_addr)
xc->setMiscReg(MISCREG_LLFLAG, false);
}
template <class XC>
inline void

View File

@@ -41,11 +41,18 @@
* ISA-specific helper functions for locked memory accesses.
*/
#include "mem/packet.hh"
#include "mem/request.hh"
namespace PowerISA
{
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
}
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)

View File

@@ -37,10 +37,17 @@
* ISA-specific helper functions for locked memory accesses.
*/
#include "mem/packet.hh"
#include "mem/request.hh"
namespace SparcISA
{
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
}
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)

View File

@@ -37,10 +37,17 @@
* ISA-specific helper functions for locked memory accesses.
*/
#include "mem/packet.hh"
#include "mem/request.hh"
namespace X86ISA
{
template <class XC>
inline void
handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
{
}
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2011 ARM Limited
* Copyright (c) 2010-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -435,6 +435,18 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
cacheBlockMask = ~(bs - 1);
}
// Unlock the cpu-local monitor when the CPU sees a snoop to a locked
// address. The CPU can speculatively execute a LL operation after a pending
// SC operation in the pipeline and that can make the cache monitor the CPU
// is connected to valid while it really shouldn't be.
for (int x = 0; x < cpu->numActiveThreads(); x++) {
ThreadContext *tc = cpu->getContext(x);
bool no_squash = cpu->thread[x]->noSquashFromTC;
cpu->thread[x]->noSquashFromTC = true;
TheISA::handleLockedSnoop(tc, pkt, cacheBlockMask);
cpu->thread[x]->noSquashFromTC = no_squash;
}
// If this is the only load in the LSQ we don't care
if (load_idx == loadTail)
return;