Skip to content

Commit

Permalink
Fixes to memory derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
Henrik Karlsson committed Mar 30, 2023
1 parent 2ccea83 commit c0b7800
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 27 deletions.
8 changes: 6 additions & 2 deletions api/s3k-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ bool s3k_memory_parent(union s3k_cap parent, union s3k_cap child)
if (parent.type == S3K_CAPTY_MEMORY && child.type == S3K_CAPTY_MEMORY) {
return parent.memory.offset == child.memory.offset
&& parent.memory.begin <= child.memory.begin
&& child.memory.end <= parent.memory.end;
&& child.memory.end <= parent.memory.end
&& ((parent.memory.rwx & child.memory.rwx)
== child.memory.rwx);
}
if (parent.type == S3K_CAPTY_MEMORY && child.type == S3K_CAPTY_PMP) {
uint64_t pmp_begin = s3k_pmp_napot_begin(child.pmp.addr);
Expand Down Expand Up @@ -145,7 +147,9 @@ bool s3k_memory_derive(union s3k_cap parent, union s3k_cap child)
return parent.memory.offset == child.memory.offset
&& parent.memory.free == child.memory.begin
&& parent.memory.free == child.memory.free
&& child.memory.end <= parent.memory.end;
&& child.memory.end <= parent.memory.end
&& ((parent.memory.rwx & child.memory.rwx)
== child.memory.rwx);
}
if (parent.type == S3K_CAPTY_MEMORY && child.type == S3K_CAPTY_PMP) {
uint64_t pmp_begin = s3k_pmp_napot_begin(child.pmp.addr);
Expand Down
8 changes: 6 additions & 2 deletions src/cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ bool cap_memory_parent(union cap parent, union cap child)
if (parent.type == CAPTY_MEMORY && child.type == CAPTY_MEMORY) {
return parent.memory.offset == child.memory.offset
&& parent.memory.begin <= child.memory.begin
&& child.memory.end <= parent.memory.end;
&& child.memory.end <= parent.memory.end
&& ((parent.memory.rwx & child.memory.rwx)
== child.memory.rwx);
}
if (parent.type == CAPTY_MEMORY && child.type == CAPTY_PMP) {
uint64_t pmp_begin = pmp_napot_begin(child.pmp.addr);
Expand Down Expand Up @@ -82,7 +84,9 @@ bool cap_memory_derive(union cap parent, union cap child)
return parent.memory.offset == child.memory.offset
&& parent.memory.free == child.memory.begin
&& parent.memory.free == child.memory.free
&& child.memory.end <= parent.memory.end;
&& child.memory.end <= parent.memory.end
&& ((parent.memory.rwx & child.memory.rwx)
== child.memory.rwx);
}
if (parent.type == CAPTY_MEMORY && child.type == CAPTY_PMP) {
uint64_t pmp_begin = pmp_napot_begin(child.pmp.addr);
Expand Down
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
$(info Unit tests requires Google Test to be installed)
vpath %.c ../src
SRCS=cap.c cnode.c exception.c ticket_lock.c proc.c schedule.c syscall.c \
syscall_lock.c syscall_monitor.c syscall_ipc.c mockup.c
syscall_lock.c syscall_monitor.c syscall_ipc.c mockup.c ../api/s3k-utils.c
TEST_SRCS=$(wildcard test_*.C)

OBJS=$(patsubst %.c,obj/%.o, $(SRCS))
Expand Down
118 changes: 118 additions & 0 deletions test/test_api.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
extern "C" {
#include "../api/s3k.h"
#include "cap.h"
}
#include <gtest/gtest.h>

namespace
{
class ApiTest : public ::testing::Test
{
protected:
ApiTest()
{
}

~ApiTest() override
{
}

void SetUp() override
{
}

void TearDown() override
{
}

unsigned long long llrand()
{
unsigned long long r = 0;

for (int i = 0; i < 5; ++i) {
r = (r << 15) | (rand() & 0x7FFF);
}

return r & 0xFFFFFFFFFFFFFFFFULL;
}
};
} // namespace

TEST_F(ApiTest, TimeCap)
{
union cap cap;
union s3k_cap s3k_cap;
// Test if time capabilities match
for (int i = 0; i < 100; ++i) {
uint64_t begin = llrand();
uint64_t end = llrand();
uint64_t hartid = llrand();
cap = CAP_TIME(hartid, begin, end);
s3k_cap = s3k_time(hartid, begin, end);
ASSERT_EQ(cap.raw, s3k_cap.raw);
}
}

TEST_F(ApiTest, TimeParent)
{
union cap cap, cap_child;
union s3k_cap s3k_cap, s3k_cap_child;

// Test if parent predicate match
int children = 0;
while (children < 120) {
uint64_t raw1 = llrand();
uint64_t raw2 = llrand();
cap.raw = raw1;
cap_child.raw = raw2;
s3k_cap.raw = raw1;
s3k_cap_child.raw = raw2;
ASSERT_EQ(cap_time_parent(cap, cap_child),
s3k_time_parent(s3k_cap, s3k_cap_child));
if (cap_time_parent(cap, cap_child))
children++;
}
}

TEST_F(ApiTest, MemoryCap)
{
// Test if memory capabilities match
union cap cap;
union s3k_cap s3k_cap;
for (int i = 0; i < 100; ++i) {
uint64_t begin = llrand() % 0x8001;
uint64_t end = llrand() % 0x8001;
uint64_t free = llrand() % 0x8001;
uint64_t offset = llrand();
uint64_t rwx = llrand();
uint64_t lock = llrand();
cap = CAP_MEMORY(begin, end, offset, rwx);
cap.memory.lock = lock;
cap.memory.free = free;
s3k_cap = s3k_memory(begin, end, offset, rwx);
s3k_cap.memory.lock = lock;
s3k_cap.memory.free = free;
ASSERT_EQ(cap.raw, s3k_cap.raw);
}
}

TEST_F(ApiTest, MemoryParent)
{
// Test if memory capabilities match
union cap cap, cap_child;
union s3k_cap s3k_cap, s3k_cap_child;
// Test if parent predicate match
int children = 0;
while (children < 120) {
uint64_t raw1 = llrand();
uint64_t raw2 = llrand();
cap.raw = raw1;
cap_child.raw = raw2;
s3k_cap.raw = raw1;
s3k_cap_child.raw = raw2;
ASSERT_EQ(cap_memory_parent(cap, cap_child),
s3k_memory_parent(s3k_cap, s3k_cap_child));
if (cap_memory_parent(cap, cap_child))
children++;
}
}
38 changes: 16 additions & 22 deletions test/test_cap.C
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
extern "C" {
#include "../api/s3k-utils.c"
#include "../api/s3k.h"
#include "cap.h"
}
#include <gtest/gtest.h>
Expand Down Expand Up @@ -160,6 +160,21 @@ TEST_F(CapTest, MemoryDerive)
// OFFSET NOT EQ
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x100, 0x200, 8, CAP_RWX),
CAP_MEMORY(0x100, 0x200, 7, CAP_RWX)));
// Bad permissions
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_R),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RW)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_R),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RWX)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_R),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RX)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_RW),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RWX)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_RW),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RX)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_RX),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RWX)));
EXPECT_FALSE(cap_memory_derive(CAP_MEMORY(0x0, 0x3000, 8, CAP_RX),
CAP_MEMORY(0x0, 0x2000, 8, CAP_RW)));
}

TEST_F(CapTest, PmpAddr)
Expand All @@ -173,24 +188,3 @@ TEST_F(CapTest, PmpAddr)
EXPECT_EQ(0x210000, pmp_napot_begin(0x85fff));
EXPECT_EQ(0x220000, pmp_napot_end(0x85fff));
}

TEST_F(CapTest, MatchAPICap)
{
union cap cap;
union s3k_cap s3k_cap;
cap = CAP_TIME(0x1, 0x1, 0x20);
s3k_cap = s3k_time(0x1, 0x1, 0x20);
EXPECT_EQ(cap.raw, s3k_cap.raw);

cap = CAP_MEMORY(0x100, 0x200, 0x3, CAP_RWX);
s3k_cap = s3k_memory(0x100, 0x200, 0x3, CAP_RWX);
EXPECT_EQ(cap.raw, s3k_cap.raw);

cap = CAP_PMP(0x100, CAP_RWX);
s3k_cap = s3k_pmp(0x100, CAP_RWX);
EXPECT_EQ(cap.raw, s3k_cap.raw);

cap = CAP_MONITOR(0x1, 0x10);
s3k_cap = s3k_monitor(0x1, 0x10);
EXPECT_EQ(cap.raw, s3k_cap.raw);
}

0 comments on commit c0b7800

Please sign in to comment.