Add testcases for #PF handling
This commit is contained in:
		
							parent
							
								
									f280a9c382
								
							
						
					
					
						commit
						6da887d069
					
				| @ -1,5 +1,5 @@ | ||||
| include ../test_common.mk | ||||
| 
 | ||||
| EXTRA_C_FLAGS := -Wno-return-stack-address | ||||
| EXTRA_C_FLAGS := -Wno-return-stack-address -g | ||||
| EXTRA_LINK_FLAGS := -lpthread | ||||
| BIN_ARGS := | ||||
|  | ||||
							
								
								
									
										122
									
								
								test/mmap/main.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										122
									
								
								test/mmap/main.c
									
									
									
									
									
								
							| @ -62,6 +62,28 @@ static int get_a_valid_range_of_hints(size_t *hint_begin, size_t *hint_end) { | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static int create_random_file(char *path, size_t size) { | ||||
|     FILE *myFile = fopen(path, "w"); | ||||
|     FILE *urandom = fopen("/dev/urandom", "r"); | ||||
|     const size_t unit_size = 256 * 1024; | ||||
|     size_t write_len = 0; | ||||
| 
 | ||||
|     char *tmp = calloc(1, unit_size); | ||||
|     while (write_len < size) { | ||||
|         int write_once_len = unit_size; | ||||
|         if (size - write_len < unit_size) { | ||||
|             write_once_len = size - write_len; | ||||
|         } | ||||
|         size_t ret = fread(tmp, 1, write_once_len, urandom); | ||||
|         fwrite(tmp, 1, ret, myFile); | ||||
|         write_len += write_once_len; | ||||
|     } | ||||
| 
 | ||||
|     fclose(myFile); | ||||
|     fclose(urandom); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static size_t HINT_BEGIN, HINT_END; | ||||
| 
 | ||||
| int test_suite_init() { | ||||
| @ -1417,6 +1439,103 @@ int test_file_backed_mremap_mem_may_move() { | ||||
|     return _test_file_backed_mremap(file_backed_mremap_mem_may_move); | ||||
| } | ||||
| 
 | ||||
| int test_random_mmap_file() { | ||||
|     char *test_buf = calloc(1, 1024); | ||||
| 
 | ||||
|     char *file_path = "/root/myfile"; | ||||
|     const size_t file_len = 4 * 1024 * 1024; //4M
 | ||||
|     create_random_file(file_path, file_len); | ||||
| 
 | ||||
|     int fd = open(file_path, O_RDWR, 0600); | ||||
|     if (fd < 0) { | ||||
|         THROW_ERROR("open file error"); | ||||
|     } | ||||
| 
 | ||||
|     int ret = pread(fd, test_buf, 1024, PAGE_SIZE * 4); | ||||
|     if (ret != 1024) { | ||||
|         THROW_ERROR("read failed"); | ||||
|     } | ||||
| 
 | ||||
|     // Allocate in the new chunk. So that the access can trigger PF.
 | ||||
|     size_t desired_addr = HINT_BEGIN + DEFAULT_CHUNK_SIZE; | ||||
|     char *file = mmap((void *)desired_addr, file_len, PROT_READ, MAP_PRIVATE, fd, 0); | ||||
|     if ((size_t)file != desired_addr) { | ||||
|         THROW_ERROR("mmap with desired addr failed"); | ||||
|     } | ||||
| 
 | ||||
|     int offset = 1 * PAGE_SIZE; | ||||
|     void *addr = mmap((void *)(file + offset), 4096, PROT_READ | PROT_EXEC, | ||||
|                       MAP_PRIVATE | MAP_FIXED, fd, offset); | ||||
|     if (addr != file + offset) { | ||||
|         THROW_ERROR("mmap with desired addr failed"); | ||||
|     } | ||||
| 
 | ||||
|     offset =  2 * PAGE_SIZE; | ||||
|     addr = mmap(file + offset, 8192, PROT_READ, MAP_FIXED | MAP_PRIVATE, fd, offset); | ||||
|     if (addr != file + offset) { | ||||
|         THROW_ERROR("mmap with desired addr failed"); | ||||
|     } | ||||
| 
 | ||||
|     offset = 4 * PAGE_SIZE; | ||||
|     addr = mmap(file + offset, 8192 * 2, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fd, | ||||
|                 offset); | ||||
|     if (addr != file + offset) { | ||||
|         THROW_ERROR("mmap with desired addr failed"); | ||||
|     } | ||||
| 
 | ||||
|     if (memcmp(test_buf + 512, addr + 512, 512) != 0 ) { | ||||
|         THROW_ERROR("content mismatch"); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int test_user_space_pf_trigger() { | ||||
|     size_t total_len = 4 * PAGE_SIZE; | ||||
|     size_t magic_length = 100 * MB;     // Used to find a uncommitted memory
 | ||||
|     int init_prot = PROT_READ | PROT_EXEC; | ||||
|     void *buf = mmap((void *)(HINT_END + magic_length), total_len, init_prot, | ||||
|                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
|     if (buf == MAP_FAILED) { | ||||
|         THROW_ERROR("mmap failed"); | ||||
|     } | ||||
|     // Trigger PF by read
 | ||||
|     char test = ((char *)buf)[0]; | ||||
|     if (test != 0) { | ||||
|         THROW_ERROR("check test valure failed"); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| int test_kernel_space_pf_trigger() { | ||||
|     size_t total_len = 4 * PAGE_SIZE; | ||||
|     size_t magic_length = 200 * MB;     // Used to find a uncommitted memory
 | ||||
|     int init_prot = PROT_READ | PROT_WRITE; | ||||
|     void *buf = mmap((void *)(HINT_END + magic_length), total_len, init_prot, | ||||
|                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
|     if (buf == MAP_FAILED) { | ||||
|         THROW_ERROR("mmap failed"); | ||||
|     } | ||||
| 
 | ||||
|     char *file_path = "/root/test-file"; | ||||
|     const size_t file_len = total_len * 2; | ||||
|     create_random_file(file_path, file_len); | ||||
| 
 | ||||
|     int fd = open(file_path, O_RDWR, 0600); | ||||
|     if (fd < 0) { | ||||
|         THROW_ERROR("open file error"); | ||||
|     } | ||||
| 
 | ||||
|     // Read to uncommitted memory will trigger #PF and handled by the kernel
 | ||||
|     int ret = pread(fd, buf, total_len, 1024); | ||||
|     if (ret != total_len) { | ||||
|         THROW_ERROR("read failed"); | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| // ============================================================================
 | ||||
| // Test suite main
 | ||||
| // ============================================================================
 | ||||
| @ -1464,6 +1583,9 @@ static test_case_t test_cases[] = { | ||||
|     TEST_CASE(test_mprotect_multiple_vmas), | ||||
|     TEST_CASE(test_mprotect_grow_down), | ||||
|     TEST_CASE(test_mremap_concurrent), | ||||
|     TEST_CASE(test_random_mmap_file), | ||||
|     TEST_CASE(test_user_space_pf_trigger), | ||||
|     TEST_CASE(test_kernel_space_pf_trigger), | ||||
| }; | ||||
| 
 | ||||
| int main() { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user