Skip to content

Commit 309a7de

Browse files
committed
cpu-o3: Fix SMT privilege-return fetch redirects
Change-Id: I03b2ac110f55736f2075a86ade085daa4893c4d1
1 parent 67e58ff commit 309a7de

3 files changed

Lines changed: 22 additions & 19 deletions

File tree

src/cpu/o3/commit.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,6 +1866,8 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
18661866
if (head_inst->isSerializeAfter() && head_inst->isNonSpeculative() &&
18671867
head_inst->isReturn()) {
18681868
traceLogPrivReturn(head_inst, tid);
1869+
// Restart fetch after the committed privilege state takes effect.
1870+
squashAfter(tid, head_inst);
18691871
}
18701872

18711873
committedPC[tid] = head_inst->pcState().instAddr();

src/cpu/o3/fetch.cc

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -557,13 +557,6 @@ Fetch::handleMultiCacheLineFetch(Addr vaddr, ThreadID tid, Addr pc)
557557

558558
threads[tid].cacheReq.addRequest(first_mem_req); // packet will be created later
559559

560-
// Initiate translation for first request
561-
updateCacheRequestStatusByRequest(tid, first_mem_req, TlbWait);
562-
setAllFetchStalls(StallReason::ITlbStall);
563-
FetchTranslation *trans = new FetchTranslation(this);
564-
cpu->mmu->translateTiming(first_mem_req, cpu->thread[tid]->getTC(),
565-
trans, BaseMMU::Execute);
566-
567560
// Prepare second request (head of second cache line)
568561
fetchPC += fetchSize; // Move to start of next cache line
569562
assert(fetchPC % cacheBlkSize == 0);
@@ -584,6 +577,18 @@ Fetch::handleMultiCacheLineFetch(Addr vaddr, ThreadID tid, Addr pc)
584577

585578
threads[tid].cacheReq.addRequest(second_mem_req); // Add second request to cache request
586579

580+
// Initiate translations after both requests are registered. Some MMU paths
581+
// complete synchronously, so callbacks must see the full request group.
582+
updateCacheRequestStatusByRequest(tid, first_mem_req, TlbWait);
583+
setAllFetchStalls(StallReason::ITlbStall);
584+
FetchTranslation *trans = new FetchTranslation(this);
585+
cpu->mmu->translateTiming(first_mem_req, cpu->thread[tid]->getTC(),
586+
trans, BaseMMU::Execute);
587+
588+
if (threads[tid].cacheReq.findRequestIndex(second_mem_req) == SIZE_MAX) {
589+
return true;
590+
}
591+
587592
DPRINTF(Fetch, "[tid:%i] Initiating translation for second cache line\n", tid);
588593

589594
// Always initiate translation for second request, regardless of first request status
@@ -950,17 +955,12 @@ Fetch::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc)
950955
bool
951956
Fetch::validateTranslationRequest(ThreadID tid, const RequestPtr &mem_req)
952957
{
953-
// Check if this request belongs to current cache request
954-
bool isExpectedReq = false;
955-
for (size_t i = 0; i < threads[tid].cacheReq.requests.size(); i++) {
956-
if (mem_req == threads[tid].cacheReq.requests[i]) {
957-
isExpectedReq = true;
958-
break;
959-
}
960-
}
958+
const size_t reqIndex = threads[tid].cacheReq.findRequestIndex(mem_req);
961959

962-
// Check if request should be processed using new state system
963-
if (!isExpectedReq || !hasPendingCacheRequests(tid)) {
960+
// Check this request's status, not the request group's overall status:
961+
// another cacheline in the same fetch may already have failed.
962+
if (reqIndex == SIZE_MAX ||
963+
threads[tid].cacheReq.requestStatus[reqIndex] != TlbWait) {
964964
DPRINTF(Fetch, "[tid:%i] Ignoring translation completed after squash or unexpected request\n", tid);
965965
DPRINTF(Fetch, "[tid:%i] Ignoring req addr=%#lx\n", tid, mem_req->getVaddr());
966966
++fetchStats.tlbSquashes;

src/cpu/o3/iew.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,8 @@ IEW::SquashCheckAfterExe(DynInstPtr inst)
15311531
inst->pcState(*new_pc);
15321532
}
15331533

1534-
if (inst->mispredicted() && !loadNotExecuted) {
1534+
if (inst->mispredicted() && !loadNotExecuted &&
1535+
!inst->isNonSpeculative()) {
15351536
fetchRedirect[tid] = true;
15361537

15371538
DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "
@@ -1978,7 +1979,7 @@ IEW::checkMisprediction(const DynInstPtr& inst)
19781979
inst->pcState(*new_pc);
19791980
}
19801981

1981-
if (inst->mispredicted()) {
1982+
if (inst->mispredicted() && !inst->isNonSpeculative()) {
19821983
fetchRedirect[tid] = true;
19831984

19841985
DPRINTF(IEW, "[tid:%i] [sn:%llu] Execute: "

0 commit comments

Comments
 (0)