aarch64,fastpath: Fixup ASID validation checks
When switching to the new thread, it's VSpace must have a valid ASID mapping. This means that the ASID in the vspace cap must resolve to the same vspace object as the vspace cap does. In addition, when the VSpace object is for a stage 2 translation there must be a currently assigned hardware VMID for the vspace. Otherwise the slowpath must be taken. Once these checks are done, the TTBR registers can be directly updated without needing to perform another ASID translation. Signed-off-by: Kent McLeod <kent@kry10.com>
This commit is contained in:
parent
1ae9360300
commit
ebcfcb7016
3 changed files with 42 additions and 3 deletions
|
|
@ -36,7 +36,7 @@ switchToThread_fp(tcb_t *thread, vspace_root_t *vroot, pde_t stored_hw_asid)
|
|||
vcpu_switch(thread->tcbArch.tcbVCPU);
|
||||
}
|
||||
asid = (asid_t)(stored_hw_asid.words[0] & 0xffff);
|
||||
armv_contextSwitch(vroot, asid);
|
||||
armv_contextSwitch_HWASID(vroot, asid);
|
||||
|
||||
#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
|
||||
benchmark_utilisation_switch(NODE_STATE(ksCurThread), thread);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
#include <config.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
|
||||
|
||||
static inline void armv_contextSwitch_HWASID(vspace_root_t *vspace, asid_t asid)
|
||||
{
|
||||
setCurrentUserVSpaceRoot(ttbr_new(asid, pptr_to_paddr(vspace)));
|
||||
}
|
||||
|
||||
/*
|
||||
* In AARCH64, hardware and virtual asids are the same and are written
|
||||
* when updating the translation table base register.
|
||||
|
|
|
|||
|
|
@ -99,7 +99,23 @@ void NORETURN fastpath_call(word_t cptr, word_t msgInfo)
|
|||
stored_hw_asid.words[0] = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_AARCH64
|
||||
stored_hw_asid.words[0] = cap_vtable_root_get_mappedASID(newVTable);
|
||||
/* Need to test that the ASID is still valid */
|
||||
asid_t asid = cap_vtable_root_get_mappedASID(newVTable);
|
||||
asid_map_t asid_map = findMapForASID(asid);
|
||||
if (unlikely(asid_map_get_type(asid_map) != asid_map_asid_map_vspace ||
|
||||
VSPACE_PTR(asid_map_asid_map_vspace_get_vspace_root(asid_map)) != cap_pd)) {
|
||||
slowpath(SysCall);
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/* Ensure the vmid is valid. */
|
||||
if (unlikely(!asid_map_asid_map_vspace_get_stored_vmid_valid(asid_map))) {
|
||||
slowpath(SysCall);
|
||||
}
|
||||
/* vmids are the tags used instead of hw_asids in hyp mode */
|
||||
stored_hw_asid.words[0] = asid_map_asid_map_vspace_get_stored_hw_vmid(asid_map);
|
||||
#else
|
||||
stored_hw_asid.words[0] = asid;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_RISCV
|
||||
|
|
@ -352,7 +368,24 @@ void NORETURN fastpath_reply_recv(word_t cptr, word_t msgInfo)
|
|||
stored_hw_asid.words[0] = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_AARCH64
|
||||
stored_hw_asid.words[0] = cap_vtable_root_get_mappedASID(newVTable);
|
||||
/* Need to test that the ASID is still valid */
|
||||
asid_t asid = cap_vtable_root_get_mappedASID(newVTable);
|
||||
asid_map_t asid_map = findMapForASID(asid);
|
||||
if (unlikely(asid_map_get_type(asid_map) != asid_map_asid_map_vspace ||
|
||||
VSPACE_PTR(asid_map_asid_map_vspace_get_vspace_root(asid_map)) != cap_pd)) {
|
||||
slowpath(SysReplyRecv);
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
/* Ensure the vmid is valid. */
|
||||
if (unlikely(!asid_map_asid_map_vspace_get_stored_vmid_valid(asid_map))) {
|
||||
slowpath(SysReplyRecv);
|
||||
}
|
||||
|
||||
/* vmids are the tags used instead of hw_asids in hyp mode */
|
||||
stored_hw_asid.words[0] = asid_map_asid_map_vspace_get_stored_hw_vmid(asid_map);
|
||||
#else
|
||||
stored_hw_asid.words[0] = asid;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_RISCV
|
||||
|
|
|
|||
Loading…
Reference in a new issue