From d1a5d76b1c16ac4f2e386d90926fbce50df2efbd Mon Sep 17 00:00:00 2001 From: Matthew Sotoudeh Date: Sat, 18 May 2024 15:55:38 -0700 Subject: more info on reservation --- imc/checker.c | 2 +- magic_buddy/magic_buddy.c | 8 ++++++-- magic_buddy/magic_buddy.h | 10 +++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/imc/checker.c b/imc/checker.c index a7f62ff..91cdfa8 100644 --- a/imc/checker.c +++ b/imc/checker.c @@ -51,7 +51,7 @@ void check_main() { verbose("Reserving %p -- %p\n", redzone_start, redzone_end); assert(reserve(redzone_start, (uint8_t*)redzone_end - (uint8_t*)redzone_start, - curr_buddy)); + 0, 0, curr_buddy)); } size_t size_options[] = {1, 128, 1024, 5, 167, 10500}; diff --git a/magic_buddy/magic_buddy.c b/magic_buddy/magic_buddy.c index da18d4a..89daaa4 100644 --- a/magic_buddy/magic_buddy.c +++ b/magic_buddy/magic_buddy.c @@ -148,7 +148,8 @@ static struct free_block *rhs_child_of(struct free_block *block, size_t logsize, // NOTE: this method is perhaps more complicated than it needs to be because we // take great pains to avoid writing to the region that is being reserved // (e.g., in case it is device MMIO). -int reserve(void *start, size_t size, struct buddy *state) { +int reserve(void *start, size_t size, void **out_start, size_t *out_size, + struct buddy *state) { // (1) find the first free block to the left of start uint8_t *base = state->base; size_t virtual_start = (uint8_t*)start - base; @@ -169,7 +170,8 @@ int reserve(void *start, size_t size, struct buddy *state) { int needs_zero = 1; size_t min_logsize = size2log(sizeof(struct free_block), 1); pop(block); - for (size_t logsize = block->logsize; logsize > min_logsize;) { + size_t logsize = block->logsize; + while (logsize > min_logsize) { struct free_block *rhs_child = rhs_child_of(block, logsize, state); if ((void*)rhs_child <= start) { // move right block = rhs_child; @@ -183,6 +185,8 @@ int reserve(void *start, size_t size, struct buddy *state) { } } if (needs_zero) memset(block, 0, sizeof(struct free_block)); + if (out_start) *out_start = block; + if (out_size) *out_size = logsize; return 1; } diff --git a/magic_buddy/magic_buddy.h b/magic_buddy/magic_buddy.h index 167397b..3b5e8d0 100644 --- a/magic_buddy/magic_buddy.h +++ b/magic_buddy/magic_buddy.h @@ -42,10 +42,18 @@ void *reallocate(void *old, size_t new_size, size_t old_size, struct buddy *state); // Attempts to reserve a range [@start,@start+@size). +// // Returns 1 if success, 0 otherwise. +// // Whenever possible, we avoid writing anything into the reserved region. +// +// If the reservation succeeds, and @out_start (@out_size) is negative, it puts +// the start (size) of the actually reserved region into *@out_start +// (*@out_size). These can be passed into liberate(...) later to unreserve. +// // O(1) -int reserve(void *start, size_t size, struct buddy *state); +int reserve(void *start, size_t size, void **out_start, size_t *out_size, + struct buddy *state); // Update @state to assume the memory pool has been copied to // [@new_base,@new_base+@new_size) -- cgit v1.2.3