hw: be more accurate in synchronizing ASID/Pages

Fix #3651
This commit is contained in:
Stefan Kalkowski 2020-02-14 17:33:48 +01:00 committed by Christian Helmuth
parent b76bd57ed1
commit 8cc48d5688
10 changed files with 73 additions and 19 deletions

View File

@ -17,7 +17,7 @@ SRC_CC += spec/arm/platform_support.cc
# add assembly sources
SRC_S += spec/arm/crt0.s
SRC_S += spec/arm/exception_vector.s
SRC_S += spec/arm/exception_vector.S
vpath spec/32bit/memory_map.cc $(BASE_DIR)/../base-hw/src/lib/hw

View File

@ -175,6 +175,7 @@ unsigned Bootstrap::Platform::enable_mmu()
/* wait for other cores' coherency activation */
smp_coherency_enabled.wait_for(NR_OF_CPUS);
Cpu::synchronization_barrier();
asm volatile("dsb sy\n"
"isb sy\n" ::: "memory");
return Cpu::Mpidr::Aff_0::get(Cpu::Mpidr::read());
}

View File

@ -83,3 +83,24 @@ void Arm_cpu::mmu_fault_status(Fsr::access_t fsr, Thread_fault & fault)
default: fault.type = Thread_fault::UNKNOWN;
};
}
void Arm_cpu::switch_to(Arm_cpu::Context&, Arm_cpu::Mmu_context & o)
{
if (o.cidr == 0) return;
Cidr::access_t cidr = Cidr::read();
if (cidr != o.cidr) {
/**
* First switch to global mappings only to prevent
* that wrong branch predicts result due to ASID
* and Page-Table not being in sync (see ARM RM B 3.10.4)
*/
Cidr::write(0);
Cpu::synchronization_barrier();
Ttbr0::write(o.ttbr0);
Cpu::synchronization_barrier();
Cidr::write(o.cidr);
Cpu::synchronization_barrier();
}
}

View File

@ -110,16 +110,7 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
else Tlbiall::write(0);
}
void switch_to(Context&, Mmu_context & o)
{
if (o.cidr == 0) return;
Cidr::access_t cidr = Cidr::read();
if (cidr != o.cidr) {
Cidr::write(o.cidr);
Ttbr0::write(o.ttbr0);
}
}
void switch_to(Context&, Mmu_context & o);
static void mmu_fault(Context & c, Kernel::Thread_fault & fault);
static void mmu_fault_status(Fsr::access_t fsr,

View File

@ -12,6 +12,7 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#include <synchronize.s>
/*********************
** Constant values **
@ -123,6 +124,8 @@
ldr r1, [r1]
blx r1
SYSTEM_REGISTER_SYNC_BARRIER /* synchronize after the context switch */
/*
* Go to kernel entry code
*/
@ -164,4 +167,5 @@
ldr r1, [sp, #16*4]
msr spsr_cxsf, r1
ldm sp, {r0-r14}^
SYSTEM_REGISTER_SYNC_BARRIER /* synchronize after the context switch */
subs pc, lr, #0

View File

@ -18,6 +18,11 @@
/* core includes */
#include <spec/arm/cpu_support.h>
namespace Genode { using Cpu = Arm_cpu; }
namespace Genode { struct Cpu; }
struct Genode::Cpu : Arm_cpu
{
static inline void synchronization_barrier() {}
};
#endif /* _CORE__SPEC__ARM_V6__CPU_H_ */

View File

@ -0,0 +1,15 @@
/*
* \brief Assembler macros for ARMv6
* \author Stefan Kalkowski
* \date 2020-02-16
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
.macro SYSTEM_REGISTER_SYNC_BARRIER
.endm

View File

@ -41,6 +41,12 @@ struct Genode::Arm_v7_cpu : Arm_cpu
else Tlbiallis::write(0);
} else Arm_cpu::invalidate_tlb(asid);
}
static inline void synchronization_barrier()
{
asm volatile("dsb sy\n"
"isb sy\n" ::: "memory");
}
};
#endif /* _CORE__SPEC__ARM_V7__CPU_SUPPORT_H_ */

View File

@ -0,0 +1,17 @@
/*
* \brief Assembler macros for ARMv7
* \author Stefan Kalkowski
* \date 2020-02-16
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
.macro SYSTEM_REGISTER_SYNC_BARRIER
dsb sy
isb sy
.endm

View File

@ -286,12 +286,6 @@ struct Hw::Arm_cpu
** Cache maintainance functions **
**********************************/
static inline void synchronization_barrier()
{
asm volatile("dsb\n"
"isb\n");
}
static inline void wait_for_xchg(volatile void * addr,
unsigned long new_value,
unsigned long expected_value)