make size of primary CoW buffer configurable
This commit is contained in:
parent
23a408e2cf
commit
c9dac7704d
@ -76,6 +76,7 @@ typedef struct kafl_mem_state {
|
|||||||
|
|
||||||
char* workdir;
|
char* workdir;
|
||||||
uint32_t worker_id;
|
uint32_t worker_id;
|
||||||
|
uint64_t cow_primary_size;
|
||||||
|
|
||||||
char* redqueen_workdir;
|
char* redqueen_workdir;
|
||||||
char* data_bar_fd_0;
|
char* data_bar_fd_0;
|
||||||
@ -354,6 +355,10 @@ static void pci_kafl_guest_realize(DeviceState *dev, Error **errp){
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s->cow_primary_size){
|
||||||
|
set_global_cow_cache_primary_size(s->cow_primary_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (!s->workdir || !verify_workdir_state(s, errp)){
|
if (!s->workdir || !verify_workdir_state(s, errp)){
|
||||||
fprintf(stderr, "Invalid work dir...\n");
|
fprintf(stderr, "Invalid work dir...\n");
|
||||||
abort();
|
abort();
|
||||||
@ -407,6 +412,7 @@ static Property kafl_guest_properties[] = {
|
|||||||
DEFINE_PROP_STRING("workdir", kafl_mem_state, workdir),
|
DEFINE_PROP_STRING("workdir", kafl_mem_state, workdir),
|
||||||
DEFINE_PROP_UINT32("worker_id", kafl_mem_state, worker_id, 0xFFFF),
|
DEFINE_PROP_UINT32("worker_id", kafl_mem_state, worker_id, 0xFFFF),
|
||||||
|
|
||||||
|
DEFINE_PROP_UINT64("cow_primary_size", kafl_mem_state, cow_primary_size, 0),
|
||||||
/*
|
/*
|
||||||
* Since DEFINE_PROP_UINT64 is somehow broken (signed/unsigned madness),
|
* Since DEFINE_PROP_UINT64 is somehow broken (signed/unsigned madness),
|
||||||
* let's use DEFINE_PROP_STRING and post-process all values by strtol...
|
* let's use DEFINE_PROP_STRING and post-process all values by strtol...
|
||||||
|
@ -14,6 +14,20 @@
|
|||||||
//0x200
|
//0x200
|
||||||
#define PAGE_MASK 0xFFFFFFFFFFFFF000
|
#define PAGE_MASK 0xFFFFFFFFFFFFF000
|
||||||
|
|
||||||
|
uint64_t global_cow_primary_size = COW_CACHE_PRIMARY_MINIMUM_SIZE;
|
||||||
|
bool global_cow_primary_size_adjustable = true;
|
||||||
|
|
||||||
|
void set_global_cow_cache_primary_size(uint64_t new_size){
|
||||||
|
if (global_cow_primary_size_adjustable && new_size > COW_CACHE_PRIMARY_MINIMUM_SIZE && (new_size & 0xFFF) == 0){
|
||||||
|
global_cow_primary_size = new_size;
|
||||||
|
global_cow_primary_size_adjustable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint64_t get_global_cow_cache_primary_size(void){
|
||||||
|
return global_cow_primary_size;
|
||||||
|
}
|
||||||
|
|
||||||
cow_cache_t* cow_cache_new(const char* filename){
|
cow_cache_t* cow_cache_new(const char* filename){
|
||||||
|
|
||||||
//printf("%s: \"%s\"\n", __func__, filename);
|
//printf("%s: \"%s\"\n", __func__, filename);
|
||||||
@ -23,9 +37,10 @@ cow_cache_t* cow_cache_new(const char* filename){
|
|||||||
self->lookup_secondary = kh_init(COW_CACHE);
|
self->lookup_secondary = kh_init(COW_CACHE);
|
||||||
self->lookup_secondary_tmp = kh_init(COW_CACHE);
|
self->lookup_secondary_tmp = kh_init(COW_CACHE);
|
||||||
|
|
||||||
self->data_primary = mmap(NULL, COW_CACHE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
self->cow_primary_size = COW_CACHE_PRIMARY_MINIMUM_SIZE;
|
||||||
|
self->data_primary = mmap(NULL, self->cow_primary_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
assert(self->data_primary != MAP_FAILED);
|
assert(self->data_primary != MAP_FAILED);
|
||||||
//memset(self->data_primary, COW_CACHE_SIZE/CHUNK_SIZE, CHUNK_SIZE);
|
//memset(self->data_primary, COW_CACHE_PRIMARY_MINIMUM_SIZE/CHUNK_SIZE, CHUNK_SIZE);
|
||||||
|
|
||||||
self->data_secondary = mmap(NULL, COW_CACHE_SECONDARY_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
self->data_secondary = mmap(NULL, COW_CACHE_SECONDARY_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
assert(self->data_secondary != MAP_FAILED);
|
assert(self->data_secondary != MAP_FAILED);
|
||||||
@ -80,6 +95,7 @@ static char* gen_file_name(cow_cache_t* self, const char* filename_prefix, const
|
|||||||
|
|
||||||
void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool switch_mode){
|
void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool switch_mode){
|
||||||
assert(!self->enabled_fuzz);
|
assert(!self->enabled_fuzz);
|
||||||
|
global_cow_primary_size_adjustable = false;
|
||||||
|
|
||||||
//printf("%s: %s\n", __func__, self->filename);
|
//printf("%s: %s\n", __func__, self->filename);
|
||||||
|
|
||||||
@ -98,6 +114,11 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw
|
|||||||
struct stat buffer;
|
struct stat buffer;
|
||||||
assert(stat (tmp2, &buffer) == 0);
|
assert(stat (tmp2, &buffer) == 0);
|
||||||
|
|
||||||
|
if (buffer.st_size > get_global_cow_cache_primary_size()){
|
||||||
|
fprintf(stderr, "ERROR: in-memory CoW buffer is too small compared to snapshot file (buffer: 0x%lx / file: 0x%lx)\n", get_global_cow_cache_primary_size(), buffer.st_size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if(buffer.st_size){
|
if(buffer.st_size){
|
||||||
self->lookup_primary = kh_load(COW_CACHE, tmp1);
|
self->lookup_primary = kh_load(COW_CACHE, tmp1);
|
||||||
}
|
}
|
||||||
@ -109,14 +130,24 @@ void read_primary_buffer(cow_cache_t* self, const char* filename_prefix, bool sw
|
|||||||
|
|
||||||
//printf("TRY TO MMAP : %lx\n", buffer.st_size);
|
//printf("TRY TO MMAP : %lx\n", buffer.st_size);
|
||||||
if(switch_mode){
|
if(switch_mode){
|
||||||
self->data_primary = mmap(0, COW_CACHE_SIZE, PROT_READ, MAP_SHARED, fd, 0);
|
munmap(self->data_primary, self->cow_primary_size);
|
||||||
|
self->cow_primary_size = get_global_cow_cache_primary_size();
|
||||||
|
self->data_primary = mmap(0, self->cow_primary_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
assert(self->data_primary);
|
assert(self->data_primary);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
void* ptr = mmap(0, COW_CACHE_SIZE, PROT_READ , MAP_SHARED, fd, 0);
|
|
||||||
|
if(get_global_cow_cache_primary_size() != self->cow_primary_size){
|
||||||
|
munmap(self->data_primary, self->cow_primary_size);
|
||||||
|
self->cow_primary_size = get_global_cow_cache_primary_size();
|
||||||
|
self->data_primary = mmap(NULL, self->cow_primary_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||||
|
assert(self->data_primary != MAP_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ptr = mmap(0, COW_CACHE_PRIMARY_MINIMUM_SIZE, PROT_READ , MAP_SHARED, fd, 0);
|
||||||
assert(ptr);
|
assert(ptr);
|
||||||
memcpy(self->data_primary, ptr, buffer.st_size);
|
memcpy(self->data_primary, ptr, buffer.st_size);
|
||||||
munmap(ptr, COW_CACHE_SIZE);
|
munmap(ptr, COW_CACHE_PRIMARY_MINIMUM_SIZE);
|
||||||
}
|
}
|
||||||
//printf("self->data_primary -> %p\n", self->data_primary );
|
//printf("self->data_primary -> %p\n", self->data_primary );
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -395,7 +426,7 @@ static inline void write_to_primary_buffer(cow_cache_t* self, BlockBackend *blk,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IN CASE THE BUFFER IS FULL -> ABORT! */
|
/* IN CASE THE BUFFER IS FULL -> ABORT! */
|
||||||
assert(self->offset_primary < COW_CACHE_SIZE);
|
assert(self->offset_primary < self->cow_primary_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef COW_CACHE_DEBUG
|
#ifdef COW_CACHE_DEBUG
|
||||||
@ -515,8 +546,8 @@ static int cow_cache_write(cow_cache_t* self, BlockBackend *blk, int64_t offset,
|
|||||||
|
|
||||||
void switch_to_fuzz_mode(cow_cache_t* self){
|
void switch_to_fuzz_mode(cow_cache_t* self){
|
||||||
self->enabled_fuzz = true;
|
self->enabled_fuzz = true;
|
||||||
assert(!mprotect(self->data_primary, COW_CACHE_SIZE, PROT_READ));
|
assert(!mprotect(self->data_primary, self->cow_primary_size, PROT_READ));
|
||||||
printf("[qemu-nyx] switch to secondary CoW buffer\n");
|
printf("[qemu-nyx] switching to secondary CoW buffer\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cow_cache_read_entry(void* opaque){
|
void cow_cache_read_entry(void* opaque){
|
||||||
|
@ -12,14 +12,16 @@
|
|||||||
|
|
||||||
//#define DEBUG_COW_LAYER
|
//#define DEBUG_COW_LAYER
|
||||||
|
|
||||||
/* 2GB Cache */
|
/* Minimum size of CoW buffer that stores data written to
|
||||||
//#define COW_CACHE_SIZE 0x80000000
|
* the block device between boot time and root snapshot (3GB)
|
||||||
|
*/
|
||||||
|
#define COW_CACHE_PRIMARY_MINIMUM_SIZE 0xC0000000
|
||||||
|
|
||||||
// 3GB
|
/* Size of CoW buffer which stores data written to
|
||||||
#define COW_CACHE_SIZE 0xC0000000
|
* the block device between the root snapshot and the
|
||||||
|
* next snapshot restore (3GB). This buffer is allocated
|
||||||
// 512MB
|
* twice to store the incremental snapshot delta.
|
||||||
//#define COW_CACHE_SECONDARY_SIZE 0x20000000
|
*/
|
||||||
#define COW_CACHE_SECONDARY_SIZE 0xC0000000
|
#define COW_CACHE_SECONDARY_SIZE 0xC0000000
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +36,8 @@ typedef struct cow_cache_s{
|
|||||||
void* data_secondary;
|
void* data_secondary;
|
||||||
void* data_secondary_tmp;
|
void* data_secondary_tmp;
|
||||||
|
|
||||||
|
uint64_t cow_primary_size;
|
||||||
|
|
||||||
char* filename;
|
char* filename;
|
||||||
uint64_t offset_primary;
|
uint64_t offset_primary;
|
||||||
uint64_t offset_secondary;
|
uint64_t offset_secondary;
|
||||||
@ -70,3 +74,5 @@ void cow_cache_disable(cow_cache_t* self);
|
|||||||
|
|
||||||
void cow_cache_enable_tmp_mode(cow_cache_t* self);
|
void cow_cache_enable_tmp_mode(cow_cache_t* self);
|
||||||
void cow_cache_disable_tmp_mode(cow_cache_t* self);
|
void cow_cache_disable_tmp_mode(cow_cache_t* self);
|
||||||
|
|
||||||
|
void set_global_cow_cache_primary_size(uint64_t new_size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user