@ -84,6 +84,9 @@ static MemoryRegion io_mem_unassigned;
*/
# define RAM_RESIZEABLE (1 << 2)
/* An extra page is mapped on top of this RAM.
*/
# define RAM_EXTRA (1 << 3)
# endif
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER ( cpus ) ;
@ -1185,10 +1188,13 @@ static void *file_ram_alloc(RAMBlock *block,
char * filename ;
char * sanitized_name ;
char * c ;
void * ptr ;
void * area = NULL ;
int fd ;
uint64_t hpagesize ;
uint64_t total ;
Error * local_err = NULL ;
size_t offset ;
hpagesize = gethugepagesize ( path , & local_err ) ;
if ( local_err ) {
@ -1232,6 +1238,7 @@ static void *file_ram_alloc(RAMBlock *block,
g_free ( filename ) ;
memory = ROUND_UP ( memory , hpagesize ) ;
total = memory + hpagesize ;
/*
* ftruncate is not supported by hugetlbfs in older
@ -1243,16 +1250,40 @@ static void *file_ram_alloc(RAMBlock *block,
perror ( " ftruncate " ) ;
}
area = mmap ( 0 , memory , PROT_READ | PROT_WRITE ,
( block - > flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE ) ,
ptr = mmap ( 0 , total , PROT_NONE , MAP_PRIVATE | MAP_ANONYMOUS ,
- 1 , 0 ) ;
if ( ptr = = MAP_FAILED ) {
error_setg_errno ( errp , errno ,
" unable to allocate memory range for hugepages " ) ;
close ( fd ) ;
goto error ;
}
offset = QEMU_ALIGN_UP ( ( uintptr_t ) ptr , hpagesize ) - ( uintptr_t ) ptr ;
area = mmap ( ptr + offset , memory , PROT_READ | PROT_WRITE ,
( block - > flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE ) |
MAP_FIXED ,
fd , 0 ) ;
if ( area = = MAP_FAILED ) {
error_setg_errno ( errp , errno ,
" unable to map backing store for hugepages " ) ;
munmap ( ptr , total ) ;
close ( fd ) ;
goto error ;
}
if ( offset > 0 ) {
munmap ( ptr , offset ) ;
}
ptr + = offset ;
total - = offset ;
if ( total > memory + getpagesize ( ) ) {
munmap ( ptr + memory + getpagesize ( ) ,
total - memory - getpagesize ( ) ) ;
}
if ( mem_prealloc ) {
os_mem_prealloc ( fd , area , memory ) ;
}
@ -1570,6 +1601,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
new_block - > used_length = size ;
new_block - > max_length = size ;
new_block - > flags = share ? RAM_SHARED : 0 ;
new_block - > flags | = RAM_EXTRA ;
new_block - > host = file_ram_alloc ( new_block , size ,
mem_path , errp ) ;
if ( ! new_block - > host ) {
@ -1671,7 +1703,11 @@ static void reclaim_ramblock(RAMBlock *block)
xen_invalidate_map_cache_entry ( block - > host ) ;
# ifndef _WIN32
} else if ( block - > fd > = 0 ) {
munmap ( block - > host , block - > max_length ) ;
if ( block - > flags & RAM_EXTRA ) {
munmap ( block - > host , block - > max_length + getpagesize ( ) ) ;
} else {
munmap ( block - > host , block - > max_length ) ;
}
close ( block - > fd ) ;
# endif
} else {