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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user