mem: Add support for secure packets in the snoop filter

Secure and non-secure data can coexist in the cache and therefore the
snoop filter should treat differently packets with secure and non
secure accesses. This patch uses the lower bits of the line address to
keep track of whether the packet is addressing secure memory or not.

Change-Id: I54a5e614dad566a5083582bede86c86896f2c2c1
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com>
This commit is contained in:
Nikos Nikoleris 2016-08-12 14:11:45 +01:00
parent 080d4e08d6
commit ee7d8fdcb2
3 changed files with 34 additions and 7 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011-2015 ARM Limited * Copyright (c) 2011-2016 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -266,7 +266,7 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
if (snoopFilter && !system->bypassCaches()) { if (snoopFilter && !system->bypassCaches()) {
// Let the snoop filter know about the success of the send operation // Let the snoop filter know about the success of the send operation
snoopFilter->finishRequest(!success, addr); snoopFilter->finishRequest(!success, addr, pkt->isSecure());
} }
// check if we were successful in sending the packet onwards // check if we were successful in sending the packet onwards
@ -666,7 +666,7 @@ CoherentXBar::recvAtomic(PacketPtr pkt, PortID slave_port_id)
// operation, and do it even before sending it onwards to // operation, and do it even before sending it onwards to
// avoid situations where atomic upward snoops sneak in // avoid situations where atomic upward snoops sneak in
// between and change the filter state // between and change the filter state
snoopFilter->finishRequest(false, pkt->getAddr()); snoopFilter->finishRequest(false, pkt->getAddr(), pkt->isSecure());
snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID, snoop_result = forwardAtomic(pkt, slave_port_id, InvalidPortID,
sf_res.first); sf_res.first);

View file

@ -69,6 +69,9 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping() && bool allocate = !cpkt->req->isUncacheable() && slave_port.isSnooping() &&
cpkt->fromCache(); cpkt->fromCache();
Addr line_addr = cpkt->getBlockAddr(linesize); Addr line_addr = cpkt->getBlockAddr(linesize);
if (cpkt->isSecure()) {
line_addr |= LineSecure;
}
SnoopMask req_port = portToMask(slave_port); SnoopMask req_port = portToMask(slave_port);
reqLookupResult = cachedLocations.find(line_addr); reqLookupResult = cachedLocations.find(line_addr);
bool is_hit = (reqLookupResult != cachedLocations.end()); bool is_hit = (reqLookupResult != cachedLocations.end());
@ -146,12 +149,16 @@ SnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port)
} }
void void
SnoopFilter::finishRequest(bool will_retry, const Addr addr) SnoopFilter::finishRequest(bool will_retry, Addr addr, bool is_secure)
{ {
if (reqLookupResult != cachedLocations.end()) { if (reqLookupResult != cachedLocations.end()) {
// since we rely on the caller, do a basic check to ensure // since we rely on the caller, do a basic check to ensure
// that finishRequest is being called following lookupRequest // that finishRequest is being called following lookupRequest
assert(reqLookupResult->first == (addr & ~(Addr(linesize - 1)))); Addr line_addr = (addr & ~(Addr(linesize - 1)));
if (is_secure) {
line_addr |= LineSecure;
}
assert(reqLookupResult->first == line_addr);
if (will_retry) { if (will_retry) {
// Undo any changes made in lookupRequest to the snoop filter // Undo any changes made in lookupRequest to the snoop filter
// entry if the request will come again. retryItem holds // entry if the request will come again. retryItem holds
@ -175,6 +182,9 @@ SnoopFilter::lookupSnoop(const Packet* cpkt)
assert(cpkt->isRequest()); assert(cpkt->isRequest());
Addr line_addr = cpkt->getBlockAddr(linesize); Addr line_addr = cpkt->getBlockAddr(linesize);
if (cpkt->isSecure()) {
line_addr |= LineSecure;
}
auto sf_it = cachedLocations.find(line_addr); auto sf_it = cachedLocations.find(line_addr);
bool is_hit = (sf_it != cachedLocations.end()); bool is_hit = (sf_it != cachedLocations.end());
@ -243,6 +253,9 @@ SnoopFilter::updateSnoopResponse(const Packet* cpkt,
} }
Addr line_addr = cpkt->getBlockAddr(linesize); Addr line_addr = cpkt->getBlockAddr(linesize);
if (cpkt->isSecure()) {
line_addr |= LineSecure;
}
SnoopMask rsp_mask = portToMask(rsp_port); SnoopMask rsp_mask = portToMask(rsp_port);
SnoopMask req_mask = portToMask(req_port); SnoopMask req_mask = portToMask(req_port);
SnoopItem& sf_item = cachedLocations[line_addr]; SnoopItem& sf_item = cachedLocations[line_addr];
@ -289,6 +302,9 @@ SnoopFilter::updateSnoopForward(const Packet* cpkt,
assert(cpkt->cacheResponding()); assert(cpkt->cacheResponding());
Addr line_addr = cpkt->getBlockAddr(linesize); Addr line_addr = cpkt->getBlockAddr(linesize);
if (cpkt->isSecure()) {
line_addr |= LineSecure;
}
auto sf_it = cachedLocations.find(line_addr); auto sf_it = cachedLocations.find(line_addr);
bool is_hit = sf_it != cachedLocations.end(); bool is_hit = sf_it != cachedLocations.end();
@ -328,6 +344,9 @@ SnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port)
// next check if we actually allocated an entry // next check if we actually allocated an entry
Addr line_addr = cpkt->getBlockAddr(linesize); Addr line_addr = cpkt->getBlockAddr(linesize);
if (cpkt->isSecure()) {
line_addr |= LineSecure;
}
auto sf_it = cachedLocations.find(line_addr); auto sf_it = cachedLocations.find(line_addr);
if (sf_it == cachedLocations.end()) if (sf_it == cachedLocations.end())
return; return;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2015 ARM Limited * Copyright (c) 2013-2016 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -143,7 +143,7 @@ class SnoopFilter : public SimObject {
* @param will_retry This request will retry on this bus / snoop filter * @param will_retry This request will retry on this bus / snoop filter
* @param addr Packet address, merely for sanity checking * @param addr Packet address, merely for sanity checking
*/ */
void finishRequest(bool will_retry, const Addr addr); void finishRequest(bool will_retry, Addr addr, bool is_secure);
/** /**
* Handle an incoming snoop from below (the master port). These * Handle an incoming snoop from below (the master port). These
@ -282,6 +282,14 @@ class SnoopFilter : public SimObject {
/** Max capacity in terms of cache blocks tracked, for sanity checking */ /** Max capacity in terms of cache blocks tracked, for sanity checking */
const unsigned maxEntryCount; const unsigned maxEntryCount;
/**
* Use the lower bits of the address to keep track of the line status
*/
enum LineStatus {
/** block holds data from the secure memory space */
LineSecure = 0x01,
};
/** Statistics */ /** Statistics */
Stats::Scalar totRequests; Stats::Scalar totRequests;
Stats::Scalar hitSingleRequests; Stats::Scalar hitSingleRequests;