kernel: Add invalidation utility routines to VMTranslationMap.
These allow us to move a lot of the basic logic out of the TranslationMaps. In the process, it extends the fix applied to x86 in the previous commit to all the other maps.
This commit is contained in:
@@ -89,6 +89,10 @@ protected:
|
||||
void UnaccessedPageUnmapped(VMArea* area,
|
||||
page_num_t pageNumber);
|
||||
|
||||
static void InvalidateUserTLB(CPUSet cpus, intptr_t context);
|
||||
static void InvalidateTLBList(CPUSet cpus, intptr_t context,
|
||||
addr_t* invalidPages, int32 count);
|
||||
|
||||
protected:
|
||||
recursive_lock fLock;
|
||||
int32 fMapCount;
|
||||
|
||||
@@ -107,18 +107,7 @@ ARMVMTranslationMap::Flush()
|
||||
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(0);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
InvalidateUserTLB(PagingStructures()->active_on_cpus, x86_read_cr3());
|
||||
}
|
||||
} else {
|
||||
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
|
||||
@@ -129,17 +118,8 @@ ARMVMTranslationMap::Flush()
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
arch_cpu_invalidate_tlb_list(0, fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
InvalidateTLBList(PagingStructures()->active_on_cpus, x86_read_cr3(),
|
||||
fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
}
|
||||
fInvalidPagesCount = 0;
|
||||
|
||||
@@ -107,18 +107,7 @@ M68KVMTranslationMap::Flush()
|
||||
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(0);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
InvalidateUserTLB(PagingStructures()->active_on_cpus, x86_read_cr3());
|
||||
}
|
||||
} else {
|
||||
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
|
||||
@@ -129,17 +118,8 @@ M68KVMTranslationMap::Flush()
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
arch_cpu_invalidate_tlb_list(0, fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
InvalidateTLBList(PagingStructures()->active_on_cpus, x86_read_cr3(),
|
||||
fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
}
|
||||
fInvalidPagesCount = 0;
|
||||
|
||||
@@ -107,18 +107,7 @@ PPCVMTranslationMap::Flush()
|
||||
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(0);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
InvalidateUserTLB(PagingStructures()->active_on_cpus, x86_read_cr3());
|
||||
}
|
||||
} else {
|
||||
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
|
||||
@@ -129,17 +118,8 @@ PPCVMTranslationMap::Flush()
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
arch_cpu_invalidate_tlb_list(0, fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
InvalidateTLBList(PagingStructures()->active_on_cpus, x86_read_cr3(),
|
||||
fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
}
|
||||
fInvalidPagesCount = 0;
|
||||
|
||||
@@ -623,9 +623,6 @@ RISCV64VMTranslationMap::ClearAccessedAndModified(VMArea* area, addr_t address,
|
||||
void
|
||||
RISCV64VMTranslationMap::Flush()
|
||||
{
|
||||
// copy of X86VMTranslationMap::Flush
|
||||
// TODO: move to common VMTranslationMap class
|
||||
|
||||
if (fInvalidPagesCount <= 0)
|
||||
return;
|
||||
|
||||
@@ -640,18 +637,7 @@ RISCV64VMTranslationMap::Flush()
|
||||
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = fActiveOnCpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(0);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
InvalidateUserTLB(fActiveOnCpus, x86_read_cr3());
|
||||
}
|
||||
} else {
|
||||
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
|
||||
@@ -662,17 +648,8 @@ RISCV64VMTranslationMap::Flush()
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = fActiveOnCpus;
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
arch_cpu_invalidate_tlb_list(0, fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
InvalidateTLBList(fActiveOnCpus, x86_read_cr3(),
|
||||
fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
}
|
||||
fInvalidPagesCount = 0;
|
||||
|
||||
@@ -107,20 +107,7 @@ X86VMTranslationMap::Flush()
|
||||
smp_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
const bool current = cpuMask.GetBit(cpu);
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
if (current)
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
x86_read_cr3(), 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else if (current) {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(0);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
InvalidateUserTLB(PagingStructures()->active_on_cpus, x86_read_cr3());
|
||||
}
|
||||
} else {
|
||||
TRACE("flush_tmap: %d pages to invalidate, invalidate list\n",
|
||||
@@ -131,19 +118,8 @@ X86VMTranslationMap::Flush()
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else {
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
CPUSet cpuMask = PagingStructures()->active_on_cpus;
|
||||
const bool current = cpuMask.GetBit(cpu);
|
||||
cpuMask.ClearBit(cpu);
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
if (current)
|
||||
cpuMask.SetBit(cpu);
|
||||
smp_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
x86_read_cr3(), (addr_t)fInvalidPages, fInvalidPagesCount, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else if (current) {
|
||||
arch_cpu_invalidate_tlb_list(0, fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
InvalidateTLBList(PagingStructures()->active_on_cpus, x86_read_cr3(),
|
||||
fInvalidPages, fInvalidPagesCount);
|
||||
}
|
||||
}
|
||||
fInvalidPagesCount = 0;
|
||||
|
||||
@@ -334,6 +334,46 @@ VMTranslationMap::UnaccessedPageUnmapped(VMArea* area, page_num_t pageNumber)
|
||||
}
|
||||
|
||||
|
||||
/*! Invokes arch_cpu_user_tlb_invalidate() on the specified CPUs. */
|
||||
void
|
||||
VMTranslationMap::InvalidateUserTLB(CPUSet cpus, intptr_t context)
|
||||
{
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
const bool current = cpus.GetBit(cpu);
|
||||
cpus.ClearBit(cpu);
|
||||
if (!cpus.IsEmpty()) {
|
||||
if (current)
|
||||
cpus.SetBit(cpu);
|
||||
smp_multicast_ici(cpus, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
context, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
} else if (current) {
|
||||
cpu_status state = disable_interrupts();
|
||||
arch_cpu_user_tlb_invalidate(context);
|
||||
restore_interrupts(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Invokes arch_cpu_invalidate_tlb_list() on the specified CPUs. */
|
||||
void
|
||||
VMTranslationMap::InvalidateTLBList(CPUSet cpus, intptr_t context,
|
||||
addr_t* invalidPages, int32 count)
|
||||
{
|
||||
int32 cpu = smp_get_current_cpu();
|
||||
const bool current = cpus.GetBit(cpu);
|
||||
cpus.ClearBit(cpu);
|
||||
if (!cpus.IsEmpty()) {
|
||||
if (current)
|
||||
cpus.SetBit(cpu);
|
||||
smp_multicast_ici(cpus, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
context, (addr_t)invalidPages, count, NULL,
|
||||
SMP_MSG_FLAG_SYNC);
|
||||
} else if (current) {
|
||||
arch_cpu_invalidate_tlb_list(context, invalidPages, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ReverseMappingInfoCallback
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user