[PATCH 6/6 v2] libdl/rtl-obj.c: synchronize cache after code relocation.
Gedare Bloom
gedare at rtems.org
Wed Jul 20 13:48:23 UTC 2016
I'm OK with it but would like Chris to take a look if he gets around to it.
On Wed, Jul 20, 2016 at 4:55 AM, Pavel Pisa <pisa at cmp.felk.cvut.cz> wrote:
> From be993a950be6c382b70609bcbc38be9bd161e1d4 Mon Sep 17 00:00:00 2001
> Message-Id: <be993a950be6c382b70609bcbc38be9bd161e1d4.1469004576.git.pisa at cmp.felk.cvut.cz>
> From: Pavel Pisa <pisa at cmp.felk.cvut.cz>
> Date: Wed, 20 Jul 2016 10:49:19 +0200
> Subject: [PATCH] libdl/rtl-obj.c: synchronize cache after code relocation.
> To: rtems-devel at rtems.org
>
> Memory content changes caused by relocation has to be
> propagated to memory/cache level which is used/snooped
> during instruction cache fill.
> ---
> cpukit/libdl/rtl-elf.c | 2 ++
> cpukit/libdl/rtl-obj.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++--
> cpukit/libdl/rtl-obj.h | 7 ++++++
> cpukit/libdl/rtl-rap.c | 2 ++
> 4 files changed, 74 insertions(+), 2 deletions(-)
>
> V2:
> - rtems_rtl_obj_synchronize_cache () without return value
> - use rtems_cache_get_instruction_line_size () to skip
> cache synchronization when given BSP build does not
> provide/use instruction cache but CPUkit architecture
> variant covers even systems with cache
>
> diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
> index 0eee540..48d81df 100644
> --- a/cpukit/libdl/rtl-elf.c
> +++ b/cpukit/libdl/rtl-elf.c
> @@ -941,6 +941,8 @@ rtems_rtl_elf_file_load (rtems_rtl_obj_t* obj, int fd)
> if (!rtems_rtl_obj_relocate (obj, fd, rtems_rtl_elf_relocator, &ehdr))
> return false;
>
> + rtems_rtl_obj_synchronize_cache (obj);
> +
> rtems_rtl_symbol_obj_erase_local (obj);
>
> if (!rtems_rtl_elf_load_details (obj))
> diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
> index 00a1c6e..f61d4e5 100644
> --- a/cpukit/libdl/rtl-obj.c
> +++ b/cpukit/libdl/rtl-obj.c
> @@ -558,6 +558,69 @@ rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj,
> return rtems_rtl_obj_section_handler (mask, obj, fd, handler, data);
> }
>
> +/**
> + * Cache synchronization after runtime object load (dlopen)
> + */
> +typedef struct
> +{
> + uint32_t mask;
> + void *start_va;
> + void *end_va;
> +} rtems_rtl_obj_sect_sync_ctx_t;
> +
> +static bool
> +rtems_rtl_obj_sect_sync_handler (rtems_chain_node* node, void* data)
> +{
> + rtems_rtl_obj_sect_t* sect = (rtems_rtl_obj_sect_t*) node;
> + rtems_rtl_obj_sect_sync_ctx_t* sync_ctx = data;
> + uintptr_t old_end;
> + uintptr_t new_start;
> +
> + if ( !(sect->flags & sync_ctx->mask) || !sect->size)
> + return true;
> +
> + if (sync_ctx->end_va == sync_ctx->start_va) {
> + sync_ctx->start_va = sect->base;
> + } else {
> + old_end = (uintptr_t)sync_ctx->end_va & ~(CPU_CACHE_LINE_BYTES - 1);
> + new_start = (uintptr_t)sect->base & ~(CPU_CACHE_LINE_BYTES - 1);
> + if ( (sect->base < sync_ctx->start_va) ||
> + (new_start - old_end > CPU_CACHE_LINE_BYTES) ) {
> + rtems_cache_instruction_sync_after_code_change(sync_ctx->start_va,
> + sync_ctx->end_va - sync_ctx->start_va + 1);
> + sync_ctx->start_va = sect->base;
> + }
> + }
> +
> + sync_ctx->end_va = sect->base + sect->size;
> +
> + return true;
> +}
> +
> +void
> +rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj)
> +{
> + rtems_rtl_obj_sect_sync_ctx_t sync_ctx;
> +
> + if (rtems_cache_get_instruction_line_size() == 0)
> + return;
> +
> + sync_ctx.mask = RTEMS_RTL_OBJ_SECT_TEXT | RTEMS_RTL_OBJ_SECT_CONST |
> + RTEMS_RTL_OBJ_SECT_DATA | RTEMS_RTL_OBJ_SECT_BSS |
> + RTEMS_RTL_OBJ_SECT_EXEC;
> +
> + sync_ctx.start_va = 0;
> + sync_ctx.end_va = sync_ctx.start_va;
> + rtems_rtl_chain_iterate (&obj->sections,
> + rtems_rtl_obj_sect_sync_handler,
> + &sync_ctx);
> +
> + if (sync_ctx.end_va != sync_ctx.start_va) {
> + rtems_cache_instruction_sync_after_code_change(sync_ctx.start_va,
> + sync_ctx.end_va - sync_ctx.start_va);
> + }
> +}
> +
> bool
> rtems_rtl_obj_load_symbols (rtems_rtl_obj_t* obj,
> int fd,
> @@ -618,8 +681,6 @@ rtems_rtl_obj_sections_loader (uint32_t mask,
> first = false;
> }
>
> - rtems_cache_instruction_sync_after_code_change(base, base_offset);
> -
> node = rtems_chain_next (node);
> }
>
> diff --git a/cpukit/libdl/rtl-obj.h b/cpukit/libdl/rtl-obj.h
> index 1202fd5..80fc60f 100644
> --- a/cpukit/libdl/rtl-obj.h
> +++ b/cpukit/libdl/rtl-obj.h
> @@ -494,6 +494,13 @@ bool rtems_rtl_obj_relocate (rtems_rtl_obj_t* obj,
> void* data);
>
> /**
> + * Synchronize caches to make code visible to CPU(s)
> + *
> + * @param obj The object file's descriptor.
> + */
> +void rtems_rtl_obj_synchronize_cache (rtems_rtl_obj_t* obj);
> +
> +/**
> * Relocate an object file's unresolved reference.
> *
> * @param rec The unresolved relocation record.
> diff --git a/cpukit/libdl/rtl-rap.c b/cpukit/libdl/rtl-rap.c
> index 439eb20..a7fcb9f 100644
> --- a/cpukit/libdl/rtl-rap.c
> +++ b/cpukit/libdl/rtl-rap.c
> @@ -970,6 +970,8 @@ rtems_rtl_rap_file_load (rtems_rtl_obj_t* obj, int fd)
> if (!rtems_rtl_rap_relocate (&rap, obj))
> return false;
>
> + rtems_rtl_obj_synchronize_cache (obj);
> +
> return true;
> }
>
> --
> 1.9.1
>
More information about the devel
mailing list