Page MenuHomeFreeBSD

kinst: replace KINST_TRAMP_INIT
ClosedPublic

Authored by christos on Apr 11 2023, 2:44 PM.
Tags
Referenced Files
Unknown Object (File)
Oct 12 2024, 11:13 AM
Unknown Object (File)
Sep 18 2024, 9:44 PM
Unknown Object (File)
Sep 17 2024, 5:50 PM
Unknown Object (File)
Sep 17 2024, 5:58 AM
Unknown Object (File)
Sep 17 2024, 1:54 AM
Unknown Object (File)
Sep 11 2024, 10:07 AM
Unknown Object (File)
Sep 11 2024, 10:07 AM
Unknown Object (File)
Sep 11 2024, 10:07 AM
Subscribers

Details

Summary

The current implementation of KINST_TRAMP_INIT is working only on amd64,
where the breakpoint instruction is one byte long, which might not be the case
for other architectures (e.g in RISC-V it's either 2 or 4 bytes). This patch
introduces two machine-dependent constants, KINST_TRAMP_FILL_PATTERN and
KINST_TRAMP_FILL_SIZE, which hold the fill instruction (might not always be
KINST_PATCHVAL for all architectures) and the size of that instruction in
bytes respectively.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

christos updated this revision to Diff 120151.

Provide full diff.

Get rid of amd64-specific calculation comment KINST_TRAMPS_PER_CHUNK.

Add a KINST_TRAMP_FILL constant and use this instead of KINST_PATCHVAL. In
the RISC-V port we want to use the compressed patch value, instead of the
regular one, so KINST_PATCHVAL doesn't work in this case.

Also add a KINST_TRAMP_FILL_SIZE constant to correct the step in
KINST_TRAMP_INIT.

christos retitled this revision from kinst(4): generalize KINST_TRAMP_INIT to kinst: generalize KINST_TRAMP_INIT.Apr 29 2023, 10:21 AM
sys/cddl/dev/kinst/trampoline.c
41

Can this be a regular C function?

christos marked an inline comment as done.
christos retitled this revision from kinst: generalize KINST_TRAMP_INIT to kinst: replace KINST_TRAMP_INIT.

Make KINST_TRAMP_FILL into a regular function.

sys/cddl/dev/kinst/trampoline.c
70

Here you're assuming that the platform is little endian. For example, on amd64, it assumes that storing int v = 0xcc and copying the first byte of v will do the right thing. It does in this case, but it's fragile to assume that.

A different solution which doesn't have this problem is to get rid of v and define a byte array which contains the breakpoint. For instance, on amd64:

#define KINST_TRAMP_FILL_PATTERN ((uint8_t []){0xcc})

...
for (i = 0; i < size; i+= FILL_SIZE)
    memcpy(addr + i, KINST_TRAMP_FILL_PATTERN, KINST_TRAMP_FILL_SIZE);

or make a macro which does the memset.

christos marked an inline comment as done.
christos edited the summary of this revision. (Show Details)

Make the algorithm endian-agnostic.

Approved.

Consider whether we might want to simply implement kinst_trampoline_fill() once per platform. It's not exactly a lot of code.

sys/cddl/dev/kinst/amd64/kinst_isa.h
24

Note that this won't work when the patchval is longer than one byte.

sys/cddl/dev/kinst/trampoline.c
69

I think this line is too long.

This revision is now accepted and ready to land.May 23 2023, 1:23 PM

Consider whether we might want to simply implement kinst_trampoline_fill() once per platform. It's not exactly a lot of code.

I don't think that's needed. The machine-dependent definitions are already in the kinst_isa.h files of each architecture.

sys/cddl/dev/kinst/amd64/kinst_isa.h
24

This file is machine-dependent. Here are the definitions for RISC-V:

#define KINST_TRAMP_FILL_PATTERN	((uint32_t []){KINST_PATCHVAL})
#define KINST_TRAMP_FILL_SIZE		sizeof(uint32_t)

The ARM64 ones are the same, and it does work.

sys/cddl/dev/kinst/trampoline.c
69

Yeap, I'll split it.

christos marked an inline comment as done.

Split line.

This revision now requires review to proceed.May 23 2023, 1:45 PM

Approved

sys/cddl/dev/kinst/amd64/kinst_isa.h
24

Yep. Ok, fair enough.

This revision is now accepted and ready to land.May 23 2023, 1:51 PM
This revision was automatically updated to reflect the committed changes.