Use ASID map bitfield for aarch64
This uses the asid_map bitfield from x86 for aarch64 to map from ASID to a given address space. This will allow for alternate mappings from ASIDs in the future as well as moving small amounts of metadata into the the ASID table itself. Co-authored-by: Kent McLeod <kent@kry10.com> Signed-off-by: Kent McLeod <kent@kry10.com>
This commit is contained in:
parent
83a02a96fc
commit
14a0b4ac5e
4 changed files with 81 additions and 38 deletions
|
|
@ -49,6 +49,8 @@ void deleteASID(asid_t asid, vspace_root_t *vspace);
|
|||
hw_asid_t getHWASID(asid_t asid);
|
||||
#endif
|
||||
|
||||
asid_map_t findMapForASID(asid_t asid);
|
||||
|
||||
#ifdef __clang__
|
||||
static const region_t BOOT_RODATA mode_reserved_region[] = {};
|
||||
#else
|
||||
|
|
@ -88,10 +90,10 @@ static inline exception_t performASIDPoolInvocation(asid_t asid, asid_pool_t *po
|
|||
{
|
||||
cap_page_upper_directory_cap_ptr_set_capPUDMappedASID(&cte->cap, asid);
|
||||
cap_page_upper_directory_cap_ptr_set_capPUDIsMapped(&cte->cap, 1);
|
||||
poolPtr->array[asid & MASK(asidLowBits)] =
|
||||
PUDE_PTR(cap_page_upper_directory_cap_get_capPUDBasePtr(cte->cap));
|
||||
asid_map_t asid_map = asid_map_asid_map_vspace_new(cap_page_upper_directory_cap_get_capPUDBasePtr(cte->cap));
|
||||
poolPtr->array[asid & MASK(asidLowBits)] = asid_map;
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
vspace_root_t *vtable = poolPtr->array[asid & MASK(asidLowBits)];
|
||||
vspace_root_t *vtable = (vspace_root_t *)cap_page_upper_directory_cap_get_capPUDBasePtr(cte->cap);
|
||||
vtable[VTABLE_SMMU_SLOT] = vtable_invalid_smmu_new(0);
|
||||
#endif
|
||||
return EXCEPTION_NONE;
|
||||
|
|
@ -132,11 +134,11 @@ static inline exception_t performASIDPoolInvocation(asid_t asid, asid_pool_t *po
|
|||
{
|
||||
cap_page_global_directory_cap_ptr_set_capPGDMappedASID(&cte->cap, asid);
|
||||
cap_page_global_directory_cap_ptr_set_capPGDIsMapped(&cte->cap, 1);
|
||||
poolPtr->array[asid & MASK(asidLowBits)] =
|
||||
PGDE_PTR(cap_page_global_directory_cap_get_capPGDBasePtr(cte->cap));
|
||||
asid_map_t asid_map = asid_map_asid_map_vspace_new(cap_page_global_directory_cap_get_capPGDBasePtr(cte->cap));
|
||||
poolPtr->array[asid & MASK(asidLowBits)] = asid_map;
|
||||
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
vspace_root_t *vtable = poolPtr->array[asid & MASK(asidLowBits)];
|
||||
vspace_root_t *vtable = (vspace_root_t *)cap_page_global_directory_cap_get_capPGDBasePtr(cte->cap);
|
||||
vtable[VTABLE_SMMU_SLOT] = vtable_invalid_smmu_new(0);
|
||||
#endif
|
||||
return EXCEPTION_NONE;
|
||||
|
|
|
|||
|
|
@ -239,6 +239,23 @@ block vm_attributes {
|
|||
|
||||
---- ARM-specific object types
|
||||
|
||||
block asid_map_none {
|
||||
padding 63
|
||||
field type 1
|
||||
}
|
||||
|
||||
block asid_map_vspace {
|
||||
padding 16
|
||||
field_high vspace_root 36
|
||||
padding 11
|
||||
field type 1
|
||||
}
|
||||
|
||||
tagged_union asid_map type {
|
||||
tag asid_map_none 0
|
||||
tag asid_map_vspace 1
|
||||
}
|
||||
|
||||
-- PGDE, PUDE, PDEs and PTEs, assuming 48-bit physical address
|
||||
base 64(48,0)
|
||||
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ typedef pgde_t vspace_root_t;
|
|||
#define VCPU_REF(p) ((word_t)(p))
|
||||
|
||||
struct asid_pool {
|
||||
vspace_root_t *array[BIT(asidLowBits)];
|
||||
asid_map_t array[BIT(asidLowBits)];
|
||||
};
|
||||
typedef struct asid_pool asid_pool_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -551,24 +551,36 @@ BOOT_CODE void activate_kernel_vspace(void)
|
|||
BOOT_CODE void write_it_asid_pool(cap_t it_ap_cap, cap_t it_vspace_cap)
|
||||
{
|
||||
asid_pool_t *ap = ASID_POOL_PTR(pptr_of_cap(it_ap_cap));
|
||||
ap->array[IT_ASID] = (void *)(pptr_of_cap(it_vspace_cap));
|
||||
asid_map_t asid_map = asid_map_asid_map_vspace_new(pptr_of_cap(it_vspace_cap));
|
||||
ap->array[IT_ASID] = asid_map;
|
||||
armKSASIDTable[IT_ASID >> asidLowBits] = ap;
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
vspace_root_t *vtable = ap->array[IT_ASID];
|
||||
vspace_root_t *vtable = cap_vtable_root_get_basePtr(it_vspace_cap);
|
||||
vtable[VTABLE_SMMU_SLOT] = vtable_invalid_smmu_new(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ==================== BOOT CODE FINISHES HERE ==================== */
|
||||
|
||||
static findVSpaceForASID_ret_t findVSpaceForASID(asid_t asid)
|
||||
asid_map_t findMapForASID(asid_t asid)
|
||||
{
|
||||
findVSpaceForASID_ret_t ret;
|
||||
asid_pool_t *poolPtr;
|
||||
vspace_root_t *vspace_root;
|
||||
|
||||
poolPtr = armKSASIDTable[asid >> asidLowBits];
|
||||
if (!poolPtr) {
|
||||
return asid_map_asid_map_none_new();
|
||||
}
|
||||
|
||||
return poolPtr->array[asid & MASK(asidLowBits)];
|
||||
}
|
||||
|
||||
static findVSpaceForASID_ret_t findVSpaceForASID(asid_t asid)
|
||||
{
|
||||
findVSpaceForASID_ret_t ret;
|
||||
asid_map_t asid_map;
|
||||
|
||||
asid_map = findMapForASID(asid);
|
||||
if (asid_map_get_type(asid_map) != asid_map_asid_map_vspace) {
|
||||
current_lookup_fault = lookup_fault_invalid_root_new();
|
||||
|
||||
ret.vspace_root = NULL;
|
||||
|
|
@ -576,16 +588,7 @@ static findVSpaceForASID_ret_t findVSpaceForASID(asid_t asid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
vspace_root = poolPtr->array[asid & MASK(asidLowBits)];
|
||||
if (!vspace_root) {
|
||||
current_lookup_fault = lookup_fault_invalid_root_new();
|
||||
|
||||
ret.vspace_root = NULL;
|
||||
ret.status = EXCEPTION_LOOKUP_FAULT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.vspace_root = vspace_root;
|
||||
ret.vspace_root = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);
|
||||
ret.status = EXCEPTION_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1078,8 +1081,10 @@ static void invalidateASID(asid_t asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(vtable);
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);
|
||||
|
||||
vtable[VTABLE_VMID_SLOT] = vtable_invalid_new(0, false);
|
||||
}
|
||||
|
|
@ -1091,8 +1096,10 @@ static vspace_root_t PURE loadHWASID(asid_t asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(vtable);
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);
|
||||
|
||||
return vtable[VTABLE_VMID_SLOT];
|
||||
}
|
||||
|
|
@ -1104,8 +1111,10 @@ static void storeHWASID(asid_t asid, hw_asid_t hw_asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(vtable);
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);
|
||||
|
||||
/* Store HW VMID in the last entry
|
||||
Masquerade as an invalid PDGE */
|
||||
|
|
@ -1182,7 +1191,10 @@ static vspace_root_t getASIDBindCB(asid_t asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);;
|
||||
assert(vtable);
|
||||
|
||||
return vtable[VTABLE_SMMU_SLOT];
|
||||
|
|
@ -1196,7 +1208,10 @@ void increaseASIDBindCB(asid_t asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);;
|
||||
assert(vtable);
|
||||
|
||||
stored_info = vtable[VTABLE_SMMU_SLOT];
|
||||
|
|
@ -1211,7 +1226,10 @@ void decreaseASIDBindCB(asid_t asid)
|
|||
asidPool = armKSASIDTable[asid >> asidLowBits];
|
||||
assert(asidPool);
|
||||
|
||||
vspace_root_t *vtable = asidPool->array[asid & MASK(asidLowBits)];
|
||||
asid_map_t asid_map = asidPool->array[asid & MASK(asidLowBits)];
|
||||
assert(asid_map_get_type(asid_map) == asid_map_asid_map_vspace);
|
||||
|
||||
vspace_root_t *vtable = (vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map);;
|
||||
assert(vtable);
|
||||
|
||||
stored_info = vtable[VTABLE_SMMU_SLOT];
|
||||
|
|
@ -1404,13 +1422,17 @@ void deleteASID(asid_t asid, vspace_root_t *vspace)
|
|||
|
||||
poolPtr = armKSASIDTable[asid >> asidLowBits];
|
||||
|
||||
if (poolPtr != NULL && poolPtr->array[asid & MASK(asidLowBits)] == vspace) {
|
||||
invalidateTLBByASID(asid);
|
||||
if (poolPtr != NULL) {
|
||||
asid_map_t asid_map = poolPtr->array[asid & MASK(asidLowBits)];
|
||||
if (asid_map_get_type(asid_map) == asid_map_asid_map_vspace &&
|
||||
(vspace_root_t *)asid_map_asid_map_vspace_get_vspace_root(asid_map) == vspace) {
|
||||
invalidateTLBByASID(asid);
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
invalidateASIDEntry(asid);
|
||||
invalidateASIDEntry(asid);
|
||||
#endif
|
||||
poolPtr->array[asid & MASK(asidLowBits)] = NULL;
|
||||
setVMRoot(NODE_STATE(ksCurThread));
|
||||
poolPtr->array[asid & MASK(asidLowBits)] = asid_map_asid_map_none_new();
|
||||
setVMRoot(NODE_STATE(ksCurThread));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1422,7 +1444,8 @@ void deleteASIDPool(asid_t asid_base, asid_pool_t *pool)
|
|||
|
||||
if (armKSASIDTable[asid_base >> asidLowBits] == pool) {
|
||||
for (offset = 0; offset < BIT(asidLowBits); offset++) {
|
||||
if (pool->array[offset]) {
|
||||
asid_map_t asid_map = pool->array[offset];
|
||||
if (asid_map_get_type(asid_map) == asid_map_asid_map_vspace) {
|
||||
invalidateTLBByASID(asid_base + offset);
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
invalidateASIDEntry(asid_base + offset);
|
||||
|
|
@ -2406,7 +2429,8 @@ exception_t decodeARMMMUInvocation(word_t invLabel, word_t length, cptr_t cptr,
|
|||
|
||||
/* Find first free ASID */
|
||||
asid = cap_asid_pool_cap_get_capASIDBase(cap);
|
||||
for (i = 0; i < (1 << asidLowBits) && (asid + i == 0 || pool->array[i]); i++);
|
||||
for (i = 0; i < (1 << asidLowBits) && (asid + i == 0
|
||||
|| (asid_map_get_type(pool->array[i]) != asid_map_asid_map_none)); i++);
|
||||
|
||||
if (unlikely(i == 1 << asidLowBits)) {
|
||||
current_syscall_error.type = seL4_DeleteFirst;
|
||||
|
|
|
|||
Loading…
Reference in a new issue