diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index a8216204f8..74624e31ea 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -264,6 +264,7 @@ TLB::insert(TlbEntry &entry) table[i] = table[i-1]; table[0] = entry; + observedPageSizes.insert(entry.N); stats.inserts++; ppRefills->notify(1); } @@ -314,12 +315,14 @@ TLB::flushAll() } stats.flushTlb++; + observedPageSizes.clear(); } void TLB::flush(const TLBIOp& tlbi_op) { int x = 0; + bool valid_entry = false; TlbEntry *te; while (x < size) { te = &table[x]; @@ -328,10 +331,13 @@ TLB::flush(const TLBIOp& tlbi_op) te->valid = false; stats.flushedEntries++; } + valid_entry = valid_entry || te->valid; ++x; } stats.flushTlb++; + if (!valid_entry) + observedPageSizes.clear(); } void diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh index e42c06d58d..8ede9a331a 100644 --- a/src/arch/arm/tlb.hh +++ b/src/arch/arm/tlb.hh @@ -156,6 +156,16 @@ class TLB : public BaseTLB int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU vmid_t vmid; + /** Set of observed page sizes in the TLB + * We update the set conservatively, therefore allowing + * false positives but not false negatives. + * This means there could be a stored page size with + * no matching TLB entry (e.g. it has been invalidated), + * but if the page size is not in the set, we are certain + * there is no associated TLB with that size + */ + std::set observedPageSizes; + public: using Params = ArmTLBParams; using Lookup = TlbEntry::Lookup;