Skip to content

Commit

Permalink
c18n: Option to export compartment switch counts
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgao committed Jun 4, 2024
1 parent b7e170a commit 97df9be
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 8 deletions.
11 changes: 11 additions & 0 deletions libexec/rtld-elf/aarch64/rtld_c18n_asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,13 @@ TRAMP(tramp_update_fp_untagged)
clrtag c29, TRUSTED_STACK_C
TRAMPEND(tramp_update_fp_untagged)

TRAMP(tramp_count_entry)
1: ldr c24, #0 /* To be patched at runtime */
stadd w25, [c24]
TRAMPEND(tramp_count_entry)

PATCH_POINT(tramp_count_entry, counter, 1b)

TRAMP(tramp_call_hook)
1: ldr c12, #0 /* To be patched at runtime */

Expand Down Expand Up @@ -453,6 +460,10 @@ TRAMP(tramp_invoke_res)
#endif
TRAMPEND(tramp_invoke_res)

TRAMP(tramp_count_return)
stadd w25, [c24]
TRAMPEND(tramp_count_return)

TRAMP(tramp_pop_frame)
mrs TRUSTED_STACK_C, TRUSTED_STACK

Expand Down
33 changes: 27 additions & 6 deletions libexec/rtld-elf/aarch64/rtld_c18n_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <sys/param.h>
#include <sys/mman.h>

#include <cheri/c18n.h>

#include <stdlib.h>

#include "debug.h"
Expand All @@ -51,21 +53,32 @@ tramp_compile(char **entry, const struct tramp_data *data)
IMPORT(push_frame);
IMPORT(update_fp);
IMPORT(update_fp_untagged);
IMPORT(count_entry);
IMPORT(call_hook);
IMPORT(invoke_exe);
IMPORT(clear_mem_args);
IMPORT(clear_ret_args_indirect);
IMPORT(clear_ret_args);
IMPORT(invoke_res);
IMPORT(count_return);
IMPORT(pop_frame);

size_t size = 0;
char *buf = *entry;
size_t hook_off, header_off, target_off, landing_off, unused_regs;
size_t hook_off, count_off;
size_t header_off, target_off, landing_off, unused_regs;
bool executive = cheri_getperm(data->target) & CHERI_PERM_EXECUTIVE;
bool count = ld_compartment_switch_count != NULL;
bool hook = ld_compartment_utrace != NULL ||
ld_compartment_overhead != NULL;

#define COPY_VALUE(val) ({ \
size_t _old_size = size; \
*(typeof(val) *)(buf + size) = val; \
size += sizeof(val); \
_old_size; \
})

#define COPY(template) \
do { \
memcpy(buf + size, tramp_##template, \
Expand Down Expand Up @@ -113,11 +126,11 @@ tramp_compile(char **entry, const struct tramp_data *data)
*PATCH_INS(_offset) |= _value; \
} while (0)

if (hook) {
*(void **)(buf + size) = tramp_hook;
hook_off = size;
size += sizeof(void *);
}
if (hook)
hook_off = COPY_VALUE(&tramp_hook);

if (count)
count_off = COPY_VALUE(&c18n_stats->rcs_switch);

*(struct tramp_header *)(buf + size) = (struct tramp_header) {
.target = data->target,
Expand All @@ -143,6 +156,11 @@ tramp_compile(char **entry, const struct tramp_data *data)
else
COPY(update_fp_untagged);

if (count) {
COPY(count_entry);
PATCH_LDR_IMM(count_entry, counter, count_off);
}

if (hook) {
COPY(call_hook);
PATCH_LDR_IMM(call_hook, function, hook_off);
Expand Down Expand Up @@ -174,6 +192,9 @@ tramp_compile(char **entry, const struct tramp_data *data)
*/
PATCH_ADR(landing_off, size + 1);

if (count)
COPY(count_return);

if (hook) {
COPY(call_hook);
PATCH_LDR_IMM(call_hook, function, hook_off);
Expand Down
3 changes: 3 additions & 0 deletions libexec/rtld-elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ enum {
LD_COMPARTMENT_SIG,
LD_COMPARTMENT_UNWIND,
LD_COMPARTMENT_STATS,
LD_COMPARTMENT_SWITCH_COUNT,
#endif
};

Expand Down Expand Up @@ -454,6 +455,7 @@ static struct ld_env_var_desc ld_env_vars[] = {
LD_ENV_DESC(COMPARTMENT_SIG, false),
LD_ENV_DESC(COMPARTMENT_UNWIND, false),
LD_ENV_DESC(COMPARTMENT_STATS, false),
LD_ENV_DESC(COMPARTMENT_SWITCH_COUNT, false),
#endif
};

Expand Down Expand Up @@ -859,6 +861,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
ld_compartment_sig = ld_get_env_var(LD_COMPARTMENT_SIG);
ld_compartment_unwind = ld_get_env_var(LD_COMPARTMENT_UNWIND);
ld_compartment_stats = ld_get_env_var(LD_COMPARTMENT_STATS);
ld_compartment_switch_count = ld_get_env_var(LD_COMPARTMENT_SWITCH_COUNT);
/*
* DISABLE takes precedence over ENABLE.
*/
Expand Down
3 changes: 3 additions & 0 deletions libexec/rtld-elf/rtld_c18n.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ const char *ld_compartment_unwind;
/* Export compartmentalisation statistics to a file */
const char *ld_compartment_stats;

/* Export count of compartment switches to statistics */
const char *ld_compartment_switch_count;

struct rtld_c18n_stats *c18n_stats;

#define INC_NUM_COMPART (c18n_stats->rcs_compart++, comparts.size++)
Expand Down
1 change: 1 addition & 0 deletions libexec/rtld-elf/rtld_c18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extern const char *ld_compartment_overhead;
extern const char *ld_compartment_sig;
extern const char *ld_compartment_unwind;
extern const char *ld_compartment_stats;
extern const char *ld_compartment_switch_count;
extern struct rtld_c18n_stats *c18n_stats;

/*
Expand Down
1 change: 1 addition & 0 deletions sys/cheri/c18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct rtld_c18n_stats {
_Atomic(size_t) rcs_tramp;
_Atomic(size_t) rcs_tramp_page;
_Atomic(size_t) rcs_bytes_total;
_Atomic(size_t) rcs_switch;
};

/*
Expand Down
2 changes: 2 additions & 0 deletions usr.bin/procstat/procstat.1
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ total size of
.Xr c18n 7
data structures (including stack lookup tables, trampoline lookup tables, etc.,
but excluding execution stacks and trampolines which have dedicated counters)
.It SWTCH
number of compartment switches performed so far
.El
.Ss CHERI information
Display the process ID, command, and CHERI-specific information:
Expand Down
8 changes: 6 additions & 2 deletions usr.bin/procstat/procstat_c18n.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ procstat_c18n(struct procstat *procstat, struct kinfo_proc *kipp)
struct rtld_c18n_stats rcs;

if ((procstat_opts & PS_OPT_NOHEADER) == 0)
xo_emit("{T:/%5s %-19s %5s %5s %6s %5s %5s}\n",
"PID", "COMM", "COMP", "STKS", "TRMPS", "TRPGS", "MEM");
xo_emit("{T:/%5s %-19s %5s %5s %6s %5s %5s %5s}\n",
"PID", "COMM", "COMP", "STKS", "TRMPS", "TRPGS", "MEM",
"SWTCH");

xo_emit("{k:process_id/%5d/%d}", kipp->ki_pid);
xo_emit(" {:command/%-19s/%s}", kipp->ki_comm);
Expand All @@ -58,13 +59,16 @@ procstat_c18n(struct procstat *procstat, struct kinfo_proc *kipp)
xo_emit(" {:trampolines/%6s/%s}", "-");
xo_emit(" {:tramppages/%5s/%s}", "-");
xo_emit(" {:memory/%5s/%s}", "-");
xo_emit(" {:switches/%5s/%s}", "-");
} else {
xo_emit(" {:compartments/%5zu/%zu}", rcs.rcs_compart);
xo_emit(" {:stacks/%5zu/%zu}", rcs.rcs_ustack);
xo_emit(" {:trampolines/%6zu/%zu}", rcs.rcs_tramp);
xo_emit(" {:tramppages/%5zu/%zu}", rcs.rcs_tramp_page);
xo_emit(" {[:5}{h,hn-decimal:memory/%zu/%zu}{]:}",
rcs.rcs_bytes_total);
xo_emit(" {[:5}{h,hn-decimal,hn-1000:switches/%zu/%zu}{]:}",
rcs.rcs_switch);
}
xo_emit("\n");
}

0 comments on commit 97df9be

Please sign in to comment.