arch: arm64: cache: delete arm64_dcache_all

Delete arm64_dcache_all function, because it is unused and in order to
avoid future usage of set/way cache maintenance instructions. It isn't
safe to use them.

Set/way operations are not guaranteed to affect all caches prior to the
PoC, and may require other IMPLEMENTATION DEFINED maintenance.

Exposing set/way cache maintenance to virtual machines is unsafe, not
least because the instructions are not permission-checked, but also
because they are not broadcast between CPUs.

Signed-off-by: Mykola Kvach <mykola_kvach@epam.com>
This commit is contained in:
Mykola Kvach 2023-08-01 15:29:11 +03:00 committed by Carles Cufí
parent c9b534c4eb
commit 867ba172b4

View file

@ -139,96 +139,19 @@ done:
return 0;
}
/*
* operation for all data cache
* ops: K_CACHE_INVD: invalidate
* K_CACHE_WB: clean
* K_CACHE_WB_INVD: clean and invalidate
*/
static ALWAYS_INLINE int arm64_dcache_all(int op)
{
uint32_t clidr_el1, csselr_el1, ccsidr_el1;
uint8_t loc, ctype, cache_level, line_size, way_pos;
uint32_t max_ways, max_sets, dc_val, set, way;
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
return -ENOTSUP;
}
/* Data barrier before start */
barrier_dsync_fence_full();
clidr_el1 = read_clidr_el1();
loc = (clidr_el1 >> CLIDR_EL1_LOC_SHIFT) & CLIDR_EL1_LOC_MASK;
if (!loc) {
return 0;
}
for (cache_level = 0; cache_level < loc; cache_level++) {
ctype = (clidr_el1 >> CLIDR_EL1_CTYPE_SHIFT(cache_level))
& CLIDR_EL1_CTYPE_MASK;
/* No data cache, continue */
if (ctype < 2) {
continue;
}
/* select cache level */
csselr_el1 = cache_level << 1;
write_csselr_el1(csselr_el1);
barrier_isync_fence_full();
ccsidr_el1 = read_ccsidr_el1();
line_size = (ccsidr_el1 >> CCSIDR_EL1_LN_SZ_SHIFT
& CCSIDR_EL1_LN_SZ_MASK) + 4;
max_ways = (ccsidr_el1 >> CCSIDR_EL1_WAYS_SHIFT)
& CCSIDR_EL1_WAYS_MASK;
max_sets = (ccsidr_el1 >> CCSIDR_EL1_SETS_SHIFT)
& CCSIDR_EL1_SETS_MASK;
/* 32-log2(ways), bit position of way in DC operand */
way_pos = __builtin_clz(max_ways);
for (set = 0; set <= max_sets; set++) {
for (way = 0; way <= max_ways; way++) {
/* way number, aligned to pos in DC operand */
dc_val = way << way_pos;
/* cache level, aligned to pos in DC operand */
dc_val |= csselr_el1;
/* set number, aligned to pos in DC operand */
dc_val |= set << line_size;
if (op == K_CACHE_INVD) {
dc_ops("isw", dc_val);
} else if (op == K_CACHE_WB_INVD) {
dc_ops("cisw", dc_val);
} else if (op == K_CACHE_WB) {
dc_ops("csw", dc_val);
}
}
}
}
/* Restore csselr_el1 to level 0 */
write_csselr_el1(0);
barrier_dsync_fence_full();
barrier_isync_fence_full();
return 0;
}
static ALWAYS_INLINE int arch_dcache_flush_all(void)
{
return arm64_dcache_all(K_CACHE_WB);
return -ENOTSUP;
}
static ALWAYS_INLINE int arch_dcache_invd_all(void)
{
return arm64_dcache_all(K_CACHE_INVD);
return -ENOTSUP;
}
static ALWAYS_INLINE int arch_dcache_flush_and_invd_all(void)
{
return arm64_dcache_all(K_CACHE_WB_INVD);
return -ENOTSUP;
}
static ALWAYS_INLINE int arch_dcache_flush_range(void *addr, size_t size)