aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-08-21 23:31:48 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-08-21 23:31:48 +0300
commit97ffab0a8472981b927d0f4e81bb72f6ecd69b86 (patch)
treec8a36352d599dc9477a6e647878d5e6191b4e98f
parentab011165cd440b5535d39febd8118e3e26b64b57 (diff)
downloadkmi-97ffab0a8472981b927d0f4e81bb72f6ecd69b86.tar.gz
kmi-97ffab0a8472981b927d0f4e81bb72f6ecd69b86.zip
add malloc test
-rw-r--r--include/kmi/attrs.h2
-rw-r--r--src/pmem.c15
-rw-r--r--src/regions.c5
-rw-r--r--src/sp_tree.c14
-rw-r--r--src/uapi/dispatch.c1
-rw-r--r--src/uapi/ipc.c2
-rw-r--r--tests/malloc/check.mk4
-rw-r--r--tests/malloc/init.c42
-rw-r--r--tests/malloc/source.mk2
-rw-r--r--tests/scripts/makefile1
10 files changed, 75 insertions, 13 deletions
diff --git a/include/kmi/attrs.h b/include/kmi/attrs.h
index f789310..56aca34 100644
--- a/include/kmi/attrs.h
+++ b/include/kmi/attrs.h
@@ -50,6 +50,8 @@
/** Don't inline function. */
#define __noinline __attribute__((noinline))
+#define __inline inline __attribute__((always_inline))
+
/** Function should not return. */
#define __noreturn __attribute__((noreturn))
diff --git a/src/pmem.c b/src/pmem.c
index 47bb319..e2177ea 100644
--- a/src/pmem.c
+++ b/src/pmem.c
@@ -111,7 +111,9 @@ static pm_t __zero_if(bool populate, pm_t cont, size_t size)
*/
static size_t __get_set_size(struct mm_bucket *bucket)
{
- return sizeof(bucket->bmap[0]) + bucket->bits / 8;
+ return align_up(sizeof(bucket->bmap[0])
+ + (bucket->bits + 1) / sizeof(void *),
+ sizeof(void *));
}
/**
@@ -149,7 +151,7 @@ static size_t __get_set_index(struct mm_bucket *bucket, struct mm_bmap *bmap)
static void __attach_set(struct mm_bucket *bucket, struct mm_bmap *bmap)
{
/* already attached */
- if (bmap->next)
+ if (bmap->next || bucket->head == bmap)
return;
bmap->next = bucket->head;
@@ -174,6 +176,9 @@ static void __detach_set(struct mm_bucket *bucket, struct mm_bmap *bmap)
if (bmap->prev)
bmap->prev->next = bmap->next;
+
+ bmap->next = NULL;
+ bmap->prev = NULL;
}
/**
@@ -271,6 +276,8 @@ static pm_t __alloc_page(enum mm_order order)
__get_bit(bucket, a, &set, &bit);
bmap = __get_set(bucket, set);
+ bmap->next = NULL;
+ bmap->prev = NULL;
bmap->used = 0;
bitmap_clear_all(bmap->bits, bmap->size);
__attach_set(bucket, bmap);
@@ -376,7 +383,9 @@ static pm_t __maybe_populate_bucket(size_t n, pm_t cont, enum mm_order order,
bucket->head = NULL;
}
- size_t set_size = sizeof(struct mm_bmap) + bits / 8;
+ size_t set_size = align_up(sizeof(struct mm_bmap)
+ + (bits + 1) / sizeof(void *),
+ sizeof(void *));
cont += sizeof(struct mm_bucket);
diff --git a/src/regions.c b/src/regions.c
index 9849ba8..fcfa0cc 100644
--- a/src/regions.c
+++ b/src/regions.c
@@ -85,8 +85,9 @@ static void free_mem_node(struct mem_region *m)
* @param m Free memory region to insert.
* @return \c m.
*/
-static struct mem_region *__insert_free_region(struct mem_region_root *r,
- struct mem_region *m)
+static __inline struct mem_region *__insert_free_region(
+ struct mem_region_root *r,
+ struct mem_region *m)
{
/* this could be simplified by using my gsptrees in kmx, but at least
* this ensures 'inlining' of the condition checking so I'll let it stay
diff --git a/src/sp_tree.c b/src/sp_tree.c
index 5166cc3..0c5b3c4 100644
--- a/src/sp_tree.c
+++ b/src/sp_tree.c
@@ -21,7 +21,7 @@
*
* @param n Node to turn left.
*/
-static void __sp_turn_left(struct sp_node *n)
+static __inline void __sp_turn_left(struct sp_node *n)
{
struct sp_node *l = sp_left(n);
struct sp_node *p = sp_paren(n);
@@ -51,7 +51,7 @@ static void __sp_turn_left(struct sp_node *n)
*
* @param n Node to turn right.
*/
-static void __sp_turn_right(struct sp_node *n)
+static __inline void __sp_turn_right(struct sp_node *n)
{
struct sp_node *r = sp_right(n);
struct sp_node *p = sp_paren(n);
@@ -78,7 +78,7 @@ static void __sp_turn_right(struct sp_node *n)
* @param n Node to calculate balance for.
* @return Balance of node.
*/
-static int_fast16_t __sp_balance(struct sp_node *n)
+static __inline int_fast16_t __sp_balance(struct sp_node *n)
{
int_fast16_t l = 0;
int_fast16_t r = 0;
@@ -98,7 +98,7 @@ static int_fast16_t __sp_balance(struct sp_node *n)
* @param n Node to calculate highest hint for.
* @return Highest hint.
*/
-static int_fast16_t __sp_max_hint(struct sp_node *n)
+static __inline int_fast16_t __sp_max_hint(struct sp_node *n)
{
int_fast16_t l = 0;
int_fast16_t r = 0;
@@ -121,7 +121,7 @@ static int_fast16_t __sp_max_hint(struct sp_node *n)
* @param root Root of tree.
* @param n Node to start balancing operation from.
*/
-static void __sp_update(struct sp_node **root, struct sp_node *n)
+static __inline void __sp_update(struct sp_node **root, struct sp_node *n)
{
while (n) {
int b = __sp_balance(n);
@@ -175,7 +175,7 @@ void sp_insert(struct sp_node **root, struct sp_node *p, struct sp_node *n,
* @param n Node to replace.
* @param r Node to replace with.
*/
-static void __sp_replace_right(struct sp_node *n, struct sp_node *r)
+static __inline void __sp_replace_right(struct sp_node *n, struct sp_node *r)
{
struct sp_node *p = sp_paren(n);
struct sp_node *rp = sp_paren(r);
@@ -212,7 +212,7 @@ static void __sp_replace_right(struct sp_node *n, struct sp_node *r)
* @param n Node to replace.
* @param l Node to replace with.
*/
-static void __sp_replace_left(struct sp_node *n, struct sp_node *l)
+static __inline void __sp_replace_left(struct sp_node *n, struct sp_node *l)
{
struct sp_node *p = sp_paren(n);
struct sp_node *lp = sp_paren(l);
diff --git a/src/uapi/dispatch.c b/src/uapi/dispatch.c
index 5e29922..ad53536 100644
--- a/src/uapi/dispatch.c
+++ b/src/uapi/dispatch.c
@@ -93,5 +93,6 @@ void handle_syscall(sys_arg_t syscall, sys_arg_t a, sys_arg_t b,
if (check_canary(t)) {
bug("Syscall %zu overwrote stack canary\n", syscall);
+ set_canary(t);
}
}
diff --git a/src/uapi/ipc.c b/src/uapi/ipc.c
index 71dae83..4a5a6d9 100644
--- a/src/uapi/ipc.c
+++ b/src/uapi/ipc.c
@@ -85,7 +85,7 @@ static inline void finalize_rpc(struct tcb *t, struct tcb *r, vm_t s)
* @return RPC stack difference that should be passed to finalize_rpc().
*/
static inline vm_t enter_rpc(struct tcb *t, struct sys_ret a,
- enum ipc_flags flags)
+ enum ipc_flags flags)
{
/* reuse current rpc stack location if we're being kicked */
vm_t rpc_stack = (is_set(flags, IPC_TAIL) &&
diff --git a/tests/malloc/check.mk b/tests/malloc/check.mk
new file mode 100644
index 0000000..3a178cb
--- /dev/null
+++ b/tests/malloc/check.mk
@@ -0,0 +1,4 @@
+malloc: do-malloc
+ @grep 'BUG' reports/malloc/log \
+ && echo 'BUG' > reports/malloc/OK \
+ || tail -n1 reports/malloc/log | tr -d '\r' > reports/malloc/OK
diff --git a/tests/malloc/init.c b/tests/malloc/init.c
new file mode 100644
index 0000000..5048e82
--- /dev/null
+++ b/tests/malloc/init.c
@@ -0,0 +1,42 @@
+#include <common/test.h>
+
+START(pid, tid, d0, d1, d2, d3)
+{
+ UNUSED(pid);
+ UNUSED(tid);
+ UNUSED(d0);
+ UNUSED(d1);
+ UNUSED(d2);
+ UNUSED(d3);
+
+ printf("allocating space for pointers...\n");
+ /* 12 MiB / 4K */
+ void **allocs = sys_req_mem(200 * sizeof(void *), VM_W | VM_R);
+ check(allocs, "initial allocation failed\n");
+
+ printf("allocating memory until we run out...\n");
+
+ long i = 0;
+ while (1) {
+ char *p = sys_req_mem(1, VM_W | VM_R);
+ if (!p)
+ break;
+
+ /* check that we actually got a page */
+ *p = 'a';
+ allocs[i++] = p;
+ }
+
+ printf("ran out of memory, freeing...\n");
+ for (; i >= 0; --i)
+ sys_free_mem((uintptr_t)allocs[i]);
+
+ printf("freed all memory, doing one last allocation to check we're good...\n");
+ /* not super exhaustive but would hopefully go haywire if the page
+ * allocator got corrupted or something */
+ char *p = sys_req_mem(1, VM_W | VM_R);
+ *p = 'b';
+ sys_free_mem((uintptr_t)p);
+ sys_free_mem((uintptr_t)allocs);
+ ok();
+}
diff --git a/tests/malloc/source.mk b/tests/malloc/source.mk
new file mode 100644
index 0000000..9498682
--- /dev/null
+++ b/tests/malloc/source.mk
@@ -0,0 +1,2 @@
+DO != ./scripts/gen-prog -n malloc -p init init.c
+DO != ./scripts/gen-simple -n malloc -p init
diff --git a/tests/scripts/makefile b/tests/scripts/makefile
index 8079c3c..530e0bb 100644
--- a/tests/scripts/makefile
+++ b/tests/scripts/makefile
@@ -20,6 +20,7 @@ QEMU := qemu-system-$(ARCH) -machine virt -kernel ../kmi.bin \
-monitor none \
-nographic \
-no-reboot \
+ -m 128M \
-initrd
KMI := ../kmi.bin