Add testcases for #PF handling
This commit is contained in:
		
							parent
							
								
									f280a9c382
								
							
						
					
					
						commit
						6da887d069
					
				| @ -1,5 +1,5 @@ | |||||||
| include ../test_common.mk | include ../test_common.mk | ||||||
| 
 | 
 | ||||||
| EXTRA_C_FLAGS := -Wno-return-stack-address | EXTRA_C_FLAGS := -Wno-return-stack-address -g | ||||||
| EXTRA_LINK_FLAGS := -lpthread | EXTRA_LINK_FLAGS := -lpthread | ||||||
| BIN_ARGS := | 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; |     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; | static size_t HINT_BEGIN, HINT_END; | ||||||
| 
 | 
 | ||||||
| int test_suite_init() { | 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); |     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
 | // Test suite main
 | ||||||
| // ============================================================================
 | // ============================================================================
 | ||||||
| @ -1464,6 +1583,9 @@ static test_case_t test_cases[] = { | |||||||
|     TEST_CASE(test_mprotect_multiple_vmas), |     TEST_CASE(test_mprotect_multiple_vmas), | ||||||
|     TEST_CASE(test_mprotect_grow_down), |     TEST_CASE(test_mprotect_grow_down), | ||||||
|     TEST_CASE(test_mremap_concurrent), |     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() { | int main() { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user