arch-x86, mem: Add support to tag tlb entries with PCID
This change adds support to tag tlb entries with PCID to
avoid the conflict between different processes with same
virtual addresses sharing a tlb. This eventually is required
to enable smt support for x86.
Change-Id: Ia91dc371482793962e3fc83afe7a3fd2cdb60eab
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35836
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index f4831b3..bb1ccdb 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -504,8 +504,22 @@
}
if (doEndWalk) {
if (doTLBInsert)
- if (!functional)
- walker->tlb->insert(entry.vaddr, entry);
+ if (!functional) {
+
+ // Check if PCIDE is set in CR4
+ CR4 cr4 = tc->readMiscRegNoEffect(misc_reg::Cr4);
+ if (cr4.pcide){
+ CR3 cr3 = tc->readMiscRegNoEffect(misc_reg::Cr3);
+ walker->tlb->insert(entry.vaddr, entry, cr3.pcid);
+ }
+ else{
+ // The current PCID is always 000H if PCIDE
+ // is not set [sec 4.10.1 of Intel's Software
+ // Developer Manual]
+ walker->tlb->insert(entry.vaddr, entry, 0x000);
+ }
+ }
+
endWalk();
} else {
PacketPtr oldRead = read;
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index 9d26653..5ccd3e8 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -97,8 +97,14 @@
}
TlbEntry *
-TLB::insert(Addr vpn, const TlbEntry &entry)
+TLB::insert(Addr vpn, const TlbEntry &entry, uint64_t pcid)
{
+ //Adding pcid to the page address so
+ //that multiple processes using the same
+ //tlb do not conflict when using the same
+ //virtual addresses
+ vpn = concAddrPcid(vpn, pcid);
+
// If somebody beat us to it, just use that existing entry.
TlbEntry *newEntry = trie.lookup(vpn);
if (newEntry) {
@@ -115,8 +121,14 @@
*newEntry = entry;
newEntry->lruSeq = nextSeq();
newEntry->vaddr = vpn;
- newEntry->trieHandle =
- trie.insert(vpn, TlbEntryTrie::MaxBits - entry.logBytes, newEntry);
+ if (FullSystem) {
+ newEntry->trieHandle =
+ trie.insert(vpn, TlbEntryTrie::MaxBits-entry.logBytes, newEntry);
+ }
+ else {
+ newEntry->trieHandle =
+ trie.insert(vpn, TlbEntryTrie::MaxBits, newEntry);
+ }
return newEntry;
}
@@ -390,7 +402,22 @@
if (m5Reg.paging) {
DPRINTF(TLB, "Paging enabled.\n");
// The vaddr already has the segment base applied.
- TlbEntry *entry = lookup(vaddr);
+
+ //Appending the pcid (last 12 bits of CR3) to the
+ //page aligned vaddr if pcide is set
+ CR4 cr4 = tc->readMiscRegNoEffect(misc_reg::Cr4);
+ Addr pageAlignedVaddr = vaddr & (~mask(X86ISA::PageShift));
+ CR3 cr3 = tc->readMiscRegNoEffect(misc_reg::Cr3);
+ uint64_t pcid;
+
+ if (cr4.pcide)
+ pcid = cr3.pcid;
+ else
+ pcid = 0x000;
+
+ pageAlignedVaddr = concAddrPcid(pageAlignedVaddr, pcid);
+ TlbEntry *entry = lookup(pageAlignedVaddr);
+
if (mode == BaseMMU::Read) {
stats.rdAccesses++;
} else {
@@ -412,7 +439,7 @@
delayedResponse = true;
return fault;
}
- entry = lookup(vaddr);
+ entry = lookup(pageAlignedVaddr);
assert(entry);
} else {
Process *p = tc->getProcessPtr();
@@ -428,7 +455,8 @@
entry = insert(alignedVaddr, TlbEntry(
p->pTable->pid(), alignedVaddr, pte->paddr,
pte->flags & EmulationPageTable::Uncacheable,
- pte->flags & EmulationPageTable::ReadOnly));
+ pte->flags & EmulationPageTable::ReadOnly),
+ pcid);
}
DPRINTF(TLB, "Miss was serviced.\n");
}
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index 68fe259..95c3482 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -76,6 +76,11 @@
TlbEntry *lookup(Addr va, bool update_lru = true);
void setConfigAddress(uint32_t addr);
+ //concatenate Page Addr and pcid
+ inline Addr concAddrPcid(Addr vpn, uint64_t pcid)
+ {
+ return (vpn | pcid);
+ }
protected:
@@ -156,7 +161,7 @@
Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc,
BaseMMU::Mode mode) const override;
- TlbEntry *insert(Addr vpn, const TlbEntry &entry);
+ TlbEntry *insert(Addr vpn, const TlbEntry &entry, uint64_t pcid);
// Checkpointing
void serialize(CheckpointOut &cp) const override;