dcp: Free iovad_dcp including dart L2 tables on shutdown

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2022-03-29 13:10:32 +02:00 committed by Hector Martin
parent 9356e60803
commit d08793a456
6 changed files with 45 additions and 3 deletions

View file

@ -271,6 +271,31 @@ void dart_unmap(dart_dev_t *dart, uintptr_t iova, size_t len)
dart_tlb_invalidate(dart);
}
void dart_free_l2(dart_dev_t *dart, uintptr_t iova)
{
if (iova & ((1 << 25) - 1)) {
printf("dart: %08lx is not at the start of L2 table\n", iova);
return;
}
u32 ttbr = (iova >> 36) & 0x3;
u32 l1_index = (iova >> 25) & 0x7ff;
if (!(dart->l1[ttbr][l1_index] & DART_PTE_VALID))
return;
u64 *l2 = dart_get_l2(dart, l1_index);
for (u32 idx = 0; idx < 2048; idx++) {
if (l2[idx] & DART_PTE_VALID) {
printf("dart: %08lx is still mapped\n", iova + (idx << 14));
return;
}
}
dart->l1[ttbr][l1_index] = 0;
free(l2);
}
static void *dart_translate_internal(dart_dev_t *dart, uintptr_t iova, int silent)
{
u32 ttbr = (iova >> 36) & 0x3;

View file

@ -11,6 +11,7 @@ dart_dev_t *dart_init(uintptr_t base, u8 device, bool keep_pts);
dart_dev_t *dart_init_adt(const char *path, int instance, int device, bool keep_pts);
int dart_map(dart_dev_t *dart, uintptr_t iova, void *bfr, size_t len);
void dart_unmap(dart_dev_t *dart, uintptr_t iova, size_t len);
void dart_free_l2(dart_dev_t *dart, uintptr_t iova);
void *dart_translate(dart_dev_t *dart, uintptr_t iova);
u64 dart_search(dart_dev_t *dart, void *paddr);
s64 dart_find_iova(dart_dev_t *dart, s64 start, size_t len);

View file

@ -48,7 +48,7 @@ dcp_dev_t *dcp_init(const char *dcp_path, const char *dcp_dart_path, const char
rtkit_hibernate(dcp->rtkit);
rtkit_free(dcp->rtkit);
out_iovad:
iovad_shutdown(dcp->iovad_dcp);
iovad_shutdown(dcp->iovad_dcp, dcp->dart_dcp);
dart_shutdown(dcp->dart_disp);
out_dart_dcp:
dart_shutdown(dcp->dart_dcp);
@ -62,6 +62,7 @@ int dcp_shutdown(dcp_dev_t *dcp)
rtkit_hibernate(dcp->rtkit);
rtkit_free(dcp->rtkit);
dart_shutdown(dcp->dart_disp);
iovad_shutdown(dcp->iovad_dcp, dcp->dart_dcp);
dart_shutdown(dcp->dart_dcp);
free(dcp);

View file

@ -12,11 +12,18 @@ struct iova_block {
};
struct iova_domain {
u64 base;
u64 limit;
struct iova_block *free_list;
};
iova_domain_t *iovad_init(u64 base, u64 limit)
{
if (base != ALIGN_UP(base, SZ_32M)) {
printf("iovad_init: base it not is not aligned to SZ_32M\n");
return NULL;
}
iova_domain_t *iovad = malloc(sizeof(*iovad));
if (!iovad)
return NULL;
@ -33,12 +40,14 @@ iova_domain_t *iovad_init(u64 base, u64 limit)
blk->iova = base;
blk->sz = limit - SZ_16K;
blk->next = NULL;
iovad->base = base;
iovad->limit = limit;
iovad->free_list = blk;
return iovad;
}
void iovad_shutdown(iova_domain_t *iovad)
void iovad_shutdown(iova_domain_t *iovad, dart_dev_t *dart)
{
struct iova_block *blk = iovad->free_list;
@ -49,6 +58,10 @@ void iovad_shutdown(iova_domain_t *iovad)
free(blk_free);
}
if (dart)
for (u64 addr = iovad->base; addr < iovad->limit; addr += SZ_32M)
dart_free_l2(dart, addr);
free(iovad);
}

View file

@ -3,12 +3,13 @@
#ifndef IOVA_H
#define IOVA_H
#include "dart.h"
#include "types.h"
typedef struct iova_domain iova_domain_t;
iova_domain_t *iovad_init(u64 base, u64 limit);
void iovad_shutdown(iova_domain_t *iovad);
void iovad_shutdown(iova_domain_t *iovad, dart_dev_t *dart);
bool iova_reserve(iova_domain_t *iovad, u64 iova, size_t sz);
u64 iova_alloc(iova_domain_t *iovad, size_t sz);

View file

@ -47,6 +47,7 @@ typedef s64 ssize_t;
#define SZ_4K (1 << 12)
#define SZ_16K (1 << 14)
#define SZ_1M (1 << 20)
#define SZ_32M (1 << 25)
#ifdef __ASSEMBLER__